class Zip64CDLocator( struct_parser.CreateStruct( "Zip64CDLocator_t", """ uint32_t magic = 0x07064b50; uint32_t disk_with_cd = 0; uint64_t offset_of_end_cd; uint32_t number_of_disks = 1; """)): def IsValid(self): return (self.magic == 0x07064b50 and self.disk_with_cd == 0 and self.number_of_disks == 1)
class Zip64FileHeaderExtensibleField(struct_parser.CreateStruct( "Zip64FileHeaderExtensibleField_t", """ uint16_t header_id = 1; uint16_t data_size = 28; uint64_t file_size; uint64_t compress_size; uint64_t relative_offset_local_header; uint32_t disk_number_start = 0; """)): pass
class ZipFileHeader( struct_parser.CreateStruct( "ZipFileHeader_t", """ uint32_t magic = 0x4034b50; uint16_t version = 0x14; uint16_t flags = 0x8; uint16_t compression_method; uint16_t lastmodtime; uint16_t lastmoddate; uint32_t crc32; int32_t compress_size; int32_t file_size; uint16_t file_name_length; uint16_t extra_field_len = 0; """)): def IsValid(self): return self.magic == 0x4034b50
class Zip64EndCD(struct_parser.CreateStruct( "Zip64EndCD_t", """ uint32_t magic = 0x06064b50; uint64_t size_of_header = 0; uint16_t version_made_by = 0x2d; uint16_t version_needed = 0x2d; uint32_t number_of_disk = 0; uint32_t number_of_disk_with_cd = 0; uint64_t number_of_entries_in_volume; uint64_t number_of_entries_in_total; uint64_t size_of_cd; uint64_t offset_of_cd; """)): def IsValid(self): return self.magic == 0x06064b50
class Zip64EndCD( struct_parser.CreateStruct( "Zip64EndCD_t", """ uint32_t magic = 0x06064b50; uint64_t size_of_header = 0; uint16_t version_made_by = 0x2d; uint16_t version_needed = 0x2d; uint32_t number_of_disk = 0; uint32_t number_of_disk_with_cd = 0; uint64_t number_of_entries_in_volume; uint64_t total_entries_in_cd; uint64_t size_of_cd; uint64_t offset_of_cd; """)): magic_string = b'PK\x06\x06' def IsValid(self): return self.magic == 0x06064b50 @classmethod def FromBuffer(cls, buffer): """Instantiate an EndCentralDirectory from this buffer.""" # Not enough data to contain an EndCentralDirectory if len(buffer) > cls.sizeof(): # Scan the buffer backwards for an End of Central Directory magic end = len(buffer) - cls.sizeof() + 4 while True: index = buffer.rfind(cls.magic_string, 0, end) if index < 0: break end_cd = cls(buffer[index:]) if end_cd.IsValid(): return end_cd, index end = index raise IOError("Unable to find EndCentralDirectory")
class CDFileHeader( struct_parser.CreateStruct( "CDFileHeader_t", """ uint32_t magic = 0x2014b50; uint16_t version_made_by = 0x317; uint16_t version_needed = 0x14; uint16_t flags = 0x8; uint16_t compression_method; uint16_t dostime; uint16_t dosdate; uint32_t crc32; uint32_t compress_size = 0xFFFFFFFF; uint32_t file_size = 0xFFFFFFFF; uint16_t file_name_length; uint16_t extra_field_len = 0; uint16_t file_comment_length = 0; uint16_t disk_number_start = 0; uint16_t internal_file_attr = 0; uint32_t external_file_attr = 0o644 << 16L; uint32_t relative_offset_local_header = 0xffffffff; """)): def IsValid(self): return self.magic == 0x2014b50
class EndCentralDirectory( struct_parser.CreateStruct("EndCentralDirectory_t", definition=""" uint32_t magic = 0x6054b50; uint16_t number_of_this_disk = 0; uint16_t disk_with_cd = 0; uint16_t total_entries_in_cd_on_disk; uint16_t total_entries_in_cd; uint32_t size_of_cd = 0xFFFFFFFF; uint32_t offset_of_cd = 0xFFFFFFFF; uint16_t comment_len = 0; """)): magic_string = b'PK\x05\x06' def IsValid(self): return self.magic == 0x6054b50 @classmethod def FromBuffer(cls, buffer): """Instantiate an EndCentralDirectory from this buffer.""" # Not enough data to contain an EndCentralDirectory if len(buffer) > cls.sizeof(): # Scan the buffer backwards for an End of Central Directory magic end = len(buffer) - cls.sizeof() + 4 while True: index = buffer.rfind(cls.magic_string, 0, end) if index < 0: break end_cd = cls(buffer[index:]) if end_cd.IsValid(): return end_cd, index end = index raise IOError("Unable to find EndCentralDirectory")