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
75 #include "../mono/zlib/zlib.h"
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 z_crc_t
* 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 successfully 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
)
590 ZPOS64_T central_pos
;
593 uLong number_disk
; /* number of the current dist, used for
594 spaning ZIP, unsupported, always 0*/
595 uLong number_disk_with_CD
; /* number the the disk with central dir, used
596 for spaning ZIP, unsupported, always 0*/
597 ZPOS64_T number_entry_CD
; /* total number of entries in
599 (same than number_entry on nospan) */
603 if (unz_copyright
[0]!=' ')
606 us
.z_filefunc
.zseek32_file
= NULL
;
607 us
.z_filefunc
.ztell32_file
= NULL
;
608 if (pzlib_filefunc64_32_def
==NULL
)
609 fill_fopen64_filefunc(&us
.z_filefunc
.zfile_func64
);
611 us
.z_filefunc
= *pzlib_filefunc64_32_def
;
612 us
.is64bitOpenFunction
= is64bitOpenFunction
;
616 us
.filestream
= ZOPEN64(us
.z_filefunc
,
618 ZLIB_FILEFUNC_MODE_READ
|
619 ZLIB_FILEFUNC_MODE_EXISTING
);
620 if (us
.filestream
==NULL
)
623 central_pos
= unz64local_SearchCentralDir64(&us
.z_filefunc
,us
.filestream
);
631 if (ZSEEK64(us
.z_filefunc
, us
.filestream
,
632 central_pos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
635 /* the signature, already checked */
636 if (unz64local_getLong(&us
.z_filefunc
, us
.filestream
,&uL
)!=UNZ_OK
)
639 /* size of zip64 end of central directory record */
640 if (unz64local_getLong64(&us
.z_filefunc
, us
.filestream
,&uL64
)!=UNZ_OK
)
643 /* version made by */
644 if (unz64local_getShort(&us
.z_filefunc
, us
.filestream
,&uS
)!=UNZ_OK
)
647 /* version needed to extract */
648 if (unz64local_getShort(&us
.z_filefunc
, us
.filestream
,&uS
)!=UNZ_OK
)
651 /* number of this disk */
652 if (unz64local_getLong(&us
.z_filefunc
, us
.filestream
,&number_disk
)!=UNZ_OK
)
655 /* number of the disk with the start of the central directory */
656 if (unz64local_getLong(&us
.z_filefunc
, us
.filestream
,&number_disk_with_CD
)!=UNZ_OK
)
659 /* total number of entries in the central directory on this disk */
660 if (unz64local_getLong64(&us
.z_filefunc
, us
.filestream
,&us
.gi
.number_entry
)!=UNZ_OK
)
663 /* total number of entries in the central directory */
664 if (unz64local_getLong64(&us
.z_filefunc
, us
.filestream
,&number_entry_CD
)!=UNZ_OK
)
667 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
668 (number_disk_with_CD
!=0) ||
672 /* size of the central directory */
673 if (unz64local_getLong64(&us
.z_filefunc
, us
.filestream
,&us
.size_central_dir
)!=UNZ_OK
)
676 /* offset of start of central directory with respect to the
677 starting disk number */
678 if (unz64local_getLong64(&us
.z_filefunc
, us
.filestream
,&us
.offset_central_dir
)!=UNZ_OK
)
681 us
.gi
.size_comment
= 0;
685 central_pos
= unz64local_SearchCentralDir(&us
.z_filefunc
,us
.filestream
);
691 if (ZSEEK64(us
.z_filefunc
, us
.filestream
,
692 central_pos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
695 /* the signature, already checked */
696 if (unz64local_getLong(&us
.z_filefunc
, us
.filestream
,&uL
)!=UNZ_OK
)
699 /* number of this disk */
700 if (unz64local_getShort(&us
.z_filefunc
, us
.filestream
,&number_disk
)!=UNZ_OK
)
703 /* number of the disk with the start of the central directory */
704 if (unz64local_getShort(&us
.z_filefunc
, us
.filestream
,&number_disk_with_CD
)!=UNZ_OK
)
707 /* total number of entries in the central dir on this disk */
708 if (unz64local_getShort(&us
.z_filefunc
, us
.filestream
,&uL
)!=UNZ_OK
)
710 us
.gi
.number_entry
= uL
;
712 /* total number of entries in the central dir */
713 if (unz64local_getShort(&us
.z_filefunc
, us
.filestream
,&uL
)!=UNZ_OK
)
715 number_entry_CD
= uL
;
717 if ((number_entry_CD
!=us
.gi
.number_entry
) ||
718 (number_disk_with_CD
!=0) ||
722 /* size of the central directory */
723 if (unz64local_getLong(&us
.z_filefunc
, us
.filestream
,&uL
)!=UNZ_OK
)
725 us
.size_central_dir
= uL
;
727 /* offset of start of central directory with respect to the
728 starting disk number */
729 if (unz64local_getLong(&us
.z_filefunc
, us
.filestream
,&uL
)!=UNZ_OK
)
731 us
.offset_central_dir
= uL
;
733 /* zipfile comment length */
734 if (unz64local_getShort(&us
.z_filefunc
, us
.filestream
,&us
.gi
.size_comment
)!=UNZ_OK
)
738 if ((central_pos
<us
.offset_central_dir
+us
.size_central_dir
) &&
744 ZCLOSE64(us
.z_filefunc
, us
.filestream
);
748 us
.byte_before_the_zipfile
= central_pos
-
749 (us
.offset_central_dir
+us
.size_central_dir
);
750 us
.central_pos
= central_pos
;
751 us
.pfile_in_zip_read
= NULL
;
755 s
=(unz64_s
*)ALLOC(sizeof(unz64_s
));
759 unzGoToFirstFile((unzFile
)s
);
765 extern unzFile ZEXPORT
unzOpen2 (const char *path
,
766 zlib_filefunc_def
* pzlib_filefunc32_def
)
768 if (pzlib_filefunc32_def
!= NULL
)
770 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill
;
771 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill
,pzlib_filefunc32_def
);
772 return unzOpenInternal(path
, &zlib_filefunc64_32_def_fill
, 0);
775 return unzOpenInternal(path
, NULL
, 0);
778 extern unzFile ZEXPORT
unzOpen2_64 (const void *path
,
779 zlib_filefunc64_def
* pzlib_filefunc_def
)
781 if (pzlib_filefunc_def
!= NULL
)
783 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill
;
784 zlib_filefunc64_32_def_fill
.zfile_func64
= *pzlib_filefunc_def
;
785 zlib_filefunc64_32_def_fill
.ztell32_file
= NULL
;
786 zlib_filefunc64_32_def_fill
.zseek32_file
= NULL
;
787 return unzOpenInternal(path
, &zlib_filefunc64_32_def_fill
, 1);
790 return unzOpenInternal(path
, NULL
, 1);
793 extern unzFile ZEXPORT
unzOpen (const char *path
)
795 return unzOpenInternal(path
, NULL
, 0);
798 extern unzFile ZEXPORT
unzOpen64 (const void *path
)
800 return unzOpenInternal(path
, NULL
, 1);
804 Close a ZipFile opened with unzOpen.
805 If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
806 these files MUST be closed with unzCloseCurrentFile before call unzClose.
807 return UNZ_OK if there is no problem. */
808 extern int ZEXPORT
unzClose (unzFile file
)
812 return UNZ_PARAMERROR
;
815 if (s
->pfile_in_zip_read
!=NULL
)
816 unzCloseCurrentFile(file
);
818 ZCLOSE64(s
->z_filefunc
, s
->filestream
);
825 Write info about the ZipFile in the *pglobal_info structure.
826 No preparation of the structure is needed
827 return UNZ_OK if there is no problem. */
828 extern int ZEXPORT
unzGetGlobalInfo64 (unzFile file
, unz_global_info64
* pglobal_info
)
832 return UNZ_PARAMERROR
;
838 extern int ZEXPORT
unzGetGlobalInfo (unzFile file
, unz_global_info
* pglobal_info32
)
842 return UNZ_PARAMERROR
;
844 /* to do : check if number_entry is not truncated */
845 pglobal_info32
->number_entry
= (uLong
)s
->gi
.number_entry
;
846 pglobal_info32
->size_comment
= s
->gi
.size_comment
;
850 Translate date/time from Dos format to tm_unz (readable more easilty)
852 local
void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate
, tm_unz
* ptm
)
855 uDate
= (ZPOS64_T
)(ulDosDate
>>16);
856 ptm
->tm_mday
= (uInt
)(uDate
&0x1f) ;
857 ptm
->tm_mon
= (uInt
)((((uDate
)&0x1E0)/0x20)-1) ;
858 ptm
->tm_year
= (uInt
)(((uDate
&0x0FE00)/0x0200)+1980) ;
860 ptm
->tm_hour
= (uInt
) ((ulDosDate
&0xF800)/0x800);
861 ptm
->tm_min
= (uInt
) ((ulDosDate
&0x7E0)/0x20) ;
862 ptm
->tm_sec
= (uInt
) (2*(ulDosDate
&0x1f)) ;
866 Get Info about the current file in the zipfile, with internal only info
868 local
int unz64local_GetCurrentFileInfoInternal
OF((unzFile file
,
869 unz_file_info64
*pfile_info
,
870 unz_file_info64_internal
871 *pfile_info_internal
,
873 uLong fileNameBufferSize
,
875 uLong extraFieldBufferSize
,
877 uLong commentBufferSize
));
879 local
int unz64local_GetCurrentFileInfoInternal (unzFile file
,
880 unz_file_info64
*pfile_info
,
881 unz_file_info64_internal
882 *pfile_info_internal
,
884 uLong fileNameBufferSize
,
886 uLong extraFieldBufferSize
,
888 uLong commentBufferSize
)
891 unz_file_info64 file_info
;
892 unz_file_info64_internal file_info_internal
;
899 return UNZ_PARAMERROR
;
901 if (ZSEEK64(s
->z_filefunc
, s
->filestream
,
902 s
->pos_in_central_dir
+s
->byte_before_the_zipfile
,
903 ZLIB_FILEFUNC_SEEK_SET
)!=0)
907 /* we check the magic */
910 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&uMagic
) != UNZ_OK
)
912 else if (uMagic
!=0x02014b50)
916 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.version
) != UNZ_OK
)
919 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.version_needed
) != UNZ_OK
)
922 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.flag
) != UNZ_OK
)
925 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.compression_method
) != UNZ_OK
)
928 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.dosDate
) != UNZ_OK
)
931 unz64local_DosDateToTmuDate(file_info
.dosDate
,&file_info
.tmu_date
);
933 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.crc
) != UNZ_OK
)
936 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&uL
) != UNZ_OK
)
938 file_info
.compressed_size
= uL
;
940 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&uL
) != UNZ_OK
)
942 file_info
.uncompressed_size
= uL
;
944 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.size_filename
) != UNZ_OK
)
947 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.size_file_extra
) != UNZ_OK
)
950 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.size_file_comment
) != UNZ_OK
)
953 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.disk_num_start
) != UNZ_OK
)
956 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&file_info
.internal_fa
) != UNZ_OK
)
959 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&file_info
.external_fa
) != UNZ_OK
)
962 // relative offset of local header
963 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&uL
) != UNZ_OK
)
965 file_info_internal
.offset_curfile
= uL
;
967 lSeek
+=file_info
.size_filename
;
968 if ((err
==UNZ_OK
) && (szFileName
!=NULL
))
971 if (file_info
.size_filename
<fileNameBufferSize
)
973 *(szFileName
+file_info
.size_filename
)='\0';
974 uSizeRead
= file_info
.size_filename
;
977 uSizeRead
= fileNameBufferSize
;
979 if ((file_info
.size_filename
>0) && (fileNameBufferSize
>0))
980 if (ZREAD64(s
->z_filefunc
, s
->filestream
,szFileName
,uSizeRead
)!=uSizeRead
)
986 if ((err
==UNZ_OK
) && (extraField
!=NULL
))
989 if (file_info
.size_file_extra
<extraFieldBufferSize
)
990 uSizeRead
= file_info
.size_file_extra
;
992 uSizeRead
= extraFieldBufferSize
;
996 if (ZSEEK64(s
->z_filefunc
, s
->filestream
,lSeek
,ZLIB_FILEFUNC_SEEK_CUR
)==0)
1002 if ((file_info
.size_file_extra
>0) && (extraFieldBufferSize
>0))
1003 if (ZREAD64(s
->z_filefunc
, s
->filestream
,extraField
,(uLong
)uSizeRead
)!=uSizeRead
)
1006 lSeek
+= file_info
.size_file_extra
- (uLong
)uSizeRead
;
1009 lSeek
+= file_info
.size_file_extra
;
1012 if ((err
==UNZ_OK
) && (file_info
.size_file_extra
!= 0))
1016 // since lSeek now points to after the extra field we need to move back
1017 lSeek
-= file_info
.size_file_extra
;
1021 if (ZSEEK64(s
->z_filefunc
, s
->filestream
,lSeek
,ZLIB_FILEFUNC_SEEK_CUR
)==0)
1027 while(acc
< file_info
.size_file_extra
)
1032 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&headerId
) != UNZ_OK
)
1035 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&dataSize
) != UNZ_OK
)
1038 /* ZIP64 extra fields */
1039 if (headerId
== 0x0001)
1043 if(file_info
.uncompressed_size
== MAXU32
)
1045 if (unz64local_getLong64(&s
->z_filefunc
, s
->filestream
,&file_info
.uncompressed_size
) != UNZ_OK
)
1049 if(file_info
.compressed_size
== MAXU32
)
1051 if (unz64local_getLong64(&s
->z_filefunc
, s
->filestream
,&file_info
.compressed_size
) != UNZ_OK
)
1055 if(file_info_internal
.offset_curfile
== MAXU32
)
1057 /* Relative Header offset */
1058 if (unz64local_getLong64(&s
->z_filefunc
, s
->filestream
,&file_info_internal
.offset_curfile
) != UNZ_OK
)
1062 if(file_info
.disk_num_start
== MAXU32
)
1064 /* Disk Start Number */
1065 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&uL
) != UNZ_OK
)
1072 if (ZSEEK64(s
->z_filefunc
, s
->filestream
,dataSize
,ZLIB_FILEFUNC_SEEK_CUR
)!=0)
1076 acc
+= 2 + 2 + dataSize
;
1080 if ((err
==UNZ_OK
) && (szComment
!=NULL
))
1083 if (file_info
.size_file_comment
<commentBufferSize
)
1085 *(szComment
+file_info
.size_file_comment
)='\0';
1086 uSizeRead
= file_info
.size_file_comment
;
1089 uSizeRead
= commentBufferSize
;
1093 if (ZSEEK64(s
->z_filefunc
, s
->filestream
,lSeek
,ZLIB_FILEFUNC_SEEK_CUR
)==0)
1099 if ((file_info
.size_file_comment
>0) && (commentBufferSize
>0))
1100 if (ZREAD64(s
->z_filefunc
, s
->filestream
,szComment
,uSizeRead
)!=uSizeRead
)
1102 lSeek
+=file_info
.size_file_comment
- uSizeRead
;
1105 lSeek
+=file_info
.size_file_comment
;
1108 if ((err
==UNZ_OK
) && (pfile_info
!=NULL
))
1109 *pfile_info
=file_info
;
1111 if ((err
==UNZ_OK
) && (pfile_info_internal
!=NULL
))
1112 *pfile_info_internal
=file_info_internal
;
1120 Write info about the ZipFile in the *pglobal_info structure.
1121 No preparation of the structure is needed
1122 return UNZ_OK if there is no problem.
1124 extern int ZEXPORT
unzGetCurrentFileInfo64 (unzFile file
,
1125 unz_file_info64
* pfile_info
,
1126 char * szFileName
, uLong fileNameBufferSize
,
1127 void *extraField
, uLong extraFieldBufferSize
,
1128 char* szComment
, uLong commentBufferSize
)
1130 return unz64local_GetCurrentFileInfoInternal(file
,pfile_info
,NULL
,
1131 szFileName
,fileNameBufferSize
,
1132 extraField
,extraFieldBufferSize
,
1133 szComment
,commentBufferSize
);
1136 extern int ZEXPORT
unzGetCurrentFileInfo (unzFile file
,
1137 unz_file_info
* pfile_info
,
1138 char * szFileName
, uLong fileNameBufferSize
,
1139 void *extraField
, uLong extraFieldBufferSize
,
1140 char* szComment
, uLong commentBufferSize
)
1143 unz_file_info64 file_info64
;
1144 err
= unz64local_GetCurrentFileInfoInternal(file
,&file_info64
,NULL
,
1145 szFileName
,fileNameBufferSize
,
1146 extraField
,extraFieldBufferSize
,
1147 szComment
,commentBufferSize
);
1148 if ((err
==UNZ_OK
) && (pfile_info
!= NULL
))
1150 pfile_info
->version
= file_info64
.version
;
1151 pfile_info
->version_needed
= file_info64
.version_needed
;
1152 pfile_info
->flag
= file_info64
.flag
;
1153 pfile_info
->compression_method
= file_info64
.compression_method
;
1154 pfile_info
->dosDate
= file_info64
.dosDate
;
1155 pfile_info
->crc
= file_info64
.crc
;
1157 pfile_info
->size_filename
= file_info64
.size_filename
;
1158 pfile_info
->size_file_extra
= file_info64
.size_file_extra
;
1159 pfile_info
->size_file_comment
= file_info64
.size_file_comment
;
1161 pfile_info
->disk_num_start
= file_info64
.disk_num_start
;
1162 pfile_info
->internal_fa
= file_info64
.internal_fa
;
1163 pfile_info
->external_fa
= file_info64
.external_fa
;
1165 pfile_info
->tmu_date
= file_info64
.tmu_date
,
1168 pfile_info
->compressed_size
= (uLong
)file_info64
.compressed_size
;
1169 pfile_info
->uncompressed_size
= (uLong
)file_info64
.uncompressed_size
;
1175 Set the current file of the zipfile to the first file.
1176 return UNZ_OK if there is no problem
1178 extern int ZEXPORT
unzGoToFirstFile (unzFile file
)
1183 return UNZ_PARAMERROR
;
1185 s
->pos_in_central_dir
=s
->offset_central_dir
;
1187 err
=unz64local_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
1188 &s
->cur_file_info_internal
,
1189 NULL
,0,NULL
,0,NULL
,0);
1190 s
->current_file_ok
= (err
== UNZ_OK
);
1195 Set the current file of the zipfile to the next file.
1196 return UNZ_OK if there is no problem
1197 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1199 extern int ZEXPORT
unzGoToNextFile (unzFile file
)
1205 return UNZ_PARAMERROR
;
1207 if (!s
->current_file_ok
)
1208 return UNZ_END_OF_LIST_OF_FILE
;
1209 if (s
->gi
.number_entry
!= 0xffff) /* 2^16 files overflow hack */
1210 if (s
->num_file
+1==s
->gi
.number_entry
)
1211 return UNZ_END_OF_LIST_OF_FILE
;
1213 s
->pos_in_central_dir
+= SIZECENTRALDIRITEM
+ s
->cur_file_info
.size_filename
+
1214 s
->cur_file_info
.size_file_extra
+ s
->cur_file_info
.size_file_comment
;
1216 err
= unz64local_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
1217 &s
->cur_file_info_internal
,
1218 NULL
,0,NULL
,0,NULL
,0);
1219 s
->current_file_ok
= (err
== UNZ_OK
);
1225 Try locate the file szFileName in the zipfile.
1226 For the iCaseSensitivity signification, see unzStringFileNameCompare
1229 UNZ_OK if the file is found. It becomes the current file.
1230 UNZ_END_OF_LIST_OF_FILE if the file is not found
1232 extern int ZEXPORT
unzLocateFile (unzFile file
, const char *szFileName
, int iCaseSensitivity
)
1237 /* We remember the 'current' position in the file so that we can jump
1238 * back there if we fail.
1240 unz_file_info64 cur_file_infoSaved
;
1241 unz_file_info64_internal cur_file_info_internalSaved
;
1242 ZPOS64_T num_fileSaved
;
1243 ZPOS64_T pos_in_central_dirSaved
;
1247 return UNZ_PARAMERROR
;
1249 if (strlen(szFileName
)>=UNZ_MAXFILENAMEINZIP
)
1250 return UNZ_PARAMERROR
;
1253 if (!s
->current_file_ok
)
1254 return UNZ_END_OF_LIST_OF_FILE
;
1256 /* Save the current state */
1257 num_fileSaved
= s
->num_file
;
1258 pos_in_central_dirSaved
= s
->pos_in_central_dir
;
1259 cur_file_infoSaved
= s
->cur_file_info
;
1260 cur_file_info_internalSaved
= s
->cur_file_info_internal
;
1262 err
= unzGoToFirstFile(file
);
1264 while (err
== UNZ_OK
)
1266 char szCurrentFileName
[UNZ_MAXFILENAMEINZIP
+1];
1267 err
= unzGetCurrentFileInfo64(file
,NULL
,
1268 szCurrentFileName
,sizeof(szCurrentFileName
)-1,
1272 if (unzStringFileNameCompare(szCurrentFileName
,
1273 szFileName
,iCaseSensitivity
)==0)
1275 err
= unzGoToNextFile(file
);
1279 /* We failed, so restore the state of the 'current file' to where we
1282 s
->num_file
= num_fileSaved
;
1283 s
->pos_in_central_dir
= pos_in_central_dirSaved
;
1284 s
->cur_file_info
= cur_file_infoSaved
;
1285 s
->cur_file_info_internal
= cur_file_info_internalSaved
;
1291 ///////////////////////////////////////////
1292 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1293 // I need random access
1295 // Further optimization could be realized by adding an ability
1296 // to cache the directory in memory. The goal being a single
1297 // comprehensive file read to put the file I need in a memory.
1301 typedef struct unz_file_pos_s
1303 ZPOS64_T pos_in_zip_directory; // offset in file
1304 ZPOS64_T num_of_file; // # of file
1308 extern int ZEXPORT
unzGetFilePos64(unzFile file
, unz64_file_pos
* file_pos
)
1312 if (file
==NULL
|| file_pos
==NULL
)
1313 return UNZ_PARAMERROR
;
1315 if (!s
->current_file_ok
)
1316 return UNZ_END_OF_LIST_OF_FILE
;
1318 file_pos
->pos_in_zip_directory
= s
->pos_in_central_dir
;
1319 file_pos
->num_of_file
= s
->num_file
;
1324 extern int ZEXPORT
unzGetFilePos(
1326 unz_file_pos
* file_pos
)
1328 unz64_file_pos file_pos64
;
1329 int err
= unzGetFilePos64(file
,&file_pos64
);
1332 file_pos
->pos_in_zip_directory
= (uLong
)file_pos64
.pos_in_zip_directory
;
1333 file_pos
->num_of_file
= (uLong
)file_pos64
.num_of_file
;
1338 extern int ZEXPORT
unzGoToFilePos64(unzFile file
, const unz64_file_pos
* file_pos
)
1343 if (file
==NULL
|| file_pos
==NULL
)
1344 return UNZ_PARAMERROR
;
1347 /* jump to the right spot */
1348 s
->pos_in_central_dir
= file_pos
->pos_in_zip_directory
;
1349 s
->num_file
= file_pos
->num_of_file
;
1351 /* set the current file */
1352 err
= unz64local_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
1353 &s
->cur_file_info_internal
,
1354 NULL
,0,NULL
,0,NULL
,0);
1355 /* return results */
1356 s
->current_file_ok
= (err
== UNZ_OK
);
1360 extern int ZEXPORT
unzGoToFilePos(
1362 unz_file_pos
* file_pos
)
1364 unz64_file_pos file_pos64
;
1365 if (file_pos
== NULL
)
1366 return UNZ_PARAMERROR
;
1368 file_pos64
.pos_in_zip_directory
= file_pos
->pos_in_zip_directory
;
1369 file_pos64
.num_of_file
= file_pos
->num_of_file
;
1370 return unzGoToFilePos64(file
,&file_pos64
);
1374 // Unzip Helper Functions - should be here?
1375 ///////////////////////////////////////////
1379 Read the local header of the current zipfile
1380 Check the coherency of the local header and info in the end of central
1381 directory about this file
1382 store in *piSizeVar the size of extra info in local header
1383 (filename and size of extra field data)
1385 local
int unz64local_CheckCurrentFileCoherencyHeader (unz64_s
* s
, uInt
* piSizeVar
,
1386 ZPOS64_T
* poffset_local_extrafield
,
1387 uInt
* psize_local_extrafield
)
1389 uLong uMagic
,uData
,uFlags
;
1390 uLong size_filename
;
1391 uLong size_extra_field
;
1395 *poffset_local_extrafield
= 0;
1396 *psize_local_extrafield
= 0;
1398 if (ZSEEK64(s
->z_filefunc
, s
->filestream
,s
->cur_file_info_internal
.offset_curfile
+
1399 s
->byte_before_the_zipfile
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1405 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&uMagic
) != UNZ_OK
)
1407 else if (uMagic
!=0x04034b50)
1411 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
)
1414 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1417 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&uFlags
) != UNZ_OK
)
1420 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
)
1422 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compression_method
))
1425 if ((err
==UNZ_OK
) && (s
->cur_file_info
.compression_method
!=0) &&
1426 /* #ifdef HAVE_BZIP2 */
1427 (s
->cur_file_info
.compression_method
!=Z_BZIP2ED
) &&
1429 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1432 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* date/time */
1435 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* crc */
1437 else if ((err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.crc
) && ((uFlags
& 8)==0))
1440 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* size compr */
1442 else if (uData
!= 0xFFFFFFFF && (err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.compressed_size
) && ((uFlags
& 8)==0))
1445 if (unz64local_getLong(&s
->z_filefunc
, s
->filestream
,&uData
) != UNZ_OK
) /* size uncompr */
1447 else if (uData
!= 0xFFFFFFFF && (err
==UNZ_OK
) && (uData
!=s
->cur_file_info
.uncompressed_size
) && ((uFlags
& 8)==0))
1450 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&size_filename
) != UNZ_OK
)
1452 else if ((err
==UNZ_OK
) && (size_filename
!=s
->cur_file_info
.size_filename
))
1455 *piSizeVar
+= (uInt
)size_filename
;
1457 if (unz64local_getShort(&s
->z_filefunc
, s
->filestream
,&size_extra_field
) != UNZ_OK
)
1459 *poffset_local_extrafield
= s
->cur_file_info_internal
.offset_curfile
+
1460 SIZEZIPLOCALHEADER
+ size_filename
;
1461 *psize_local_extrafield
= (uInt
)size_extra_field
;
1463 *piSizeVar
+= (uInt
)size_extra_field
;
1469 Open for reading data the current file in the zipfile.
1470 If there is no error and the file is opened, the return value is UNZ_OK.
1472 extern int ZEXPORT
unzOpenCurrentFile3 (unzFile file
, int* method
,
1473 int* level
, int raw
, const char* password
)
1478 file_in_zip64_read_info_s
* pfile_in_zip_read_info
;
1479 ZPOS64_T offset_local_extrafield
; /* offset of the local extra field */
1480 uInt size_local_extrafield
; /* size of the local extra field */
1484 if (password
!= NULL
)
1485 return UNZ_PARAMERROR
;
1489 return UNZ_PARAMERROR
;
1491 if (!s
->current_file_ok
)
1492 return UNZ_PARAMERROR
;
1494 if (s
->pfile_in_zip_read
!= NULL
)
1495 unzCloseCurrentFile(file
);
1497 if (unz64local_CheckCurrentFileCoherencyHeader(s
,&iSizeVar
, &offset_local_extrafield
,&size_local_extrafield
)!=UNZ_OK
)
1498 return UNZ_BADZIPFILE
;
1500 pfile_in_zip_read_info
= (file_in_zip64_read_info_s
*)ALLOC(sizeof(file_in_zip64_read_info_s
));
1501 if (pfile_in_zip_read_info
==NULL
)
1502 return UNZ_INTERNALERROR
;
1504 pfile_in_zip_read_info
->read_buffer
=(char*)ALLOC(UNZ_BUFSIZE
);
1505 pfile_in_zip_read_info
->offset_local_extrafield
= offset_local_extrafield
;
1506 pfile_in_zip_read_info
->size_local_extrafield
= size_local_extrafield
;
1507 pfile_in_zip_read_info
->pos_local_extrafield
=0;
1508 pfile_in_zip_read_info
->raw
=raw
;
1510 if (pfile_in_zip_read_info
->read_buffer
==NULL
)
1512 TRYFREE(pfile_in_zip_read_info
);
1513 return UNZ_INTERNALERROR
;
1516 pfile_in_zip_read_info
->stream_initialised
=0;
1519 *method
= (int)s
->cur_file_info
.compression_method
;
1524 switch (s
->cur_file_info
.flag
& 0x06)
1526 case 6 : *level
= 1; break;
1527 case 4 : *level
= 2; break;
1528 case 2 : *level
= 9; break;
1532 if ((s
->cur_file_info
.compression_method
!=0) &&
1533 /* #ifdef HAVE_BZIP2 */
1534 (s
->cur_file_info
.compression_method
!=Z_BZIP2ED
) &&
1536 (s
->cur_file_info
.compression_method
!=Z_DEFLATED
))
1540 pfile_in_zip_read_info
->crc32_wait
=s
->cur_file_info
.crc
;
1541 pfile_in_zip_read_info
->crc32
=0;
1542 pfile_in_zip_read_info
->total_out_64
=0;
1543 pfile_in_zip_read_info
->compression_method
= s
->cur_file_info
.compression_method
;
1544 pfile_in_zip_read_info
->filestream
=s
->filestream
;
1545 pfile_in_zip_read_info
->z_filefunc
=s
->z_filefunc
;
1546 pfile_in_zip_read_info
->byte_before_the_zipfile
=s
->byte_before_the_zipfile
;
1548 pfile_in_zip_read_info
->stream
.total_out
= 0;
1550 if ((s
->cur_file_info
.compression_method
==Z_BZIP2ED
) && (!raw
))
1553 pfile_in_zip_read_info
->bstream
.bzalloc
= (void *(*) (void *, int, int))0;
1554 pfile_in_zip_read_info
->bstream
.bzfree
= (free_func
)0;
1555 pfile_in_zip_read_info
->bstream
.opaque
= (voidpf
)0;
1556 pfile_in_zip_read_info
->bstream
.state
= (voidpf
)0;
1558 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1559 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1560 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1561 pfile_in_zip_read_info
->stream
.next_in
= (voidpf
)0;
1562 pfile_in_zip_read_info
->stream
.avail_in
= 0;
1564 err
=BZ2_bzDecompressInit(&pfile_in_zip_read_info
->bstream
, 0, 0);
1566 pfile_in_zip_read_info
->stream_initialised
=Z_BZIP2ED
;
1569 TRYFREE(pfile_in_zip_read_info
);
1573 pfile_in_zip_read_info
->raw
=1;
1576 else if ((s
->cur_file_info
.compression_method
==Z_DEFLATED
) && (!raw
))
1578 pfile_in_zip_read_info
->stream
.zalloc
= (alloc_func
)0;
1579 pfile_in_zip_read_info
->stream
.zfree
= (free_func
)0;
1580 pfile_in_zip_read_info
->stream
.opaque
= (voidpf
)0;
1581 pfile_in_zip_read_info
->stream
.next_in
= 0;
1582 pfile_in_zip_read_info
->stream
.avail_in
= 0;
1584 err
=inflateInit2(&pfile_in_zip_read_info
->stream
, -MAX_WBITS
);
1586 pfile_in_zip_read_info
->stream_initialised
=Z_DEFLATED
;
1589 TRYFREE(pfile_in_zip_read_info
);
1592 /* windowBits is passed < 0 to tell that there is no zlib header.
1593 * Note that in this case inflate *requires* an extra "dummy" byte
1594 * after the compressed stream in order to complete decompression and
1595 * return Z_STREAM_END.
1596 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1597 * size of both compressed and uncompressed data
1600 pfile_in_zip_read_info
->rest_read_compressed
=
1601 s
->cur_file_info
.compressed_size
;
1602 pfile_in_zip_read_info
->rest_read_uncompressed
=
1603 s
->cur_file_info
.uncompressed_size
;
1606 pfile_in_zip_read_info
->pos_in_zipfile
=
1607 s
->cur_file_info_internal
.offset_curfile
+ SIZEZIPLOCALHEADER
+
1610 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)0;
1612 s
->pfile_in_zip_read
= pfile_in_zip_read_info
;
1616 if (password
!= NULL
)
1619 s
->pcrc_32_tab
= get_crc_table();
1620 init_keys(password
,s
->keys
,s
->pcrc_32_tab
);
1621 if (ZSEEK64(s
->z_filefunc
, s
->filestream
,
1622 s
->pfile_in_zip_read
->pos_in_zipfile
+
1623 s
->pfile_in_zip_read
->byte_before_the_zipfile
,
1625 return UNZ_INTERNALERROR
;
1626 if(ZREAD64(s
->z_filefunc
, s
->filestream
,source
, 12)<12)
1627 return UNZ_INTERNALERROR
;
1629 for (i
= 0; i
<12; i
++)
1630 zdecode(s
->keys
,s
->pcrc_32_tab
,source
[i
]);
1632 s
->pfile_in_zip_read
->pos_in_zipfile
+=12;
1641 extern int ZEXPORT
unzOpenCurrentFile (unzFile file
)
1643 return unzOpenCurrentFile3(file
, NULL
, NULL
, 0, NULL
);
1646 extern int ZEXPORT
unzOpenCurrentFilePassword (unzFile file
, const char* password
)
1648 return unzOpenCurrentFile3(file
, NULL
, NULL
, 0, password
);
1651 extern int ZEXPORT
unzOpenCurrentFile2 (unzFile file
, int* method
, int* level
, int raw
)
1653 return unzOpenCurrentFile3(file
, method
, level
, raw
, NULL
);
1656 /** Addition for GDAL : START */
1658 extern ZPOS64_T ZEXPORT
unzGetCurrentFileZStreamPos64( unzFile file
)
1661 file_in_zip64_read_info_s
* pfile_in_zip_read_info
;
1664 return 0; //UNZ_PARAMERROR;
1665 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1666 if (pfile_in_zip_read_info
==NULL
)
1667 return 0; //UNZ_PARAMERROR;
1668 return pfile_in_zip_read_info
->pos_in_zipfile
+
1669 pfile_in_zip_read_info
->byte_before_the_zipfile
;
1672 /** Addition for GDAL : END */
1675 Read bytes from the current file.
1676 buf contain buffer where data must be copied
1677 len the size of buf.
1679 return the number of byte copied if somes bytes are copied
1680 return 0 if the end of file was reached
1681 return <0 with error code if there is an error
1682 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1684 extern int ZEXPORT
unzReadCurrentFile (unzFile file
, voidp buf
, unsigned len
)
1689 file_in_zip64_read_info_s
* pfile_in_zip_read_info
;
1691 return UNZ_PARAMERROR
;
1693 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1695 if (pfile_in_zip_read_info
==NULL
)
1696 return UNZ_PARAMERROR
;
1699 if (pfile_in_zip_read_info
->read_buffer
== NULL
)
1700 return UNZ_END_OF_LIST_OF_FILE
;
1704 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)buf
;
1706 pfile_in_zip_read_info
->stream
.avail_out
= (uInt
)len
;
1708 if ((len
>pfile_in_zip_read_info
->rest_read_uncompressed
) &&
1709 (!(pfile_in_zip_read_info
->raw
)))
1710 pfile_in_zip_read_info
->stream
.avail_out
=
1711 (uInt
)pfile_in_zip_read_info
->rest_read_uncompressed
;
1713 if ((len
>pfile_in_zip_read_info
->rest_read_compressed
+
1714 pfile_in_zip_read_info
->stream
.avail_in
) &&
1715 (pfile_in_zip_read_info
->raw
))
1716 pfile_in_zip_read_info
->stream
.avail_out
=
1717 (uInt
)pfile_in_zip_read_info
->rest_read_compressed
+
1718 pfile_in_zip_read_info
->stream
.avail_in
;
1720 while (pfile_in_zip_read_info
->stream
.avail_out
>0)
1722 if ((pfile_in_zip_read_info
->stream
.avail_in
==0) &&
1723 (pfile_in_zip_read_info
->rest_read_compressed
>0))
1725 uInt uReadThis
= UNZ_BUFSIZE
;
1726 if (pfile_in_zip_read_info
->rest_read_compressed
<uReadThis
)
1727 uReadThis
= (uInt
)pfile_in_zip_read_info
->rest_read_compressed
;
1730 if (ZSEEK64(pfile_in_zip_read_info
->z_filefunc
,
1731 pfile_in_zip_read_info
->filestream
,
1732 pfile_in_zip_read_info
->pos_in_zipfile
+
1733 pfile_in_zip_read_info
->byte_before_the_zipfile
,
1734 ZLIB_FILEFUNC_SEEK_SET
)!=0)
1736 if (ZREAD64(pfile_in_zip_read_info
->z_filefunc
,
1737 pfile_in_zip_read_info
->filestream
,
1738 pfile_in_zip_read_info
->read_buffer
,
1739 uReadThis
)!=uReadThis
)
1747 for(i
=0;i
<uReadThis
;i
++)
1748 pfile_in_zip_read_info
->read_buffer
[i
] =
1749 zdecode(s
->keys
,s
->pcrc_32_tab
,
1750 pfile_in_zip_read_info
->read_buffer
[i
]);
1755 pfile_in_zip_read_info
->pos_in_zipfile
+= uReadThis
;
1757 pfile_in_zip_read_info
->rest_read_compressed
-=uReadThis
;
1759 pfile_in_zip_read_info
->stream
.next_in
=
1760 (Bytef
*)pfile_in_zip_read_info
->read_buffer
;
1761 pfile_in_zip_read_info
->stream
.avail_in
= (uInt
)uReadThis
;
1764 if ((pfile_in_zip_read_info
->compression_method
==0) || (pfile_in_zip_read_info
->raw
))
1768 if ((pfile_in_zip_read_info
->stream
.avail_in
== 0) &&
1769 (pfile_in_zip_read_info
->rest_read_compressed
== 0))
1770 return (iRead
==0) ? UNZ_EOF
: iRead
;
1772 if (pfile_in_zip_read_info
->stream
.avail_out
<
1773 pfile_in_zip_read_info
->stream
.avail_in
)
1774 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_out
;
1776 uDoCopy
= pfile_in_zip_read_info
->stream
.avail_in
;
1778 for (i
=0;i
<uDoCopy
;i
++)
1779 *(pfile_in_zip_read_info
->stream
.next_out
+i
) =
1780 *(pfile_in_zip_read_info
->stream
.next_in
+i
);
1782 pfile_in_zip_read_info
->total_out_64
= pfile_in_zip_read_info
->total_out_64
+ uDoCopy
;
1784 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,
1785 pfile_in_zip_read_info
->stream
.next_out
,
1787 pfile_in_zip_read_info
->rest_read_uncompressed
-=uDoCopy
;
1788 pfile_in_zip_read_info
->stream
.avail_in
-= uDoCopy
;
1789 pfile_in_zip_read_info
->stream
.avail_out
-= uDoCopy
;
1790 pfile_in_zip_read_info
->stream
.next_out
+= uDoCopy
;
1791 pfile_in_zip_read_info
->stream
.next_in
+= uDoCopy
;
1792 pfile_in_zip_read_info
->stream
.total_out
+= uDoCopy
;
1795 else if (pfile_in_zip_read_info
->compression_method
==Z_BZIP2ED
)
1798 uLong uTotalOutBefore
,uTotalOutAfter
;
1799 const Bytef
*bufBefore
;
1802 pfile_in_zip_read_info
->bstream
.next_in
= (char*)pfile_in_zip_read_info
->stream
.next_in
;
1803 pfile_in_zip_read_info
->bstream
.avail_in
= pfile_in_zip_read_info
->stream
.avail_in
;
1804 pfile_in_zip_read_info
->bstream
.total_in_lo32
= pfile_in_zip_read_info
->stream
.total_in
;
1805 pfile_in_zip_read_info
->bstream
.total_in_hi32
= 0;
1806 pfile_in_zip_read_info
->bstream
.next_out
= (char*)pfile_in_zip_read_info
->stream
.next_out
;
1807 pfile_in_zip_read_info
->bstream
.avail_out
= pfile_in_zip_read_info
->stream
.avail_out
;
1808 pfile_in_zip_read_info
->bstream
.total_out_lo32
= pfile_in_zip_read_info
->stream
.total_out
;
1809 pfile_in_zip_read_info
->bstream
.total_out_hi32
= 0;
1811 uTotalOutBefore
= pfile_in_zip_read_info
->bstream
.total_out_lo32
;
1812 bufBefore
= (const Bytef
*)pfile_in_zip_read_info
->bstream
.next_out
;
1814 err
=BZ2_bzDecompress(&pfile_in_zip_read_info
->bstream
);
1816 uTotalOutAfter
= pfile_in_zip_read_info
->bstream
.total_out_lo32
;
1817 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1819 pfile_in_zip_read_info
->total_out_64
= pfile_in_zip_read_info
->total_out_64
+ uOutThis
;
1821 pfile_in_zip_read_info
->crc32
= crc32(pfile_in_zip_read_info
->crc32
,bufBefore
, (uInt
)(uOutThis
));
1822 pfile_in_zip_read_info
->rest_read_uncompressed
-= uOutThis
;
1823 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1825 pfile_in_zip_read_info
->stream
.next_in
= (Bytef
*)pfile_in_zip_read_info
->bstream
.next_in
;
1826 pfile_in_zip_read_info
->stream
.avail_in
= pfile_in_zip_read_info
->bstream
.avail_in
;
1827 pfile_in_zip_read_info
->stream
.total_in
= pfile_in_zip_read_info
->bstream
.total_in_lo32
;
1828 pfile_in_zip_read_info
->stream
.next_out
= (Bytef
*)pfile_in_zip_read_info
->bstream
.next_out
;
1829 pfile_in_zip_read_info
->stream
.avail_out
= pfile_in_zip_read_info
->bstream
.avail_out
;
1830 pfile_in_zip_read_info
->stream
.total_out
= pfile_in_zip_read_info
->bstream
.total_out_lo32
;
1832 if (err
==BZ_STREAM_END
)
1833 return (iRead
==0) ? UNZ_EOF
: iRead
;
1840 ZPOS64_T uTotalOutBefore
,uTotalOutAfter
;
1841 const Bytef
*bufBefore
;
1843 int flush
=Z_SYNC_FLUSH
;
1845 uTotalOutBefore
= pfile_in_zip_read_info
->stream
.total_out
;
1846 bufBefore
= pfile_in_zip_read_info
->stream
.next_out
;
1849 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1850 pfile_in_zip_read_info->stream.avail_out) &&
1851 (pfile_in_zip_read_info->rest_read_compressed == 0))
1854 err
=inflate(&pfile_in_zip_read_info
->stream
,flush
);
1856 if ((err
>=0) && (pfile_in_zip_read_info
->stream
.msg
!=NULL
))
1859 uTotalOutAfter
= pfile_in_zip_read_info
->stream
.total_out
;
1860 uOutThis
= uTotalOutAfter
-uTotalOutBefore
;
1862 pfile_in_zip_read_info
->total_out_64
= pfile_in_zip_read_info
->total_out_64
+ uOutThis
;
1864 pfile_in_zip_read_info
->crc32
=
1865 crc32(pfile_in_zip_read_info
->crc32
,bufBefore
,
1868 pfile_in_zip_read_info
->rest_read_uncompressed
-=
1871 iRead
+= (uInt
)(uTotalOutAfter
- uTotalOutBefore
);
1873 if (err
==Z_STREAM_END
)
1874 return (iRead
==0) ? UNZ_EOF
: iRead
;
1887 Give the current position in uncompressed data
1889 extern z_off_t ZEXPORT
unztell (unzFile file
)
1892 file_in_zip64_read_info_s
* pfile_in_zip_read_info
;
1894 return UNZ_PARAMERROR
;
1896 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1898 if (pfile_in_zip_read_info
==NULL
)
1899 return UNZ_PARAMERROR
;
1901 return (z_off_t
)pfile_in_zip_read_info
->stream
.total_out
;
1904 extern ZPOS64_T ZEXPORT
unztell64 (unzFile file
)
1908 file_in_zip64_read_info_s
* pfile_in_zip_read_info
;
1910 return (ZPOS64_T
)-1;
1912 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1914 if (pfile_in_zip_read_info
==NULL
)
1915 return (ZPOS64_T
)-1;
1917 return pfile_in_zip_read_info
->total_out_64
;
1922 return 1 if the end of file was reached, 0 elsewhere
1924 extern int ZEXPORT
unzeof (unzFile file
)
1927 file_in_zip64_read_info_s
* pfile_in_zip_read_info
;
1929 return UNZ_PARAMERROR
;
1931 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1933 if (pfile_in_zip_read_info
==NULL
)
1934 return UNZ_PARAMERROR
;
1936 if (pfile_in_zip_read_info
->rest_read_uncompressed
== 0)
1945 Read extra field from the current file (opened by unzOpenCurrentFile)
1946 This is the local-header version of the extra field (sometimes, there is
1947 more info in the local-header version than in the central-header)
1949 if buf==NULL, it return the size of the local extra field that can be read
1951 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1953 the return value is the number of bytes copied in buf, or (if <0)
1956 extern int ZEXPORT
unzGetLocalExtrafield (unzFile file
, voidp buf
, unsigned len
)
1959 file_in_zip64_read_info_s
* pfile_in_zip_read_info
;
1961 ZPOS64_T size_to_read
;
1964 return UNZ_PARAMERROR
;
1966 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
1968 if (pfile_in_zip_read_info
==NULL
)
1969 return UNZ_PARAMERROR
;
1971 size_to_read
= (pfile_in_zip_read_info
->size_local_extrafield
-
1972 pfile_in_zip_read_info
->pos_local_extrafield
);
1975 return (int)size_to_read
;
1977 if (len
>size_to_read
)
1978 read_now
= (uInt
)size_to_read
;
1980 read_now
= (uInt
)len
;
1985 if (ZSEEK64(pfile_in_zip_read_info
->z_filefunc
,
1986 pfile_in_zip_read_info
->filestream
,
1987 pfile_in_zip_read_info
->offset_local_extrafield
+
1988 pfile_in_zip_read_info
->pos_local_extrafield
,
1989 ZLIB_FILEFUNC_SEEK_SET
)!=0)
1992 if (ZREAD64(pfile_in_zip_read_info
->z_filefunc
,
1993 pfile_in_zip_read_info
->filestream
,
1994 buf
,read_now
)!=read_now
)
1997 return (int)read_now
;
2001 Close the file in zip opened with unzOpenCurrentFile
2002 Return UNZ_CRCERROR if all the file was read but the CRC is not good
2004 extern int ZEXPORT
unzCloseCurrentFile (unzFile file
)
2009 file_in_zip64_read_info_s
* pfile_in_zip_read_info
;
2011 return UNZ_PARAMERROR
;
2013 pfile_in_zip_read_info
=s
->pfile_in_zip_read
;
2015 if (pfile_in_zip_read_info
==NULL
)
2016 return UNZ_PARAMERROR
;
2019 if ((pfile_in_zip_read_info
->rest_read_uncompressed
== 0) &&
2020 (!pfile_in_zip_read_info
->raw
))
2022 if (pfile_in_zip_read_info
->crc32
!= pfile_in_zip_read_info
->crc32_wait
)
2027 TRYFREE(pfile_in_zip_read_info
->read_buffer
);
2028 pfile_in_zip_read_info
->read_buffer
= NULL
;
2029 if (pfile_in_zip_read_info
->stream_initialised
== Z_DEFLATED
)
2030 inflateEnd(&pfile_in_zip_read_info
->stream
);
2032 else if (pfile_in_zip_read_info
->stream_initialised
== Z_BZIP2ED
)
2033 BZ2_bzDecompressEnd(&pfile_in_zip_read_info
->bstream
);
2037 pfile_in_zip_read_info
->stream_initialised
= 0;
2038 TRYFREE(pfile_in_zip_read_info
);
2040 s
->pfile_in_zip_read
=NULL
;
2047 Get the global comment string of the ZipFile, in the szComment buffer.
2048 uSizeBuf is the size of the szComment buffer.
2049 return the number of byte copied or an error code <0
2051 extern int ZEXPORT
unzGetGlobalComment (unzFile file
, char * szComment
, uLong uSizeBuf
)
2056 return (int)UNZ_PARAMERROR
;
2059 uReadThis
= uSizeBuf
;
2060 if (uReadThis
>s
->gi
.size_comment
)
2061 uReadThis
= s
->gi
.size_comment
;
2063 if (ZSEEK64(s
->z_filefunc
,s
->filestream
,s
->central_pos
+22,ZLIB_FILEFUNC_SEEK_SET
)!=0)
2069 if (ZREAD64(s
->z_filefunc
,s
->filestream
,szComment
,uReadThis
)!=uReadThis
)
2073 if ((szComment
!= NULL
) && (uSizeBuf
> s
->gi
.size_comment
))
2074 *(szComment
+s
->gi
.size_comment
)='\0';
2075 return (int)uReadThis
;
2078 /* Additions by RX '2004 */
2079 extern ZPOS64_T ZEXPORT
unzGetOffset64(unzFile file
)
2084 return 0; //UNZ_PARAMERROR;
2086 if (!s
->current_file_ok
)
2088 if (s
->gi
.number_entry
!= 0 && s
->gi
.number_entry
!= 0xffff)
2089 if (s
->num_file
==s
->gi
.number_entry
)
2091 return s
->pos_in_central_dir
;
2094 extern uLong ZEXPORT
unzGetOffset (unzFile file
)
2099 return 0; //UNZ_PARAMERROR;
2100 offset64
= unzGetOffset64(file
);
2101 return (uLong
)offset64
;
2104 extern int ZEXPORT
unzSetOffset64(unzFile file
, ZPOS64_T pos
)
2110 return UNZ_PARAMERROR
;
2113 s
->pos_in_central_dir
= pos
;
2114 s
->num_file
= s
->gi
.number_entry
; /* hack */
2115 err
= unz64local_GetCurrentFileInfoInternal(file
,&s
->cur_file_info
,
2116 &s
->cur_file_info_internal
,
2117 NULL
,0,NULL
,0,NULL
,0);
2118 s
->current_file_ok
= (err
== UNZ_OK
);
2122 extern int ZEXPORT
unzSetOffset (unzFile file
, uLong pos
)
2124 return unzSetOffset64(file
,pos
);