File indexing completed on 2025-01-26 04:24:55
0001 /* unzip.c -- IO for uncompress .zip files using zlib 0002 Version 1.1, February 14h, 2010 0003 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 0004 0005 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 0006 0007 Modifications of Unzip for Zip64 0008 Copyright (C) 2007-2008 Even Rouault 0009 0010 Modifications for Zip64 support on both zip and unzip 0011 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 0012 0013 Modifications for QIODevice support and other QuaZIP fixes 0014 Copyright (C) 2005-2014 Sergey A. Tachenov 0015 0016 For more info read MiniZip_info.txt 0017 0018 0019 ------------------------------------------------------------------------------------ 0020 Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of 0021 compatibility with older software. The following is from the original crypt.c. 0022 Code woven in by Terry Thorsen 1/2003. 0023 0024 Copyright (c) 1990-2000 Info-ZIP. All rights reserved. 0025 0026 See the accompanying file LICENSE, version 2000-Apr-09 or later 0027 (the contents of which are also included in zip.h) for terms of use. 0028 If, for some reason, all these files are missing, the Info-ZIP license 0029 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html 0030 0031 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] 0032 0033 The encryption/decryption parts of this source code (as opposed to the 0034 non-echoing password parts) were originally written in Europe. The 0035 whole source package can be freely distributed, including from the USA. 0036 (Prior to January 2000, re-export from the US was a violation of US law.) 0037 0038 This encryption code is a direct transcription of the algorithm from 0039 Roger Schlafly, described by Phil Katz in the file appnote.txt. This 0040 file (appnote.txt) is distributed with the PKZIP program (even in the 0041 version without encryption capabilities). 0042 0043 ------------------------------------------------------------------------------------ 0044 0045 Changes in unzip.c 0046 0047 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos 0048 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* 0049 2007-2008 - Even Rouault - Remove old C style function prototypes 0050 2007-2008 - Even Rouault - Add unzip support for ZIP64 0051 0052 Copyright (C) 2007-2008 Even Rouault 0053 0054 0055 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). 0056 Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G 0057 should only read the compressed/uncompressed size from the Zip64 format if 0058 the size from normal header was 0xFFFFFFFF 0059 Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant 0060 Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) 0061 Patch created by Daniel Borca 0062 0063 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer 0064 0065 Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson 0066 0067 */ 0068 0069 0070 #include <stdio.h> 0071 #include <stdlib.h> 0072 #include <string.h> 0073 0074 #include "zlib.h" 0075 #if (ZLIB_VERNUM < 0x1270) 0076 typedef uLongf z_crc_t; 0077 #endif 0078 #include "unzip.h" 0079 0080 #ifdef STDC 0081 # include <stddef.h> 0082 # include <string.h> 0083 # include <stdlib.h> 0084 #endif 0085 #ifdef NO_ERRNO_H 0086 extern int errno; 0087 #else 0088 # include <errno.h> 0089 #endif 0090 0091 0092 #ifndef local 0093 # define local static 0094 #endif 0095 /* compile with -Dlocal if your debugger can't find static symbols */ 0096 0097 0098 #ifndef CASESENSITIVITYDEFAULT_NO 0099 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) 0100 # define CASESENSITIVITYDEFAULT_NO 0101 # endif 0102 #endif 0103 0104 0105 #ifndef UNZ_BUFSIZE 0106 #define UNZ_BUFSIZE (16384) 0107 #endif 0108 0109 #ifndef UNZ_MAXFILENAMEINZIP 0110 #define UNZ_MAXFILENAMEINZIP (256) 0111 #endif 0112 0113 #ifndef ALLOC 0114 # define ALLOC(size) (malloc(size)) 0115 #endif 0116 #ifndef TRYFREE 0117 # define TRYFREE(p) {if (p) free(p);} 0118 #endif 0119 0120 #define SIZECENTRALDIRITEM (0x2e) 0121 #define SIZEZIPLOCALHEADER (0x1e) 0122 0123 0124 const char unz_copyright[] = 0125 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; 0126 0127 /* unz_file_info_interntal contain internal info about a file in zipfile*/ 0128 typedef struct unz_file_info64_internal_s 0129 { 0130 ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ 0131 } unz_file_info64_internal; 0132 0133 0134 /* file_in_zip_read_info_s contain internal information about a file in zipfile, 0135 when reading and decompress it */ 0136 typedef struct 0137 { 0138 char *read_buffer; /* internal buffer for compressed data */ 0139 z_stream stream; /* zLib stream structure for inflate */ 0140 0141 #ifdef HAVE_BZIP2 0142 bz_stream bstream; /* bzLib stream structure for bziped */ 0143 #endif 0144 0145 ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ 0146 uLong stream_initialised; /* flag set if stream structure is initialised*/ 0147 0148 ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ 0149 uInt size_local_extrafield;/* size of the local extra field */ 0150 ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ 0151 ZPOS64_T total_out_64; 0152 0153 uLong crc32; /* crc32 of all data uncompressed */ 0154 uLong crc32_wait; /* crc32 we must obtain after decompress all */ 0155 ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ 0156 ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ 0157 zlib_filefunc64_32_def z_filefunc; 0158 voidpf filestream; /* io structore of the zipfile */ 0159 uLong compression_method; /* compression method (0==store) */ 0160 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 0161 int raw; 0162 } file_in_zip64_read_info_s; 0163 0164 0165 /* unz64_s contain internal information about the zipfile 0166 */ 0167 typedef struct 0168 { 0169 zlib_filefunc64_32_def z_filefunc; 0170 int is64bitOpenFunction; 0171 voidpf filestream; /* io structore of the zipfile */ 0172 unz_global_info64 gi; /* public global information */ 0173 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 0174 ZPOS64_T num_file; /* number of the current file in the zipfile*/ 0175 ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ 0176 ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ 0177 ZPOS64_T central_pos; /* position of the beginning of the central dir*/ 0178 0179 ZPOS64_T size_central_dir; /* size of the central directory */ 0180 ZPOS64_T offset_central_dir; /* offset of start of central directory with 0181 respect to the starting disk number */ 0182 0183 unz_file_info64 cur_file_info; /* public info about the current file in zip*/ 0184 unz_file_info64_internal cur_file_info_internal; /* private info about it*/ 0185 file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current 0186 file if we are decompressing it */ 0187 int encrypted; 0188 0189 int isZip64; 0190 unsigned flags; 0191 0192 # ifndef NOUNCRYPT 0193 unsigned long keys[3]; /* keys defining the pseudo-random sequence */ 0194 const z_crc_t FAR * pcrc_32_tab; 0195 # endif 0196 } unz64_s; 0197 0198 0199 #ifndef NOUNCRYPT 0200 #include "crypt.h" 0201 #endif 0202 0203 /* =========================================================================== 0204 Read a byte from a gz_stream; update next_in and avail_in. Return EOF 0205 for end of file. 0206 IN assertion: the stream s has been sucessfully opened for reading. 0207 */ 0208 0209 0210 local int unz64local_getByte OF(( 0211 const zlib_filefunc64_32_def* pzlib_filefunc_def, 0212 voidpf filestream, 0213 int *pi)); 0214 0215 local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) 0216 { 0217 unsigned char c; 0218 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); 0219 if (err==1) 0220 { 0221 *pi = (int)c; 0222 return UNZ_OK; 0223 } 0224 else 0225 { 0226 if (ZERROR64(*pzlib_filefunc_def,filestream)) 0227 return UNZ_ERRNO; 0228 else 0229 return UNZ_EOF; 0230 } 0231 } 0232 0233 0234 /* =========================================================================== 0235 Reads a long in LSB order from the given gz_stream. Sets 0236 */ 0237 local int unz64local_getShort OF(( 0238 const zlib_filefunc64_32_def* pzlib_filefunc_def, 0239 voidpf filestream, 0240 uLong *pX)); 0241 0242 local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, 0243 voidpf filestream, 0244 uLong *pX) 0245 { 0246 uLong x ; 0247 int i = 0; 0248 int err; 0249 0250 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0251 x = (uLong)i; 0252 0253 if (err==UNZ_OK) 0254 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0255 x |= ((uLong)i)<<8; 0256 0257 if (err==UNZ_OK) 0258 *pX = x; 0259 else 0260 *pX = 0; 0261 return err; 0262 } 0263 0264 local int unz64local_getLong OF(( 0265 const zlib_filefunc64_32_def* pzlib_filefunc_def, 0266 voidpf filestream, 0267 uLong *pX)); 0268 0269 local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, 0270 voidpf filestream, 0271 uLong *pX) 0272 { 0273 uLong x ; 0274 int i = 0; 0275 int err; 0276 0277 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0278 x = (uLong)i; 0279 0280 if (err==UNZ_OK) 0281 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0282 x |= ((uLong)i)<<8; 0283 0284 if (err==UNZ_OK) 0285 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0286 x |= ((uLong)i)<<16; 0287 0288 if (err==UNZ_OK) 0289 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0290 x += ((uLong)i)<<24; 0291 0292 if (err==UNZ_OK) 0293 *pX = x; 0294 else 0295 *pX = 0; 0296 return err; 0297 } 0298 0299 local int unz64local_getLong64 OF(( 0300 const zlib_filefunc64_32_def* pzlib_filefunc_def, 0301 voidpf filestream, 0302 ZPOS64_T *pX)); 0303 0304 0305 local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, 0306 voidpf filestream, 0307 ZPOS64_T *pX) 0308 { 0309 ZPOS64_T x ; 0310 int i = 0; 0311 int err; 0312 0313 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0314 x = (ZPOS64_T)i; 0315 0316 if (err==UNZ_OK) 0317 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0318 x |= ((ZPOS64_T)i)<<8; 0319 0320 if (err==UNZ_OK) 0321 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0322 x |= ((ZPOS64_T)i)<<16; 0323 0324 if (err==UNZ_OK) 0325 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0326 x |= ((ZPOS64_T)i)<<24; 0327 0328 if (err==UNZ_OK) 0329 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0330 x |= ((ZPOS64_T)i)<<32; 0331 0332 if (err==UNZ_OK) 0333 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0334 x |= ((ZPOS64_T)i)<<40; 0335 0336 if (err==UNZ_OK) 0337 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0338 x |= ((ZPOS64_T)i)<<48; 0339 0340 if (err==UNZ_OK) 0341 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); 0342 x |= ((ZPOS64_T)i)<<56; 0343 0344 if (err==UNZ_OK) 0345 *pX = x; 0346 else 0347 *pX = 0; 0348 return err; 0349 } 0350 0351 /* My own strcmpi / strcasecmp */ 0352 local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) 0353 { 0354 for (;;) 0355 { 0356 char c1=*(fileName1++); 0357 char c2=*(fileName2++); 0358 if ((c1>='a') && (c1<='z')) 0359 c1 -= 0x20; 0360 if ((c2>='a') && (c2<='z')) 0361 c2 -= 0x20; 0362 if (c1=='\0') 0363 return ((c2=='\0') ? 0 : -1); 0364 if (c2=='\0') 0365 return 1; 0366 if (c1<c2) 0367 return -1; 0368 if (c1>c2) 0369 return 1; 0370 } 0371 } 0372 0373 0374 #ifdef CASESENSITIVITYDEFAULT_NO 0375 #define CASESENSITIVITYDEFAULTVALUE 2 0376 #else 0377 #define CASESENSITIVITYDEFAULTVALUE 1 0378 #endif 0379 0380 #ifndef STRCMPCASENOSENTIVEFUNCTION 0381 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal 0382 #endif 0383 0384 /* 0385 Compare two filename (fileName1,fileName2). 0386 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) 0387 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi 0388 or strcasecmp) 0389 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system 0390 (like 1 on Unix, 2 on Windows) 0391 0392 */ 0393 extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, 0394 const char* fileName2, 0395 int iCaseSensitivity) 0396 0397 { 0398 if (iCaseSensitivity==0) 0399 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; 0400 0401 if (iCaseSensitivity==1) 0402 return strcmp(fileName1,fileName2); 0403 0404 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); 0405 } 0406 0407 #ifndef BUFREADCOMMENT 0408 #define BUFREADCOMMENT (0x400) 0409 #endif 0410 0411 /* 0412 Locate the Central directory of a zipfile (at the end, just before 0413 the global comment) 0414 */ 0415 local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); 0416 local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) 0417 { 0418 unsigned char* buf; 0419 ZPOS64_T uSizeFile; 0420 ZPOS64_T uBackRead; 0421 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ 0422 ZPOS64_T uPosFound=0; 0423 0424 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 0425 return 0; 0426 0427 0428 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); 0429 0430 if (uMaxBack>uSizeFile) 0431 uMaxBack = uSizeFile; 0432 0433 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 0434 if (buf==NULL) 0435 return 0; 0436 0437 uBackRead = 4; 0438 while (uBackRead<uMaxBack) 0439 { 0440 uLong uReadSize; 0441 ZPOS64_T uReadPos ; 0442 int i; 0443 if (uBackRead+BUFREADCOMMENT>uMaxBack) 0444 uBackRead = uMaxBack; 0445 else 0446 uBackRead+=BUFREADCOMMENT; 0447 uReadPos = uSizeFile-uBackRead ; 0448 0449 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 0450 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); 0451 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 0452 break; 0453 0454 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 0455 break; 0456 0457 for (i=(int)uReadSize-3; (i--)>0;) 0458 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 0459 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) 0460 { 0461 uPosFound = uReadPos+i; 0462 break; 0463 } 0464 0465 if (uPosFound!=0) 0466 break; 0467 } 0468 TRYFREE(buf); 0469 return uPosFound; 0470 } 0471 0472 0473 /* 0474 Locate the Central directory 64 of a zipfile (at the end, just before 0475 the global comment) 0476 */ 0477 local ZPOS64_T unz64local_SearchCentralDir64 OF(( 0478 const zlib_filefunc64_32_def* pzlib_filefunc_def, 0479 voidpf filestream)); 0480 0481 local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, 0482 voidpf filestream) 0483 { 0484 unsigned char* buf; 0485 ZPOS64_T uSizeFile; 0486 ZPOS64_T uBackRead; 0487 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ 0488 ZPOS64_T uPosFound=0; 0489 uLong uL; 0490 ZPOS64_T relativeOffset; 0491 0492 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 0493 return 0; 0494 0495 0496 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); 0497 0498 if (uMaxBack>uSizeFile) 0499 uMaxBack = uSizeFile; 0500 0501 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 0502 if (buf==NULL) 0503 return 0; 0504 0505 uBackRead = 4; 0506 while (uBackRead<uMaxBack) 0507 { 0508 uLong uReadSize; 0509 ZPOS64_T uReadPos; 0510 int i; 0511 if (uBackRead+BUFREADCOMMENT>uMaxBack) 0512 uBackRead = uMaxBack; 0513 else 0514 uBackRead+=BUFREADCOMMENT; 0515 uReadPos = uSizeFile-uBackRead ; 0516 0517 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 0518 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); 0519 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 0520 break; 0521 0522 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 0523 break; 0524 0525 for (i=(int)uReadSize-3; (i--)>0;) 0526 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 0527 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) 0528 { 0529 uPosFound = uReadPos+i; 0530 break; 0531 } 0532 0533 if (uPosFound!=0) 0534 break; 0535 } 0536 TRYFREE(buf); 0537 if (uPosFound == 0) 0538 return 0; 0539 0540 /* Zip64 end of central directory locator */ 0541 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) 0542 return 0; 0543 0544 /* the signature, already checked */ 0545 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 0546 return 0; 0547 0548 /* number of the disk with the start of the zip64 end of central directory */ 0549 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 0550 return 0; 0551 if (uL != 0) 0552 return 0; 0553 0554 /* relative offset of the zip64 end of central directory record */ 0555 if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) 0556 return 0; 0557 0558 /* total number of disks */ 0559 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 0560 return 0; 0561 if (uL != 1) 0562 return 0; 0563 0564 /* Goto end of central directory record */ 0565 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) 0566 return 0; 0567 0568 /* the signature */ 0569 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 0570 return 0; 0571 0572 if (uL != 0x06064b50) 0573 return 0; 0574 0575 return relativeOffset; 0576 } 0577 0578 /* 0579 Open a Zip file. path contain the full pathname (by example, 0580 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer 0581 "zlib/zlib114.zip". 0582 If the zipfile cannot be opened (file doesn't exist or in not valid), the 0583 return value is NULL. 0584 Else, the return value is a unzFile Handle, usable with other function 0585 of this unzip package. 0586 */ 0587 extern unzFile unzOpenInternal (voidpf file, 0588 zlib_filefunc64_32_def* pzlib_filefunc64_32_def, 0589 int is64bitOpenFunction, unsigned flags) 0590 { 0591 unz64_s us; 0592 unz64_s *s; 0593 ZPOS64_T central_pos; 0594 uLong uL; 0595 0596 uLong number_disk; /* number of the current dist, used for 0597 spaning ZIP, unsupported, always 0*/ 0598 uLong number_disk_with_CD; /* number the the disk with central dir, used 0599 for spaning ZIP, unsupported, always 0*/ 0600 ZPOS64_T number_entry_CD; /* total number of entries in 0601 the central dir 0602 (same than number_entry on nospan) */ 0603 0604 int err=UNZ_OK; 0605 0606 if (unz_copyright[0]!=' ') 0607 return NULL; 0608 0609 us.flags = flags; 0610 us.z_filefunc.zseek32_file = NULL; 0611 us.z_filefunc.ztell32_file = NULL; 0612 if (pzlib_filefunc64_32_def==NULL) 0613 fill_qiodevice64_filefunc(&us.z_filefunc.zfile_func64); 0614 else 0615 us.z_filefunc = *pzlib_filefunc64_32_def; 0616 us.is64bitOpenFunction = is64bitOpenFunction; 0617 0618 0619 0620 us.filestream = ZOPEN64(us.z_filefunc, 0621 file, 0622 ZLIB_FILEFUNC_MODE_READ | 0623 ZLIB_FILEFUNC_MODE_EXISTING); 0624 if (us.filestream==NULL) 0625 return NULL; 0626 0627 central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); 0628 if (central_pos) 0629 { 0630 uLong uS; 0631 ZPOS64_T uL64; 0632 0633 us.isZip64 = 1; 0634 0635 if (ZSEEK64(us.z_filefunc, us.filestream, 0636 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) 0637 err=UNZ_ERRNO; 0638 0639 /* the signature, already checked */ 0640 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 0641 err=UNZ_ERRNO; 0642 0643 /* size of zip64 end of central directory record */ 0644 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) 0645 err=UNZ_ERRNO; 0646 0647 /* version made by */ 0648 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) 0649 err=UNZ_ERRNO; 0650 0651 /* version needed to extract */ 0652 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) 0653 err=UNZ_ERRNO; 0654 0655 /* number of this disk */ 0656 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) 0657 err=UNZ_ERRNO; 0658 0659 /* number of the disk with the start of the central directory */ 0660 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) 0661 err=UNZ_ERRNO; 0662 0663 /* total number of entries in the central directory on this disk */ 0664 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) 0665 err=UNZ_ERRNO; 0666 0667 /* total number of entries in the central directory */ 0668 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) 0669 err=UNZ_ERRNO; 0670 0671 if ((number_entry_CD!=us.gi.number_entry) || 0672 (number_disk_with_CD!=0) || 0673 (number_disk!=0)) 0674 err=UNZ_BADZIPFILE; 0675 0676 /* size of the central directory */ 0677 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) 0678 err=UNZ_ERRNO; 0679 0680 /* offset of start of central directory with respect to the 0681 starting disk number */ 0682 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) 0683 err=UNZ_ERRNO; 0684 0685 us.gi.size_comment = 0; 0686 } 0687 else 0688 { 0689 central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); 0690 if (central_pos==0) 0691 err=UNZ_ERRNO; 0692 0693 us.isZip64 = 0; 0694 0695 if (ZSEEK64(us.z_filefunc, us.filestream, 0696 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) 0697 err=UNZ_ERRNO; 0698 0699 /* the signature, already checked */ 0700 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 0701 err=UNZ_ERRNO; 0702 0703 /* number of this disk */ 0704 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) 0705 err=UNZ_ERRNO; 0706 0707 /* number of the disk with the start of the central directory */ 0708 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) 0709 err=UNZ_ERRNO; 0710 0711 /* total number of entries in the central dir on this disk */ 0712 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 0713 err=UNZ_ERRNO; 0714 us.gi.number_entry = uL; 0715 0716 /* total number of entries in the central dir */ 0717 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 0718 err=UNZ_ERRNO; 0719 number_entry_CD = uL; 0720 0721 if ((number_entry_CD!=us.gi.number_entry) || 0722 (number_disk_with_CD!=0) || 0723 (number_disk!=0)) 0724 err=UNZ_BADZIPFILE; 0725 0726 /* size of the central directory */ 0727 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 0728 err=UNZ_ERRNO; 0729 us.size_central_dir = uL; 0730 0731 /* offset of start of central directory with respect to the 0732 starting disk number */ 0733 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 0734 err=UNZ_ERRNO; 0735 us.offset_central_dir = uL; 0736 0737 /* zipfile comment length */ 0738 if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) 0739 err=UNZ_ERRNO; 0740 } 0741 0742 if ((central_pos<us.offset_central_dir+us.size_central_dir) && 0743 (err==UNZ_OK)) 0744 err=UNZ_BADZIPFILE; 0745 0746 if (err!=UNZ_OK) 0747 { 0748 if ((us.flags & UNZ_AUTO_CLOSE) != 0) 0749 ZCLOSE64(us.z_filefunc, us.filestream); 0750 else 0751 ZFAKECLOSE64(us.z_filefunc, us.filestream); 0752 return NULL; 0753 } 0754 0755 us.byte_before_the_zipfile = central_pos - 0756 (us.offset_central_dir+us.size_central_dir); 0757 us.central_pos = central_pos; 0758 us.pfile_in_zip_read = NULL; 0759 us.encrypted = 0; 0760 0761 0762 s=(unz64_s*)ALLOC(sizeof(unz64_s)); 0763 if( s != NULL) 0764 { 0765 *s=us; 0766 unzGoToFirstFile((unzFile)s); 0767 } 0768 return (unzFile)s; 0769 } 0770 0771 0772 extern unzFile ZEXPORT unzOpen2 (voidpf file, 0773 zlib_filefunc_def* pzlib_filefunc32_def) 0774 { 0775 if (pzlib_filefunc32_def != NULL) 0776 { 0777 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; 0778 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); 0779 return unzOpenInternal(file, &zlib_filefunc64_32_def_fill, 0, UNZ_DEFAULT_FLAGS); 0780 } 0781 else 0782 return unzOpenInternal(file, NULL, 0, UNZ_DEFAULT_FLAGS); 0783 } 0784 0785 extern unzFile ZEXPORT unzOpen2_64 (voidpf file, 0786 zlib_filefunc64_def* pzlib_filefunc_def) 0787 { 0788 if (pzlib_filefunc_def != NULL) 0789 { 0790 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; 0791 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; 0792 zlib_filefunc64_32_def_fill.ztell32_file = NULL; 0793 zlib_filefunc64_32_def_fill.zseek32_file = NULL; 0794 return unzOpenInternal(file, &zlib_filefunc64_32_def_fill, 1, UNZ_DEFAULT_FLAGS); 0795 } 0796 else 0797 return unzOpenInternal(file, NULL, 1, UNZ_DEFAULT_FLAGS); 0798 } 0799 0800 extern unzFile ZEXPORT unzOpen (voidpf file) 0801 { 0802 return unzOpenInternal(file, NULL, 0, UNZ_DEFAULT_FLAGS); 0803 } 0804 0805 extern unzFile ZEXPORT unzOpen64 (voidpf file) 0806 { 0807 return unzOpenInternal(file, NULL, 1, UNZ_DEFAULT_FLAGS); 0808 } 0809 0810 /* 0811 Close a ZipFile opened with unzipOpen. 0812 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), 0813 these files MUST be closed with unzipCloseCurrentFile before call unzipClose. 0814 return UNZ_OK if there is no problem. */ 0815 extern int ZEXPORT unzClose (unzFile file) 0816 { 0817 unz64_s* s; 0818 if (file==NULL) 0819 return UNZ_PARAMERROR; 0820 s=(unz64_s*)file; 0821 0822 if (s->pfile_in_zip_read!=NULL) 0823 unzCloseCurrentFile(file); 0824 0825 if ((s->flags & UNZ_AUTO_CLOSE) != 0) 0826 ZCLOSE64(s->z_filefunc, s->filestream); 0827 else 0828 ZFAKECLOSE64(s->z_filefunc, s->filestream); 0829 TRYFREE(s); 0830 return UNZ_OK; 0831 } 0832 0833 0834 /* 0835 Write info about the ZipFile in the *pglobal_info structure. 0836 No preparation of the structure is needed 0837 return UNZ_OK if there is no problem. */ 0838 extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) 0839 { 0840 unz64_s* s; 0841 if (file==NULL) 0842 return UNZ_PARAMERROR; 0843 s=(unz64_s*)file; 0844 *pglobal_info=s->gi; 0845 return UNZ_OK; 0846 } 0847 0848 extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) 0849 { 0850 unz64_s* s; 0851 if (file==NULL) 0852 return UNZ_PARAMERROR; 0853 s=(unz64_s*)file; 0854 /* to do : check if number_entry is not truncated */ 0855 pglobal_info32->number_entry = (uLong)s->gi.number_entry; 0856 pglobal_info32->size_comment = s->gi.size_comment; 0857 return UNZ_OK; 0858 } 0859 /* 0860 Translate date/time from Dos format to tm_unz (readable more easilty) 0861 */ 0862 local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) 0863 { 0864 ZPOS64_T uDate; 0865 uDate = (ZPOS64_T)(ulDosDate>>16); 0866 ptm->tm_mday = (uInt)(uDate&0x1f) ; 0867 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; 0868 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; 0869 0870 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); 0871 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; 0872 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; 0873 } 0874 0875 /* 0876 Get Info about the current file in the zipfile, with internal only info 0877 */ 0878 local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, 0879 unz_file_info64 *pfile_info, 0880 unz_file_info64_internal 0881 *pfile_info_internal, 0882 char *szFileName, 0883 uLong fileNameBufferSize, 0884 void *extraField, 0885 uLong extraFieldBufferSize, 0886 char *szComment, 0887 uLong commentBufferSize)); 0888 0889 local int unz64local_GetCurrentFileInfoInternal (unzFile file, 0890 unz_file_info64 *pfile_info, 0891 unz_file_info64_internal 0892 *pfile_info_internal, 0893 char *szFileName, 0894 uLong fileNameBufferSize, 0895 void *extraField, 0896 uLong extraFieldBufferSize, 0897 char *szComment, 0898 uLong commentBufferSize) 0899 { 0900 unz64_s* s; 0901 unz_file_info64 file_info; 0902 unz_file_info64_internal file_info_internal; 0903 int err=UNZ_OK; 0904 uLong uMagic; 0905 ZPOS64_T llSeek=0; 0906 uLong uL; 0907 0908 if (file==NULL) 0909 return UNZ_PARAMERROR; 0910 s=(unz64_s*)file; 0911 if (ZSEEK64(s->z_filefunc, s->filestream, 0912 s->pos_in_central_dir+s->byte_before_the_zipfile, 0913 ZLIB_FILEFUNC_SEEK_SET)!=0) 0914 err=UNZ_ERRNO; 0915 0916 0917 /* we check the magic */ 0918 if (err==UNZ_OK) 0919 { 0920 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) 0921 err=UNZ_ERRNO; 0922 else if (uMagic!=0x02014b50) 0923 err=UNZ_BADZIPFILE; 0924 } 0925 0926 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) 0927 err=UNZ_ERRNO; 0928 0929 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) 0930 err=UNZ_ERRNO; 0931 0932 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) 0933 err=UNZ_ERRNO; 0934 0935 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) 0936 err=UNZ_ERRNO; 0937 0938 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) 0939 err=UNZ_ERRNO; 0940 0941 unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); 0942 0943 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) 0944 err=UNZ_ERRNO; 0945 0946 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) 0947 err=UNZ_ERRNO; 0948 file_info.compressed_size = uL; 0949 0950 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) 0951 err=UNZ_ERRNO; 0952 file_info.uncompressed_size = uL; 0953 0954 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) 0955 err=UNZ_ERRNO; 0956 0957 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) 0958 err=UNZ_ERRNO; 0959 0960 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) 0961 err=UNZ_ERRNO; 0962 0963 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) 0964 err=UNZ_ERRNO; 0965 0966 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) 0967 err=UNZ_ERRNO; 0968 0969 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) 0970 err=UNZ_ERRNO; 0971 0972 /* relative offset of local header */ 0973 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) 0974 err=UNZ_ERRNO; 0975 file_info_internal.offset_curfile = uL; 0976 0977 llSeek+=file_info.size_filename; 0978 if ((err==UNZ_OK) && (szFileName!=NULL)) 0979 { 0980 uLong uSizeRead ; 0981 if (file_info.size_filename<fileNameBufferSize) 0982 { 0983 *(szFileName+file_info.size_filename)='\0'; 0984 uSizeRead = file_info.size_filename; 0985 } 0986 else 0987 uSizeRead = fileNameBufferSize; 0988 0989 if ((file_info.size_filename>0) && (fileNameBufferSize>0)) 0990 if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) 0991 err=UNZ_ERRNO; 0992 llSeek -= uSizeRead; 0993 } 0994 0995 /* Read extrafield */ 0996 if ((err==UNZ_OK) && (extraField!=NULL)) 0997 { 0998 ZPOS64_T uSizeRead ; 0999 if (file_info.size_file_extra<extraFieldBufferSize) 1000 uSizeRead = file_info.size_file_extra; 1001 else 1002 uSizeRead = extraFieldBufferSize; 1003 1004 if (llSeek!=0) 1005 { 1006 if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 1007 llSeek=0; 1008 else 1009 err=UNZ_ERRNO; 1010 } 1011 1012 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) 1013 if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) 1014 err=UNZ_ERRNO; 1015 1016 llSeek += file_info.size_file_extra - (uLong)uSizeRead; 1017 } 1018 else 1019 llSeek += file_info.size_file_extra; 1020 1021 1022 if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) 1023 { 1024 uLong acc = 0; 1025 1026 /* since lSeek now points to after the extra field we need to move back */ 1027 llSeek -= file_info.size_file_extra; 1028 1029 if (llSeek!=0) 1030 { 1031 if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 1032 llSeek=0; 1033 else 1034 err=UNZ_ERRNO; 1035 } 1036 1037 while(acc < file_info.size_file_extra) 1038 { 1039 uLong headerId; 1040 uLong dataSize; 1041 1042 if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) 1043 err=UNZ_ERRNO; 1044 1045 if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) 1046 err=UNZ_ERRNO; 1047 1048 /* ZIP64 extra fields */ 1049 if (headerId == 0x0001) 1050 { 1051 uLong uL; 1052 1053 if(file_info.uncompressed_size == (ZPOS64_T)0xFFFFFFFFu) 1054 { 1055 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) 1056 err=UNZ_ERRNO; 1057 } 1058 1059 if(file_info.compressed_size == (ZPOS64_T)0xFFFFFFFFu) 1060 { 1061 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) 1062 err=UNZ_ERRNO; 1063 } 1064 1065 if(file_info_internal.offset_curfile == (ZPOS64_T)0xFFFFFFFFu) 1066 { 1067 /* Relative Header offset */ 1068 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) 1069 err=UNZ_ERRNO; 1070 } 1071 1072 if(file_info.disk_num_start == 0xFFFFFFFFu) 1073 { 1074 /* Disk Start Number */ 1075 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) 1076 err=UNZ_ERRNO; 1077 } 1078 1079 } 1080 else 1081 { 1082 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) 1083 err=UNZ_ERRNO; 1084 } 1085 1086 acc += 2 + 2 + dataSize; 1087 } 1088 } 1089 1090 if ((err==UNZ_OK) && (szComment!=NULL)) 1091 { 1092 uLong uSizeRead ; 1093 if (file_info.size_file_comment<commentBufferSize) 1094 { 1095 *(szComment+file_info.size_file_comment)='\0'; 1096 uSizeRead = file_info.size_file_comment; 1097 } 1098 else 1099 uSizeRead = commentBufferSize; 1100 1101 if (llSeek!=0) 1102 { 1103 if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 1104 llSeek=0; 1105 else 1106 err=UNZ_ERRNO; 1107 } 1108 1109 if ((file_info.size_file_comment>0) && (commentBufferSize>0)) 1110 if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) 1111 err=UNZ_ERRNO; 1112 llSeek+=file_info.size_file_comment - uSizeRead; 1113 } 1114 else 1115 llSeek+=file_info.size_file_comment; 1116 1117 1118 if ((err==UNZ_OK) && (pfile_info!=NULL)) 1119 *pfile_info=file_info; 1120 1121 if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) 1122 *pfile_info_internal=file_info_internal; 1123 1124 return err; 1125 } 1126 1127 1128 1129 /* 1130 Write info about the ZipFile in the *pglobal_info structure. 1131 No preparation of the structure is needed 1132 return UNZ_OK if there is no problem. 1133 */ 1134 extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, 1135 unz_file_info64 * pfile_info, 1136 char * szFileName, uLong fileNameBufferSize, 1137 void *extraField, uLong extraFieldBufferSize, 1138 char* szComment, uLong commentBufferSize) 1139 { 1140 return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, 1141 szFileName,fileNameBufferSize, 1142 extraField,extraFieldBufferSize, 1143 szComment,commentBufferSize); 1144 } 1145 1146 extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, 1147 unz_file_info * pfile_info, 1148 char * szFileName, uLong fileNameBufferSize, 1149 void *extraField, uLong extraFieldBufferSize, 1150 char* szComment, uLong commentBufferSize) 1151 { 1152 int err; 1153 unz_file_info64 file_info64; 1154 err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, 1155 szFileName,fileNameBufferSize, 1156 extraField,extraFieldBufferSize, 1157 szComment,commentBufferSize); 1158 if (err==UNZ_OK && pfile_info != NULL) 1159 { 1160 pfile_info->version = file_info64.version; 1161 pfile_info->version_needed = file_info64.version_needed; 1162 pfile_info->flag = file_info64.flag; 1163 pfile_info->compression_method = file_info64.compression_method; 1164 pfile_info->dosDate = file_info64.dosDate; 1165 pfile_info->crc = file_info64.crc; 1166 1167 pfile_info->size_filename = file_info64.size_filename; 1168 pfile_info->size_file_extra = file_info64.size_file_extra; 1169 pfile_info->size_file_comment = file_info64.size_file_comment; 1170 1171 pfile_info->disk_num_start = file_info64.disk_num_start; 1172 pfile_info->internal_fa = file_info64.internal_fa; 1173 pfile_info->external_fa = file_info64.external_fa; 1174 1175 pfile_info->tmu_date = file_info64.tmu_date, 1176 1177 1178 pfile_info->compressed_size = (uLong)file_info64.compressed_size; 1179 pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; 1180 1181 } 1182 return err; 1183 } 1184 /* 1185 Set the current file of the zipfile to the first file. 1186 return UNZ_OK if there is no problem 1187 */ 1188 extern int ZEXPORT unzGoToFirstFile (unzFile file) 1189 { 1190 int err=UNZ_OK; 1191 unz64_s* s; 1192 if (file==NULL) 1193 return UNZ_PARAMERROR; 1194 s=(unz64_s*)file; 1195 s->pos_in_central_dir=s->offset_central_dir; 1196 s->num_file=0; 1197 err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, 1198 &s->cur_file_info_internal, 1199 NULL,0,NULL,0,NULL,0); 1200 s->current_file_ok = (err == UNZ_OK); 1201 return err; 1202 } 1203 1204 /* 1205 Set the current file of the zipfile to the next file. 1206 return UNZ_OK if there is no problem 1207 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. 1208 */ 1209 extern int ZEXPORT unzGoToNextFile (unzFile file) 1210 { 1211 unz64_s* s; 1212 int err; 1213 1214 if (file==NULL) 1215 return UNZ_PARAMERROR; 1216 s=(unz64_s*)file; 1217 if (!s->current_file_ok) 1218 return UNZ_END_OF_LIST_OF_FILE; 1219 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ 1220 if (s->num_file+1==s->gi.number_entry) 1221 return UNZ_END_OF_LIST_OF_FILE; 1222 1223 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + 1224 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; 1225 s->num_file++; 1226 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, 1227 &s->cur_file_info_internal, 1228 NULL,0,NULL,0,NULL,0); 1229 s->current_file_ok = (err == UNZ_OK); 1230 return err; 1231 } 1232 1233 1234 /* 1235 Try locate the file szFileName in the zipfile. 1236 For the iCaseSensitivity signification, see unzipStringFileNameCompare 1237 1238 return value : 1239 UNZ_OK if the file is found. It becomes the current file. 1240 UNZ_END_OF_LIST_OF_FILE if the file is not found 1241 */ 1242 extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) 1243 { 1244 unz64_s* s; 1245 int err; 1246 1247 /* We remember the 'current' position in the file so that we can jump 1248 * back there if we fail. 1249 */ 1250 unz_file_info64 cur_file_infoSaved; 1251 unz_file_info64_internal cur_file_info_internalSaved; 1252 ZPOS64_T num_fileSaved; 1253 ZPOS64_T pos_in_central_dirSaved; 1254 1255 1256 if (file==NULL) 1257 return UNZ_PARAMERROR; 1258 1259 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) 1260 return UNZ_PARAMERROR; 1261 1262 s=(unz64_s*)file; 1263 if (!s->current_file_ok) 1264 return UNZ_END_OF_LIST_OF_FILE; 1265 1266 /* Save the current state */ 1267 num_fileSaved = s->num_file; 1268 pos_in_central_dirSaved = s->pos_in_central_dir; 1269 cur_file_infoSaved = s->cur_file_info; 1270 cur_file_info_internalSaved = s->cur_file_info_internal; 1271 1272 err = unzGoToFirstFile(file); 1273 1274 while (err == UNZ_OK) 1275 { 1276 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; 1277 err = unzGetCurrentFileInfo64(file,NULL, 1278 szCurrentFileName,sizeof(szCurrentFileName)-1, 1279 NULL,0,NULL,0); 1280 if (err == UNZ_OK) 1281 { 1282 if (unzStringFileNameCompare(szCurrentFileName, 1283 szFileName,iCaseSensitivity)==0) 1284 return UNZ_OK; 1285 err = unzGoToNextFile(file); 1286 } 1287 } 1288 1289 /* We failed, so restore the state of the 'current file' to where we 1290 * were. 1291 */ 1292 s->num_file = num_fileSaved ; 1293 s->pos_in_central_dir = pos_in_central_dirSaved ; 1294 s->cur_file_info = cur_file_infoSaved; 1295 s->cur_file_info_internal = cur_file_info_internalSaved; 1296 return err; 1297 } 1298 1299 1300 /* 1301 /////////////////////////////////////////// 1302 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) 1303 // I need random access 1304 // 1305 // Further optimization could be realized by adding an ability 1306 // to cache the directory in memory. The goal being a single 1307 // comprehensive file read to put the file I need in a memory. 1308 */ 1309 1310 /* 1311 typedef struct unz_file_pos_s 1312 { 1313 ZPOS64_T pos_in_zip_directory; // offset in file 1314 ZPOS64_T num_of_file; // # of file 1315 } unz_file_pos; 1316 */ 1317 1318 extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) 1319 { 1320 unz64_s* s; 1321 1322 if (file==NULL || file_pos==NULL) 1323 return UNZ_PARAMERROR; 1324 s=(unz64_s*)file; 1325 if (!s->current_file_ok) 1326 return UNZ_END_OF_LIST_OF_FILE; 1327 1328 file_pos->pos_in_zip_directory = s->pos_in_central_dir; 1329 file_pos->num_of_file = s->num_file; 1330 1331 return UNZ_OK; 1332 } 1333 1334 extern int ZEXPORT unzGetFilePos( 1335 unzFile file, 1336 unz_file_pos* file_pos) 1337 { 1338 unz64_file_pos file_pos64; 1339 int err = unzGetFilePos64(file,&file_pos64); 1340 if (err==UNZ_OK) 1341 { 1342 file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; 1343 file_pos->num_of_file = (uLong)file_pos64.num_of_file; 1344 } 1345 return err; 1346 } 1347 1348 extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) 1349 { 1350 unz64_s* s; 1351 int err; 1352 1353 if (file==NULL || file_pos==NULL) 1354 return UNZ_PARAMERROR; 1355 s=(unz64_s*)file; 1356 1357 /* jump to the right spot */ 1358 s->pos_in_central_dir = file_pos->pos_in_zip_directory; 1359 s->num_file = file_pos->num_of_file; 1360 1361 /* set the current file */ 1362 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, 1363 &s->cur_file_info_internal, 1364 NULL,0,NULL,0,NULL,0); 1365 /* return results */ 1366 s->current_file_ok = (err == UNZ_OK); 1367 return err; 1368 } 1369 1370 extern int ZEXPORT unzGoToFilePos( 1371 unzFile file, 1372 unz_file_pos* file_pos) 1373 { 1374 unz64_file_pos file_pos64; 1375 if (file_pos == NULL) 1376 return UNZ_PARAMERROR; 1377 1378 file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; 1379 file_pos64.num_of_file = file_pos->num_of_file; 1380 return unzGoToFilePos64(file,&file_pos64); 1381 } 1382 1383 /* Unzip Helper Functions - should be here? */ 1384 /*///////////////////////////////////////// */ 1385 1386 /* 1387 Read the local header of the current zipfile 1388 Check the coherency of the local header and info in the end of central 1389 directory about this file 1390 store in *piSizeVar the size of extra info in local header 1391 (filename and size of extra field data) 1392 */ 1393 local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, 1394 ZPOS64_T * poffset_local_extrafield, 1395 uInt * psize_local_extrafield) 1396 { 1397 uLong uMagic,uData,uFlags; 1398 uLong size_filename; 1399 uLong size_extra_field; 1400 int err=UNZ_OK; 1401 1402 *piSizeVar = 0; 1403 *poffset_local_extrafield = 0; 1404 *psize_local_extrafield = 0; 1405 1406 if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + 1407 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) 1408 return UNZ_ERRNO; 1409 1410 1411 if (err==UNZ_OK) 1412 { 1413 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) 1414 err=UNZ_ERRNO; 1415 else if (uMagic!=0x04034b50) 1416 err=UNZ_BADZIPFILE; 1417 } 1418 1419 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) 1420 err=UNZ_ERRNO; 1421 /* 1422 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) 1423 err=UNZ_BADZIPFILE; 1424 */ 1425 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) 1426 err=UNZ_ERRNO; 1427 1428 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) 1429 err=UNZ_ERRNO; 1430 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) 1431 err=UNZ_BADZIPFILE; 1432 1433 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && 1434 /* #ifdef HAVE_BZIP2 */ 1435 (s->cur_file_info.compression_method!=Z_BZIP2ED) && 1436 /* #endif */ 1437 (s->cur_file_info.compression_method!=Z_DEFLATED)) 1438 err=UNZ_BADZIPFILE; 1439 1440 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ 1441 err=UNZ_ERRNO; 1442 1443 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ 1444 err=UNZ_ERRNO; 1445 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) 1446 err=UNZ_BADZIPFILE; 1447 1448 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ 1449 err=UNZ_ERRNO; 1450 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) 1451 err=UNZ_BADZIPFILE; 1452 1453 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ 1454 err=UNZ_ERRNO; 1455 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) 1456 err=UNZ_BADZIPFILE; 1457 1458 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) 1459 err=UNZ_ERRNO; 1460 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) 1461 err=UNZ_BADZIPFILE; 1462 1463 *piSizeVar += (uInt)size_filename; 1464 1465 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) 1466 err=UNZ_ERRNO; 1467 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + 1468 SIZEZIPLOCALHEADER + size_filename; 1469 *psize_local_extrafield = (uInt)size_extra_field; 1470 1471 *piSizeVar += (uInt)size_extra_field; 1472 1473 return err; 1474 } 1475 1476 /* 1477 Open for reading data the current file in the zipfile. 1478 If there is no error and the file is opened, the return value is UNZ_OK. 1479 */ 1480 extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, 1481 int* level, int raw, const char* password) 1482 { 1483 int err=UNZ_OK; 1484 uInt iSizeVar; 1485 unz64_s* s; 1486 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1487 ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ 1488 uInt size_local_extrafield; /* size of the local extra field */ 1489 # ifndef NOUNCRYPT 1490 char source[12]; 1491 # else 1492 if (password != NULL) 1493 return UNZ_PARAMERROR; 1494 # endif 1495 1496 if (file==NULL) 1497 return UNZ_PARAMERROR; 1498 s=(unz64_s*)file; 1499 if (!s->current_file_ok) 1500 return UNZ_PARAMERROR; 1501 1502 if (s->pfile_in_zip_read != NULL) 1503 unzCloseCurrentFile(file); 1504 1505 if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) 1506 return UNZ_BADZIPFILE; 1507 1508 pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); 1509 if (pfile_in_zip_read_info==NULL) 1510 return UNZ_INTERNALERROR; 1511 1512 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); 1513 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; 1514 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; 1515 pfile_in_zip_read_info->pos_local_extrafield=0; 1516 pfile_in_zip_read_info->raw=raw; 1517 1518 if (pfile_in_zip_read_info->read_buffer==NULL) 1519 { 1520 TRYFREE(pfile_in_zip_read_info); 1521 return UNZ_INTERNALERROR; 1522 } 1523 1524 pfile_in_zip_read_info->stream_initialised=0; 1525 1526 if (method!=NULL) 1527 *method = (int)s->cur_file_info.compression_method; 1528 1529 if (level!=NULL) 1530 { 1531 *level = 6; 1532 switch (s->cur_file_info.flag & 0x06) 1533 { 1534 case 6 : *level = 1; break; 1535 case 4 : *level = 2; break; 1536 case 2 : *level = 9; break; 1537 } 1538 } 1539 1540 if ((s->cur_file_info.compression_method!=0) && 1541 /* #ifdef HAVE_BZIP2 */ 1542 (s->cur_file_info.compression_method!=Z_BZIP2ED) && 1543 /* #endif */ 1544 (s->cur_file_info.compression_method!=Z_DEFLATED)) 1545 1546 err=UNZ_BADZIPFILE; 1547 1548 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; 1549 pfile_in_zip_read_info->crc32=0; 1550 pfile_in_zip_read_info->total_out_64=0; 1551 pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; 1552 pfile_in_zip_read_info->filestream=s->filestream; 1553 pfile_in_zip_read_info->z_filefunc=s->z_filefunc; 1554 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; 1555 1556 pfile_in_zip_read_info->stream.total_out = 0; 1557 1558 if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) 1559 { 1560 #ifdef HAVE_BZIP2 1561 pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; 1562 pfile_in_zip_read_info->bstream.bzfree = (free_func)0; 1563 pfile_in_zip_read_info->bstream.opaque = (voidpf)0; 1564 pfile_in_zip_read_info->bstream.state = (voidpf)0; 1565 1566 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; 1567 pfile_in_zip_read_info->stream.zfree = (free_func)0; 1568 pfile_in_zip_read_info->stream.opaque = (voidpf)0; 1569 pfile_in_zip_read_info->stream.next_in = (voidpf)0; 1570 pfile_in_zip_read_info->stream.avail_in = 0; 1571 1572 err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); 1573 if (err == Z_OK) 1574 pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; 1575 else 1576 { 1577 TRYFREE(pfile_in_zip_read_info); 1578 return err; 1579 } 1580 #else 1581 pfile_in_zip_read_info->raw=1; 1582 #endif 1583 } 1584 else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) 1585 { 1586 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; 1587 pfile_in_zip_read_info->stream.zfree = (free_func)0; 1588 pfile_in_zip_read_info->stream.opaque = (voidpf)0; 1589 pfile_in_zip_read_info->stream.next_in = 0; 1590 pfile_in_zip_read_info->stream.avail_in = 0; 1591 1592 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); 1593 if (err == Z_OK) 1594 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; 1595 else 1596 { 1597 TRYFREE(pfile_in_zip_read_info); 1598 return err; 1599 } 1600 /* windowBits is passed < 0 to tell that there is no zlib header. 1601 * Note that in this case inflate *requires* an extra "dummy" byte 1602 * after the compressed stream in order to complete decompression and 1603 * return Z_STREAM_END. 1604 * In unzip, i don't wait absolutely Z_STREAM_END because I known the 1605 * size of both compressed and uncompressed data 1606 */ 1607 } 1608 pfile_in_zip_read_info->rest_read_compressed = 1609 s->cur_file_info.compressed_size ; 1610 pfile_in_zip_read_info->rest_read_uncompressed = 1611 s->cur_file_info.uncompressed_size ; 1612 1613 1614 pfile_in_zip_read_info->pos_in_zipfile = 1615 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + 1616 iSizeVar; 1617 1618 pfile_in_zip_read_info->stream.avail_in = (uInt)0; 1619 1620 s->pfile_in_zip_read = pfile_in_zip_read_info; 1621 s->encrypted = 0; 1622 1623 # ifndef NOUNCRYPT 1624 if (password != NULL) 1625 { 1626 int i; 1627 s->pcrc_32_tab = get_crc_table(); 1628 init_keys(password,s->keys,s->pcrc_32_tab); 1629 if (ZSEEK64(s->z_filefunc, s->filestream, 1630 s->pfile_in_zip_read->pos_in_zipfile + 1631 s->pfile_in_zip_read->byte_before_the_zipfile, 1632 SEEK_SET)!=0) 1633 return UNZ_INTERNALERROR; 1634 if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) 1635 return UNZ_INTERNALERROR; 1636 1637 for (i = 0; i<12; i++) 1638 zdecode(s->keys,s->pcrc_32_tab,source[i]); 1639 1640 s->pfile_in_zip_read->pos_in_zipfile+=12; 1641 s->encrypted=1; 1642 } 1643 # endif 1644 1645 1646 return UNZ_OK; 1647 } 1648 1649 extern int ZEXPORT unzOpenCurrentFile (unzFile file) 1650 { 1651 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); 1652 } 1653 1654 extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) 1655 { 1656 return unzOpenCurrentFile3(file, NULL, NULL, 0, password); 1657 } 1658 1659 extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) 1660 { 1661 return unzOpenCurrentFile3(file, method, level, raw, NULL); 1662 } 1663 1664 /** Addition for GDAL : START */ 1665 1666 extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) 1667 { 1668 unz64_s* s; 1669 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1670 s=(unz64_s*)file; 1671 if (file==NULL) 1672 return 0; /*UNZ_PARAMERROR; */ 1673 pfile_in_zip_read_info=s->pfile_in_zip_read; 1674 if (pfile_in_zip_read_info==NULL) 1675 return 0; /*UNZ_PARAMERROR; */ 1676 return pfile_in_zip_read_info->pos_in_zipfile + 1677 pfile_in_zip_read_info->byte_before_the_zipfile; 1678 } 1679 1680 /** Addition for GDAL : END */ 1681 1682 /* 1683 Read bytes from the current file. 1684 buf contain buffer where data must be copied 1685 len the size of buf. 1686 1687 return the number of byte copied if somes bytes are copied 1688 return 0 if the end of file was reached 1689 return <0 with error code if there is an error 1690 (UNZ_ERRNO for IO error, or zLib error for uncompress error) 1691 */ 1692 extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) 1693 { 1694 int err=UNZ_OK; 1695 uInt iRead = 0; 1696 unz64_s* s; 1697 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1698 if (file==NULL) 1699 return UNZ_PARAMERROR; 1700 s=(unz64_s*)file; 1701 pfile_in_zip_read_info=s->pfile_in_zip_read; 1702 1703 if (pfile_in_zip_read_info==NULL) 1704 return UNZ_PARAMERROR; 1705 1706 1707 if (pfile_in_zip_read_info->read_buffer == NULL) 1708 return UNZ_END_OF_LIST_OF_FILE; 1709 if (len==0) 1710 return 0; 1711 1712 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; 1713 1714 pfile_in_zip_read_info->stream.avail_out = (uInt)len; 1715 1716 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && 1717 (!(pfile_in_zip_read_info->raw))) 1718 pfile_in_zip_read_info->stream.avail_out = 1719 (uInt)pfile_in_zip_read_info->rest_read_uncompressed; 1720 1721 if ((len>pfile_in_zip_read_info->rest_read_compressed+ 1722 pfile_in_zip_read_info->stream.avail_in) && 1723 (pfile_in_zip_read_info->raw)) 1724 pfile_in_zip_read_info->stream.avail_out = 1725 (uInt)pfile_in_zip_read_info->rest_read_compressed+ 1726 pfile_in_zip_read_info->stream.avail_in; 1727 1728 while (pfile_in_zip_read_info->stream.avail_out>0) 1729 { 1730 if ((pfile_in_zip_read_info->stream.avail_in==0) && 1731 (pfile_in_zip_read_info->rest_read_compressed>0)) 1732 { 1733 uInt uReadThis = UNZ_BUFSIZE; 1734 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis) 1735 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; 1736 if (uReadThis == 0) 1737 return UNZ_EOF; 1738 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, 1739 pfile_in_zip_read_info->filestream, 1740 pfile_in_zip_read_info->pos_in_zipfile + 1741 pfile_in_zip_read_info->byte_before_the_zipfile, 1742 ZLIB_FILEFUNC_SEEK_SET)!=0) 1743 return UNZ_ERRNO; 1744 if (ZREAD64(pfile_in_zip_read_info->z_filefunc, 1745 pfile_in_zip_read_info->filestream, 1746 pfile_in_zip_read_info->read_buffer, 1747 uReadThis)!=uReadThis) 1748 return UNZ_ERRNO; 1749 1750 1751 # ifndef NOUNCRYPT 1752 if(s->encrypted) 1753 { 1754 uInt i; 1755 for(i=0;i<uReadThis;i++) 1756 pfile_in_zip_read_info->read_buffer[i] = 1757 zdecode(s->keys,s->pcrc_32_tab, 1758 pfile_in_zip_read_info->read_buffer[i]); 1759 } 1760 # endif 1761 1762 1763 pfile_in_zip_read_info->pos_in_zipfile += uReadThis; 1764 1765 pfile_in_zip_read_info->rest_read_compressed-=uReadThis; 1766 1767 pfile_in_zip_read_info->stream.next_in = 1768 (Bytef*)pfile_in_zip_read_info->read_buffer; 1769 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; 1770 } 1771 1772 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) 1773 { 1774 uInt uDoCopy,i ; 1775 1776 if ((pfile_in_zip_read_info->stream.avail_in == 0) && 1777 (pfile_in_zip_read_info->rest_read_compressed == 0)) 1778 return (iRead==0) ? UNZ_EOF : iRead; 1779 1780 if (pfile_in_zip_read_info->stream.avail_out < 1781 pfile_in_zip_read_info->stream.avail_in) 1782 uDoCopy = pfile_in_zip_read_info->stream.avail_out ; 1783 else 1784 uDoCopy = pfile_in_zip_read_info->stream.avail_in ; 1785 1786 for (i=0;i<uDoCopy;i++) 1787 *(pfile_in_zip_read_info->stream.next_out+i) = 1788 *(pfile_in_zip_read_info->stream.next_in+i); 1789 1790 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; 1791 1792 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, 1793 pfile_in_zip_read_info->stream.next_out, 1794 uDoCopy); 1795 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; 1796 pfile_in_zip_read_info->stream.avail_in -= uDoCopy; 1797 pfile_in_zip_read_info->stream.avail_out -= uDoCopy; 1798 pfile_in_zip_read_info->stream.next_out += uDoCopy; 1799 pfile_in_zip_read_info->stream.next_in += uDoCopy; 1800 pfile_in_zip_read_info->stream.total_out += uDoCopy; 1801 iRead += uDoCopy; 1802 } 1803 else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) 1804 { 1805 #ifdef HAVE_BZIP2 1806 uLong uTotalOutBefore,uTotalOutAfter; 1807 const Bytef *bufBefore; 1808 uLong uOutThis; 1809 1810 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; 1811 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; 1812 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; 1813 pfile_in_zip_read_info->bstream.total_in_hi32 = 0; 1814 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; 1815 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; 1816 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; 1817 pfile_in_zip_read_info->bstream.total_out_hi32 = 0; 1818 1819 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; 1820 bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; 1821 1822 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); 1823 1824 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; 1825 uOutThis = uTotalOutAfter-uTotalOutBefore; 1826 1827 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; 1828 1829 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); 1830 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; 1831 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); 1832 1833 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; 1834 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; 1835 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; 1836 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; 1837 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; 1838 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; 1839 1840 if (err==BZ_STREAM_END) 1841 return (iRead==0) ? UNZ_EOF : iRead; 1842 if (err!=BZ_OK) 1843 break; 1844 #endif 1845 } /* end Z_BZIP2ED */ 1846 else 1847 { 1848 uInt uAvailOutBefore,uAvailOutAfter; 1849 const Bytef *bufBefore; 1850 uInt uOutThis; 1851 int flush=Z_SYNC_FLUSH; 1852 1853 uAvailOutBefore = pfile_in_zip_read_info->stream.avail_out; 1854 bufBefore = pfile_in_zip_read_info->stream.next_out; 1855 1856 err=inflate(&pfile_in_zip_read_info->stream,flush); 1857 1858 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) 1859 err = Z_DATA_ERROR; 1860 1861 uAvailOutAfter = pfile_in_zip_read_info->stream.avail_out; 1862 uOutThis = uAvailOutBefore - uAvailOutAfter; 1863 1864 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; 1865 1866 pfile_in_zip_read_info->crc32 1867 = crc32(pfile_in_zip_read_info->crc32,bufBefore, uOutThis); 1868 1869 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; 1870 1871 iRead += uAvailOutBefore - uAvailOutAfter; 1872 1873 if (err==Z_STREAM_END) 1874 return (iRead==0) ? UNZ_EOF : iRead; 1875 if (err!=Z_OK) 1876 break; 1877 } 1878 } 1879 1880 if (err==Z_OK) 1881 return iRead; 1882 return err; 1883 } 1884 1885 1886 /* 1887 Give the current position in uncompressed data 1888 */ 1889 extern z_off_t ZEXPORT unztell (unzFile file) 1890 { 1891 unz64_s* s; 1892 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1893 if (file==NULL) 1894 return UNZ_PARAMERROR; 1895 s=(unz64_s*)file; 1896 pfile_in_zip_read_info=s->pfile_in_zip_read; 1897 1898 if (pfile_in_zip_read_info==NULL) 1899 return UNZ_PARAMERROR; 1900 1901 return (z_off_t)pfile_in_zip_read_info->stream.total_out; 1902 } 1903 1904 extern ZPOS64_T ZEXPORT unztell64 (unzFile file) 1905 { 1906 1907 unz64_s* s; 1908 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1909 if (file==NULL) 1910 return (ZPOS64_T)-1; 1911 s=(unz64_s*)file; 1912 pfile_in_zip_read_info=s->pfile_in_zip_read; 1913 1914 if (pfile_in_zip_read_info==NULL) 1915 return (ZPOS64_T)-1; 1916 1917 return pfile_in_zip_read_info->total_out_64; 1918 } 1919 1920 1921 /* 1922 return 1 if the end of file was reached, 0 elsewhere 1923 */ 1924 extern int ZEXPORT unzeof (unzFile file) 1925 { 1926 unz64_s* s; 1927 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1928 if (file==NULL) 1929 return UNZ_PARAMERROR; 1930 s=(unz64_s*)file; 1931 pfile_in_zip_read_info=s->pfile_in_zip_read; 1932 1933 if (pfile_in_zip_read_info==NULL) 1934 return UNZ_PARAMERROR; 1935 1936 if (pfile_in_zip_read_info->rest_read_uncompressed == 0) 1937 return 1; 1938 else 1939 return 0; 1940 } 1941 1942 1943 1944 /* 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) 1948 1949 if buf==NULL, it return the size of the local extra field that can be read 1950 1951 if buf!=NULL, len is the size of the buffer, the extra header is copied in 1952 buf. 1953 the return value is the number of bytes copied in buf, or (if <0) 1954 the error code 1955 */ 1956 extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) 1957 { 1958 unz64_s* s; 1959 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1960 uInt read_now; 1961 ZPOS64_T size_to_read; 1962 1963 if (file==NULL) 1964 return UNZ_PARAMERROR; 1965 s=(unz64_s*)file; 1966 pfile_in_zip_read_info=s->pfile_in_zip_read; 1967 1968 if (pfile_in_zip_read_info==NULL) 1969 return UNZ_PARAMERROR; 1970 1971 size_to_read = (pfile_in_zip_read_info->size_local_extrafield - 1972 pfile_in_zip_read_info->pos_local_extrafield); 1973 1974 if (buf==NULL) 1975 return (int)size_to_read; 1976 1977 if (len>size_to_read) 1978 read_now = (uInt)size_to_read; 1979 else 1980 read_now = (uInt)len ; 1981 1982 if (read_now==0) 1983 return 0; 1984 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) 1990 return UNZ_ERRNO; 1991 1992 if (ZREAD64(pfile_in_zip_read_info->z_filefunc, 1993 pfile_in_zip_read_info->filestream, 1994 buf,read_now)!=read_now) 1995 return UNZ_ERRNO; 1996 1997 return (int)read_now; 1998 } 1999 2000 /* 2001 Close the file in zip opened with unzipOpenCurrentFile 2002 Return UNZ_CRCERROR if all the file was read but the CRC is not good 2003 */ 2004 extern int ZEXPORT unzCloseCurrentFile (unzFile file) 2005 { 2006 int err=UNZ_OK; 2007 2008 unz64_s* s; 2009 file_in_zip64_read_info_s* pfile_in_zip_read_info; 2010 if (file==NULL) 2011 return UNZ_PARAMERROR; 2012 s=(unz64_s*)file; 2013 pfile_in_zip_read_info=s->pfile_in_zip_read; 2014 2015 if (pfile_in_zip_read_info==NULL) 2016 return UNZ_PARAMERROR; 2017 2018 2019 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && 2020 (!pfile_in_zip_read_info->raw)) 2021 { 2022 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) 2023 err=UNZ_CRCERROR; 2024 } 2025 2026 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); 2031 #ifdef HAVE_BZIP2 2032 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) 2033 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); 2034 #endif 2035 2036 2037 pfile_in_zip_read_info->stream_initialised = 0; 2038 TRYFREE(pfile_in_zip_read_info); 2039 2040 s->pfile_in_zip_read=NULL; 2041 2042 return err; 2043 } 2044 2045 2046 /* 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 2050 */ 2051 extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) 2052 { 2053 unz64_s* s; 2054 uLong uReadThis ; 2055 if (file==NULL) 2056 return (int)UNZ_PARAMERROR; 2057 s=(unz64_s*)file; 2058 2059 uReadThis = uSizeBuf; 2060 if (uReadThis>s->gi.size_comment) 2061 uReadThis = s->gi.size_comment; 2062 2063 if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) 2064 return UNZ_ERRNO; 2065 2066 if (uReadThis>0) 2067 { 2068 *szComment='\0'; 2069 if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) 2070 return UNZ_ERRNO; 2071 } 2072 2073 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) 2074 *(szComment+s->gi.size_comment)='\0'; 2075 return (int)uReadThis; 2076 } 2077 2078 /* Additions by RX '2004 */ 2079 extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) 2080 { 2081 unz64_s* s; 2082 2083 if (file==NULL) 2084 return 0; /*UNZ_PARAMERROR; */ 2085 s=(unz64_s*)file; 2086 if (!s->current_file_ok) 2087 return 0; 2088 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) 2089 if (s->num_file==s->gi.number_entry) 2090 return 0; 2091 return s->pos_in_central_dir; 2092 } 2093 2094 extern uLong ZEXPORT unzGetOffset (unzFile file) 2095 { 2096 ZPOS64_T offset64; 2097 2098 if (file==NULL) 2099 return 0; /*UNZ_PARAMERROR; */ 2100 offset64 = unzGetOffset64(file); 2101 return (uLong)offset64; 2102 } 2103 2104 extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) 2105 { 2106 unz64_s* s; 2107 int err; 2108 2109 if (file==NULL) 2110 return UNZ_PARAMERROR; 2111 s=(unz64_s*)file; 2112 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); 2119 return err; 2120 } 2121 2122 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) 2123 { 2124 return unzSetOffset64(file,pos); 2125 } 2126 2127 2128 int ZEXPORT unzSetFlags(unzFile file, unsigned flags) 2129 { 2130 unz64_s* s; 2131 if (file == NULL) 2132 return UNZ_PARAMERROR; 2133 s = (unz64_s*)file; 2134 s->flags |= flags; 2135 return UNZ_OK; 2136 } 2137 2138 2139 int ZEXPORT unzClearFlags(unzFile file, unsigned flags) 2140 { 2141 unz64_s* s; 2142 if (file == NULL) 2143 return UNZ_PARAMERROR; 2144 s = (unz64_s*)file; 2145 s->flags &= ~flags; 2146 return UNZ_OK; 2147 }