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 patches received from Gilles Vollant
57 Oct-2009 - Mathias Svensson - Applied support to unzip files with compression method 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
91 /* compile with -Dlocal if your debugger can't find static symbols */
94 #ifndef CASESENSITIVITYDEFAULT_NO
95 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
96 # define CASESENSITIVITYDEFAULT_NO
102 #define UNZ_BUFSIZE (16384)
105 #ifndef UNZ_MAXFILENAMEINZIP
106 #define UNZ_MAXFILENAMEINZIP (256)
110 # define ALLOC(size) (malloc(size))
113 #define SIZECENTRALDIRITEM (0x2e)
114 #define SIZEZIPLOCALHEADER (0x1e)
117 const char unz_copyright[] =
118 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
120 /* unz_file_info64_internal contain internal info about a file in zipfile*/
121 typedef struct unz_file_info64_internal_s
123 ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
124 } unz_file_info64_internal;
127 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
128 when reading and decompress it */
131 char *read_buffer; /* internal buffer for compressed data */
132 z_stream stream; /* zLib stream structure for inflate */
135 bz_stream bstream; /* bzLib stream structure for bziped */
138 ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
139 uLong stream_initialised; /* flag set if stream structure is initialised*/
141 ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
142 uInt size_local_extrafield;/* size of the local extra field */
143 ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
144 ZPOS64_T total_out_64;
146 uLong crc32; /* crc32 of all data uncompressed */
147 uLong crc32_wait; /* crc32 we must obtain after decompress all */
148 ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
149 ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
150 zlib_filefunc64_32_def z_filefunc;
151 voidpf filestream; /* io structure of the zipfile */
152 uLong compression_method; /* compression method (0==store) */
153 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
155 } file_in_zip64_read_info_s;
158 /* unz64_s contain internal information about the zipfile
162 zlib_filefunc64_32_def z_filefunc;
163 int is64bitOpenFunction;
164 voidpf filestream; /* io structure of the zipfile */
165 unz_global_info64 gi; /* public global information */
166 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
167 ZPOS64_T num_file; /* number of the current file in the zipfile*/
168 ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
169 ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
170 ZPOS64_T central_pos; /* position of the beginning of the central dir*/
172 ZPOS64_T size_central_dir; /* size of the central directory */
173 ZPOS64_T offset_central_dir; /* offset of start of central directory with
174 respect to the starting disk number */
176 unz_file_info64 cur_file_info; /* public info about the current file in zip*/
177 unz_file_info64_internal cur_file_info_internal; /* private info about it*/
178 file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
179 file if we are decompressing it */
185 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
186 const z_crc_t* pcrc_32_tab;
196 /* ===========================================================================
197 Reads a long in LSB order from the given gz_stream. Sets
200 local int unz64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def,
204 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,2);
207 *pX = c[0] | ((uLong)c[1] << 8);
213 if (ZERROR64(*pzlib_filefunc_def,filestream))
220 local int unz64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def,
224 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,4);
227 *pX = c[0] | ((uLong)c[1] << 8) | ((uLong)c[2] << 16) | ((uLong)c[3] << 24);
233 if (ZERROR64(*pzlib_filefunc_def,filestream))
241 local int unz64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
245 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,8);
248 *pX = c[0] | ((ZPOS64_T)c[1] << 8) | ((ZPOS64_T)c[2] << 16) | ((ZPOS64_T)c[3] << 24)
249 | ((ZPOS64_T)c[4] << 32) | ((ZPOS64_T)c[5] << 40) | ((ZPOS64_T)c[6] << 48) | ((ZPOS64_T)c[7] << 56);
255 if (ZERROR64(*pzlib_filefunc_def,filestream))
262 /* My own strcmpi / strcasecmp */
263 local int strcmpcasenosensitive_internal(const char* fileName1, const char* fileName2) {
266 char c1=*(fileName1++);
267 char c2=*(fileName2++);
268 if ((c1>='a') && (c1<='z'))
270 if ((c2>='a') && (c2<='z'))
273 return ((c2=='\0') ? 0 : -1);
284 #ifdef CASESENSITIVITYDEFAULT_NO
285 #define CASESENSITIVITYDEFAULTVALUE 2
287 #define CASESENSITIVITYDEFAULTVALUE 1
290 #ifndef STRCMPCASENOSENTIVEFUNCTION
291 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
295 Compare two filenames (fileName1,fileName2).
296 If iCaseSensitivity = 1, comparison is case sensitive (like strcmp)
297 If iCaseSensitivity = 2, comparison is not case sensitive (like strcmpi
299 If iCaseSensitivity = 0, case sensitivity is default of your operating system
300 (like 1 on Unix, 2 on Windows)
303 extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
304 const char* fileName2,
305 int iCaseSensitivity) {
306 if (iCaseSensitivity==0)
307 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
309 if (iCaseSensitivity==1)
310 return strcmp(fileName1,fileName2);
312 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
315 #ifndef BUFREADCOMMENT
316 #define BUFREADCOMMENT (0x400)
319 #ifndef CENTRALDIRINVALID
320 #define CENTRALDIRINVALID ((ZPOS64_T)(-1))
324 Locate the Central directory of a zipfile (at the end, just before
327 local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) {
331 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
332 ZPOS64_T uPosFound=CENTRALDIRINVALID;
334 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
335 return CENTRALDIRINVALID;
338 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
340 if (uMaxBack>uSizeFile)
341 uMaxBack = uSizeFile;
343 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
345 return CENTRALDIRINVALID;
348 while (uBackRead<uMaxBack)
353 if (uBackRead+BUFREADCOMMENT>uMaxBack)
354 uBackRead = uMaxBack;
356 uBackRead+=BUFREADCOMMENT;
357 uReadPos = uSizeFile-uBackRead ;
359 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
360 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
361 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
364 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
367 for (i=(int)uReadSize-3; (i--)>0;)
368 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
369 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
371 uPosFound = uReadPos+(unsigned)i;
375 if (uPosFound!=CENTRALDIRINVALID)
384 Locate the Central directory 64 of a zipfile (at the end, just before
387 local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
392 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
393 ZPOS64_T uPosFound=CENTRALDIRINVALID;
395 ZPOS64_T relativeOffset;
397 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
398 return CENTRALDIRINVALID;
401 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
403 if (uMaxBack>uSizeFile)
404 uMaxBack = uSizeFile;
406 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
408 return CENTRALDIRINVALID;
411 while (uBackRead<uMaxBack)
416 if (uBackRead+BUFREADCOMMENT>uMaxBack)
417 uBackRead = uMaxBack;
419 uBackRead+=BUFREADCOMMENT;
420 uReadPos = uSizeFile-uBackRead ;
422 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
423 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
424 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
427 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
430 for (i=(int)uReadSize-3; (i--)>0;)
431 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
432 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
434 uPosFound = uReadPos+(unsigned)i;
438 if (uPosFound!=CENTRALDIRINVALID)
442 if (uPosFound == CENTRALDIRINVALID)
443 return CENTRALDIRINVALID;
445 /* Zip64 end of central directory locator */
446 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
447 return CENTRALDIRINVALID;
449 /* the signature, already checked */
450 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
451 return CENTRALDIRINVALID;
453 /* number of the disk with the start of the zip64 end of central directory */
454 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
455 return CENTRALDIRINVALID;
457 return CENTRALDIRINVALID;
459 /* relative offset of the zip64 end of central directory record */
460 if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
461 return CENTRALDIRINVALID;
463 /* total number of disks */
464 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
465 return CENTRALDIRINVALID;
467 return CENTRALDIRINVALID;
469 /* Goto end of central directory record */
470 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
471 return CENTRALDIRINVALID;
474 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
475 return CENTRALDIRINVALID;
477 if (uL != 0x06064b50)
478 return CENTRALDIRINVALID;
480 return relativeOffset;
484 Open a Zip file. path contain the full pathname (by example,
485 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
487 If the zipfile cannot be opened (file doesn't exist or in not valid), the
488 return value is NULL.
489 Else, the return value is a unzFile Handle, usable with other function
490 of this unzip package.
492 local unzFile unzOpenInternal(const void *path,
493 zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
494 int is64bitOpenFunction) {
497 ZPOS64_T central_pos;
500 uLong number_disk; /* number of the current disk, used for
501 spanning ZIP, unsupported, always 0*/
502 uLong number_disk_with_CD; /* number the disk with central dir, used
503 for spanning ZIP, unsupported, always 0*/
504 ZPOS64_T number_entry_CD; /* total number of entries in
506 (same than number_entry on nospan) */
510 if (unz_copyright[0]!=' ')
513 us.z_filefunc.zseek32_file = NULL;
514 us.z_filefunc.ztell32_file = NULL;
515 if (pzlib_filefunc64_32_def==NULL)
516 fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
518 us.z_filefunc = *pzlib_filefunc64_32_def;
519 us.is64bitOpenFunction = is64bitOpenFunction;
523 us.filestream = ZOPEN64(us.z_filefunc,
525 ZLIB_FILEFUNC_MODE_READ |
526 ZLIB_FILEFUNC_MODE_EXISTING);
527 if (us.filestream==NULL)
530 central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
531 if (central_pos!=CENTRALDIRINVALID)
538 if (ZSEEK64(us.z_filefunc, us.filestream,
539 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
542 /* the signature, already checked */
543 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
546 /* size of zip64 end of central directory record */
547 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
550 /* version made by */
551 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
554 /* version needed to extract */
555 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
558 /* number of this disk */
559 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
562 /* number of the disk with the start of the central directory */
563 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
566 /* total number of entries in the central directory on this disk */
567 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
570 /* total number of entries in the central directory */
571 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
574 if ((number_entry_CD!=us.gi.number_entry) ||
575 (number_disk_with_CD!=0) ||
579 /* size of the central directory */
580 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
583 /* offset of start of central directory with respect to the
584 starting disk number */
585 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
588 us.gi.size_comment = 0;
592 central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
593 if (central_pos==CENTRALDIRINVALID)
598 if (ZSEEK64(us.z_filefunc, us.filestream,
599 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
602 /* the signature, already checked */
603 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
606 /* number of this disk */
607 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
610 /* number of the disk with the start of the central directory */
611 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
614 /* total number of entries in the central dir on this disk */
615 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
617 us.gi.number_entry = uL;
619 /* total number of entries in the central dir */
620 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
622 number_entry_CD = uL;
624 if ((number_entry_CD!=us.gi.number_entry) ||
625 (number_disk_with_CD!=0) ||
629 /* size of the central directory */
630 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
632 us.size_central_dir = uL;
634 /* offset of start of central directory with respect to the
635 starting disk number */
636 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
638 us.offset_central_dir = uL;
640 /* zipfile comment length */
641 if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
645 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
651 ZCLOSE64(us.z_filefunc, us.filestream);
655 us.byte_before_the_zipfile = central_pos -
656 (us.offset_central_dir+us.size_central_dir);
657 us.central_pos = central_pos;
658 us.pfile_in_zip_read = NULL;
662 s=(unz64_s*)ALLOC(sizeof(unz64_s));
666 unzGoToFirstFile((unzFile)s);
672 extern unzFile ZEXPORT unzOpen2(const char *path,
673 zlib_filefunc_def* pzlib_filefunc32_def) {
674 if (pzlib_filefunc32_def != NULL)
676 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
677 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
678 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
681 return unzOpenInternal(path, NULL, 0);
684 extern unzFile ZEXPORT unzOpen2_64(const void *path,
685 zlib_filefunc64_def* pzlib_filefunc_def) {
686 if (pzlib_filefunc_def != NULL)
688 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
689 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
690 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
691 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
692 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
695 return unzOpenInternal(path, NULL, 1);
698 extern unzFile ZEXPORT unzOpen(const char *path) {
699 return unzOpenInternal(path, NULL, 0);
702 extern unzFile ZEXPORT unzOpen64(const void *path) {
703 return unzOpenInternal(path, NULL, 1);
707 Close a ZipFile opened with unzOpen.
708 If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
709 these files MUST be closed with unzCloseCurrentFile before call unzClose.
710 return UNZ_OK if there is no problem. */
711 extern int ZEXPORT unzClose(unzFile file) {
714 return UNZ_PARAMERROR;
717 if (s->pfile_in_zip_read!=NULL)
718 unzCloseCurrentFile(file);
720 ZCLOSE64(s->z_filefunc, s->filestream);
727 Write info about the ZipFile in the *pglobal_info structure.
728 No preparation of the structure is needed
729 return UNZ_OK if there is no problem. */
730 extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64* pglobal_info) {
733 return UNZ_PARAMERROR;
739 extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32) {
742 return UNZ_PARAMERROR;
744 /* to do : check if number_entry is not truncated */
745 pglobal_info32->number_entry = (uLong)s->gi.number_entry;
746 pglobal_info32->size_comment = s->gi.size_comment;
750 Translate date/time from Dos format to tm_unz (readable more easily)
752 local void unz64local_DosDateToTmuDate(ZPOS64_T ulDosDate, tm_unz* ptm) {
754 uDate = (ZPOS64_T)(ulDosDate>>16);
755 ptm->tm_mday = (int)(uDate&0x1f) ;
756 ptm->tm_mon = (int)((((uDate)&0x1E0)/0x20)-1) ;
757 ptm->tm_year = (int)(((uDate&0x0FE00)/0x0200)+1980) ;
759 ptm->tm_hour = (int) ((ulDosDate &0xF800)/0x800);
760 ptm->tm_min = (int) ((ulDosDate&0x7E0)/0x20) ;
761 ptm->tm_sec = (int) (2*(ulDosDate&0x1f)) ;
765 Get Info about the current file in the zipfile, with internal only info
767 local int unz64local_GetCurrentFileInfoInternal(unzFile file,
768 unz_file_info64 *pfile_info,
769 unz_file_info64_internal
770 *pfile_info_internal,
772 uLong fileNameBufferSize,
774 uLong extraFieldBufferSize,
776 uLong commentBufferSize) {
778 unz_file_info64 file_info;
779 unz_file_info64_internal file_info_internal;
786 return UNZ_PARAMERROR;
788 if (ZSEEK64(s->z_filefunc, s->filestream,
789 s->pos_in_central_dir+s->byte_before_the_zipfile,
790 ZLIB_FILEFUNC_SEEK_SET)!=0)
794 /* we check the magic */
797 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
799 else if (uMagic!=0x02014b50)
803 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
806 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
809 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
812 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
815 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
818 unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
820 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
823 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
825 file_info.compressed_size = uL;
827 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
829 file_info.uncompressed_size = uL;
831 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
834 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
837 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
840 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
843 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
846 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
849 // relative offset of local header
850 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
852 file_info_internal.offset_curfile = uL;
854 lSeek+=file_info.size_filename;
855 if ((err==UNZ_OK) && (szFileName!=NULL))
858 if (file_info.size_filename<fileNameBufferSize)
860 *(szFileName+file_info.size_filename)='\0';
861 uSizeRead = file_info.size_filename;
864 uSizeRead = fileNameBufferSize;
866 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
867 if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
873 if ((err==UNZ_OK) && (extraField!=NULL))
876 if (file_info.size_file_extra<extraFieldBufferSize)
877 uSizeRead = file_info.size_file_extra;
879 uSizeRead = extraFieldBufferSize;
883 if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
889 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
890 if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
893 lSeek += file_info.size_file_extra - (uLong)uSizeRead;
896 lSeek += file_info.size_file_extra;
899 if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
903 // since lSeek now points to after the extra field we need to move back
904 lSeek -= file_info.size_file_extra;
908 if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
914 while(acc < file_info.size_file_extra)
919 if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
922 if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
925 /* ZIP64 extra fields */
926 if (headerId == 0x0001)
928 if(file_info.uncompressed_size == MAXU32)
930 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
934 if(file_info.compressed_size == MAXU32)
936 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
940 if(file_info_internal.offset_curfile == MAXU32)
942 /* Relative Header offset */
943 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
947 if(file_info.disk_num_start == 0xffff)
949 /* Disk Start Number */
950 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
957 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
961 acc += 2 + 2 + dataSize;
965 if ((err==UNZ_OK) && (szComment!=NULL))
968 if (file_info.size_file_comment<commentBufferSize)
970 *(szComment+file_info.size_file_comment)='\0';
971 uSizeRead = file_info.size_file_comment;
974 uSizeRead = commentBufferSize;
978 if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
984 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
985 if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
987 lSeek+=file_info.size_file_comment - uSizeRead;
990 lSeek+=file_info.size_file_comment;
993 if ((err==UNZ_OK) && (pfile_info!=NULL))
994 *pfile_info=file_info;
996 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
997 *pfile_info_internal=file_info_internal;
1005 Write info about the ZipFile in the *pglobal_info structure.
1006 No preparation of the structure is needed
1007 return UNZ_OK if there is no problem.
1009 extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file,
1010 unz_file_info64 * pfile_info,
1011 char * szFileName, uLong fileNameBufferSize,
1012 void *extraField, uLong extraFieldBufferSize,
1013 char* szComment, uLong commentBufferSize) {
1014 return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
1015 szFileName,fileNameBufferSize,
1016 extraField,extraFieldBufferSize,
1017 szComment,commentBufferSize);
1020 extern int ZEXPORT unzGetCurrentFileInfo(unzFile file,
1021 unz_file_info * pfile_info,
1022 char * szFileName, uLong fileNameBufferSize,
1023 void *extraField, uLong extraFieldBufferSize,
1024 char* szComment, uLong commentBufferSize) {
1026 unz_file_info64 file_info64;
1027 err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
1028 szFileName,fileNameBufferSize,
1029 extraField,extraFieldBufferSize,
1030 szComment,commentBufferSize);
1031 if ((err==UNZ_OK) && (pfile_info != NULL))
1033 pfile_info->version = file_info64.version;
1034 pfile_info->version_needed = file_info64.version_needed;
1035 pfile_info->flag = file_info64.flag;
1036 pfile_info->compression_method = file_info64.compression_method;
1037 pfile_info->dosDate = file_info64.dosDate;
1038 pfile_info->crc = file_info64.crc;
1040 pfile_info->size_filename = file_info64.size_filename;
1041 pfile_info->size_file_extra = file_info64.size_file_extra;
1042 pfile_info->size_file_comment = file_info64.size_file_comment;
1044 pfile_info->disk_num_start = file_info64.disk_num_start;
1045 pfile_info->internal_fa = file_info64.internal_fa;
1046 pfile_info->external_fa = file_info64.external_fa;
1048 pfile_info->tmu_date = file_info64.tmu_date;
1051 pfile_info->compressed_size = (uLong)file_info64.compressed_size;
1052 pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
1058 Set the current file of the zipfile to the first file.
1059 return UNZ_OK if there is no problem
1061 extern int ZEXPORT unzGoToFirstFile(unzFile file) {
1065 return UNZ_PARAMERROR;
1067 s->pos_in_central_dir=s->offset_central_dir;
1069 err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1070 &s->cur_file_info_internal,
1071 NULL,0,NULL,0,NULL,0);
1072 s->current_file_ok = (err == UNZ_OK);
1077 Set the current file of the zipfile to the next file.
1078 return UNZ_OK if there is no problem
1079 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1081 extern int ZEXPORT unzGoToNextFile(unzFile file) {
1086 return UNZ_PARAMERROR;
1088 if (!s->current_file_ok)
1089 return UNZ_END_OF_LIST_OF_FILE;
1090 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
1091 if (s->num_file+1==s->gi.number_entry)
1092 return UNZ_END_OF_LIST_OF_FILE;
1094 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1095 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
1097 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1098 &s->cur_file_info_internal,
1099 NULL,0,NULL,0,NULL,0);
1100 s->current_file_ok = (err == UNZ_OK);
1106 Try locate the file szFileName in the zipfile.
1107 For the iCaseSensitivity signification, see unzStringFileNameCompare
1110 UNZ_OK if the file is found. It becomes the current file.
1111 UNZ_END_OF_LIST_OF_FILE if the file is not found
1113 extern int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity) {
1117 /* We remember the 'current' position in the file so that we can jump
1118 * back there if we fail.
1120 unz_file_info64 cur_file_infoSaved;
1121 unz_file_info64_internal cur_file_info_internalSaved;
1122 ZPOS64_T num_fileSaved;
1123 ZPOS64_T pos_in_central_dirSaved;
1127 return UNZ_PARAMERROR;
1129 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
1130 return UNZ_PARAMERROR;
1133 if (!s->current_file_ok)
1134 return UNZ_END_OF_LIST_OF_FILE;
1136 /* Save the current state */
1137 num_fileSaved = s->num_file;
1138 pos_in_central_dirSaved = s->pos_in_central_dir;
1139 cur_file_infoSaved = s->cur_file_info;
1140 cur_file_info_internalSaved = s->cur_file_info_internal;
1142 err = unzGoToFirstFile(file);
1144 while (err == UNZ_OK)
1146 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
1147 err = unzGetCurrentFileInfo64(file,NULL,
1148 szCurrentFileName,sizeof(szCurrentFileName)-1,
1152 if (unzStringFileNameCompare(szCurrentFileName,
1153 szFileName,iCaseSensitivity)==0)
1155 err = unzGoToNextFile(file);
1159 /* We failed, so restore the state of the 'current file' to where we
1162 s->num_file = num_fileSaved ;
1163 s->pos_in_central_dir = pos_in_central_dirSaved ;
1164 s->cur_file_info = cur_file_infoSaved;
1165 s->cur_file_info_internal = cur_file_info_internalSaved;
1171 ///////////////////////////////////////////
1172 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1173 // I need random access
1175 // Further optimization could be realized by adding an ability
1176 // to cache the directory in memory. The goal being a single
1177 // comprehensive file read to put the file I need in a memory.
1181 typedef struct unz_file_pos_s
1183 ZPOS64_T pos_in_zip_directory; // offset in file
1184 ZPOS64_T num_of_file; // # of file
1188 extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) {
1191 if (file==NULL || file_pos==NULL)
1192 return UNZ_PARAMERROR;
1194 if (!s->current_file_ok)
1195 return UNZ_END_OF_LIST_OF_FILE;
1197 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
1198 file_pos->num_of_file = s->num_file;
1203 extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos* file_pos) {
1204 unz64_file_pos file_pos64;
1205 int err = unzGetFilePos64(file,&file_pos64);
1208 file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
1209 file_pos->num_of_file = (uLong)file_pos64.num_of_file;
1214 extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) {
1218 if (file==NULL || file_pos==NULL)
1219 return UNZ_PARAMERROR;
1222 /* jump to the right spot */
1223 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1224 s->num_file = file_pos->num_of_file;
1226 /* set the current file */
1227 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1228 &s->cur_file_info_internal,
1229 NULL,0,NULL,0,NULL,0);
1230 /* return results */
1231 s->current_file_ok = (err == UNZ_OK);
1235 extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos* file_pos) {
1236 unz64_file_pos file_pos64;
1237 if (file_pos == NULL)
1238 return UNZ_PARAMERROR;
1240 file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
1241 file_pos64.num_of_file = file_pos->num_of_file;
1242 return unzGoToFilePos64(file,&file_pos64);
1246 // Unzip Helper Functions - should be here?
1247 ///////////////////////////////////////////
1251 Read the local header of the current zipfile
1252 Check the coherency of the local header and info in the end of central
1253 directory about this file
1254 store in *piSizeVar the size of extra info in local header
1255 (filename and size of extra field data)
1257 local int unz64local_CheckCurrentFileCoherencyHeader(unz64_s* s, uInt* piSizeVar,
1258 ZPOS64_T * poffset_local_extrafield,
1259 uInt * psize_local_extrafield) {
1260 uLong uMagic,uData,uFlags;
1261 uLong size_filename;
1262 uLong size_extra_field;
1266 *poffset_local_extrafield = 0;
1267 *psize_local_extrafield = 0;
1269 if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
1270 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
1276 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
1278 else if (uMagic!=0x04034b50)
1282 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1285 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1288 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1291 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1293 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1296 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1297 /* #ifdef HAVE_BZIP2 */
1298 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1300 (s->cur_file_info.compression_method!=Z_DEFLATED))
1303 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1306 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1308 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
1311 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1313 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
1316 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1318 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
1321 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1323 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1326 *piSizeVar += (uInt)size_filename;
1328 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1330 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1331 SIZEZIPLOCALHEADER + size_filename;
1332 *psize_local_extrafield = (uInt)size_extra_field;
1334 *piSizeVar += (uInt)size_extra_field;
1340 Open for reading data the current file in the zipfile.
1341 If there is no error and the file is opened, the return value is UNZ_OK.
1343 extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method,
1344 int* level, int raw, const char* password) {
1348 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1349 ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
1350 uInt size_local_extrafield; /* size of the local extra field */
1354 if (password != NULL)
1355 return UNZ_PARAMERROR;
1359 return UNZ_PARAMERROR;
1361 if (!s->current_file_ok)
1362 return UNZ_PARAMERROR;
1364 if (s->pfile_in_zip_read != NULL)
1365 unzCloseCurrentFile(file);
1367 if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1368 return UNZ_BADZIPFILE;
1370 pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
1371 if (pfile_in_zip_read_info==NULL)
1372 return UNZ_INTERNALERROR;
1374 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1375 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1376 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1377 pfile_in_zip_read_info->pos_local_extrafield=0;
1378 pfile_in_zip_read_info->raw=raw;
1380 if (pfile_in_zip_read_info->read_buffer==NULL)
1382 free(pfile_in_zip_read_info);
1383 return UNZ_INTERNALERROR;
1386 pfile_in_zip_read_info->stream_initialised=0;
1389 *method = (int)s->cur_file_info.compression_method;
1394 switch (s->cur_file_info.flag & 0x06)
1396 case 6 : *level = 1; break;
1397 case 4 : *level = 2; break;
1398 case 2 : *level = 9; break;
1402 if ((s->cur_file_info.compression_method!=0) &&
1403 /* #ifdef HAVE_BZIP2 */
1404 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1406 (s->cur_file_info.compression_method!=Z_DEFLATED))
1410 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1411 pfile_in_zip_read_info->crc32=0;
1412 pfile_in_zip_read_info->total_out_64=0;
1413 pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
1414 pfile_in_zip_read_info->filestream=s->filestream;
1415 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1416 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1418 pfile_in_zip_read_info->stream.total_out = 0;
1420 if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
1423 pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
1424 pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
1425 pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
1426 pfile_in_zip_read_info->bstream.state = (voidpf)0;
1428 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1429 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1430 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1431 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1432 pfile_in_zip_read_info->stream.avail_in = 0;
1434 err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
1436 pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
1439 free(pfile_in_zip_read_info->read_buffer);
1440 free(pfile_in_zip_read_info);
1444 pfile_in_zip_read_info->raw=1;
1447 else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
1449 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1450 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1451 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1452 pfile_in_zip_read_info->stream.next_in = 0;
1453 pfile_in_zip_read_info->stream.avail_in = 0;
1455 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1457 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
1460 free(pfile_in_zip_read_info->read_buffer);
1461 free(pfile_in_zip_read_info);
1464 /* windowBits is passed < 0 to tell that there is no zlib header.
1465 * Note that in this case inflate *requires* an extra "dummy" byte
1466 * after the compressed stream in order to complete decompression and
1467 * return Z_STREAM_END.
1468 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1469 * size of both compressed and uncompressed data
1472 pfile_in_zip_read_info->rest_read_compressed =
1473 s->cur_file_info.compressed_size ;
1474 pfile_in_zip_read_info->rest_read_uncompressed =
1475 s->cur_file_info.uncompressed_size ;
1478 pfile_in_zip_read_info->pos_in_zipfile =
1479 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1482 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1484 s->pfile_in_zip_read = pfile_in_zip_read_info;
1488 if (password != NULL)
1491 s->pcrc_32_tab = get_crc_table();
1492 init_keys(password,s->keys,s->pcrc_32_tab);
1493 if (ZSEEK64(s->z_filefunc, s->filestream,
1494 s->pfile_in_zip_read->pos_in_zipfile +
1495 s->pfile_in_zip_read->byte_before_the_zipfile,
1497 return UNZ_INTERNALERROR;
1498 if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
1499 return UNZ_INTERNALERROR;
1501 for (i = 0; i<12; i++)
1502 zdecode(s->keys,s->pcrc_32_tab,source[i]);
1504 s->pfile_in_zip_read->pos_in_zipfile+=12;
1513 extern int ZEXPORT unzOpenCurrentFile(unzFile file) {
1514 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1517 extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char* password) {
1518 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1521 extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int* method, int* level, int raw) {
1522 return unzOpenCurrentFile3(file, method, level, raw, NULL);
1525 /** Addition for GDAL : START */
1527 extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file) {
1529 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1532 return 0; //UNZ_PARAMERROR;
1533 pfile_in_zip_read_info=s->pfile_in_zip_read;
1534 if (pfile_in_zip_read_info==NULL)
1535 return 0; //UNZ_PARAMERROR;
1536 return pfile_in_zip_read_info->pos_in_zipfile +
1537 pfile_in_zip_read_info->byte_before_the_zipfile;
1540 /** Addition for GDAL : END */
1543 Read bytes from the current file.
1544 buf contain buffer where data must be copied
1545 len the size of buf.
1547 return the number of byte copied if some bytes are copied
1548 return 0 if the end of file was reached
1549 return <0 with error code if there is an error
1550 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1552 extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len) {
1556 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1558 return UNZ_PARAMERROR;
1560 pfile_in_zip_read_info=s->pfile_in_zip_read;
1562 if (pfile_in_zip_read_info==NULL)
1563 return UNZ_PARAMERROR;
1566 if (pfile_in_zip_read_info->read_buffer == NULL)
1567 return UNZ_END_OF_LIST_OF_FILE;
1571 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1573 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1575 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1576 (!(pfile_in_zip_read_info->raw)))
1577 pfile_in_zip_read_info->stream.avail_out =
1578 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1580 if ((len>pfile_in_zip_read_info->rest_read_compressed+
1581 pfile_in_zip_read_info->stream.avail_in) &&
1582 (pfile_in_zip_read_info->raw))
1583 pfile_in_zip_read_info->stream.avail_out =
1584 (uInt)pfile_in_zip_read_info->rest_read_compressed+
1585 pfile_in_zip_read_info->stream.avail_in;
1587 while (pfile_in_zip_read_info->stream.avail_out>0)
1589 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1590 (pfile_in_zip_read_info->rest_read_compressed>0))
1592 uInt uReadThis = UNZ_BUFSIZE;
1593 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1594 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1597 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1598 pfile_in_zip_read_info->filestream,
1599 pfile_in_zip_read_info->pos_in_zipfile +
1600 pfile_in_zip_read_info->byte_before_the_zipfile,
1601 ZLIB_FILEFUNC_SEEK_SET)!=0)
1603 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1604 pfile_in_zip_read_info->filestream,
1605 pfile_in_zip_read_info->read_buffer,
1606 uReadThis)!=uReadThis)
1614 for(i=0;i<uReadThis;i++)
1615 pfile_in_zip_read_info->read_buffer[i] =
1616 zdecode(s->keys,s->pcrc_32_tab,
1617 pfile_in_zip_read_info->read_buffer[i]);
1622 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1624 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1626 pfile_in_zip_read_info->stream.next_in =
1627 (Bytef*)pfile_in_zip_read_info->read_buffer;
1628 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1631 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1635 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1636 (pfile_in_zip_read_info->rest_read_compressed == 0))
1637 return (iRead==0) ? UNZ_EOF : (int)iRead;
1639 if (pfile_in_zip_read_info->stream.avail_out <
1640 pfile_in_zip_read_info->stream.avail_in)
1641 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1643 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1645 for (i=0;i<uDoCopy;i++)
1646 *(pfile_in_zip_read_info->stream.next_out+i) =
1647 *(pfile_in_zip_read_info->stream.next_in+i);
1649 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
1651 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1652 pfile_in_zip_read_info->stream.next_out,
1654 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1655 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1656 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1657 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1658 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1659 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1662 else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
1665 uLong uTotalOutBefore,uTotalOutAfter;
1666 const Bytef *bufBefore;
1669 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
1670 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
1671 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
1672 pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
1673 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
1674 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
1675 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
1676 pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
1678 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
1679 bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
1681 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
1683 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
1684 uOutThis = uTotalOutAfter-uTotalOutBefore;
1686 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1688 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
1689 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
1690 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1692 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
1693 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
1694 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
1695 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
1696 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
1697 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
1699 if (err==BZ_STREAM_END)
1700 return (iRead==0) ? UNZ_EOF : iRead;
1707 ZPOS64_T uTotalOutBefore,uTotalOutAfter;
1708 const Bytef *bufBefore;
1710 int flush=Z_SYNC_FLUSH;
1712 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1713 bufBefore = pfile_in_zip_read_info->stream.next_out;
1716 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1717 pfile_in_zip_read_info->stream.avail_out) &&
1718 (pfile_in_zip_read_info->rest_read_compressed == 0))
1721 err=inflate(&pfile_in_zip_read_info->stream,flush);
1723 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1726 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1727 /* Detect overflow, because z_stream.total_out is uLong (32 bits) */
1728 if (uTotalOutAfter<uTotalOutBefore)
1729 uTotalOutAfter += 1LL << 32; /* Add maximum value of uLong + 1 */
1730 uOutThis = uTotalOutAfter-uTotalOutBefore;
1732 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1734 pfile_in_zip_read_info->crc32 =
1735 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1738 pfile_in_zip_read_info->rest_read_uncompressed -=
1741 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1743 if (err==Z_STREAM_END)
1744 return (iRead==0) ? UNZ_EOF : (int)iRead;
1757 Give the current position in uncompressed data
1759 extern z_off_t ZEXPORT unztell(unzFile file) {
1761 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1763 return UNZ_PARAMERROR;
1765 pfile_in_zip_read_info=s->pfile_in_zip_read;
1767 if (pfile_in_zip_read_info==NULL)
1768 return UNZ_PARAMERROR;
1770 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1773 extern ZPOS64_T ZEXPORT unztell64(unzFile file) {
1776 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1778 return (ZPOS64_T)-1;
1780 pfile_in_zip_read_info=s->pfile_in_zip_read;
1782 if (pfile_in_zip_read_info==NULL)
1783 return (ZPOS64_T)-1;
1785 return pfile_in_zip_read_info->total_out_64;
1790 return 1 if the end of file was reached, 0 elsewhere
1792 extern int ZEXPORT unzeof(unzFile file) {
1794 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1796 return UNZ_PARAMERROR;
1798 pfile_in_zip_read_info=s->pfile_in_zip_read;
1800 if (pfile_in_zip_read_info==NULL)
1801 return UNZ_PARAMERROR;
1803 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1812 Read extra field from the current file (opened by unzOpenCurrentFile)
1813 This is the local-header version of the extra field (sometimes, there is
1814 more info in the local-header version than in the central-header)
1816 if buf==NULL, it return the size of the local extra field that can be read
1818 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1820 the return value is the number of bytes copied in buf, or (if <0)
1823 extern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len) {
1825 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1827 ZPOS64_T size_to_read;
1830 return UNZ_PARAMERROR;
1832 pfile_in_zip_read_info=s->pfile_in_zip_read;
1834 if (pfile_in_zip_read_info==NULL)
1835 return UNZ_PARAMERROR;
1837 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1838 pfile_in_zip_read_info->pos_local_extrafield);
1841 return (int)size_to_read;
1843 if (len>size_to_read)
1844 read_now = (uInt)size_to_read;
1846 read_now = (uInt)len ;
1851 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1852 pfile_in_zip_read_info->filestream,
1853 pfile_in_zip_read_info->offset_local_extrafield +
1854 pfile_in_zip_read_info->pos_local_extrafield,
1855 ZLIB_FILEFUNC_SEEK_SET)!=0)
1858 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1859 pfile_in_zip_read_info->filestream,
1860 buf,read_now)!=read_now)
1863 return (int)read_now;
1867 Close the file in zip opened with unzOpenCurrentFile
1868 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1870 extern int ZEXPORT unzCloseCurrentFile(unzFile file) {
1874 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1876 return UNZ_PARAMERROR;
1878 pfile_in_zip_read_info=s->pfile_in_zip_read;
1880 if (pfile_in_zip_read_info==NULL)
1881 return UNZ_PARAMERROR;
1884 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1885 (!pfile_in_zip_read_info->raw))
1887 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1892 free(pfile_in_zip_read_info->read_buffer);
1893 pfile_in_zip_read_info->read_buffer = NULL;
1894 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
1895 inflateEnd(&pfile_in_zip_read_info->stream);
1897 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
1898 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
1902 pfile_in_zip_read_info->stream_initialised = 0;
1903 free(pfile_in_zip_read_info);
1905 s->pfile_in_zip_read=NULL;
1912 Get the global comment string of the ZipFile, in the szComment buffer.
1913 uSizeBuf is the size of the szComment buffer.
1914 return the number of byte copied or an error code <0
1916 extern int ZEXPORT unzGetGlobalComment(unzFile file, char * szComment, uLong uSizeBuf) {
1920 return (int)UNZ_PARAMERROR;
1923 uReadThis = uSizeBuf;
1924 if (uReadThis>s->gi.size_comment)
1925 uReadThis = s->gi.size_comment;
1927 if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1933 if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1937 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1938 *(szComment+s->gi.size_comment)='\0';
1939 return (int)uReadThis;
1942 /* Additions by RX '2004 */
1943 extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) {
1947 return 0; //UNZ_PARAMERROR;
1949 if (!s->current_file_ok)
1951 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1952 if (s->num_file==s->gi.number_entry)
1954 return s->pos_in_central_dir;
1957 extern uLong ZEXPORT unzGetOffset(unzFile file) {
1961 return 0; //UNZ_PARAMERROR;
1962 offset64 = unzGetOffset64(file);
1963 return (uLong)offset64;
1966 extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) {
1971 return UNZ_PARAMERROR;
1974 s->pos_in_central_dir = pos;
1975 s->num_file = s->gi.number_entry; /* hack */
1976 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1977 &s->cur_file_info_internal,
1978 NULL,0,NULL,0,NULL,0);
1979 s->current_file_ok = (err == UNZ_OK);
1983 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) {
1984 return unzSetOffset64(file,pos);