1 /* unzip.c -- IO for uncompress .zip files using zlib
2 Version 1.1, February 14h, 2010
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
7 Modifications of Unzip for Zip64
8 Copyright (C) 2007-2008 Even Rouault
10 Modifications for Zip64 support on both zip and unzip
11 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
13 For more info read MiniZip_info.txt
16 ------------------------------------------------------------------------------------
17 Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
18 compatibility with older software. The following is from the original crypt.c.
19 Code woven in by Terry Thorsen 1/2003.
21 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
23 See the accompanying file LICENSE, version 2000-Apr-09 or later
24 (the contents of which are also included in zip.h) for terms of use.
25 If, for some reason, all these files are missing, the Info-ZIP license
26 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
28 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
30 The encryption/decryption parts of this source code (as opposed to the
31 non-echoing password parts) were originally written in Europe. The
32 whole source package can be freely distributed, including from the USA.
33 (Prior to January 2000, re-export from the US was a violation of US law.)
35 This encryption code is a direct transcription of the algorithm from
36 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
37 file (appnote.txt) is distributed with the PKZIP program (even in the
38 version without encryption capabilities).
40 ------------------------------------------------------------------------------------
44 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
45 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
46 2007-2008 - Even Rouault - Remove old C style function prototypes
47 2007-2008 - Even Rouault - Add unzip support for ZIP64
49 Copyright (C) 2007-2008 Even Rouault
52 Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
53 Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
54 should only read the compressed/uncompressed size from the Zip64 format if
55 the size from normal header was 0xFFFFFFFF
56 Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
57 Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
58 Patch created by Daniel Borca
60 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
62 Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
93 /* compile with -Dlocal if your debugger can't find static symbols */
96 #ifndef CASESENSITIVITYDEFAULT_NO
97 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
98 # define CASESENSITIVITYDEFAULT_NO
104 #define UNZ_BUFSIZE (16384)
107 #ifndef UNZ_MAXFILENAMEINZIP
108 #define UNZ_MAXFILENAMEINZIP (256)
112 # define ALLOC(size) (malloc(size))
115 # define TRYFREE(p) {if (p) free(p);}
118 #define SIZECENTRALDIRITEM (0x2e)
119 #define SIZEZIPLOCALHEADER (0x1e)
122 const char unz_copyright[] =
123 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
125 /* unz_file_info_interntal contain internal info about a file in zipfile*/
126 typedef struct unz_file_info64_internal_s
128 ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
129 } unz_file_info64_internal;
132 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
133 when reading and decompress it */
136 char *read_buffer; /* internal buffer for compressed data */
137 z_stream stream; /* zLib stream structure for inflate */
140 bz_stream bstream; /* bzLib stream structure for bziped */
143 ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
144 uLong stream_initialised; /* flag set if stream structure is initialised*/
146 ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
147 uInt size_local_extrafield;/* size of the local extra field */
148 ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
149 ZPOS64_T total_out_64;
151 uLong crc32; /* crc32 of all data uncompressed */
152 uLong crc32_wait; /* crc32 we must obtain after decompress all */
153 ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
154 ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
155 zlib_filefunc64_32_def z_filefunc;
156 voidpf filestream; /* io structore of the zipfile */
157 uLong compression_method; /* compression method (0==store) */
158 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
160 } file_in_zip64_read_info_s;
163 /* unz64_s contain internal information about the zipfile
167 zlib_filefunc64_32_def z_filefunc;
168 int is64bitOpenFunction;
169 voidpf filestream; /* io structore of the zipfile */
170 unz_global_info64 gi; /* public global information */
171 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
172 ZPOS64_T num_file; /* number of the current file in the zipfile*/
173 ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
174 ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
175 ZPOS64_T central_pos; /* position of the beginning of the central dir*/
177 ZPOS64_T size_central_dir; /* size of the central directory */
178 ZPOS64_T offset_central_dir; /* offset of start of central directory with
179 respect to the starting disk number */
181 unz_file_info64 cur_file_info; /* public info about the current file in zip*/
182 unz_file_info64_internal cur_file_info_internal; /* private info about it*/
183 file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
184 file if we are decompressing it */
190 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
191 const unsigned long* pcrc_32_tab;
200 /* ===========================================================================
201 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
203 IN assertion: the stream s has been sucessfully opened for reading.
207 local int unz64local_getByte OF((
208 const zlib_filefunc64_32_def* pzlib_filefunc_def,
212 local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,
213 voidpf filestream, int *_pi)
216 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
224 if (ZERROR64(*pzlib_filefunc_def,filestream))
232 /* ===========================================================================
233 Reads a long in LSB order from the given gz_stream. Sets
235 local int unz64local_getShort OF((
236 const zlib_filefunc64_32_def* pzlib_filefunc_def,
240 local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
248 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
252 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
262 local int unz64local_getLong OF((
263 const zlib_filefunc64_32_def* pzlib_filefunc_def,
267 local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
275 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
279 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
283 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
287 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
297 local int unz64local_getLong64 OF((
298 const zlib_filefunc64_32_def* pzlib_filefunc_def,
303 local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
311 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
315 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
316 x |= ((ZPOS64_T)i)<<8;
319 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
320 x |= ((ZPOS64_T)i)<<16;
323 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
324 x |= ((ZPOS64_T)i)<<24;
327 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
328 x |= ((ZPOS64_T)i)<<32;
331 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
332 x |= ((ZPOS64_T)i)<<40;
335 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
336 x |= ((ZPOS64_T)i)<<48;
339 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
340 x |= ((ZPOS64_T)i)<<56;
349 /* My own strcmpi / strcasecmp */
350 local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
354 char c1=*(fileName1++);
355 char c2=*(fileName2++);
356 if ((c1>='a') && (c1<='z'))
358 if ((c2>='a') && (c2<='z'))
361 return ((c2=='\0') ? 0 : -1);
372 #ifdef CASESENSITIVITYDEFAULT_NO
373 #define CASESENSITIVITYDEFAULTVALUE 2
375 #define CASESENSITIVITYDEFAULTVALUE 1
378 #ifndef STRCMPCASENOSENTIVEFUNCTION
379 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
383 Compare two filename (fileName1,fileName2).
384 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
385 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
387 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
388 (like 1 on Unix, 2 on Windows)
391 extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
392 const char* fileName2,
393 int iCaseSensitivity)
396 if (iCaseSensitivity==0)
397 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
399 if (iCaseSensitivity==1)
400 return strcmp(fileName1,fileName2);
402 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
405 #ifndef BUFREADCOMMENT
406 #define BUFREADCOMMENT (0x400)
410 Locate the Central directory of a zipfile (at the end, just before
413 local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
414 local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
419 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
420 ZPOS64_T uPosFound=0;
422 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
426 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
428 if (uMaxBack>uSizeFile)
429 uMaxBack = uSizeFile;
431 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
436 while (uBackRead<uMaxBack)
441 if (uBackRead+BUFREADCOMMENT>uMaxBack)
442 uBackRead = uMaxBack;
444 uBackRead+=BUFREADCOMMENT;
445 uReadPos = uSizeFile-uBackRead ;
447 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
448 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
449 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
452 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
455 for (i=(int)uReadSize-3; (i--)>0;)
456 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
457 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
459 uPosFound = uReadPos+i;
472 Locate the Central directory 64 of a zipfile (at the end, just before
475 local ZPOS64_T unz64local_SearchCentralDir64 OF((
476 const zlib_filefunc64_32_def* pzlib_filefunc_def,
479 local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
485 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
486 ZPOS64_T uPosFound=0;
488 ZPOS64_T relativeOffset;
490 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
494 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
496 if (uMaxBack>uSizeFile)
497 uMaxBack = uSizeFile;
499 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
504 while (uBackRead<uMaxBack)
509 if (uBackRead+BUFREADCOMMENT>uMaxBack)
510 uBackRead = uMaxBack;
512 uBackRead+=BUFREADCOMMENT;
513 uReadPos = uSizeFile-uBackRead ;
515 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
516 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
517 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
520 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
523 for (i=(int)uReadSize-3; (i--)>0;)
524 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
525 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
527 uPosFound = uReadPos+i;
538 /* Zip64 end of central directory locator */
539 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
542 /* the signature, already checked */
543 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
546 /* number of the disk with the start of the zip64 end of central directory */
547 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
552 /* relative offset of the zip64 end of central directory record */
553 if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
556 /* total number of disks */
557 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
562 /* Goto end of central directory record */
563 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
567 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
570 if (uL != 0x06064b50)
573 return relativeOffset;
577 Open a Zip file. path contain the full pathname (by example,
578 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
580 If the zipfile cannot be opened (file doesn't exist or in not valid), the
581 return value is NULL.
582 Else, the return value is a unzFile Handle, usable with other function
583 of this unzip package.
585 local unzFile unzOpenInternal (const void *path,
586 zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
587 int is64bitOpenFunction)
591 ZPOS64_T central_pos;
594 uLong number_disk; /* number of the current dist, used for
595 spaning ZIP, unsupported, always 0*/
596 uLong number_disk_with_CD; /* number the the disk with central dir, used
597 for spaning ZIP, unsupported, always 0*/
598 ZPOS64_T number_entry_CD; /* total number of entries in
600 (same than number_entry on nospan) */
604 if (unz_copyright[0]!=' ')
607 us.z_filefunc.zseek32_file = NULL;
608 us.z_filefunc.ztell32_file = NULL;
609 if (pzlib_filefunc64_32_def==NULL)
610 fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
612 us.z_filefunc = *pzlib_filefunc64_32_def;
613 us.is64bitOpenFunction = is64bitOpenFunction;
617 us.filestream = ZOPEN64(us.z_filefunc,
619 ZLIB_FILEFUNC_MODE_READ |
620 ZLIB_FILEFUNC_MODE_EXISTING);
621 if (us.filestream==NULL)
624 central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
632 if (ZSEEK64(us.z_filefunc, us.filestream,
633 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
636 /* the signature, already checked */
637 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
640 /* size of zip64 end of central directory record */
641 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
644 /* version made by */
645 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
648 /* version needed to extract */
649 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
652 /* number of this disk */
653 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
656 /* number of the disk with the start of the central directory */
657 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
660 /* total number of entries in the central directory on this disk */
661 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
664 /* total number of entries in the central directory */
665 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
668 if ((number_entry_CD!=us.gi.number_entry) ||
669 (number_disk_with_CD!=0) ||
673 /* size of the central directory */
674 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
677 /* offset of start of central directory with respect to the
678 starting disk number */
679 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
682 us.gi.size_comment = 0;
686 central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
692 if (ZSEEK64(us.z_filefunc, us.filestream,
693 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
696 /* the signature, already checked */
697 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
700 /* number of this disk */
701 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
704 /* number of the disk with the start of the central directory */
705 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
708 /* total number of entries in the central dir on this disk */
709 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
711 us.gi.number_entry = uL;
713 /* total number of entries in the central dir */
714 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
716 number_entry_CD = uL;
718 if ((number_entry_CD!=us.gi.number_entry) ||
719 (number_disk_with_CD!=0) ||
723 /* size of the central directory */
724 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
726 us.size_central_dir = uL;
728 /* offset of start of central directory with respect to the
729 starting disk number */
730 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
732 us.offset_central_dir = uL;
734 /* zipfile comment length */
735 if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
739 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
745 ZCLOSE64(us.z_filefunc, us.filestream);
749 us.byte_before_the_zipfile = central_pos -
750 (us.offset_central_dir+us.size_central_dir);
751 us.central_pos = central_pos;
752 us.pfile_in_zip_read = NULL;
756 s=(unz64_s*)ALLOC(sizeof(unz64_s));
760 unzGoToFirstFile((unzFile)s);
766 extern unzFile ZEXPORT unzOpen2 (const char *path,
767 zlib_filefunc_def* pzlib_filefunc32_def)
769 if (pzlib_filefunc32_def != NULL)
771 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
772 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
773 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
776 return unzOpenInternal(path, NULL, 0);
779 extern unzFile ZEXPORT unzOpen2_64 (const void *path,
780 zlib_filefunc64_def* pzlib_filefunc_def)
782 if (pzlib_filefunc_def != NULL)
784 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
785 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
786 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
787 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
788 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
791 return unzOpenInternal(path, NULL, 1);
794 extern unzFile ZEXPORT unzOpen (const char *path)
796 return unzOpenInternal(path, NULL, 0);
799 extern unzFile ZEXPORT unzOpen64 (const void *path)
801 return unzOpenInternal(path, NULL, 1);
805 Close a ZipFile opened with unzipOpen.
806 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
807 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
808 return UNZ_OK if there is no problem. */
809 extern int ZEXPORT unzClose (unzFile file)
813 return UNZ_PARAMERROR;
816 if (s->pfile_in_zip_read!=NULL)
817 unzCloseCurrentFile(file);
819 ZCLOSE64(s->z_filefunc, s->filestream);
826 Write info about the ZipFile in the *pglobal_info structure.
827 No preparation of the structure is needed
828 return UNZ_OK if there is no problem. */
829 extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
833 return UNZ_PARAMERROR;
839 extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
843 return UNZ_PARAMERROR;
845 /* to do : check if number_entry is not truncated */
846 pglobal_info32->number_entry = (uLong)s->gi.number_entry;
847 pglobal_info32->size_comment = s->gi.size_comment;
851 Translate date/time from Dos format to tm_unz (readable more easilty)
853 local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
856 uDate = (ZPOS64_T)(ulDosDate>>16);
857 ptm->tm_mday = (uInt)(uDate&0x1f) ;
858 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
859 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
861 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
862 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
863 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
867 Get Info about the current file in the zipfile, with internal only info
869 local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
870 unz_file_info64 *pfile_info,
871 unz_file_info64_internal
872 *pfile_info_internal,
874 uLong fileNameBufferSize,
876 uLong extraFieldBufferSize,
878 uLong commentBufferSize));
880 local int unz64local_GetCurrentFileInfoInternal (unzFile file,
881 unz_file_info64 *pfile_info,
882 unz_file_info64_internal
883 *pfile_info_internal,
885 uLong fileNameBufferSize,
887 uLong extraFieldBufferSize,
889 uLong commentBufferSize)
892 unz_file_info64 file_info;
893 unz_file_info64_internal file_info_internal;
900 return UNZ_PARAMERROR;
902 if (ZSEEK64(s->z_filefunc, s->filestream,
903 s->pos_in_central_dir+s->byte_before_the_zipfile,
904 ZLIB_FILEFUNC_SEEK_SET)!=0)
908 /* we check the magic */
911 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
913 else if (uMagic!=0x02014b50)
917 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
920 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
923 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
926 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
929 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
932 unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
934 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
937 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
939 file_info.compressed_size = uL;
941 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
943 file_info.uncompressed_size = uL;
945 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
948 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
951 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
954 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
957 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
960 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
963 // relative offset of local header
964 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
966 file_info_internal.offset_curfile = uL;
968 lSeek+=file_info.size_filename;
969 if ((err==UNZ_OK) && (szFileName!=NULL))
972 if (file_info.size_filename<fileNameBufferSize)
974 *(szFileName+file_info.size_filename)='\0';
975 uSizeRead = file_info.size_filename;
978 uSizeRead = fileNameBufferSize;
980 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
981 if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
987 if ((err==UNZ_OK) && (extraField!=NULL))
990 if (file_info.size_file_extra<extraFieldBufferSize)
991 uSizeRead = file_info.size_file_extra;
993 uSizeRead = extraFieldBufferSize;
997 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1003 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
1004 if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
1007 lSeek += file_info.size_file_extra - (uLong)uSizeRead;
1010 lSeek += file_info.size_file_extra;
1013 if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
1017 // since lSeek now points to after the extra field we need to move back
1018 lSeek -= file_info.size_file_extra;
1022 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1028 while(acc < file_info.size_file_extra)
1033 if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
1036 if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
1039 /* ZIP64 extra fields */
1040 if (headerId == 0x0001)
1044 if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)
1046 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
1050 if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)
1052 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
1056 if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)
1058 /* Relative Header offset */
1059 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
1063 if(file_info.disk_num_start == (unsigned long)-1)
1065 /* Disk Start Number */
1066 if (unz64local_getLong(&s->z_filefunc, s->filestream,&tmp) != UNZ_OK)
1073 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
1077 acc += 2 + 2 + dataSize;
1081 if ((err==UNZ_OK) && (szComment!=NULL))
1084 if (file_info.size_file_comment<commentBufferSize)
1086 *(szComment+file_info.size_file_comment)='\0';
1087 uSizeRead = file_info.size_file_comment;
1090 uSizeRead = commentBufferSize;
1094 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1100 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
1101 if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
1103 lSeek+=file_info.size_file_comment - uSizeRead;
1106 lSeek+=file_info.size_file_comment;
1109 if ((err==UNZ_OK) && (pfile_info!=NULL))
1110 *pfile_info=file_info;
1112 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
1113 *pfile_info_internal=file_info_internal;
1121 Write info about the ZipFile in the *pglobal_info structure.
1122 No preparation of the structure is needed
1123 return UNZ_OK if there is no problem.
1125 extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
1126 unz_file_info64 * pfile_info,
1127 char * szFileName, uLong fileNameBufferSize,
1128 void *extraField, uLong extraFieldBufferSize,
1129 char* szComment, uLong commentBufferSize)
1131 return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
1132 szFileName,fileNameBufferSize,
1133 extraField,extraFieldBufferSize,
1134 szComment,commentBufferSize);
1137 extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
1138 unz_file_info * pfile_info,
1139 char * szFileName, uLong fileNameBufferSize,
1140 void *extraField, uLong extraFieldBufferSize,
1141 char* szComment, uLong commentBufferSize)
1144 unz_file_info64 file_info64;
1145 err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
1146 szFileName,fileNameBufferSize,
1147 extraField,extraFieldBufferSize,
1148 szComment,commentBufferSize);
1151 pfile_info->version = file_info64.version;
1152 pfile_info->version_needed = file_info64.version_needed;
1153 pfile_info->flag = file_info64.flag;
1154 pfile_info->compression_method = file_info64.compression_method;
1155 pfile_info->dosDate = file_info64.dosDate;
1156 pfile_info->crc = file_info64.crc;
1158 pfile_info->size_filename = file_info64.size_filename;
1159 pfile_info->size_file_extra = file_info64.size_file_extra;
1160 pfile_info->size_file_comment = file_info64.size_file_comment;
1162 pfile_info->disk_num_start = file_info64.disk_num_start;
1163 pfile_info->internal_fa = file_info64.internal_fa;
1164 pfile_info->external_fa = file_info64.external_fa;
1166 pfile_info->tmu_date = file_info64.tmu_date,
1169 pfile_info->compressed_size = (uLong)file_info64.compressed_size;
1170 pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
1176 Set the current file of the zipfile to the first file.
1177 return UNZ_OK if there is no problem
1179 extern int ZEXPORT unzGoToFirstFile (unzFile file)
1184 return UNZ_PARAMERROR;
1186 s->pos_in_central_dir=s->offset_central_dir;
1188 err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1189 &s->cur_file_info_internal,
1190 NULL,0,NULL,0,NULL,0);
1191 s->current_file_ok = (err == UNZ_OK);
1196 Set the current file of the zipfile to the next file.
1197 return UNZ_OK if there is no problem
1198 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1200 extern int ZEXPORT unzGoToNextFile (unzFile file)
1206 return UNZ_PARAMERROR;
1208 if (!s->current_file_ok)
1209 return UNZ_END_OF_LIST_OF_FILE;
1210 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
1211 if (s->num_file+1==s->gi.number_entry)
1212 return UNZ_END_OF_LIST_OF_FILE;
1214 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1215 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
1217 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1218 &s->cur_file_info_internal,
1219 NULL,0,NULL,0,NULL,0);
1220 s->current_file_ok = (err == UNZ_OK);
1226 Try locate the file szFileName in the zipfile.
1227 For the iCaseSensitivity signification, see unzipStringFileNameCompare
1230 UNZ_OK if the file is found. It becomes the current file.
1231 UNZ_END_OF_LIST_OF_FILE if the file is not found
1233 extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
1238 /* We remember the 'current' position in the file so that we can jump
1239 * back there if we fail.
1241 unz_file_info64 cur_file_infoSaved;
1242 unz_file_info64_internal cur_file_info_internalSaved;
1243 ZPOS64_T num_fileSaved;
1244 ZPOS64_T pos_in_central_dirSaved;
1248 return UNZ_PARAMERROR;
1250 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
1251 return UNZ_PARAMERROR;
1254 if (!s->current_file_ok)
1255 return UNZ_END_OF_LIST_OF_FILE;
1257 /* Save the current state */
1258 num_fileSaved = s->num_file;
1259 pos_in_central_dirSaved = s->pos_in_central_dir;
1260 cur_file_infoSaved = s->cur_file_info;
1261 cur_file_info_internalSaved = s->cur_file_info_internal;
1263 err = unzGoToFirstFile(file);
1265 while (err == UNZ_OK)
1267 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
1268 err = unzGetCurrentFileInfo64(file,NULL,
1269 szCurrentFileName,sizeof(szCurrentFileName)-1,
1273 if (unzStringFileNameCompare(szCurrentFileName,
1274 szFileName,iCaseSensitivity)==0)
1276 err = unzGoToNextFile(file);
1280 /* We failed, so restore the state of the 'current file' to where we
1283 s->num_file = num_fileSaved ;
1284 s->pos_in_central_dir = pos_in_central_dirSaved ;
1285 s->cur_file_info = cur_file_infoSaved;
1286 s->cur_file_info_internal = cur_file_info_internalSaved;
1292 ///////////////////////////////////////////
1293 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1294 // I need random access
1296 // Further optimization could be realized by adding an ability
1297 // to cache the directory in memory. The goal being a single
1298 // comprehensive file read to put the file I need in a memory.
1302 typedef struct unz_file_pos_s
1304 ZPOS64_T pos_in_zip_directory; // offset in file
1305 ZPOS64_T num_of_file; // # of file
1309 extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
1313 if (file==NULL || file_pos==NULL)
1314 return UNZ_PARAMERROR;
1316 if (!s->current_file_ok)
1317 return UNZ_END_OF_LIST_OF_FILE;
1319 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
1320 file_pos->num_of_file = s->num_file;
1325 extern int ZEXPORT unzGetFilePos(
1327 unz_file_pos* file_pos)
1329 unz64_file_pos file_pos64;
1330 int err = unzGetFilePos64(file,&file_pos64);
1333 file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
1334 file_pos->num_of_file = (uLong)file_pos64.num_of_file;
1339 extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
1344 if (file==NULL || file_pos==NULL)
1345 return UNZ_PARAMERROR;
1348 /* jump to the right spot */
1349 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1350 s->num_file = file_pos->num_of_file;
1352 /* set the current file */
1353 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1354 &s->cur_file_info_internal,
1355 NULL,0,NULL,0,NULL,0);
1356 /* return results */
1357 s->current_file_ok = (err == UNZ_OK);
1361 extern int ZEXPORT unzGoToFilePos(
1363 unz_file_pos* file_pos)
1365 unz64_file_pos file_pos64;
1366 if (file_pos == NULL)
1367 return UNZ_PARAMERROR;
1369 file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
1370 file_pos64.num_of_file = file_pos->num_of_file;
1371 return unzGoToFilePos64(file,&file_pos64);
1375 // Unzip Helper Functions - should be here?
1376 ///////////////////////////////////////////
1380 Read the local header of the current zipfile
1381 Check the coherency of the local header and info in the end of central
1382 directory about this file
1383 store in *piSizeVar the size of extra info in local header
1384 (filename and size of extra field data)
1386 local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
1387 ZPOS64_T * poffset_local_extrafield,
1388 uInt * psize_local_extrafield)
1390 uLong uMagic,uData,uFlags;
1391 uLong size_filename;
1392 uLong size_extra_field;
1396 *poffset_local_extrafield = 0;
1397 *psize_local_extrafield = 0;
1399 if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
1400 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
1406 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
1408 else if (uMagic!=0x04034b50)
1412 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1415 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1418 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1421 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1423 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1426 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1427 /* #ifdef HAVE_BZIP2 */
1428 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1430 (s->cur_file_info.compression_method!=Z_DEFLATED))
1433 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1436 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1438 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
1441 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1443 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
1446 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1448 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
1451 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1453 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1456 *piSizeVar += (uInt)size_filename;
1458 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1460 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1461 SIZEZIPLOCALHEADER + size_filename;
1462 *psize_local_extrafield = (uInt)size_extra_field;
1464 *piSizeVar += (uInt)size_extra_field;
1470 Open for reading data the current file in the zipfile.
1471 If there is no error and the file is opened, the return value is UNZ_OK.
1473 extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
1474 int* level, int raw, const char* password)
1479 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1480 ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
1481 uInt size_local_extrafield; /* size of the local extra field */
1485 if (password != NULL)
1486 return UNZ_PARAMERROR;
1490 return UNZ_PARAMERROR;
1492 if (!s->current_file_ok)
1493 return UNZ_PARAMERROR;
1495 if (s->pfile_in_zip_read != NULL)
1496 unzCloseCurrentFile(file);
1498 if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1499 return UNZ_BADZIPFILE;
1501 pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
1502 if (pfile_in_zip_read_info==NULL)
1503 return UNZ_INTERNALERROR;
1505 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1506 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1507 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1508 pfile_in_zip_read_info->pos_local_extrafield=0;
1509 pfile_in_zip_read_info->raw=raw;
1511 if (pfile_in_zip_read_info->read_buffer==NULL)
1513 TRYFREE(pfile_in_zip_read_info);
1514 return UNZ_INTERNALERROR;
1517 pfile_in_zip_read_info->stream_initialised=0;
1520 *method = (int)s->cur_file_info.compression_method;
1525 switch (s->cur_file_info.flag & 0x06)
1527 case 6 : *level = 1; break;
1528 case 4 : *level = 2; break;
1529 case 2 : *level = 9; break;
1533 if ((s->cur_file_info.compression_method!=0) &&
1534 /* #ifdef HAVE_BZIP2 */
1535 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1537 (s->cur_file_info.compression_method!=Z_DEFLATED))
1541 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1542 pfile_in_zip_read_info->crc32=0;
1543 pfile_in_zip_read_info->total_out_64=0;
1544 pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
1545 pfile_in_zip_read_info->filestream=s->filestream;
1546 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1547 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1549 pfile_in_zip_read_info->stream.total_out = 0;
1551 if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
1554 pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
1555 pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
1556 pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
1557 pfile_in_zip_read_info->bstream.state = (voidpf)0;
1559 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1560 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1561 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1562 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1563 pfile_in_zip_read_info->stream.avail_in = 0;
1565 err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
1567 pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
1570 TRYFREE(pfile_in_zip_read_info);
1574 pfile_in_zip_read_info->raw=1;
1577 else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
1579 pfile_in_zip_read_info->stream.zalloc = Z_NULL;
1580 pfile_in_zip_read_info->stream.zfree = Z_NULL;
1581 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1582 pfile_in_zip_read_info->stream.next_in = 0;
1583 pfile_in_zip_read_info->stream.avail_in = 0;
1585 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1587 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
1590 TRYFREE(pfile_in_zip_read_info);
1593 /* windowBits is passed < 0 to tell that there is no zlib header.
1594 * Note that in this case inflate *requires* an extra "dummy" byte
1595 * after the compressed stream in order to complete decompression and
1596 * return Z_STREAM_END.
1597 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1598 * size of both compressed and uncompressed data
1601 pfile_in_zip_read_info->rest_read_compressed =
1602 s->cur_file_info.compressed_size ;
1603 pfile_in_zip_read_info->rest_read_uncompressed =
1604 s->cur_file_info.uncompressed_size ;
1607 pfile_in_zip_read_info->pos_in_zipfile =
1608 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1611 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1613 s->pfile_in_zip_read = pfile_in_zip_read_info;
1617 if (password != NULL)
1620 s->pcrc_32_tab = get_crc_table();
1621 init_keys(password,s->keys,s->pcrc_32_tab);
1622 if (ZSEEK64(s->z_filefunc, s->filestream,
1623 s->pfile_in_zip_read->pos_in_zipfile +
1624 s->pfile_in_zip_read->byte_before_the_zipfile,
1626 return UNZ_INTERNALERROR;
1627 if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
1628 return UNZ_INTERNALERROR;
1630 for (i = 0; i<12; i++)
1631 zdecode(s->keys,s->pcrc_32_tab,source[i]);
1633 s->pfile_in_zip_read->pos_in_zipfile+=12;
1642 extern int ZEXPORT unzOpenCurrentFile (unzFile file)
1644 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1647 extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
1649 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1652 extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
1654 return unzOpenCurrentFile3(file, method, level, raw, NULL);
1657 /** Addition for GDAL : START */
1659 extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
1662 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1665 return 0; //UNZ_PARAMERROR;
1666 pfile_in_zip_read_info=s->pfile_in_zip_read;
1667 if (pfile_in_zip_read_info==NULL)
1668 return 0; //UNZ_PARAMERROR;
1669 return pfile_in_zip_read_info->pos_in_zipfile +
1670 pfile_in_zip_read_info->byte_before_the_zipfile;
1673 /** Addition for GDAL : END */
1676 Read bytes from the current file.
1677 buf contain buffer where data must be copied
1678 len the size of buf.
1680 return the number of byte copied if somes bytes are copied
1681 return 0 if the end of file was reached
1682 return <0 with error code if there is an error
1683 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1685 extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
1690 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1692 return UNZ_PARAMERROR;
1694 pfile_in_zip_read_info=s->pfile_in_zip_read;
1696 if (pfile_in_zip_read_info==NULL)
1697 return UNZ_PARAMERROR;
1700 if (pfile_in_zip_read_info->read_buffer == NULL)
1701 return UNZ_END_OF_LIST_OF_FILE;
1705 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1707 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1709 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1710 (!(pfile_in_zip_read_info->raw)))
1711 pfile_in_zip_read_info->stream.avail_out =
1712 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1714 if ((len>pfile_in_zip_read_info->rest_read_compressed+
1715 pfile_in_zip_read_info->stream.avail_in) &&
1716 (pfile_in_zip_read_info->raw))
1717 pfile_in_zip_read_info->stream.avail_out =
1718 (uInt)pfile_in_zip_read_info->rest_read_compressed+
1719 pfile_in_zip_read_info->stream.avail_in;
1721 while (pfile_in_zip_read_info->stream.avail_out>0)
1723 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1724 (pfile_in_zip_read_info->rest_read_compressed>0))
1726 uInt uReadThis = UNZ_BUFSIZE;
1727 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1728 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1731 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1732 pfile_in_zip_read_info->filestream,
1733 pfile_in_zip_read_info->pos_in_zipfile +
1734 pfile_in_zip_read_info->byte_before_the_zipfile,
1735 ZLIB_FILEFUNC_SEEK_SET)!=0)
1737 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1738 pfile_in_zip_read_info->filestream,
1739 pfile_in_zip_read_info->read_buffer,
1740 uReadThis)!=uReadThis)
1748 for(i=0;i<uReadThis;i++)
1749 pfile_in_zip_read_info->read_buffer[i] =
1750 zdecode(s->keys,s->pcrc_32_tab,
1751 pfile_in_zip_read_info->read_buffer[i]);
1756 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1758 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1760 pfile_in_zip_read_info->stream.next_in =
1761 (Bytef*)pfile_in_zip_read_info->read_buffer;
1762 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1765 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1769 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1770 (pfile_in_zip_read_info->rest_read_compressed == 0))
1771 return (iRead==0) ? UNZ_EOF : iRead;
1773 if (pfile_in_zip_read_info->stream.avail_out <
1774 pfile_in_zip_read_info->stream.avail_in)
1775 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1777 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1779 for (i=0;i<uDoCopy;i++)
1780 *(pfile_in_zip_read_info->stream.next_out+i) =
1781 *(pfile_in_zip_read_info->stream.next_in+i);
1783 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
1785 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1786 pfile_in_zip_read_info->stream.next_out,
1788 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1789 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1790 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1791 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1792 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1793 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1796 else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
1799 uLong uTotalOutBefore,uTotalOutAfter;
1800 const Bytef *bufBefore;
1803 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
1804 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
1805 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
1806 pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
1807 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
1808 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
1809 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
1810 pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
1812 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
1813 bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
1815 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
1817 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
1818 uOutThis = uTotalOutAfter-uTotalOutBefore;
1820 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1822 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
1823 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
1824 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1826 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
1827 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
1828 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
1829 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
1830 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
1831 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
1833 if (err==BZ_STREAM_END)
1834 return (iRead==0) ? UNZ_EOF : iRead;
1841 ZPOS64_T uTotalOutBefore,uTotalOutAfter;
1842 const Bytef *bufBefore;
1844 int flush=Z_SYNC_FLUSH;
1846 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1847 bufBefore = pfile_in_zip_read_info->stream.next_out;
1850 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1851 pfile_in_zip_read_info->stream.avail_out) &&
1852 (pfile_in_zip_read_info->rest_read_compressed == 0))
1855 err=inflate(&pfile_in_zip_read_info->stream,flush);
1857 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1860 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1861 uOutThis = uTotalOutAfter-uTotalOutBefore;
1863 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1865 pfile_in_zip_read_info->crc32 =
1866 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1869 pfile_in_zip_read_info->rest_read_uncompressed -=
1872 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1874 if (err==Z_STREAM_END)
1875 return (iRead==0) ? UNZ_EOF : iRead;
1888 Give the current position in uncompressed data
1890 extern z_off_t ZEXPORT unztell (unzFile file)
1893 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1895 return UNZ_PARAMERROR;
1897 pfile_in_zip_read_info=s->pfile_in_zip_read;
1899 if (pfile_in_zip_read_info==NULL)
1900 return UNZ_PARAMERROR;
1902 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1905 extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
1909 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1911 return (ZPOS64_T)-1;
1913 pfile_in_zip_read_info=s->pfile_in_zip_read;
1915 if (pfile_in_zip_read_info==NULL)
1916 return (ZPOS64_T)-1;
1918 return pfile_in_zip_read_info->total_out_64;
1923 return 1 if the end of file was reached, 0 elsewhere
1925 extern int ZEXPORT unzeof (unzFile file)
1928 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1930 return UNZ_PARAMERROR;
1932 pfile_in_zip_read_info=s->pfile_in_zip_read;
1934 if (pfile_in_zip_read_info==NULL)
1935 return UNZ_PARAMERROR;
1937 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1946 Read extra field from the current file (opened by unzOpenCurrentFile)
1947 This is the local-header version of the extra field (sometimes, there is
1948 more info in the local-header version than in the central-header)
1950 if buf==NULL, it return the size of the local extra field that can be read
1952 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1954 the return value is the number of bytes copied in buf, or (if <0)
1957 extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
1960 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1962 ZPOS64_T size_to_read;
1965 return UNZ_PARAMERROR;
1967 pfile_in_zip_read_info=s->pfile_in_zip_read;
1969 if (pfile_in_zip_read_info==NULL)
1970 return UNZ_PARAMERROR;
1972 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1973 pfile_in_zip_read_info->pos_local_extrafield);
1976 return (int)size_to_read;
1978 if (len>size_to_read)
1979 read_now = (uInt)size_to_read;
1981 read_now = (uInt)len ;
1986 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1987 pfile_in_zip_read_info->filestream,
1988 pfile_in_zip_read_info->offset_local_extrafield +
1989 pfile_in_zip_read_info->pos_local_extrafield,
1990 ZLIB_FILEFUNC_SEEK_SET)!=0)
1993 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1994 pfile_in_zip_read_info->filestream,
1995 buf,read_now)!=read_now)
1998 return (int)read_now;
2002 Close the file in zip opened with unzipOpenCurrentFile
2003 Return UNZ_CRCERROR if all the file was read but the CRC is not good
2005 extern int ZEXPORT unzCloseCurrentFile (unzFile file)
2010 file_in_zip64_read_info_s* pfile_in_zip_read_info;
2012 return UNZ_PARAMERROR;
2014 pfile_in_zip_read_info=s->pfile_in_zip_read;
2016 if (pfile_in_zip_read_info==NULL)
2017 return UNZ_PARAMERROR;
2020 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
2021 (!pfile_in_zip_read_info->raw))
2023 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
2028 TRYFREE(pfile_in_zip_read_info->read_buffer);
2029 pfile_in_zip_read_info->read_buffer = NULL;
2030 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
2031 inflateEnd(&pfile_in_zip_read_info->stream);
2033 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
2034 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
2038 pfile_in_zip_read_info->stream_initialised = 0;
2039 TRYFREE(pfile_in_zip_read_info);
2041 s->pfile_in_zip_read=NULL;
2048 Get the global comment string of the ZipFile, in the szComment buffer.
2049 uSizeBuf is the size of the szComment buffer.
2050 return the number of byte copied or an error code <0
2052 extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
2057 return (int)UNZ_PARAMERROR;
2060 uReadThis = uSizeBuf;
2061 if (uReadThis>s->gi.size_comment)
2062 uReadThis = s->gi.size_comment;
2064 if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
2070 if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
2074 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
2075 *(szComment+s->gi.size_comment)='\0';
2076 return (int)uReadThis;
2079 /* Additions by RX '2004 */
2080 extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
2085 return 0; //UNZ_PARAMERROR;
2087 if (!s->current_file_ok)
2089 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
2090 if (s->num_file==s->gi.number_entry)
2092 return s->pos_in_central_dir;
2095 extern uLong ZEXPORT unzGetOffset (unzFile file)
2100 return 0; //UNZ_PARAMERROR;
2101 offset64 = unzGetOffset64(file);
2102 return (uLong)offset64;
2105 extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
2111 return UNZ_PARAMERROR;
2114 s->pos_in_central_dir = pos;
2115 s->num_file = s->gi.number_entry; /* hack */
2116 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
2117 &s->cur_file_info_internal,
2118 NULL,0,NULL,0,NULL,0);
2119 s->current_file_ok = (err == UNZ_OK);
2123 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
2125 return unzSetOffset64(file,pos);