def gen(self): block = b'' block += b'IVFC' block += pk_u32(0x20000) block += pk_u32(self.master_hash_size) block += pk_u32(self.IVFC_MAX_LEVEL + 1) # Nb of levels block += b''.join(lvl.gen() for lvl in self.lvls) block += 0x20 * b'\0' block += self.master_hash block += 0x58 * b'\0' return block
def add(self, entry, entry_table): assert isinstance(entry, DirEntry) or isinstance( entry, FileEntry), 'Invalid entry type' index = entry.hash % self.entry_count if self.data[index] != ROMFS_ENTRY_EMPTY: entry_table.data[-1]['PreviousHash'] = self.data[index] self.data[index] = pk_u32(entry.offsets['Self'])
def gen(self): from math import log2 lvl = b'' lvl += pk_u64(self.offset) lvl += pk_u64(self.size) lvl += pk_u32(int(log2(self.block_size))) lvl += 0x4 * b'\0' return lvl
def add(self, entry): assert isinstance(entry, self.entry_type), 'Invalid entry type' if (len(self.data) <= self.entry_nb) and (self.entry_type is DirEntry): self.data.append({ 'Parent': pk_u32(entry.offsets['Parent']), 'Sibling': pk_u32(entry.offsets['Sibling']), 'Child': pk_u32(entry.offsets['Child']), 'File': pk_u32(entry.offsets['File']), 'PreviousHash': pk_u32(ROMFS_ENTRY_EMPTY), 'NameLength': pk_u32(len(entry.name)), 'Name': pad_to(entry.name.encode(), multiple=4) }) elif len(self.data) <= self.entry_nb: self.data.append({ 'Parent': pk_u32(entry.offsets['Parent']), 'Sibling': pk_u32(entry.offsets['Sibling']), 'DataOffset': pk_u64(entry.offsets['Data']), 'Size': pk_u64(entry.offsets['Size']), 'PreviousHash': pk_u32(ROMFS_ENTRY_EMPTY), 'NameLength': pk_u32(len(entry.name)), 'Name': pad_to(entry.name.encode(), multiple=4) }) else: raise ValueError('Table is already filled up')
def gen(self): table = b'' table += pk_u32(self.start_offset / self.MEDIA_SIZE) table += pk_u32(self.end_offset / self.MEDIA_SIZE) table += 0x8 * b'\xFF' return table
def __init__(self, entry_count): self.entry_count = entry_count self.data = entry_count * [pk_u32(ROMFS_ENTRY_EMPTY)]