Allow bootability

Passed as arg to write(), on by default.
This commit is contained in:
Elliot Nunn 2018-11-05 23:24:17 +08:00
parent bef9d1be1b
commit 240a746ab9
1 changed files with 19 additions and 7 deletions

View File

@ -1,5 +1,5 @@
import struct
from macresources import Resource, make_file
from macresources import Resource, make_file, parse_file
from . import btree, bitmanip, directory
@ -143,13 +143,10 @@ class Volume(directory.AbstractFolder):
def __init__(self):
super().__init__()
self.bootblocks = bytes(1024) # optional; for booting HFS volumes
self.crdate = self.mddate = self.bkdate = 0
self.name = 'Untitled'
def read(self, from_volume):
self.bootblocks = from_volume[:1024]
drSigWord, drCrDate, drLsMod, drAtrb, drNmFls, \
drVBMSt, drAllocPtr, drNmAlBlks, drAlBlkSiz, drClpSiz, drAlBlSt, \
drNxtCNID, drFreeBks, drVN, drVolBkUp, drVSeqNum, \
@ -247,7 +244,7 @@ class Volume(directory.AbstractFolder):
self.pop('Desktop DB', None)
self.pop('Desktop DF', None)
def write(self, size=800*1024, align=512, desktopdb=True):
def write(self, size=800*1024, align=512, desktopdb=True, bootable=True):
if align < 512 or align % 512:
raise ValueError('align must be multiple of 512')
@ -331,6 +328,10 @@ class Volume(directory.AbstractFolder):
wrap.path = path
wrap.cnid = drNxtCNID; drNxtCNID += 1
if isinstance(obj, File) and (obj.type, obj.creator) == (b'ZSYS', b'MACS'):
systemfolder = path2wrap[path[:-1]].cnid
systemfile = wrap
if isinstance(obj, File):
wrap.dfrk = wrap.rfrk = (0, 0)
if obj.data:
@ -423,6 +424,17 @@ class Volume(directory.AbstractFolder):
# Create the bitmap of free volume allocation blocks
bitmap = bitmanip.bits(bitmap_blk_cnt * 512 * 8, len(blkaccum))
# Create the boot blocks
try:
if bootable:
sysresources = parse_file(systemfile.of.rsrc)
boot1 = next(r for r in sysresources if (r.type, r.id) == (b'boot', 1))
bootblocks = boot1.data
if len(bootblocks) != 1024: raise ValueError
except:
bootblocks = bytes(1024)
systemfolder = 0
# Create the Volume Information Block
drSigWord = b'BD'
drNmFls = sum(isinstance(x, File) for x in self.values())
@ -437,7 +449,7 @@ class Volume(directory.AbstractFolder):
drAtrb = 1<<8 # volume attributes (hwlock, swlock, CLEANUNMOUNT, badblocks)
drVolBkUp = 0 # date and time of last backup
drVSeqNum = 0 # volume backup sequence number
drFndrInfo = bytes(32) # information used by the Finder
drFndrInfo = struct.pack('>L28x', systemfolder)
drCrDate, drLsMod, drVolBkUp = self.crdate, self.mddate, self.bkdate
vib = struct.pack('>2sLLHHHHHLLHLH28pLHLLLHLL32sHHHLHHxxxxxxxxLHHxxxxxxxx',
@ -452,7 +464,7 @@ class Volume(directory.AbstractFolder):
vib += bytes(512-len(vib))
assert all(len(x) == drAlBlkSiz for x in blkaccum)
finalchunks = [self.bootblocks, vib, bitmap, *blkaccum]
finalchunks = [bootblocks, vib, bitmap, *blkaccum]
finalchunks.append(bytes(size - sum(len(x) for x in finalchunks) - 2*512))
finalchunks.append(vib)
finalchunks.append(bytes(512))