{ The following code is a cheezy way to read the structures that exist in a zip file. it does not compress or decompress; it just reads the file information included in the file. It is not finished and has a bug that has been compensated for. Enjoy -some code is not my own, i.e. the structures themselves. } USES dos; {Structure signatures} CONST LOCAL = $04034B50; CENTRAL = $02014B50;END_OF = $06054B50; {THE following three structures are found in the zip file } {A signature WILL tell you WHICH follows the signature in the file} TYPE ZLOCALtype = record { Zip File Header } VerReqd : Word; { ..Version reqd to unzip } BitFlag : Word; { ..Bit Flag } Method : Word; { ..Compress Method } LModTime: Word; { ..Last Mod Time } LModDate: Word; { ..Last Mod Date } CRC32 : LongInt; { ..File CRC } CmpSize : LongInt; { ..Compressed Size } UncmpSz : LongInt; { ..Uncompressed Size } FNLen : Word; { ..File Name Length } EFLen : Word; { ..Extra Field Length } end; TYPE ZCENTRALtype = record { Zip File Header } MadeBy : Word; VerReqd : Word; { ..Version reqd to unzip } BitFlag : Word; { ..Bit Flag } Method : Word; { ..Compress Method } LModTime: Word; { ..Last Mod Time } LModDate: Word; { ..Last Mod Date } CRC32 : LongInt; { ..File CRC } CmpSize : LongInt; { ..Compressed Size } UncmpSz : LongInt; { ..Uncompressed Size } FNLen : Word; { ..File Name Length } EFLen : Word; { ..Extra Field Length } end; zCENTRAL2type=record DiskNo : Word; { ..Starting Disk Number } IFAttr : Word; { ..Internal File Attributes} EFAttr : LongInt; { ..External File Attributes} LHOff : LongInt; { ..Offset of local header } end; zENDType = Record { Directory End Record } DiskNo : Word; { ..Number of this disk } ZDDisk : Word; { ..Disk w/ start of dir } ZDETD : Word; { ..Dir ents this disk } ZDEnts : Word; { ..Total dir ents } ZDSize : LongInt; { ..Dir size } ZDStart : LongInt; { ..Offset to start of Dir } CmtLen : Word; { ..Zip Comment Length } end; VAR zLOCAL : zLOCALtype; zCENTRAL : zCENTRALtype; zCENTRAL2: zCENTRAL2type; zEND : zENDtype; Fi : File; FIlename:String[12]; temp : array[1..16] of char; zSignature: longInt; I : integer; {$I files.inc} {for opening files easy} {$I buffer.inc} {Using a full buffer and fake disk reads} {Nice when you don't know what structure follows} {Fill the buffer and move the info to the structure that fits} Function num2Hex(L : LongInt) : String; CONST HexChar : Array [0..15] of Char = '0123456789ABCDEF'; VAR hexs : string; tByte, I,J : byte; start : boolean; Begin HexS:=''; HexS := HexChar[(L AND $F0000000) SHR 28] + HexChar[(L AND $0F000000) SHR 24] + HexChar[(L AND $00F00000) SHR 20] + HexChar[(L AND $000F0000) SHR 16] + HexChar[(L AND $0000F000) SHR 12] + HexChar[(L AND $00000F00) SHR 8] + HexChar[(L AND $000000F0) SHR 4] + HexChar[(L AND $0000000F) ]; Start:=False; {init} j:=0; FOR I:=1 to 8 DO BEGIN {rid of leading zeros} IF hexS[i]<>'0' then Start:=true; IF start then BEGIN Inc(j,1); HexS[j]:=HexS[i]; END; END; move(j,hexS[0],1); {reset string to new size} num2Hex:=HexS; end; {HexLInt} BEGIN {-====-} {Open the file if it exists; else OpenFile returns FALSE} IF not OpenFile(fi, paramStr(1)) then BEGIN Writeln('File ', paramStr(1) ,' not found. Check syntax'); halt; END; BRead(Fi, Zsignature, 4); {Fills the buffer} {Moves 4 bytes into zSignature} IF (Zsignature<>LOCAL) and (zSignature<>CENTRAL) THEN BEGIN Writeln('File ',ParamStr(1),' does not appear to be a ZIP file.'); HALT END; WHILE 1<>0 DO BEGIN {Read the structure that fits the zSignature} IF zSignature= LOCAL THEN BEGIN Bread(fi,Zlocal,SizeOf(Zlocal) ); Writeln('LOCAL'); END; IF zSignature= CENTRAL THEN BEGIN Bread(fi,ZCentral,SizeOf(Zlocal) ); WriteLN('CENTRAL'); END; IF zSignature= END_OF THEN BEGIN Bread(fi,zEnd,SizeOf(zEnd) ); WriteLN('END'); END; {ALL three have a signature} { Writeln('long test ',num2hex(981347578));} Write('Pksignature: '); write( ((Zsignature and $F0000000) shr 28) ); write(' ', ((Zsignature and $0F000000) shr 24) ); write(' ', ((Zsignature and $00F00000) shr 20) ); write(' ', ((Zsignature and $000F0000) shr 16) ); write(' ', ((Zsignature and $0000F000) shr 12) ); write(' ', ((Zsignature and $00000F00) shr 8) ); write(' ', ((Zsignature and $000000F0) shr 4) ); write(' ', ((Zsignature and $0000000F) ) ); writeln; IF (zSignature=Local) THEN BEGIN WITH zLOCAL DO BEGIN Write('Version Required: ',(verReqd div 10),'.' ); writeln(VerReqd mod 10); writelN('BitFlag [?]: ',(bitflag) ); WriteLN('Method Used: ',(method) ); WriteLN('Last mod Time: ',num2hex(LmodTime)); WriteLN('Last mod Date: ',num2hex(LmodDate)); WriteLN('CRC32: ',num2hex(Crc32)); {Correct} Writeln('Compressed Size: ',CmpSize); {correct} WriteLn('Original Size: ',UnCmpSz); {correct} Writeln('File name Length: ',FNlen); {correct} Writeln('Extra field Length: ',EFlen); BRead(Fi,Filename[1],FNlen); move (FNlen,FileName[0],1); {init the string length} WriteLN('FileName: ',FileName); {correct} Bskip(fi,CmpSize); {skip the actual zipped part} END; END; IF (zSignature=CENTRAL) THEN BEGIN WITH zCENTRAL DO BEGIN Writeln('MAde by version : ',madeBy); Write('Version Required: ',(verReqd div 10),'.' ); writeln(VerReqd mod 10); writelN('BitFlag [?]: ',(bitflag) ); WriteLN('Method Used: ',(method) ); WriteLN('Last mod Time: ',num2hex(LmodTime)); WriteLN('Last mod Date: ',num2hex(LmodDate)); WriteLN('CRC32: ',num2hex(Crc32)); Writeln('Compressed Size: ',CmpSize); WriteLn('Original Size: ',UnCmpSz); Writeln('File name Length: ',FNlen); Writeln('Extra field Length: ',EFlen); END; WITH zCENTRAL2 DO BEGIN BSkip(fi,4); {There's blanks?? why?} Bread(Fi,zCentral2,SizeOf(zCentral2)); Writeln('Starting Disk #: ',DiskNo); WriteLN('Internal File Attr: ',IFAttr); WriteLN('External File Attr: ',EFAttr); Writeln('Local header offset: ',LHoff); BRead(Fi,Filename[1],zCENTRAL.FNlen); move (zCENTRAL.FNlen,FileName[0],1); WriteLN('FileName: ',FileName); END; END; IF (zSignature=END_OF) THEN BEGIN WITH zEND DO BEGIN WriteLN('Disk Number: ',DiskNo); WriteLN('Start of directory: ',ZDDisk); WriteLN('Total entries, disk: ',ZDETD); WriteLN('Total Entries: ',ZDEnts); WriteLN('Directory Size: ',ZDSize); WriteLN('Directory Offset: ',ZDStart); WriteLN('Zip Comment Length: ',CmtLen); halt; END; END; ReadLN; Bread(fi,zSignature,4); {read next Zsignature} END; {WHILE NOT EOF} Close(fi); END. { FILES.INC} FUNCTION FileExists(FileName: String): Boolean; VAR F: file; begin {$I-} Assign(F, FileName); Reset(F); Close(F); {$I+} FileExists:=(IOResult = 0) and (FileName <> '') end; { FileExists } FUNCTION OpenFile(VAR f: file; fileName:string): Boolean; BEGIN IF fileExists(FileName) then BEGIN Assign(f,filename); Reset(f,1); Openfile:=True; END ELSE OpenFile:=False; END; FUNCTION FileExistsWild(FileName: String): Boolean; VAR Fil: SearchRec; begin FindFirst(FileName,anyFile,Fil); FileExistsWild:=(DosError=0) and (FileName <> ''); end; { FileExists } {BUFFER.INC} CONST zBufSize=8192; TYPE zBufferType = array[1..zBufSize] of byte; VAR zBuffer: zBufferType; zCurrent: integer; nSeen : Word; PROCEDURE READBUFFER(Var f:file;nRead, Position: integer); BEGIN IF zCurrent=0 then zCurrent:=1; BlockRead(f,zBuffer[Position],nRead,nSeen); END; PROCEDURe bREAD(var f: file;var userObj; nRead: integer); VAR temp:integer; {^^^^^^^^^^^what ever the user is using!} BEGIN IF zCurrent=0 then ReadBUFFER(F, ZBufsize ,1); {init the buffer} IF zcurrent+nRead>zBufSize THEN BEGIN {Part Missing??} Temp:=ZbufSize+1-zCurrent; {Size of whats left in buffer} { Writeln('What is left in the buffer ',temp);} move(zBuffer[zCurrent], zBuffer[1], Temp); {move unread to start} ReadBUFFER(F, ZBufsize-(Temp) ,Temp); {total minus what's left} zCurrent:=1; {at position end of temp} move(zBuffer[zCurrent],userOBJ,nREAD); END else BEGIN move(ZBuffer[zCurrent],UserOBJ,nREad); zCurrent:=zCurrent+nRead; END; END; PROCEDURe bSkip(var f: file; nRead: integer); VAR temp:integer; {SKIPS A PART OF THE BUFFER} BEGIN IF zCurrent=0 then ReadBUFFER(F, ZBufsize ,1); {init the buffer} IF nRead>zBufSize then BEGIN Seek(f,FilePos(f)+nRead-(ZbufSize+1-zCurrent)); {Remeber there may still be bytes ALREADY read in the buffer} {You need not skip what's already there} {Just seek to position - already read} zCurrent:=0; END ELSE IF zcurrent+nRead>zBufSize THEN BEGIN {Part Missing??} Temp:=ZbufSize+1-zCurrent; {Size of whats left in buffer} move(zBuffer[zCurrent], zBuffer[1], Temp); {move unread to start} ReadBUFFER(F, ZBufsize-(Temp) ,Temp);{refill} {total minus what's left} zCurrent:=1+temp; {at position end of temp} END ELSE zCurrent:=zCurrent+nRead; END;