ZIP Archive Format(ZIP.rfh):
Class: Archive, Status: Headers only, Last change: 11.01.2024 17:21:22
include DosFTime.rfi
const
Days1601=DateToDays(1601,1,1);
DaySec=24*60*60;
type
//AUX
TOSCode enum byte (
IBM=0, //MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)
Amiga=1,
VMS=2, //VAX/VMS
UNIX=3,
VM_CMS=4,//VM/CMS
Atari=5, //Atari ST
HPFS=6, //OS/2 H.P.F.S.
Mac=7, //Macintosh
Z=8, //Z-System
CP_M=9, //CP/M
NTFS=10, //Windows NTFS
MVS=11, //MVS (OS/390 - Z/OS)
VSE=12, //VSE
Acorn=13, //Acorn Risc
VFAT=14, //VFAT
AltVMS=15, //alternate MVS
BeOS=16, //BeOS
Tandem=17, //Tandem
OS400=18, //OS/400
OSX=19 //OS X (Darwin)
)
TMadeVer struc
byte PrgVer
TOSCode OS
ends
TComprMethod enum word (
Stored=0, // The file is stored (no compression)
Shrunk=1, // The file is Shrunk
Reduced1=2, // The file is Reduced with compression factor 1
Reduced2=3, // The file is Reduced with compression factor 2
Reduced3=4, // The file is Reduced with compression factor 3
Reduced4=5, // The file is Reduced with compression factor 4
Imploded=6, //The file is Imploded
Tokenized=7, //Reserved for Tokenizing compression algorithm
Deflated=8, //The file is Deflated
DeflatedE=9, //Enhanced Deflating using Deflate64(tm)
ImplodedPK=10,//PKWARE Data Compression Library Imploding (old IBM TERSE)
//11 - Reserved by PKWARE
BZIP2=12, //File is compressed using BZIP2 algorithm
//13 - Reserved by PKWARE
LZMA=14, //LZMA (EFS)
//15 - Reserved by PKWARE
//16 - Reserved by PKWARE
//17 - Reserved by PKWARE
TERSE=18, //File is compressed using IBM TERSE (new)
LZ77=19, //IBM LZ77 z Architecture (PFS)
WavPack=97, //WavPack compressed data
PPMd=98 //PPMd version I, Rev 1
)
type bit
TBit num+(1)
TBit2 num+(2)
TBit3 num+(3)
TBit4 num+(4)
TBit5 num+(5)
TNoMethodF set 2 of ()
TImplodedF set 2 of (
Dict8k, //1 - 8K sliding dictionary was used, 0 - 4K
Tree3 //1- 3 Shannon-Fano trees were used, 0 - 2
)
TDeflatedF enum TBit2 (
Normal=0, // (-en) compression option was used.
Maximum=1, // (-ex) compression option was used.
Fast=2, // (-ef) compression option was used.
SuperFast=3 // (-es) compression option was used.
)
TLZMAF set 2 of (
HasEOS //end-of-stream (EOS) marker is used
)
TFileFlags(Method) struc
TBit Encrypted
case TComprMethod @:Method of
Imploded: TImplodedF
Deflated: TDeflatedF
LZMA: TLZMAF
else TNoMethodF
endc MethodF
set 13 of (
LocZero, //the fields crc-32, compressed size and uncompressed size are set
//to zero in the local header
EnhDeflRsrv, //Bit 4: Reserved for use with method 8, for enhanced
//deflating.
ComprPatch, //Bit 5: If this bit is set, this indicates that the file is
//compressed patched data. (Note: Requires PKZIP
//version 2.70 or greater)
StrongEncrypt, //Strong encryption. If this bit is set, you MUST
//set the version needed to extract value to at least
//50 and you MUST also set bit 0. If AES encryption
//is used, the version needed to extract value MUST
//be at least 51
Bit7Unused,
Bit8Unused,
Bit9Unused,
Bit10Unused,
UTF8, //Language encoding flag (EFS). If this bit is set,
//the filename and comment fields for this file
EnhComprRsrv, //Reserved by PKWARE for enhanced compression
EncryptCentralDir // Set when encrypting the Central Directory to indicate
//selected data values in the Local Header are masked to
//hide their actual values.
) FRest
ends
TDeflatedBlockType enum TBit2 (Stored=0,HTFixed=1,DynamicHT=2,Error=3)
TDynamicHTData struc
TBit5 NLiterals //# of Literal codes sent - 256 (256 - 286) All other codes are never sent.
TBit5 NDist //# of Dist codes - 1 (1 - 32)
TBit4 NLen //# of Bit Length codes - 3 (3 - 19)
array[@.NLen+3]of TBit3 BitLenLens //The lengths of the bit length codes
ends
TDeflatedData struc
TBit IsLastBl //This bit is set to 1 if this is the last compressed block in the data
TDeflatedBlockType Typ
case @.Typ of
DynamicHT: TDynamicHTData
endc D
ends: assert[@.Typ<>TDeflatedBlockType.Error]
type
TInternalAttr set 16 of (
IsText, //the file is apparently an ASCII or text file
HasControlFld ^ 0x2 //The 0x0002 bit of this field indicates, if set, that
//a 4 byte variable record length control field precedes each
//logical record indicating the length of the record.
)
TDiskNum word
TExtraDataId enum Word (
Zip64=0x0001, //Zip64 extended information extra field
AV=0x0007, //AV Info
PFS=0x0008, //Reserved for extended language encoding data (PFS)
OS2=0x0009, //OS/2
NTFS=0x000a, //NTFS
OpenVMS=0x000c, //OpenVMS
UNIX=0x000d, //UNIX
FS=0x000e, //Reserved for file stream and fork descriptors
Patch=0x000f, //Patch Descriptor
PKCS7=0x0014, //PKCS#7 Store for X.509 Certificates
X509f=0x0015, //X.509 Certificate ID and Signature for
//individual file
X509d=0x0016, //X.509 Certificate ID for Central Directory
StrongEncr=0x0017, //Strong Encryption Header
RMC=0x0018, //Record Management Controls
PKCS7r=0x0019, //PKCS#7 Encryption Recipient Certificate List
AS400=0x0065, //IBM S/390 (Z390), AS/400 (I400) attributes uncompressed
AS400C=0x0066, //Reserved for IBM S/390 (Z390), AS/400 (I400) attributes - compressed
POSZIP=0x4690 //POSZIP 4690 (reserved)
)
TOs2Extra(Sz) struc
ulong BSize //Uncompressed Block Size
TComprMethod CType //Compression type
ulong EACRC //CRC value for uncompress block
raw[] D //Compressed block
ends:[@:Size=@:Sz]
TWinFileTime struc //Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).
ulong dwLowDateTime
ulong dwHighDateTime
ends
TNTFSExtraDataVal(Id,Sz) struc
case @:id of
1: struc
TWinFileTime Mtime //File last modification time
TWinFileTime Atime //File last access time
TWinFileTime Ctime //File creation time
ends
endc C
raw[] Rest
ends:[@:Size=@:Sz]
TNTFSExtraDataRec struc
word Id //NTFS attribute tag value
word Sz //Size of attribute in bytes
TNTFSExtraDataVal(@.Id,@.Sz) D //Attribute data
ends
//TNTFSExtraDataTbl(Len) array of TNTFSExtraDataRec:[@:Size=@:Len]
TNTFSExtra(Sz) struc
ulong Rsrv //Reserved for future use
array of TNTFSExtraDataRec Tbl
ends:[@:Size=@:Sz]
TZip64Extra struc
Uint64 FSize
Uint64 CSize
ends
TExtraDataVal(Id,Sz) struc
case TExtraDataId @:id of
OS2: TOs2Extra(@@:Sz)
NTFS: TNTFSExtra(@@:Sz)
Zip64: TZip64Extra
//!!!ToDo: add other kinds of Extra data
endc C
raw[] Rest
ends:[@:Size=@:Sz]
TExtraDataRec struc
TExtraDataId Id
word Sz
TExtraDataVal(@.Id,@.Sz) D
ends
TExtraDataTbl(Len) array of TExtraDataRec:[@:Size=@:Len]
TExtraData(Len) struc
TExtraDataTbl(@:Len) Tbl
//raw[] rest
ends:[@:Size=@:Len]
// Local file header:
TLocalFileHdr struc
ulong Sign //local file header signature 4 bytes (0x04034b50)
int ExtrVer //version needed to extract 2 bytes
TFileFlags Flags //general purpose bit flag 2 bytes
TComprMethod ComprMethod //compression method 2 bytes
TFileTime LastModTime
// word LastModTime //last mod file time 2 bytes
// word LastModDate //last mod file date 2 bytes
ulong crc_32 //crc-32 4 bytes
ulong CSize //compressed size 4 bytes
ulong FSize //uncompressed size 4 bytes
word FNLen //filename length 2 bytes
word ExtraLen //extra field length 2 bytes
array[@.FNLen] of Char FName //filename (variable size)
TExtraData(@.ExtraLen) Extra//extra field (variable size)
ends:[@.Flags:Method=@.ComprMethod]:assert[@.Sign=0x04034b50/*,
@.Flags.FRest and 1 = 0*/]:let CSize=@.Extra.Tbl[?@.Id=TExtraDataId.Zip64].
D.C.Zip64.CSize exc @.CSize;
//Data descriptor:
/* This record is present when Flags.LocZero bit is set,
but then the @.Hdr.CSize expression will be incorrect, so
we made it invalid in assert clause (I suppose that we should
decompress the file data first to obtain its size in this case -
).
TDataDescr struc
ulong crc_32 //crc-32 4 bytes
ulong CSize //compressed size 4 bytes
ulong FSize //uncompressed size 4 bytes
ends
*/
TLocalFileData(Sz,ComprMethod) struc
case TComprMethod @:ComprMethod of
Deflated: TDeflatedData
endc D
raw[] Rest
ends:[@:Size=@:Sz]
TLocalFileRec struc
TLocalFileHdr Hdr
TLocalFileData(@.Hdr:CSize,@.Hdr.ComprMethod or (-@.Hdr.Flags.Encrypted)) D
//TDataDescr
ends
TLocalFiles array of TLocalFileRec ?not @.Hdr:assert!void;
// File header:
TFileHdr struc
ulong Sign //central file header signature 4 bytes (0x02014b50)
TMadeVer MadeVer //version made by 2 bytes
int ExtrVer //version needed to extract 2 bytes
TFileFlags Flags //general purpose bit flag 2 bytes
TComprMethod ComprMethod //compression method 2 bytes
TFileTime LastModTime
// word LastModTime //last mod file time 2 bytes
// word LastModDate //last mod file date 2 bytes
ulong crc_32 //crc-32 4 bytes
ulong CSize //compressed size 4 bytes
ulong FSize //uncompressed size 4 bytes
word FNLen //filename length 2 bytes
word ExtraLen //extra field length 2 bytes
word CommentLen //file comment length 2 bytes
TDiskNum StartDiskNum //disk number start 2 bytes
TInternalAttr InternalAttr //internal file attributes 2 bytes
ulong ExternalAttr //external file attributes 4 bytes
ulong LocHdrOfs //relative offset of local header 4 bytes
array[@.FNLen] of Char FName //filename (variable size)
TExtraData(@.ExtraLen) Extra//extra field (variable size)
array[@.CommentLen] of Char Comment //Comment (variable size)
ends:[@.Flags:Method=@.ComprMethod]:assert[@.Sign=0x02014b50]
TCentralDirTbl array of TFileHdr ?not @:assert!void;
// End of central dir record:
TCentralDirEndRec struc
ulong Sign //end of central dir signature 4 bytes (0x06054b50)
TDiskNum DiskNum //number of this disk 2 bytes
TDiskNum StartDiskNum //number of the disk with the start of the central directory 2 bytes
word DiskTotFiles //total number of entries in the central dir on this disk 2 bytes
word TotFiles //total number of entries in the central dir 2 bytes
ulong DirSize //size of the central directory 4 bytes
ulong StartDirOfs //offset of start of central directory with respect to the starting disk number 4 bytes
word CommentLen //zipfile comment length 2 bytes
array[@.CommentLen] of Char Comment //Comment (variable size)
ends:assert[@.Sign=0x06054b50]
TCentralDir struc
TCentralDirTbl Tbl
try
DEnd: TCentralDirEndRec
BadF: TLocalFileHdr
Nothing: void
endt DirEnd
ends:assert[(@:Size=@.DirEnd.DEnd.DirSize)exc 1/*,@.Tbl:Count=@.DirEnd.TotFiles*/]
TZipFileData struc
TLocalFiles Files
TCentralDir Dir
ends
data
0 TZipFileData D
assert D.Files[0].Hdr:assert exc 0; //We just requre that the first file
//should be present to consider the file as a ZIP archive
descr ('ZIP Archive File Format.',NL,
'Info Source: zip_form.zip at www.wotsit.org',NL,
' https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT',NL,
'To obtain this file you can also go to:',NL,
' http://www.pkware.com/download.html',NL,
' Then download --> appnote.zip',NL)
//ToDo: use https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
Other specifications.
FlexT home page,
Author`s home page.