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, voidpf filestream, int *pi)
215 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
223 if (ZERROR64(*pzlib_filefunc_def,filestream))
231 /* ===========================================================================
232 Reads a long in LSB order from the given gz_stream. Sets
234 local int unz64local_getShort OF((
235 const zlib_filefunc64_32_def* pzlib_filefunc_def,
239 local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
247 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
251 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
261 local int unz64local_getLong OF((
262 const zlib_filefunc64_32_def* pzlib_filefunc_def,
266 local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
274 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
278 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
282 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
286 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
296 local int unz64local_getLong64 OF((
297 const zlib_filefunc64_32_def* pzlib_filefunc_def,
302 local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
310 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
314 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
315 x |= ((ZPOS64_T)i)<<8;
318 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
319 x |= ((ZPOS64_T)i)<<16;
322 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
323 x |= ((ZPOS64_T)i)<<24;
326 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
327 x |= ((ZPOS64_T)i)<<32;
330 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
331 x |= ((ZPOS64_T)i)<<40;
334 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
335 x |= ((ZPOS64_T)i)<<48;
338 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
339 x |= ((ZPOS64_T)i)<<56;
348 /* My own strcmpi / strcasecmp */
349 local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
353 char c1=*(fileName1++);
354 char c2=*(fileName2++);
355 if ((c1>='a') && (c1<='z'))
357 if ((c2>='a') && (c2<='z'))
360 return ((c2=='\0') ? 0 : -1);
371 #ifdef CASESENSITIVITYDEFAULT_NO
372 #define CASESENSITIVITYDEFAULTVALUE 2
374 #define CASESENSITIVITYDEFAULTVALUE 1
377 #ifndef STRCMPCASENOSENTIVEFUNCTION
378 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
382 Compare two filename (fileName1,fileName2).
383 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
384 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
386 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
387 (like 1 on Unix, 2 on Windows)
390 extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
391 const char* fileName2,
392 int iCaseSensitivity)
395 if (iCaseSensitivity==0)
396 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
398 if (iCaseSensitivity==1)
399 return strcmp(fileName1,fileName2);
401 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
404 #ifndef BUFREADCOMMENT
405 #define BUFREADCOMMENT (0x400)
409 Locate the Central directory of a zipfile (at the end, just before
412 local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
413 local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
418 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
419 ZPOS64_T uPosFound=0;
421 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
425 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
427 if (uMaxBack>uSizeFile)
428 uMaxBack = uSizeFile;
430 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
435 while (uBackRead<uMaxBack)
440 if (uBackRead+BUFREADCOMMENT>uMaxBack)
441 uBackRead = uMaxBack;
443 uBackRead+=BUFREADCOMMENT;
444 uReadPos = uSizeFile-uBackRead ;
446 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
447 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
448 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
451 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
454 for (i=(int)uReadSize-3; (i--)>0;)
455 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
456 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
458 uPosFound = uReadPos+i;
471 Locate the Central directory 64 of a zipfile (at the end, just before
474 local ZPOS64_T unz64local_SearchCentralDir64 OF((
475 const zlib_filefunc64_32_def* pzlib_filefunc_def,
478 local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
484 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
485 ZPOS64_T uPosFound=0;
487 ZPOS64_T relativeOffset;
489 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
493 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
495 if (uMaxBack>uSizeFile)
496 uMaxBack = uSizeFile;
498 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
503 while (uBackRead<uMaxBack)
508 if (uBackRead+BUFREADCOMMENT>uMaxBack)
509 uBackRead = uMaxBack;
511 uBackRead+=BUFREADCOMMENT;
512 uReadPos = uSizeFile-uBackRead ;
514 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
515 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
516 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
519 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
522 for (i=(int)uReadSize-3; (i--)>0;)
523 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
524 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
526 uPosFound = uReadPos+i;
537 /* Zip64 end of central directory locator */
538 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
541 /* the signature, already checked */
542 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
545 /* number of the disk with the start of the zip64 end of central directory */
546 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
551 /* relative offset of the zip64 end of central directory record */
552 if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
555 /* total number of disks */
556 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
561 /* Goto end of central directory record */
562 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
566 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
569 if (uL != 0x06064b50)
572 return relativeOffset;
576 Open a Zip file. path contain the full pathname (by example,
577 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
579 If the zipfile cannot be opened (file doesn't exist or in not valid), the
580 return value is NULL.
581 Else, the return value is a unzFile Handle, usable with other function
582 of this unzip package.
584 local unzFile unzOpenInternal (const void *path,
585 zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
586 int is64bitOpenFunction)
589 memset(&us,0,sizeof(unz64_s));
592 ZPOS64_T central_pos;
595 uLong number_disk; /* number of the current dist, used for
596 spaning ZIP, unsupported, always 0*/
597 uLong number_disk_with_CD; /* number the the disk with central dir, used
598 for spaning ZIP, unsupported, always 0*/
599 ZPOS64_T number_entry_CD; /* total number of entries in
601 (same than number_entry on nospan) */
605 if (unz_copyright[0]!=' ')
608 us.z_filefunc.zseek32_file = NULL;
609 us.z_filefunc.ztell32_file = NULL;
610 if (pzlib_filefunc64_32_def==NULL)
611 fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
613 us.z_filefunc = *pzlib_filefunc64_32_def;
614 us.is64bitOpenFunction = is64bitOpenFunction;
618 us.filestream = ZOPEN64(us.z_filefunc,
620 ZLIB_FILEFUNC_MODE_READ |
621 ZLIB_FILEFUNC_MODE_EXISTING);
622 if (us.filestream==NULL)
625 central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
633 if (ZSEEK64(us.z_filefunc, us.filestream,
634 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
637 /* the signature, already checked */
638 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
641 /* size of zip64 end of central directory record */
642 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
645 /* version made by */
646 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
649 /* version needed to extract */
650 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
653 /* number of this disk */
654 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
657 /* number of the disk with the start of the central directory */
658 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
661 /* total number of entries in the central directory on this disk */
662 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
665 /* total number of entries in the central directory */
666 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
669 if ((number_entry_CD!=us.gi.number_entry) ||
670 (number_disk_with_CD!=0) ||
674 /* size of the central directory */
675 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
678 /* offset of start of central directory with respect to the
679 starting disk number */
680 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
683 us.gi.size_comment = 0;
687 central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
693 if (ZSEEK64(us.z_filefunc, us.filestream,
694 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
697 /* the signature, already checked */
698 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
701 /* number of this disk */
702 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
705 /* number of the disk with the start of the central directory */
706 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
709 /* total number of entries in the central dir on this disk */
710 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
712 us.gi.number_entry = uL;
714 /* total number of entries in the central dir */
715 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
717 number_entry_CD = uL;
719 if ((number_entry_CD!=us.gi.number_entry) ||
720 (number_disk_with_CD!=0) ||
724 /* size of the central directory */
725 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
727 us.size_central_dir = uL;
729 /* offset of start of central directory with respect to the
730 starting disk number */
731 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
733 us.offset_central_dir = uL;
735 /* zipfile comment length */
736 if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
740 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
746 ZCLOSE64(us.z_filefunc, us.filestream);
750 us.byte_before_the_zipfile = central_pos -
751 (us.offset_central_dir+us.size_central_dir);
752 us.central_pos = central_pos;
753 us.pfile_in_zip_read = NULL;
757 s=(unz64_s*)ALLOC(sizeof(unz64_s));
761 unzGoToFirstFile((unzFile)s);
767 extern unzFile ZEXPORT unzOpen2 (const char *path,
768 zlib_filefunc_def* pzlib_filefunc32_def)
770 if (pzlib_filefunc32_def != NULL)
772 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
773 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
774 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
777 return unzOpenInternal(path, NULL, 0);
780 extern unzFile ZEXPORT unzOpen2_64 (const void *path,
781 zlib_filefunc64_def* pzlib_filefunc_def)
783 if (pzlib_filefunc_def != NULL)
785 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
786 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
787 zlib_filefunc64_32_def_fill.zopen32_file = NULL;
788 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
789 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
790 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
793 return unzOpenInternal(path, NULL, 1);
796 extern unzFile ZEXPORT unzOpen (const char *path)
798 return unzOpenInternal(path, NULL, 0);
801 extern unzFile ZEXPORT unzOpen64 (const void *path)
803 return unzOpenInternal(path, NULL, 1);
807 Close a ZipFile opened with unzipOpen.
808 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
809 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
810 return UNZ_OK if there is no problem. */
811 extern int ZEXPORT unzClose (unzFile file)
815 return UNZ_PARAMERROR;
818 if (s->pfile_in_zip_read!=NULL)
819 unzCloseCurrentFile(file);
821 ZCLOSE64(s->z_filefunc, s->filestream);
828 Write info about the ZipFile in the *pglobal_info structure.
829 No preparation of the structure is needed
830 return UNZ_OK if there is no problem. */
831 extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
835 return UNZ_PARAMERROR;
841 extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
845 return UNZ_PARAMERROR;
847 /* to do : check if number_entry is not truncated */
848 pglobal_info32->number_entry = (uLong)s->gi.number_entry;
849 pglobal_info32->size_comment = s->gi.size_comment;
853 Translate date/time from Dos format to tm_unz (readable more easilty)
855 local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
858 uDate = (ZPOS64_T)(ulDosDate>>16);
859 ptm->tm_mday = (uInt)(uDate&0x1f) ;
860 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
861 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
863 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
864 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
865 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
869 Get Info about the current file in the zipfile, with internal only info
871 local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
872 unz_file_info64 *pfile_info,
873 unz_file_info64_internal
874 *pfile_info_internal,
876 uLong fileNameBufferSize,
878 uLong extraFieldBufferSize,
880 uLong commentBufferSize));
882 local int unz64local_GetCurrentFileInfoInternal (unzFile file,
883 unz_file_info64 *pfile_info,
884 unz_file_info64_internal
885 *pfile_info_internal,
887 uLong fileNameBufferSize,
889 uLong extraFieldBufferSize,
891 uLong commentBufferSize)
894 unz_file_info64 file_info;
895 unz_file_info64_internal file_info_internal;
902 return UNZ_PARAMERROR;
904 if (ZSEEK64(s->z_filefunc, s->filestream,
905 s->pos_in_central_dir+s->byte_before_the_zipfile,
906 ZLIB_FILEFUNC_SEEK_SET)!=0)
910 /* we check the magic */
913 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
915 else if (uMagic!=0x02014b50)
919 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
922 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
925 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
928 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
931 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
934 unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
936 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
939 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
941 file_info.compressed_size = uL;
943 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
945 file_info.uncompressed_size = uL;
947 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
950 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
953 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
956 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
959 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
962 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
965 // relative offset of local header
966 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
968 file_info_internal.offset_curfile = uL;
970 lSeek+=file_info.size_filename;
971 if ((err==UNZ_OK) && (szFileName!=NULL))
974 if (file_info.size_filename<fileNameBufferSize)
976 *(szFileName+file_info.size_filename)='\0';
977 uSizeRead = file_info.size_filename;
980 uSizeRead = fileNameBufferSize;
982 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
983 if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
989 if ((err==UNZ_OK) && (extraField!=NULL))
992 if (file_info.size_file_extra<extraFieldBufferSize)
993 uSizeRead = file_info.size_file_extra;
995 uSizeRead = extraFieldBufferSize;
999 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1005 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
1006 if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
1009 lSeek += file_info.size_file_extra - (uLong)uSizeRead;
1012 lSeek += file_info.size_file_extra;
1015 if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
1019 // since lSeek now points to after the extra field we need to move back
1020 lSeek -= file_info.size_file_extra;
1024 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1030 while(acc < file_info.size_file_extra)
1035 if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
1038 if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
1041 /* ZIP64 extra fields */
1042 if (headerId == 0x0001)
1046 if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)
1048 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
1052 if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)
1054 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
1058 if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)
1060 /* Relative Header offset */
1061 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
1065 if(file_info.disk_num_start == (unsigned long)-1)
1067 /* Disk Start Number */
1068 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
1075 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
1079 acc += 2 + 2 + dataSize;
1083 if ((err==UNZ_OK) && (szComment!=NULL))
1086 if (file_info.size_file_comment<commentBufferSize)
1088 *(szComment+file_info.size_file_comment)='\0';
1089 uSizeRead = file_info.size_file_comment;
1092 uSizeRead = commentBufferSize;
1096 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1102 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
1103 if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
1105 lSeek+=file_info.size_file_comment - uSizeRead;
1108 lSeek+=file_info.size_file_comment;
1111 if ((err==UNZ_OK) && (pfile_info!=NULL))
1112 *pfile_info=file_info;
1114 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
1115 *pfile_info_internal=file_info_internal;
1123 Write info about the ZipFile in the *pglobal_info structure.
1124 No preparation of the structure is needed
1125 return UNZ_OK if there is no problem.
1127 extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
1128 unz_file_info64 * pfile_info,
1129 char * szFileName, uLong fileNameBufferSize,
1130 void *extraField, uLong extraFieldBufferSize,
1131 char* szComment, uLong commentBufferSize)
1133 return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
1134 szFileName,fileNameBufferSize,
1135 extraField,extraFieldBufferSize,
1136 szComment,commentBufferSize);
1139 extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
1140 unz_file_info * pfile_info,
1141 char * szFileName, uLong fileNameBufferSize,
1142 void *extraField, uLong extraFieldBufferSize,
1143 char* szComment, uLong commentBufferSize)
1146 unz_file_info64 file_info64;
1147 err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
1148 szFileName,fileNameBufferSize,
1149 extraField,extraFieldBufferSize,
1150 szComment,commentBufferSize);
1153 pfile_info->version = file_info64.version;
1154 pfile_info->version_needed = file_info64.version_needed;
1155 pfile_info->flag = file_info64.flag;
1156 pfile_info->compression_method = file_info64.compression_method;
1157 pfile_info->dosDate = file_info64.dosDate;
1158 pfile_info->crc = file_info64.crc;
1160 pfile_info->size_filename = file_info64.size_filename;
1161 pfile_info->size_file_extra = file_info64.size_file_extra;
1162 pfile_info->size_file_comment = file_info64.size_file_comment;
1164 pfile_info->disk_num_start = file_info64.disk_num_start;
1165 pfile_info->internal_fa = file_info64.internal_fa;
1166 pfile_info->external_fa = file_info64.external_fa;
1168 pfile_info->tmu_date = file_info64.tmu_date,
1171 pfile_info->compressed_size = (uLong)file_info64.compressed_size;
1172 pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
1178 Set the current file of the zipfile to the first file.
1179 return UNZ_OK if there is no problem
1181 extern int ZEXPORT unzGoToFirstFile (unzFile file)
1186 return UNZ_PARAMERROR;
1188 s->pos_in_central_dir=s->offset_central_dir;
1190 err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1191 &s->cur_file_info_internal,
1192 NULL,0,NULL,0,NULL,0);
1193 s->current_file_ok = (err == UNZ_OK);
1198 Set the current file of the zipfile to the next file.
1199 return UNZ_OK if there is no problem
1200 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1202 extern int ZEXPORT unzGoToNextFile (unzFile file)
1208 return UNZ_PARAMERROR;
1210 if (!s->current_file_ok)
1211 return UNZ_END_OF_LIST_OF_FILE;
1212 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
1213 if (s->num_file+1==s->gi.number_entry)
1214 return UNZ_END_OF_LIST_OF_FILE;
1216 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1217 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
1219 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1220 &s->cur_file_info_internal,
1221 NULL,0,NULL,0,NULL,0);
1222 s->current_file_ok = (err == UNZ_OK);
1228 Try locate the file szFileName in the zipfile.
1229 For the iCaseSensitivity signification, see unzipStringFileNameCompare
1232 UNZ_OK if the file is found. It becomes the current file.
1233 UNZ_END_OF_LIST_OF_FILE if the file is not found
1235 extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
1240 /* We remember the 'current' position in the file so that we can jump
1241 * back there if we fail.
1243 unz_file_info64 cur_file_infoSaved;
1244 unz_file_info64_internal cur_file_info_internalSaved;
1245 ZPOS64_T num_fileSaved;
1246 ZPOS64_T pos_in_central_dirSaved;
1250 return UNZ_PARAMERROR;
1252 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
1253 return UNZ_PARAMERROR;
1256 if (!s->current_file_ok)
1257 return UNZ_END_OF_LIST_OF_FILE;
1259 /* Save the current state */
1260 num_fileSaved = s->num_file;
1261 pos_in_central_dirSaved = s->pos_in_central_dir;
1262 cur_file_infoSaved = s->cur_file_info;
1263 cur_file_info_internalSaved = s->cur_file_info_internal;
1265 err = unzGoToFirstFile(file);
1267 while (err == UNZ_OK)
1269 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
1270 err = unzGetCurrentFileInfo64(file,NULL,
1271 szCurrentFileName,sizeof(szCurrentFileName)-1,
1275 if (unzStringFileNameCompare(szCurrentFileName,
1276 szFileName,iCaseSensitivity)==0)
1278 err = unzGoToNextFile(file);
1282 /* We failed, so restore the state of the 'current file' to where we
1285 s->num_file = num_fileSaved ;
1286 s->pos_in_central_dir = pos_in_central_dirSaved ;
1287 s->cur_file_info = cur_file_infoSaved;
1288 s->cur_file_info_internal = cur_file_info_internalSaved;
1294 ///////////////////////////////////////////
1295 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1296 // I need random access
1298 // Further optimization could be realized by adding an ability
1299 // to cache the directory in memory. The goal being a single
1300 // comprehensive file read to put the file I need in a memory.
1304 typedef struct unz_file_pos_s
1306 ZPOS64_T pos_in_zip_directory; // offset in file
1307 ZPOS64_T num_of_file; // # of file
1311 extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
1315 if (file==NULL || file_pos==NULL)
1316 return UNZ_PARAMERROR;
1318 if (!s->current_file_ok)
1319 return UNZ_END_OF_LIST_OF_FILE;
1321 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
1322 file_pos->num_of_file = s->num_file;
1327 extern int ZEXPORT unzGetFilePos(
1329 unz_file_pos* file_pos)
1331 unz64_file_pos file_pos64;
1332 int err = unzGetFilePos64(file,&file_pos64);
1335 file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
1336 file_pos->num_of_file = (uLong)file_pos64.num_of_file;
1341 extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
1346 if (file==NULL || file_pos==NULL)
1347 return UNZ_PARAMERROR;
1350 /* jump to the right spot */
1351 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1352 s->num_file = file_pos->num_of_file;
1354 /* set the current file */
1355 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1356 &s->cur_file_info_internal,
1357 NULL,0,NULL,0,NULL,0);
1358 /* return results */
1359 s->current_file_ok = (err == UNZ_OK);
1363 extern int ZEXPORT unzGoToFilePos(
1365 unz_file_pos* file_pos)
1367 unz64_file_pos file_pos64;
1368 if (file_pos == NULL)
1369 return UNZ_PARAMERROR;
1371 file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
1372 file_pos64.num_of_file = file_pos->num_of_file;
1373 return unzGoToFilePos64(file,&file_pos64);
1377 // Unzip Helper Functions - should be here?
1378 ///////////////////////////////////////////
1382 Read the local header of the current zipfile
1383 Check the coherency of the local header and info in the end of central
1384 directory about this file
1385 store in *piSizeVar the size of extra info in local header
1386 (filename and size of extra field data)
1388 local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
1389 ZPOS64_T * poffset_local_extrafield,
1390 uInt * psize_local_extrafield)
1392 uLong uMagic,uData,uFlags;
1393 uLong size_filename;
1394 uLong size_extra_field;
1398 *poffset_local_extrafield = 0;
1399 *psize_local_extrafield = 0;
1401 if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
1402 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
1408 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
1410 else if (uMagic!=0x04034b50)
1414 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1417 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1420 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1423 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1425 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1428 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1429 /* #ifdef HAVE_BZIP2 */
1430 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1432 (s->cur_file_info.compression_method!=Z_DEFLATED))
1435 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1438 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1440 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
1443 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1445 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
1448 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1450 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
1453 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1455 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1458 *piSizeVar += (uInt)size_filename;
1460 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1462 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1463 SIZEZIPLOCALHEADER + size_filename;
1464 *psize_local_extrafield = (uInt)size_extra_field;
1466 *piSizeVar += (uInt)size_extra_field;
1472 Open for reading data the current file in the zipfile.
1473 If there is no error and the file is opened, the return value is UNZ_OK.
1475 extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
1476 int* level, int raw, const char* password)
1481 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1482 ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
1483 uInt size_local_extrafield; /* size of the local extra field */
1487 if (password != NULL)
1488 return UNZ_PARAMERROR;
1492 return UNZ_PARAMERROR;
1494 if (!s->current_file_ok)
1495 return UNZ_PARAMERROR;
1497 if (s->pfile_in_zip_read != NULL)
1498 unzCloseCurrentFile(file);
1500 if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1501 return UNZ_BADZIPFILE;
1503 pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
1504 if (pfile_in_zip_read_info==NULL)
1505 return UNZ_INTERNALERROR;
1507 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1508 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1509 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1510 pfile_in_zip_read_info->pos_local_extrafield=0;
1511 pfile_in_zip_read_info->raw=raw;
1513 if (pfile_in_zip_read_info->read_buffer==NULL)
1515 TRYFREE(pfile_in_zip_read_info);
1516 return UNZ_INTERNALERROR;
1519 pfile_in_zip_read_info->stream_initialised=0;
1522 *method = (int)s->cur_file_info.compression_method;
1527 switch (s->cur_file_info.flag & 0x06)
1529 case 6 : *level = 1; break;
1530 case 4 : *level = 2; break;
1531 case 2 : *level = 9; break;
1535 if ((s->cur_file_info.compression_method!=0) &&
1536 /* #ifdef HAVE_BZIP2 */
1537 (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1539 (s->cur_file_info.compression_method!=Z_DEFLATED))
1543 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1544 pfile_in_zip_read_info->crc32=0;
1545 pfile_in_zip_read_info->total_out_64=0;
1546 pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
1547 pfile_in_zip_read_info->filestream=s->filestream;
1548 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1549 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1551 pfile_in_zip_read_info->stream.total_out = 0;
1553 if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
1556 pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
1557 pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
1558 pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
1559 pfile_in_zip_read_info->bstream.state = (voidpf)0;
1561 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1562 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1563 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1564 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1565 pfile_in_zip_read_info->stream.avail_in = 0;
1567 err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
1569 pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
1572 TRYFREE(pfile_in_zip_read_info);
1576 pfile_in_zip_read_info->raw=1;
1579 else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
1581 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1582 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1583 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1584 pfile_in_zip_read_info->stream.next_in = 0;
1585 pfile_in_zip_read_info->stream.avail_in = 0;
1587 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1589 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
1592 TRYFREE(pfile_in_zip_read_info);
1595 /* windowBits is passed < 0 to tell that there is no zlib header.
1596 * Note that in this case inflate *requires* an extra "dummy" byte
1597 * after the compressed stream in order to complete decompression and
1598 * return Z_STREAM_END.
1599 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1600 * size of both compressed and uncompressed data
1603 pfile_in_zip_read_info->rest_read_compressed =
1604 s->cur_file_info.compressed_size ;
1605 pfile_in_zip_read_info->rest_read_uncompressed =
1606 s->cur_file_info.uncompressed_size ;
1609 pfile_in_zip_read_info->pos_in_zipfile =
1610 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1613 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1615 s->pfile_in_zip_read = pfile_in_zip_read_info;
1619 if (password != NULL)
1622 s->pcrc_32_tab = get_crc_table();
1623 init_keys(password,s->keys,s->pcrc_32_tab);
1624 if (ZSEEK64(s->z_filefunc, s->filestream,
1625 s->pfile_in_zip_read->pos_in_zipfile +
1626 s->pfile_in_zip_read->byte_before_the_zipfile,
1628 return UNZ_INTERNALERROR;
1629 if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
1630 return UNZ_INTERNALERROR;
1632 for (i = 0; i<12; i++)
1633 zdecode(s->keys,s->pcrc_32_tab,source[i]);
1635 s->pfile_in_zip_read->pos_in_zipfile+=12;
1644 extern int ZEXPORT unzOpenCurrentFile (unzFile file)
1646 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1649 extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
1651 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1654 extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
1656 return unzOpenCurrentFile3(file, method, level, raw, NULL);
1659 /** Addition for GDAL : START */
1661 extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
1664 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1667 return 0; //UNZ_PARAMERROR;
1668 pfile_in_zip_read_info=s->pfile_in_zip_read;
1669 if (pfile_in_zip_read_info==NULL)
1670 return 0; //UNZ_PARAMERROR;
1671 return pfile_in_zip_read_info->pos_in_zipfile +
1672 pfile_in_zip_read_info->byte_before_the_zipfile;
1675 /** Addition for GDAL : END */
1678 Read bytes from the current file.
1679 buf contain buffer where data must be copied
1680 len the size of buf.
1682 return the number of byte copied if somes bytes are copied
1683 return 0 if the end of file was reached
1684 return <0 with error code if there is an error
1685 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1687 extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
1692 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1694 return UNZ_PARAMERROR;
1696 pfile_in_zip_read_info=s->pfile_in_zip_read;
1698 if (pfile_in_zip_read_info==NULL)
1699 return UNZ_PARAMERROR;
1702 if ((pfile_in_zip_read_info->read_buffer == NULL))
1703 return UNZ_END_OF_LIST_OF_FILE;
1707 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1709 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1711 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1712 (!(pfile_in_zip_read_info->raw)))
1713 pfile_in_zip_read_info->stream.avail_out =
1714 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1716 if ((len>pfile_in_zip_read_info->rest_read_compressed+
1717 pfile_in_zip_read_info->stream.avail_in) &&
1718 (pfile_in_zip_read_info->raw))
1719 pfile_in_zip_read_info->stream.avail_out =
1720 (uInt)pfile_in_zip_read_info->rest_read_compressed+
1721 pfile_in_zip_read_info->stream.avail_in;
1723 while (pfile_in_zip_read_info->stream.avail_out>0)
1725 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1726 (pfile_in_zip_read_info->rest_read_compressed>0))
1728 uInt uReadThis = UNZ_BUFSIZE;
1729 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1730 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1733 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1734 pfile_in_zip_read_info->filestream,
1735 pfile_in_zip_read_info->pos_in_zipfile +
1736 pfile_in_zip_read_info->byte_before_the_zipfile,
1737 ZLIB_FILEFUNC_SEEK_SET)!=0)
1739 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1740 pfile_in_zip_read_info->filestream,
1741 pfile_in_zip_read_info->read_buffer,
1742 uReadThis)!=uReadThis)
1750 for(i=0;i<uReadThis;i++)
1751 pfile_in_zip_read_info->read_buffer[i] =
1752 zdecode(s->keys,s->pcrc_32_tab,
1753 pfile_in_zip_read_info->read_buffer[i]);
1758 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1760 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1762 pfile_in_zip_read_info->stream.next_in =
1763 (Bytef*)pfile_in_zip_read_info->read_buffer;
1764 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1767 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1771 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1772 (pfile_in_zip_read_info->rest_read_compressed == 0))
1773 return (iRead==0) ? UNZ_EOF : iRead;
1775 if (pfile_in_zip_read_info->stream.avail_out <
1776 pfile_in_zip_read_info->stream.avail_in)
1777 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1779 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1781 for (i=0;i<uDoCopy;i++)
1782 *(pfile_in_zip_read_info->stream.next_out+i) =
1783 *(pfile_in_zip_read_info->stream.next_in+i);
1785 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
1787 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1788 pfile_in_zip_read_info->stream.next_out,
1790 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1791 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1792 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1793 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1794 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1795 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1798 else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
1801 uLong uTotalOutBefore,uTotalOutAfter;
1802 const Bytef *bufBefore;
1805 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
1806 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
1807 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
1808 pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
1809 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
1810 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
1811 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
1812 pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
1814 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
1815 bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
1817 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
1819 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
1820 uOutThis = uTotalOutAfter-uTotalOutBefore;
1822 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1824 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
1825 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
1826 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1828 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
1829 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
1830 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
1831 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
1832 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
1833 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
1835 if (err==BZ_STREAM_END)
1836 return (iRead==0) ? UNZ_EOF : iRead;
1843 ZPOS64_T uTotalOutBefore,uTotalOutAfter;
1844 const Bytef *bufBefore;
1846 int flush=Z_SYNC_FLUSH;
1848 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1849 bufBefore = pfile_in_zip_read_info->stream.next_out;
1852 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1853 pfile_in_zip_read_info->stream.avail_out) &&
1854 (pfile_in_zip_read_info->rest_read_compressed == 0))
1857 err=inflate(&pfile_in_zip_read_info->stream,flush);
1859 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1862 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1863 uOutThis = uTotalOutAfter-uTotalOutBefore;
1865 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1867 pfile_in_zip_read_info->crc32 =
1868 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1871 pfile_in_zip_read_info->rest_read_uncompressed -=
1874 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1876 if (err==Z_STREAM_END)
1877 return (iRead==0) ? UNZ_EOF : iRead;
1890 Give the current position in uncompressed data
1892 extern z_off_t ZEXPORT unztell (unzFile file)
1895 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1897 return UNZ_PARAMERROR;
1899 pfile_in_zip_read_info=s->pfile_in_zip_read;
1901 if (pfile_in_zip_read_info==NULL)
1902 return UNZ_PARAMERROR;
1904 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1907 extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
1911 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1913 return (ZPOS64_T)-1;
1915 pfile_in_zip_read_info=s->pfile_in_zip_read;
1917 if (pfile_in_zip_read_info==NULL)
1918 return (ZPOS64_T)-1;
1920 return pfile_in_zip_read_info->total_out_64;
1925 return 1 if the end of file was reached, 0 elsewhere
1927 extern int ZEXPORT unzeof (unzFile file)
1930 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1932 return UNZ_PARAMERROR;
1934 pfile_in_zip_read_info=s->pfile_in_zip_read;
1936 if (pfile_in_zip_read_info==NULL)
1937 return UNZ_PARAMERROR;
1939 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1948 Read extra field from the current file (opened by unzOpenCurrentFile)
1949 This is the local-header version of the extra field (sometimes, there is
1950 more info in the local-header version than in the central-header)
1952 if buf==NULL, it return the size of the local extra field that can be read
1954 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1956 the return value is the number of bytes copied in buf, or (if <0)
1959 extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
1962 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1964 ZPOS64_T size_to_read;
1967 return UNZ_PARAMERROR;
1969 pfile_in_zip_read_info=s->pfile_in_zip_read;
1971 if (pfile_in_zip_read_info==NULL)
1972 return UNZ_PARAMERROR;
1974 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1975 pfile_in_zip_read_info->pos_local_extrafield);
1978 return (int)size_to_read;
1980 if (len>size_to_read)
1981 read_now = (uInt)size_to_read;
1983 read_now = (uInt)len ;
1988 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1989 pfile_in_zip_read_info->filestream,
1990 pfile_in_zip_read_info->offset_local_extrafield +
1991 pfile_in_zip_read_info->pos_local_extrafield,
1992 ZLIB_FILEFUNC_SEEK_SET)!=0)
1995 if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1996 pfile_in_zip_read_info->filestream,
1997 buf,read_now)!=read_now)
2000 return (int)read_now;
2004 Close the file in zip opened with unzipOpenCurrentFile
2005 Return UNZ_CRCERROR if all the file was read but the CRC is not good
2007 extern int ZEXPORT unzCloseCurrentFile (unzFile file)
2012 file_in_zip64_read_info_s* pfile_in_zip_read_info;
2014 return UNZ_PARAMERROR;
2016 pfile_in_zip_read_info=s->pfile_in_zip_read;
2018 if (pfile_in_zip_read_info==NULL)
2019 return UNZ_PARAMERROR;
2022 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
2023 (!pfile_in_zip_read_info->raw))
2025 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
2030 TRYFREE(pfile_in_zip_read_info->read_buffer);
2031 pfile_in_zip_read_info->read_buffer = NULL;
2032 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
2033 inflateEnd(&pfile_in_zip_read_info->stream);
2035 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
2036 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
2040 pfile_in_zip_read_info->stream_initialised = 0;
2041 TRYFREE(pfile_in_zip_read_info);
2043 s->pfile_in_zip_read=NULL;
2050 Get the global comment string of the ZipFile, in the szComment buffer.
2051 uSizeBuf is the size of the szComment buffer.
2052 return the number of byte copied or an error code <0
2054 extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
2059 return (int)UNZ_PARAMERROR;
2062 uReadThis = uSizeBuf;
2063 if (uReadThis>s->gi.size_comment)
2064 uReadThis = s->gi.size_comment;
2066 if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
2072 if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
2076 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
2077 *(szComment+s->gi.size_comment)='\0';
2078 return (int)uReadThis;
2081 /* Additions by RX '2004 */
2082 extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
2087 return 0; //UNZ_PARAMERROR;
2089 if (!s->current_file_ok)
2091 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
2092 if (s->num_file==s->gi.number_entry)
2094 return s->pos_in_central_dir;
2097 extern uLong ZEXPORT unzGetOffset (unzFile file)
2102 return 0; //UNZ_PARAMERROR;
2103 offset64 = unzGetOffset64(file);
2104 return (uLong)offset64;
2107 extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
2113 return UNZ_PARAMERROR;
2116 s->pos_in_central_dir = pos;
2117 s->num_file = s->gi.number_entry; /* hack */
2118 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
2119 &s->cur_file_info_internal,
2120 NULL,0,NULL,0,NULL,0);
2121 s->current_file_ok = (err == UNZ_OK);
2125 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
2127 return unzSetOffset64(file,pos);