OLD | NEW |
(Empty) | |
| 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
) |
| 4 |
| 5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.
com/zLibDll/minizip.html ) |
| 6 |
| 7 Modifications of Unzip for Zip64 |
| 8 Copyright (C) 2007-2008 Even Rouault |
| 9 |
| 10 Modifications for Zip64 support on both zip and unzip |
| 11 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) |
| 12 |
| 13 For more info read MiniZip_info.txt |
| 14 |
| 15 |
| 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. |
| 20 |
| 21 Copyright (c) 1990-2000 Info-ZIP. All rights reserved. |
| 22 |
| 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 |
| 27 |
| 28 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] |
| 29 |
| 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.) |
| 34 |
| 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). |
| 39 |
| 40 ------------------------------------------------------------------------
------------ |
| 41 |
| 42 Changes in unzip.c |
| 43 |
| 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 |
| 48 |
| 49 Copyright (C) 2007-2008 Even Rouault |
| 50 |
| 51 |
| 52 Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Roua
ult added them but since this is now moved to a new project (minizip64) I rename
d 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 siz
e 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 compre
ssion mathod BZIP2 (bzip2 lib is required) |
| 58 Patch created by Daniel Borca |
| 59 |
| 60 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer |
| 61 |
| 62 Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson |
| 63 |
| 64 */ |
| 65 |
| 66 |
| 67 #include <stdio.h> |
| 68 #include <stdlib.h> |
| 69 #include <string.h> |
| 70 |
| 71 #ifndef NOUNCRYPT |
| 72 #define NOUNCRYPT |
| 73 #endif |
| 74 |
| 75 #include "third_party/zlib/zlib.h" |
| 76 #include "unzip.h" |
| 77 |
| 78 #ifdef STDC |
| 79 # include <stddef.h> |
| 80 # include <string.h> |
| 81 # include <stdlib.h> |
| 82 #endif |
| 83 #ifdef NO_ERRNO_H |
| 84 extern int errno; |
| 85 #else |
| 86 # include <errno.h> |
| 87 #endif |
| 88 |
| 89 |
| 90 #ifndef local |
| 91 # define local static |
| 92 #endif |
| 93 /* compile with -Dlocal if your debugger can't find static symbols */ |
| 94 |
| 95 |
| 96 #ifndef CASESENSITIVITYDEFAULT_NO |
| 97 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) |
| 98 # define CASESENSITIVITYDEFAULT_NO |
| 99 # endif |
| 100 #endif |
| 101 |
| 102 |
| 103 #ifndef UNZ_BUFSIZE |
| 104 #define UNZ_BUFSIZE (16384) |
| 105 #endif |
| 106 |
| 107 #ifndef UNZ_MAXFILENAMEINZIP |
| 108 #define UNZ_MAXFILENAMEINZIP (256) |
| 109 #endif |
| 110 |
| 111 #ifndef ALLOC |
| 112 # define ALLOC(size) (malloc(size)) |
| 113 #endif |
| 114 #ifndef TRYFREE |
| 115 # define TRYFREE(p) {if (p) free(p);} |
| 116 #endif |
| 117 |
| 118 #define SIZECENTRALDIRITEM (0x2e) |
| 119 #define SIZEZIPLOCALHEADER (0x1e) |
| 120 |
| 121 |
| 122 const char unz_copyright[] = |
| 123 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLi
bDll"; |
| 124 |
| 125 /* unz_file_info_interntal contain internal info about a file in zipfile*/ |
| 126 typedef struct unz_file_info64_internal_s |
| 127 { |
| 128 ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ |
| 129 } unz_file_info64_internal; |
| 130 |
| 131 |
| 132 /* file_in_zip_read_info_s contain internal information about a file in zipfile, |
| 133 when reading and decompress it */ |
| 134 typedef struct |
| 135 { |
| 136 char *read_buffer; /* internal buffer for compressed data */ |
| 137 z_stream stream; /* zLib stream structure for inflate */ |
| 138 |
| 139 #ifdef HAVE_BZIP2 |
| 140 bz_stream bstream; /* bzLib stream structure for bziped */ |
| 141 #endif |
| 142 |
| 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*/ |
| 145 |
| 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 rea
d*/ |
| 149 ZPOS64_T total_out_64; |
| 150 |
| 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)*/ |
| 159 int raw; |
| 160 } file_in_zip64_read_info_s; |
| 161 |
| 162 |
| 163 /* unz64_s contain internal information about the zipfile |
| 164 */ |
| 165 typedef struct |
| 166 { |
| 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 fi
le*/ |
| 175 ZPOS64_T central_pos; /* position of the beginning of the central d
ir*/ |
| 176 |
| 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 */ |
| 180 |
| 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 */ |
| 185 int encrypted; |
| 186 |
| 187 int isZip64; |
| 188 |
| 189 # ifndef NOUNCRYPT |
| 190 unsigned long keys[3]; /* keys defining the pseudo-random sequence */ |
| 191 const unsigned long* pcrc_32_tab; |
| 192 # endif |
| 193 } unz64_s; |
| 194 |
| 195 |
| 196 #ifndef NOUNCRYPT |
| 197 #include "crypt.h" |
| 198 #endif |
| 199 |
| 200 /* =========================================================================== |
| 201 Read a byte from a gz_stream; update next_in and avail_in. Return EOF |
| 202 for end of file. |
| 203 IN assertion: the stream s has been sucessfully opened for reading. |
| 204 */ |
| 205 |
| 206 |
| 207 local int unz64local_getByte OF(( |
| 208 const zlib_filefunc64_32_def* pzlib_filefunc_def, |
| 209 voidpf filestream, |
| 210 int *pi)); |
| 211 |
| 212 local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, v
oidpf filestream, int *pi) |
| 213 { |
| 214 unsigned char c; |
| 215 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); |
| 216 if (err==1) |
| 217 { |
| 218 *pi = (int)c; |
| 219 return UNZ_OK; |
| 220 } |
| 221 else |
| 222 { |
| 223 if (ZERROR64(*pzlib_filefunc_def,filestream)) |
| 224 return UNZ_ERRNO; |
| 225 else |
| 226 return UNZ_EOF; |
| 227 } |
| 228 } |
| 229 |
| 230 |
| 231 /* =========================================================================== |
| 232 Reads a long in LSB order from the given gz_stream. Sets |
| 233 */ |
| 234 local int unz64local_getShort OF(( |
| 235 const zlib_filefunc64_32_def* pzlib_filefunc_def, |
| 236 voidpf filestream, |
| 237 uLong *pX)); |
| 238 |
| 239 local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, |
| 240 voidpf filestream, |
| 241 uLong *pX) |
| 242 { |
| 243 uLong x ; |
| 244 int i = 0; |
| 245 int err; |
| 246 |
| 247 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 248 x = (uLong)i; |
| 249 |
| 250 if (err==UNZ_OK) |
| 251 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 252 x |= ((uLong)i)<<8; |
| 253 |
| 254 if (err==UNZ_OK) |
| 255 *pX = x; |
| 256 else |
| 257 *pX = 0; |
| 258 return err; |
| 259 } |
| 260 |
| 261 local int unz64local_getLong OF(( |
| 262 const zlib_filefunc64_32_def* pzlib_filefunc_def, |
| 263 voidpf filestream, |
| 264 uLong *pX)); |
| 265 |
| 266 local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, |
| 267 voidpf filestream, |
| 268 uLong *pX) |
| 269 { |
| 270 uLong x ; |
| 271 int i = 0; |
| 272 int err; |
| 273 |
| 274 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 275 x = (uLong)i; |
| 276 |
| 277 if (err==UNZ_OK) |
| 278 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 279 x |= ((uLong)i)<<8; |
| 280 |
| 281 if (err==UNZ_OK) |
| 282 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 283 x |= ((uLong)i)<<16; |
| 284 |
| 285 if (err==UNZ_OK) |
| 286 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 287 x += ((uLong)i)<<24; |
| 288 |
| 289 if (err==UNZ_OK) |
| 290 *pX = x; |
| 291 else |
| 292 *pX = 0; |
| 293 return err; |
| 294 } |
| 295 |
| 296 local int unz64local_getLong64 OF(( |
| 297 const zlib_filefunc64_32_def* pzlib_filefunc_def, |
| 298 voidpf filestream, |
| 299 ZPOS64_T *pX)); |
| 300 |
| 301 |
| 302 local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def
, |
| 303 voidpf filestream, |
| 304 ZPOS64_T *pX) |
| 305 { |
| 306 ZPOS64_T x ; |
| 307 int i = 0; |
| 308 int err; |
| 309 |
| 310 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 311 x = (ZPOS64_T)i; |
| 312 |
| 313 if (err==UNZ_OK) |
| 314 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 315 x |= ((ZPOS64_T)i)<<8; |
| 316 |
| 317 if (err==UNZ_OK) |
| 318 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 319 x |= ((ZPOS64_T)i)<<16; |
| 320 |
| 321 if (err==UNZ_OK) |
| 322 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 323 x |= ((ZPOS64_T)i)<<24; |
| 324 |
| 325 if (err==UNZ_OK) |
| 326 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 327 x |= ((ZPOS64_T)i)<<32; |
| 328 |
| 329 if (err==UNZ_OK) |
| 330 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 331 x |= ((ZPOS64_T)i)<<40; |
| 332 |
| 333 if (err==UNZ_OK) |
| 334 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 335 x |= ((ZPOS64_T)i)<<48; |
| 336 |
| 337 if (err==UNZ_OK) |
| 338 err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); |
| 339 x |= ((ZPOS64_T)i)<<56; |
| 340 |
| 341 if (err==UNZ_OK) |
| 342 *pX = x; |
| 343 else |
| 344 *pX = 0; |
| 345 return err; |
| 346 } |
| 347 |
| 348 /* My own strcmpi / strcasecmp */ |
| 349 local int strcmpcasenosensitive_internal (const char* fileName1, const char* fil
eName2) |
| 350 { |
| 351 for (;;) |
| 352 { |
| 353 char c1=*(fileName1++); |
| 354 char c2=*(fileName2++); |
| 355 if ((c1>='a') && (c1<='z')) |
| 356 c1 -= 0x20; |
| 357 if ((c2>='a') && (c2<='z')) |
| 358 c2 -= 0x20; |
| 359 if (c1=='\0') |
| 360 return ((c2=='\0') ? 0 : -1); |
| 361 if (c2=='\0') |
| 362 return 1; |
| 363 if (c1<c2) |
| 364 return -1; |
| 365 if (c1>c2) |
| 366 return 1; |
| 367 } |
| 368 } |
| 369 |
| 370 |
| 371 #ifdef CASESENSITIVITYDEFAULT_NO |
| 372 #define CASESENSITIVITYDEFAULTVALUE 2 |
| 373 #else |
| 374 #define CASESENSITIVITYDEFAULTVALUE 1 |
| 375 #endif |
| 376 |
| 377 #ifndef STRCMPCASENOSENTIVEFUNCTION |
| 378 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal |
| 379 #endif |
| 380 |
| 381 /* |
| 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 |
| 385 or strcasecmp) |
| 386 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system |
| 387 (like 1 on Unix, 2 on Windows) |
| 388 |
| 389 */ |
| 390 extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, |
| 391 const char* fileName2, |
| 392 int iCaseSensitivity) |
| 393 |
| 394 { |
| 395 if (iCaseSensitivity==0) |
| 396 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; |
| 397 |
| 398 if (iCaseSensitivity==1) |
| 399 return strcmp(fileName1,fileName2); |
| 400 |
| 401 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); |
| 402 } |
| 403 |
| 404 #ifndef BUFREADCOMMENT |
| 405 #define BUFREADCOMMENT (0x400) |
| 406 #endif |
| 407 |
| 408 /* |
| 409 Locate the Central directory of a zipfile (at the end, just before |
| 410 the global comment) |
| 411 */ |
| 412 local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzl
ib_filefunc_def, voidpf filestream)); |
| 413 local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f
ilefunc_def, voidpf filestream) |
| 414 { |
| 415 unsigned char* buf; |
| 416 ZPOS64_T uSizeFile; |
| 417 ZPOS64_T uBackRead; |
| 418 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ |
| 419 ZPOS64_T uPosFound=0; |
| 420 |
| 421 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) |
| 422 return 0; |
| 423 |
| 424 |
| 425 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); |
| 426 |
| 427 if (uMaxBack>uSizeFile) |
| 428 uMaxBack = uSizeFile; |
| 429 |
| 430 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); |
| 431 if (buf==NULL) |
| 432 return 0; |
| 433 |
| 434 uBackRead = 4; |
| 435 while (uBackRead<uMaxBack) |
| 436 { |
| 437 uLong uReadSize; |
| 438 ZPOS64_T uReadPos ; |
| 439 int i; |
| 440 if (uBackRead+BUFREADCOMMENT>uMaxBack) |
| 441 uBackRead = uMaxBack; |
| 442 else |
| 443 uBackRead+=BUFREADCOMMENT; |
| 444 uReadPos = uSizeFile-uBackRead ; |
| 445 |
| 446 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? |
| 447 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); |
| 448 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_S
ET)!=0) |
| 449 break; |
| 450 |
| 451 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) |
| 452 break; |
| 453 |
| 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)) |
| 457 { |
| 458 uPosFound = uReadPos+i; |
| 459 break; |
| 460 } |
| 461 |
| 462 if (uPosFound!=0) |
| 463 break; |
| 464 } |
| 465 TRYFREE(buf); |
| 466 return uPosFound; |
| 467 } |
| 468 |
| 469 |
| 470 /* |
| 471 Locate the Central directory 64 of a zipfile (at the end, just before |
| 472 the global comment) |
| 473 */ |
| 474 local ZPOS64_T unz64local_SearchCentralDir64 OF(( |
| 475 const zlib_filefunc64_32_def* pzlib_filefunc_def, |
| 476 voidpf filestream)); |
| 477 |
| 478 local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
_filefunc_def, |
| 479 voidpf filestream) |
| 480 { |
| 481 unsigned char* buf; |
| 482 ZPOS64_T uSizeFile; |
| 483 ZPOS64_T uBackRead; |
| 484 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ |
| 485 ZPOS64_T uPosFound=0; |
| 486 uLong uL; |
| 487 ZPOS64_T relativeOffset; |
| 488 |
| 489 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) |
| 490 return 0; |
| 491 |
| 492 |
| 493 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); |
| 494 |
| 495 if (uMaxBack>uSizeFile) |
| 496 uMaxBack = uSizeFile; |
| 497 |
| 498 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); |
| 499 if (buf==NULL) |
| 500 return 0; |
| 501 |
| 502 uBackRead = 4; |
| 503 while (uBackRead<uMaxBack) |
| 504 { |
| 505 uLong uReadSize; |
| 506 ZPOS64_T uReadPos; |
| 507 int i; |
| 508 if (uBackRead+BUFREADCOMMENT>uMaxBack) |
| 509 uBackRead = uMaxBack; |
| 510 else |
| 511 uBackRead+=BUFREADCOMMENT; |
| 512 uReadPos = uSizeFile-uBackRead ; |
| 513 |
| 514 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? |
| 515 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); |
| 516 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_S
ET)!=0) |
| 517 break; |
| 518 |
| 519 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) |
| 520 break; |
| 521 |
| 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)) |
| 525 { |
| 526 uPosFound = uReadPos+i; |
| 527 break; |
| 528 } |
| 529 |
| 530 if (uPosFound!=0) |
| 531 break; |
| 532 } |
| 533 TRYFREE(buf); |
| 534 if (uPosFound == 0) |
| 535 return 0; |
| 536 |
| 537 /* Zip64 end of central directory locator */ |
| 538 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET
)!=0) |
| 539 return 0; |
| 540 |
| 541 /* the signature, already checked */ |
| 542 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) |
| 543 return 0; |
| 544 |
| 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) |
| 547 return 0; |
| 548 if (uL != 0) |
| 549 return 0; |
| 550 |
| 551 /* relative offset of the zip64 end of central directory record */ |
| 552 if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ
_OK) |
| 553 return 0; |
| 554 |
| 555 /* total number of disks */ |
| 556 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) |
| 557 return 0; |
| 558 if (uL != 1) |
| 559 return 0; |
| 560 |
| 561 /* Goto end of central directory record */ |
| 562 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEE
K_SET)!=0) |
| 563 return 0; |
| 564 |
| 565 /* the signature */ |
| 566 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) |
| 567 return 0; |
| 568 |
| 569 if (uL != 0x06064b50) |
| 570 return 0; |
| 571 |
| 572 return relativeOffset; |
| 573 } |
| 574 |
| 575 /* |
| 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 |
| 578 "zlib/zlib114.zip". |
| 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. |
| 583 */ |
| 584 local unzFile unzOpenInternal (const void *path, |
| 585 zlib_filefunc64_32_def* pzlib_filefunc64_32_def, |
| 586 int is64bitOpenFunction) |
| 587 { |
| 588 unz64_s us; |
| 589 unz64_s *s; |
| 590 ZPOS64_T central_pos; |
| 591 uLong uL; |
| 592 |
| 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 |
| 598 the central dir |
| 599 (same than number_entry on nospan) */ |
| 600 |
| 601 int err=UNZ_OK; |
| 602 |
| 603 if (unz_copyright[0]!=' ') |
| 604 return NULL; |
| 605 |
| 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); |
| 610 else |
| 611 us.z_filefunc = *pzlib_filefunc64_32_def; |
| 612 us.is64bitOpenFunction = is64bitOpenFunction; |
| 613 |
| 614 |
| 615 |
| 616 us.filestream = ZOPEN64(us.z_filefunc, |
| 617 path, |
| 618 ZLIB_FILEFUNC_MODE_READ | |
| 619 ZLIB_FILEFUNC_MODE_EXISTING); |
| 620 if (us.filestream==NULL) |
| 621 return NULL; |
| 622 |
| 623 central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); |
| 624 if (central_pos) |
| 625 { |
| 626 uLong uS; |
| 627 ZPOS64_T uL64; |
| 628 |
| 629 us.isZip64 = 1; |
| 630 |
| 631 if (ZSEEK64(us.z_filefunc, us.filestream, |
| 632 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) |
| 633 err=UNZ_ERRNO; |
| 634 |
| 635 /* the signature, already checked */ |
| 636 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) |
| 637 err=UNZ_ERRNO; |
| 638 |
| 639 /* size of zip64 end of central directory record */ |
| 640 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) |
| 641 err=UNZ_ERRNO; |
| 642 |
| 643 /* version made by */ |
| 644 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) |
| 645 err=UNZ_ERRNO; |
| 646 |
| 647 /* version needed to extract */ |
| 648 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) |
| 649 err=UNZ_ERRNO; |
| 650 |
| 651 /* number of this disk */ |
| 652 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_
OK) |
| 653 err=UNZ_ERRNO; |
| 654 |
| 655 /* number of the disk with the start of the central directory */ |
| 656 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_C
D)!=UNZ_OK) |
| 657 err=UNZ_ERRNO; |
| 658 |
| 659 /* total number of entries in the central directory on this disk */ |
| 660 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_ent
ry)!=UNZ_OK) |
| 661 err=UNZ_ERRNO; |
| 662 |
| 663 /* total number of entries in the central directory */ |
| 664 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)
!=UNZ_OK) |
| 665 err=UNZ_ERRNO; |
| 666 |
| 667 if ((number_entry_CD!=us.gi.number_entry) || |
| 668 (number_disk_with_CD!=0) || |
| 669 (number_disk!=0)) |
| 670 err=UNZ_BADZIPFILE; |
| 671 |
| 672 /* size of the central directory */ |
| 673 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_
dir)!=UNZ_OK) |
| 674 err=UNZ_ERRNO; |
| 675 |
| 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_centra
l_dir)!=UNZ_OK) |
| 679 err=UNZ_ERRNO; |
| 680 |
| 681 us.gi.size_comment = 0; |
| 682 } |
| 683 else |
| 684 { |
| 685 central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); |
| 686 if (central_pos==0) |
| 687 err=UNZ_ERRNO; |
| 688 |
| 689 us.isZip64 = 0; |
| 690 |
| 691 if (ZSEEK64(us.z_filefunc, us.filestream, |
| 692 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) |
| 693 err=UNZ_ERRNO; |
| 694 |
| 695 /* the signature, already checked */ |
| 696 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) |
| 697 err=UNZ_ERRNO; |
| 698 |
| 699 /* number of this disk */ |
| 700 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ
_OK) |
| 701 err=UNZ_ERRNO; |
| 702 |
| 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) |
| 705 err=UNZ_ERRNO; |
| 706 |
| 707 /* total number of entries in the central dir on this disk */ |
| 708 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) |
| 709 err=UNZ_ERRNO; |
| 710 us.gi.number_entry = uL; |
| 711 |
| 712 /* total number of entries in the central dir */ |
| 713 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) |
| 714 err=UNZ_ERRNO; |
| 715 number_entry_CD = uL; |
| 716 |
| 717 if ((number_entry_CD!=us.gi.number_entry) || |
| 718 (number_disk_with_CD!=0) || |
| 719 (number_disk!=0)) |
| 720 err=UNZ_BADZIPFILE; |
| 721 |
| 722 /* size of the central directory */ |
| 723 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) |
| 724 err=UNZ_ERRNO; |
| 725 us.size_central_dir = uL; |
| 726 |
| 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) |
| 730 err=UNZ_ERRNO; |
| 731 us.offset_central_dir = uL; |
| 732 |
| 733 /* zipfile comment length */ |
| 734 if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_commen
t)!=UNZ_OK) |
| 735 err=UNZ_ERRNO; |
| 736 } |
| 737 |
| 738 if ((central_pos<us.offset_central_dir+us.size_central_dir) && |
| 739 (err==UNZ_OK)) |
| 740 err=UNZ_BADZIPFILE; |
| 741 |
| 742 if (err!=UNZ_OK) |
| 743 { |
| 744 ZCLOSE64(us.z_filefunc, us.filestream); |
| 745 return NULL; |
| 746 } |
| 747 |
| 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; |
| 752 us.encrypted = 0; |
| 753 |
| 754 |
| 755 s=(unz64_s*)ALLOC(sizeof(unz64_s)); |
| 756 if( s != NULL) |
| 757 { |
| 758 *s=us; |
| 759 unzGoToFirstFile((unzFile)s); |
| 760 } |
| 761 return (unzFile)s; |
| 762 } |
| 763 |
| 764 |
| 765 extern unzFile ZEXPORT unzOpen2 (const char *path, |
| 766 zlib_filefunc_def* pzlib_filefunc32_def) |
| 767 { |
| 768 if (pzlib_filefunc32_def != NULL) |
| 769 { |
| 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); |
| 773 } |
| 774 else |
| 775 return unzOpenInternal(path, NULL, 0); |
| 776 } |
| 777 |
| 778 extern unzFile ZEXPORT unzOpen2_64 (const void *path, |
| 779 zlib_filefunc64_def* pzlib_filefunc_def) |
| 780 { |
| 781 if (pzlib_filefunc_def != NULL) |
| 782 { |
| 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); |
| 788 } |
| 789 else |
| 790 return unzOpenInternal(path, NULL, 1); |
| 791 } |
| 792 |
| 793 extern unzFile ZEXPORT unzOpen (const char *path) |
| 794 { |
| 795 return unzOpenInternal(path, NULL, 0); |
| 796 } |
| 797 |
| 798 extern unzFile ZEXPORT unzOpen64 (const void *path) |
| 799 { |
| 800 return unzOpenInternal(path, NULL, 1); |
| 801 } |
| 802 |
| 803 /* |
| 804 Close a ZipFile opened with unzipOpen. |
| 805 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later)
, |
| 806 these files MUST be closed with unzipCloseCurrentFile before call unzipClose
. |
| 807 return UNZ_OK if there is no problem. */ |
| 808 extern int ZEXPORT unzClose (unzFile file) |
| 809 { |
| 810 unz64_s* s; |
| 811 if (file==NULL) |
| 812 return UNZ_PARAMERROR; |
| 813 s=(unz64_s*)file; |
| 814 |
| 815 if (s->pfile_in_zip_read!=NULL) |
| 816 unzCloseCurrentFile(file); |
| 817 |
| 818 ZCLOSE64(s->z_filefunc, s->filestream); |
| 819 TRYFREE(s); |
| 820 return UNZ_OK; |
| 821 } |
| 822 |
| 823 |
| 824 /* |
| 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) |
| 829 { |
| 830 unz64_s* s; |
| 831 if (file==NULL) |
| 832 return UNZ_PARAMERROR; |
| 833 s=(unz64_s*)file; |
| 834 *pglobal_info=s->gi; |
| 835 return UNZ_OK; |
| 836 } |
| 837 |
| 838 extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info
32) |
| 839 { |
| 840 unz64_s* s; |
| 841 if (file==NULL) |
| 842 return UNZ_PARAMERROR; |
| 843 s=(unz64_s*)file; |
| 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; |
| 847 return UNZ_OK; |
| 848 } |
| 849 /* |
| 850 Translate date/time from Dos format to tm_unz (readable more easilty) |
| 851 */ |
| 852 local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) |
| 853 { |
| 854 ZPOS64_T uDate; |
| 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) ; |
| 859 |
| 860 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); |
| 861 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; |
| 862 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; |
| 863 } |
| 864 |
| 865 /* |
| 866 Get Info about the current file in the zipfile, with internal only info |
| 867 */ |
| 868 local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, |
| 869 unz_file_info64 *pfile_info, |
| 870 unz_file_info64_internal |
| 871 *pfile_info_internal, |
| 872 char *szFileName, |
| 873 uLong fileNameBufferSize, |
| 874 void *extraField, |
| 875 uLong extraFieldBufferSize, |
| 876 char *szComment, |
| 877 uLong commentBufferSize)); |
| 878 |
| 879 local int unz64local_GetCurrentFileInfoInternal (unzFile file, |
| 880 unz_file_info64 *pfile_info, |
| 881 unz_file_info64_internal |
| 882 *pfile_info_internal, |
| 883 char *szFileName, |
| 884 uLong fileNameBufferSize, |
| 885 void *extraField, |
| 886 uLong extraFieldBufferSize, |
| 887 char *szComment, |
| 888 uLong commentBufferSize) |
| 889 { |
| 890 unz64_s* s; |
| 891 unz_file_info64 file_info; |
| 892 unz_file_info64_internal file_info_internal; |
| 893 int err=UNZ_OK; |
| 894 uLong uMagic; |
| 895 long lSeek=0; |
| 896 uLong uL; |
| 897 |
| 898 if (file==NULL) |
| 899 return UNZ_PARAMERROR; |
| 900 s=(unz64_s*)file; |
| 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) |
| 904 err=UNZ_ERRNO; |
| 905 |
| 906 |
| 907 /* we check the magic */ |
| 908 if (err==UNZ_OK) |
| 909 { |
| 910 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) |
| 911 err=UNZ_ERRNO; |
| 912 else if (uMagic!=0x02014b50) |
| 913 err=UNZ_BADZIPFILE; |
| 914 } |
| 915 |
| 916 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) !=
UNZ_OK) |
| 917 err=UNZ_ERRNO; |
| 918 |
| 919 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_nee
ded) != UNZ_OK) |
| 920 err=UNZ_ERRNO; |
| 921 |
| 922 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UN
Z_OK) |
| 923 err=UNZ_ERRNO; |
| 924 |
| 925 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression
_method) != UNZ_OK) |
| 926 err=UNZ_ERRNO; |
| 927 |
| 928 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) !=
UNZ_OK) |
| 929 err=UNZ_ERRNO; |
| 930 |
| 931 unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); |
| 932 |
| 933 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_
OK) |
| 934 err=UNZ_ERRNO; |
| 935 |
| 936 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) |
| 937 err=UNZ_ERRNO; |
| 938 file_info.compressed_size = uL; |
| 939 |
| 940 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) |
| 941 err=UNZ_ERRNO; |
| 942 file_info.uncompressed_size = uL; |
| 943 |
| 944 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filena
me) != UNZ_OK) |
| 945 err=UNZ_ERRNO; |
| 946 |
| 947 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_e
xtra) != UNZ_OK) |
| 948 err=UNZ_ERRNO; |
| 949 |
| 950 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_c
omment) != UNZ_OK) |
| 951 err=UNZ_ERRNO; |
| 952 |
| 953 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_st
art) != UNZ_OK) |
| 954 err=UNZ_ERRNO; |
| 955 |
| 956 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa
) != UNZ_OK) |
| 957 err=UNZ_ERRNO; |
| 958 |
| 959 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa)
!= UNZ_OK) |
| 960 err=UNZ_ERRNO; |
| 961 |
| 962 // relative offset of local header |
| 963 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) |
| 964 err=UNZ_ERRNO; |
| 965 file_info_internal.offset_curfile = uL; |
| 966 |
| 967 lSeek+=file_info.size_filename; |
| 968 if ((err==UNZ_OK) && (szFileName!=NULL)) |
| 969 { |
| 970 uLong uSizeRead ; |
| 971 if (file_info.size_filename<fileNameBufferSize) |
| 972 { |
| 973 *(szFileName+file_info.size_filename)='\0'; |
| 974 uSizeRead = file_info.size_filename; |
| 975 } |
| 976 else |
| 977 uSizeRead = fileNameBufferSize; |
| 978 |
| 979 if ((file_info.size_filename>0) && (fileNameBufferSize>0)) |
| 980 if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSiz
eRead) |
| 981 err=UNZ_ERRNO; |
| 982 lSeek -= uSizeRead; |
| 983 } |
| 984 |
| 985 // Read extrafield |
| 986 if ((err==UNZ_OK) && (extraField!=NULL)) |
| 987 { |
| 988 ZPOS64_T uSizeRead ; |
| 989 if (file_info.size_file_extra<extraFieldBufferSize) |
| 990 uSizeRead = file_info.size_file_extra; |
| 991 else |
| 992 uSizeRead = extraFieldBufferSize; |
| 993 |
| 994 if (lSeek!=0) |
| 995 { |
| 996 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CU
R)==0) |
| 997 lSeek=0; |
| 998 else |
| 999 err=UNZ_ERRNO; |
| 1000 } |
| 1001 |
| 1002 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) |
| 1003 if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead
)!=uSizeRead) |
| 1004 err=UNZ_ERRNO; |
| 1005 |
| 1006 lSeek += file_info.size_file_extra - (uLong)uSizeRead; |
| 1007 } |
| 1008 else |
| 1009 lSeek += file_info.size_file_extra; |
| 1010 |
| 1011 |
| 1012 if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) |
| 1013 { |
| 1014 uLong acc = 0; |
| 1015 |
| 1016 // since lSeek now points to after the extra field we need to move back |
| 1017 lSeek -= file_info.size_file_extra; |
| 1018 |
| 1019 if (lSeek!=0) |
| 1020 { |
| 1021 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CU
R)==0) |
| 1022 lSeek=0; |
| 1023 else |
| 1024 err=UNZ_ERRNO; |
| 1025 } |
| 1026 |
| 1027 while(acc < file_info.size_file_extra) |
| 1028 { |
| 1029 uLong headerId; |
| 1030 uLong dataSize; |
| 1031 |
| 1032 if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) !=
UNZ_OK) |
| 1033 err=UNZ_ERRNO; |
| 1034 |
| 1035 if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) !=
UNZ_OK) |
| 1036 err=UNZ_ERRNO; |
| 1037 |
| 1038 /* ZIP64 extra fields */ |
| 1039 if (headerId == 0x0001) |
| 1040 { |
| 1041 uLong uL; |
| 1042 |
| 1043 if(file_info.unc
ompressed_size == (ZPOS64_T)(unsigned long)-1) |
| 1044 { |
| 1045 if (unz6
4local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) !=
UNZ_OK) |
| 1046
err=UNZ_ERRNO; |
| 1047 } |
| 1048 |
| 1049 if(file_info.com
pressed_size == (ZPOS64_T)(unsigned long)-1) |
| 1050 { |
| 1051 if (unz6
4local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UN
Z_OK) |
| 1052
err=UNZ_ERRNO; |
| 1053 } |
| 1054 |
| 1055 if(file_info_int
ernal.offset_curfile == (ZPOS64_T)(unsigned long)-1) |
| 1056 { |
| 1057 /* Relat
ive Header offset */ |
| 1058 if (unz6
4local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfil
e) != UNZ_OK) |
| 1059
err=UNZ_ERRNO; |
| 1060 } |
| 1061 |
| 1062 if(file_info.dis
k_num_start == (unsigned long)-1) |
| 1063 { |
| 1064 /* Disk
Start Number */ |
| 1065 if (unz6
4local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) |
| 1066
err=UNZ_ERRNO; |
| 1067 } |
| 1068 |
| 1069 } |
| 1070 else |
| 1071 { |
| 1072 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_
SEEK_CUR)!=0) |
| 1073 err=UNZ_ERRNO; |
| 1074 } |
| 1075 |
| 1076 acc += 2 + 2 + dataSize; |
| 1077 } |
| 1078 } |
| 1079 |
| 1080 if ((err==UNZ_OK) && (szComment!=NULL)) |
| 1081 { |
| 1082 uLong uSizeRead ; |
| 1083 if (file_info.size_file_comment<commentBufferSize) |
| 1084 { |
| 1085 *(szComment+file_info.size_file_comment)='\0'; |
| 1086 uSizeRead = file_info.size_file_comment; |
| 1087 } |
| 1088 else |
| 1089 uSizeRead = commentBufferSize; |
| 1090 |
| 1091 if (lSeek!=0) |
| 1092 { |
| 1093 if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CU
R)==0) |
| 1094 lSeek=0; |
| 1095 else |
| 1096 err=UNZ_ERRNO; |
| 1097 } |
| 1098 |
| 1099 if ((file_info.size_file_comment>0) && (commentBufferSize>0)) |
| 1100 if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSize
Read) |
| 1101 err=UNZ_ERRNO; |
| 1102 lSeek+=file_info.size_file_comment - uSizeRead; |
| 1103 } |
| 1104 else |
| 1105 lSeek+=file_info.size_file_comment; |
| 1106 |
| 1107 |
| 1108 if ((err==UNZ_OK) && (pfile_info!=NULL)) |
| 1109 *pfile_info=file_info; |
| 1110 |
| 1111 if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) |
| 1112 *pfile_info_internal=file_info_internal; |
| 1113 |
| 1114 return err; |
| 1115 } |
| 1116 |
| 1117 |
| 1118 |
| 1119 /* |
| 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. |
| 1123 */ |
| 1124 extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, |
| 1125 unz_file_info64 * pfile_info, |
| 1126 char * szFileName, uLong fileNameBuffe
rSize, |
| 1127 void *extraField, uLong extraFieldBuff
erSize, |
| 1128 char* szComment, uLong commentBufferS
ize) |
| 1129 { |
| 1130 return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, |
| 1131 szFileName,fileNameBufferSize, |
| 1132 extraField,extraFieldBufferSize, |
| 1133 szComment,commentBufferSize); |
| 1134 } |
| 1135 |
| 1136 extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, |
| 1137 unz_file_info * pfile_info, |
| 1138 char * szFileName, uLong fileNameBuffe
rSize, |
| 1139 void *extraField, uLong extraFieldBuff
erSize, |
| 1140 char* szComment, uLong commentBufferS
ize) |
| 1141 { |
| 1142 int err; |
| 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) |
| 1149 { |
| 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; |
| 1156 |
| 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; |
| 1160 |
| 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; |
| 1164 |
| 1165 pfile_info->tmu_date = file_info64.tmu_date, |
| 1166 |
| 1167 |
| 1168 pfile_info->compressed_size = (uLong)file_info64.compressed_size; |
| 1169 pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; |
| 1170 |
| 1171 } |
| 1172 return err; |
| 1173 } |
| 1174 /* |
| 1175 Set the current file of the zipfile to the first file. |
| 1176 return UNZ_OK if there is no problem |
| 1177 */ |
| 1178 extern int ZEXPORT unzGoToFirstFile (unzFile file) |
| 1179 { |
| 1180 int err=UNZ_OK; |
| 1181 unz64_s* s; |
| 1182 if (file==NULL) |
| 1183 return UNZ_PARAMERROR; |
| 1184 s=(unz64_s*)file; |
| 1185 s->pos_in_central_dir=s->offset_central_dir; |
| 1186 s->num_file=0; |
| 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); |
| 1191 return err; |
| 1192 } |
| 1193 |
| 1194 /* |
| 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. |
| 1198 */ |
| 1199 extern int ZEXPORT unzGoToNextFile (unzFile file) |
| 1200 { |
| 1201 unz64_s* s; |
| 1202 int err; |
| 1203 |
| 1204 if (file==NULL) |
| 1205 return UNZ_PARAMERROR; |
| 1206 s=(unz64_s*)file; |
| 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; |
| 1212 |
| 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_commen
t ; |
| 1215 s->num_file++; |
| 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); |
| 1220 return err; |
| 1221 } |
| 1222 |
| 1223 |
| 1224 /* |
| 1225 Try locate the file szFileName in the zipfile. |
| 1226 For the iCaseSensitivity signification, see unzipStringFileNameCompare |
| 1227 |
| 1228 return value : |
| 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 |
| 1231 */ |
| 1232 extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCas
eSensitivity) |
| 1233 { |
| 1234 unz64_s* s; |
| 1235 int err; |
| 1236 |
| 1237 /* We remember the 'current' position in the file so that we can jump |
| 1238 * back there if we fail. |
| 1239 */ |
| 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; |
| 1244 |
| 1245 |
| 1246 if (file==NULL) |
| 1247 return UNZ_PARAMERROR; |
| 1248 |
| 1249 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) |
| 1250 return UNZ_PARAMERROR; |
| 1251 |
| 1252 s=(unz64_s*)file; |
| 1253 if (!s->current_file_ok) |
| 1254 return UNZ_END_OF_LIST_OF_FILE; |
| 1255 |
| 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; |
| 1261 |
| 1262 err = unzGoToFirstFile(file); |
| 1263 |
| 1264 while (err == UNZ_OK) |
| 1265 { |
| 1266 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; |
| 1267 err = unzGetCurrentFileInfo64(file,NULL, |
| 1268 szCurrentFileName,sizeof(szCurrentFileName)-
1, |
| 1269 NULL,0,NULL,0); |
| 1270 if (err == UNZ_OK) |
| 1271 { |
| 1272 if (unzStringFileNameCompare(szCurrentFileName, |
| 1273 szFileName,iCaseSensitivity)==0) |
| 1274 return UNZ_OK; |
| 1275 err = unzGoToNextFile(file); |
| 1276 } |
| 1277 } |
| 1278 |
| 1279 /* We failed, so restore the state of the 'current file' to where we |
| 1280 * were. |
| 1281 */ |
| 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; |
| 1286 return err; |
| 1287 } |
| 1288 |
| 1289 |
| 1290 /* |
| 1291 /////////////////////////////////////////// |
| 1292 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) |
| 1293 // I need random access |
| 1294 // |
| 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. |
| 1298 */ |
| 1299 |
| 1300 /* |
| 1301 typedef struct unz_file_pos_s |
| 1302 { |
| 1303 ZPOS64_T pos_in_zip_directory; // offset in file |
| 1304 ZPOS64_T num_of_file; // # of file |
| 1305 } unz_file_pos; |
| 1306 */ |
| 1307 |
| 1308 extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) |
| 1309 { |
| 1310 unz64_s* s; |
| 1311 |
| 1312 if (file==NULL || file_pos==NULL) |
| 1313 return UNZ_PARAMERROR; |
| 1314 s=(unz64_s*)file; |
| 1315 if (!s->current_file_ok) |
| 1316 return UNZ_END_OF_LIST_OF_FILE; |
| 1317 |
| 1318 file_pos->pos_in_zip_directory = s->pos_in_central_dir; |
| 1319 file_pos->num_of_file = s->num_file; |
| 1320 |
| 1321 return UNZ_OK; |
| 1322 } |
| 1323 |
| 1324 extern int ZEXPORT unzGetFilePos( |
| 1325 unzFile file, |
| 1326 unz_file_pos* file_pos) |
| 1327 { |
| 1328 unz64_file_pos file_pos64; |
| 1329 int err = unzGetFilePos64(file,&file_pos64); |
| 1330 if (err==UNZ_OK) |
| 1331 { |
| 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; |
| 1334 } |
| 1335 return err; |
| 1336 } |
| 1337 |
| 1338 extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos
) |
| 1339 { |
| 1340 unz64_s* s; |
| 1341 int err; |
| 1342 |
| 1343 if (file==NULL || file_pos==NULL) |
| 1344 return UNZ_PARAMERROR; |
| 1345 s=(unz64_s*)file; |
| 1346 |
| 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; |
| 1350 |
| 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); |
| 1357 return err; |
| 1358 } |
| 1359 |
| 1360 extern int ZEXPORT unzGoToFilePos( |
| 1361 unzFile file, |
| 1362 unz_file_pos* file_pos) |
| 1363 { |
| 1364 unz64_file_pos file_pos64; |
| 1365 if (file_pos == NULL) |
| 1366 return UNZ_PARAMERROR; |
| 1367 |
| 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); |
| 1371 } |
| 1372 |
| 1373 /* |
| 1374 // Unzip Helper Functions - should be here? |
| 1375 /////////////////////////////////////////// |
| 1376 */ |
| 1377 |
| 1378 /* |
| 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) |
| 1384 */ |
| 1385 local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVa
r, |
| 1386 ZPOS64_T * poffset_local_ext
rafield, |
| 1387 uInt * psize_local_extrafie
ld) |
| 1388 { |
| 1389 uLong uMagic,uData,uFlags; |
| 1390 uLong size_filename; |
| 1391 uLong size_extra_field; |
| 1392 int err=UNZ_OK; |
| 1393 |
| 1394 *piSizeVar = 0; |
| 1395 *poffset_local_extrafield = 0; |
| 1396 *psize_local_extrafield = 0; |
| 1397 |
| 1398 if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_cu
rfile + |
| 1399 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SE
T)!=0) |
| 1400 return UNZ_ERRNO; |
| 1401 |
| 1402 |
| 1403 if (err==UNZ_OK) |
| 1404 { |
| 1405 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) |
| 1406 err=UNZ_ERRNO; |
| 1407 else if (uMagic!=0x04034b50) |
| 1408 err=UNZ_BADZIPFILE; |
| 1409 } |
| 1410 |
| 1411 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) |
| 1412 err=UNZ_ERRNO; |
| 1413 /* |
| 1414 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) |
| 1415 err=UNZ_BADZIPFILE; |
| 1416 */ |
| 1417 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) |
| 1418 err=UNZ_ERRNO; |
| 1419 |
| 1420 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) |
| 1421 err=UNZ_ERRNO; |
| 1422 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) |
| 1423 err=UNZ_BADZIPFILE; |
| 1424 |
| 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) && |
| 1428 /* #endif */ |
| 1429 (s->cur_file_info.compression_method!=Z_DEFLATED)) |
| 1430 err=UNZ_BADZIPFILE; |
| 1431 |
| 1432 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* d
ate/time */ |
| 1433 err=UNZ_ERRNO; |
| 1434 |
| 1435 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* c
rc */ |
| 1436 err=UNZ_ERRNO; |
| 1437 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)
) |
| 1438 err=UNZ_BADZIPFILE; |
| 1439 |
| 1440 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* s
ize compr */ |
| 1441 err=UNZ_ERRNO; |
| 1442 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.co
mpressed_size) && ((uFlags & 8)==0)) |
| 1443 err=UNZ_BADZIPFILE; |
| 1444 |
| 1445 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* s
ize uncompr */ |
| 1446 err=UNZ_ERRNO; |
| 1447 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.un
compressed_size) && ((uFlags & 8)==0)) |
| 1448 err=UNZ_BADZIPFILE; |
| 1449 |
| 1450 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ
_OK) |
| 1451 err=UNZ_ERRNO; |
| 1452 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) |
| 1453 err=UNZ_BADZIPFILE; |
| 1454 |
| 1455 *piSizeVar += (uInt)size_filename; |
| 1456 |
| 1457 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) !=
UNZ_OK) |
| 1458 err=UNZ_ERRNO; |
| 1459 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + |
| 1460 SIZEZIPLOCALHEADER + size_filename; |
| 1461 *psize_local_extrafield = (uInt)size_extra_field; |
| 1462 |
| 1463 *piSizeVar += (uInt)size_extra_field; |
| 1464 |
| 1465 return err; |
| 1466 } |
| 1467 |
| 1468 /* |
| 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. |
| 1471 */ |
| 1472 extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, |
| 1473 int* level, int raw, const char* pas
sword) |
| 1474 { |
| 1475 int err=UNZ_OK; |
| 1476 uInt iSizeVar; |
| 1477 unz64_s* s; |
| 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 */ |
| 1481 # ifndef NOUNCRYPT |
| 1482 char source[12]; |
| 1483 # else |
| 1484 if (password != NULL) |
| 1485 return UNZ_PARAMERROR; |
| 1486 # endif |
| 1487 |
| 1488 if (file==NULL) |
| 1489 return UNZ_PARAMERROR; |
| 1490 s=(unz64_s*)file; |
| 1491 if (!s->current_file_ok) |
| 1492 return UNZ_PARAMERROR; |
| 1493 |
| 1494 if (s->pfile_in_zip_read != NULL) |
| 1495 unzCloseCurrentFile(file); |
| 1496 |
| 1497 if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_ex
trafield,&size_local_extrafield)!=UNZ_OK) |
| 1498 return UNZ_BADZIPFILE; |
| 1499 |
| 1500 pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zi
p64_read_info_s)); |
| 1501 if (pfile_in_zip_read_info==NULL) |
| 1502 return UNZ_INTERNALERROR; |
| 1503 |
| 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; |
| 1509 |
| 1510 if (pfile_in_zip_read_info->read_buffer==NULL) |
| 1511 { |
| 1512 TRYFREE(pfile_in_zip_read_info); |
| 1513 return UNZ_INTERNALERROR; |
| 1514 } |
| 1515 |
| 1516 pfile_in_zip_read_info->stream_initialised=0; |
| 1517 |
| 1518 if (method!=NULL) |
| 1519 *method = (int)s->cur_file_info.compression_method; |
| 1520 |
| 1521 if (level!=NULL) |
| 1522 { |
| 1523 *level = 6; |
| 1524 switch (s->cur_file_info.flag & 0x06) |
| 1525 { |
| 1526 case 6 : *level = 1; break; |
| 1527 case 4 : *level = 2; break; |
| 1528 case 2 : *level = 9; break; |
| 1529 } |
| 1530 } |
| 1531 |
| 1532 if ((s->cur_file_info.compression_method!=0) && |
| 1533 /* #ifdef HAVE_BZIP2 */ |
| 1534 (s->cur_file_info.compression_method!=Z_BZIP2ED) && |
| 1535 /* #endif */ |
| 1536 (s->cur_file_info.compression_method!=Z_DEFLATED)) |
| 1537 |
| 1538 err=UNZ_BADZIPFILE; |
| 1539 |
| 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_me
thod; |
| 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; |
| 1547 |
| 1548 pfile_in_zip_read_info->stream.total_out = 0; |
| 1549 |
| 1550 if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) |
| 1551 { |
| 1552 #ifdef HAVE_BZIP2 |
| 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; |
| 1557 |
| 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; |
| 1563 |
| 1564 err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); |
| 1565 if (err == Z_OK) |
| 1566 pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; |
| 1567 else |
| 1568 { |
| 1569 TRYFREE(pfile_in_zip_read_info); |
| 1570 return err; |
| 1571 } |
| 1572 #else |
| 1573 pfile_in_zip_read_info->raw=1; |
| 1574 #endif |
| 1575 } |
| 1576 else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) |
| 1577 { |
| 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; |
| 1583 |
| 1584 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); |
| 1585 if (err == Z_OK) |
| 1586 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; |
| 1587 else |
| 1588 { |
| 1589 TRYFREE(pfile_in_zip_read_info); |
| 1590 return err; |
| 1591 } |
| 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 |
| 1598 */ |
| 1599 } |
| 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 ; |
| 1604 |
| 1605 |
| 1606 pfile_in_zip_read_info->pos_in_zipfile = |
| 1607 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + |
| 1608 iSizeVar; |
| 1609 |
| 1610 pfile_in_zip_read_info->stream.avail_in = (uInt)0; |
| 1611 |
| 1612 s->pfile_in_zip_read = pfile_in_zip_read_info; |
| 1613 s->encrypted = 0; |
| 1614 |
| 1615 # ifndef NOUNCRYPT |
| 1616 if (password != NULL) |
| 1617 { |
| 1618 int i; |
| 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, |
| 1624 SEEK_SET)!=0) |
| 1625 return UNZ_INTERNALERROR; |
| 1626 if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) |
| 1627 return UNZ_INTERNALERROR; |
| 1628 |
| 1629 for (i = 0; i<12; i++) |
| 1630 zdecode(s->keys,s->pcrc_32_tab,source[i]); |
| 1631 |
| 1632 s->pfile_in_zip_read->pos_in_zipfile+=12; |
| 1633 s->encrypted=1; |
| 1634 } |
| 1635 # endif |
| 1636 |
| 1637 |
| 1638 return UNZ_OK; |
| 1639 } |
| 1640 |
| 1641 extern int ZEXPORT unzOpenCurrentFile (unzFile file) |
| 1642 { |
| 1643 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); |
| 1644 } |
| 1645 |
| 1646 extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* passwo
rd) |
| 1647 { |
| 1648 return unzOpenCurrentFile3(file, NULL, NULL, 0, password); |
| 1649 } |
| 1650 |
| 1651 extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, i
nt raw) |
| 1652 { |
| 1653 return unzOpenCurrentFile3(file, method, level, raw, NULL); |
| 1654 } |
| 1655 |
| 1656 /** Addition for GDAL : START */ |
| 1657 |
| 1658 extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) |
| 1659 { |
| 1660 unz64_s* s; |
| 1661 file_in_zip64_read_info_s* pfile_in_zip_read_info; |
| 1662 s=(unz64_s*)file; |
| 1663 if (file==NULL) |
| 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; |
| 1670 } |
| 1671 |
| 1672 /** Addition for GDAL : END */ |
| 1673 |
| 1674 /* |
| 1675 Read bytes from the current file. |
| 1676 buf contain buffer where data must be copied |
| 1677 len the size of buf. |
| 1678 |
| 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) |
| 1683 */ |
| 1684 extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) |
| 1685 { |
| 1686 int err=UNZ_OK; |
| 1687 uInt iRead = 0; |
| 1688 unz64_s* s; |
| 1689 file_in_zip64_read_info_s* pfile_in_zip_read_info; |
| 1690 if (file==NULL) |
| 1691 return UNZ_PARAMERROR; |
| 1692 s=(unz64_s*)file; |
| 1693 pfile_in_zip_read_info=s->pfile_in_zip_read; |
| 1694 |
| 1695 if (pfile_in_zip_read_info==NULL) |
| 1696 return UNZ_PARAMERROR; |
| 1697 |
| 1698 |
| 1699 if ((pfile_in_zip_read_info->read_buffer == NULL)) |
| 1700 return UNZ_END_OF_LIST_OF_FILE; |
| 1701 if (len==0) |
| 1702 return 0; |
| 1703 |
| 1704 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; |
| 1705 |
| 1706 pfile_in_zip_read_info->stream.avail_out = (uInt)len; |
| 1707 |
| 1708 if ((len>pfile_in_zip_read_info->rest_read_compressed+ |
| 1709 pfile_in_zip_read_info->stream.avail_in) && |
| 1710 (pfile_in_zip_read_info->raw)) |
| 1711 pfile_in_zip_read_info->stream.avail_out = |
| 1712 (uInt)pfile_in_zip_read_info->rest_read_compressed+ |
| 1713 pfile_in_zip_read_info->stream.avail_in; |
| 1714 |
| 1715 while (pfile_in_zip_read_info->stream.avail_out>0) |
| 1716 { |
| 1717 if ((pfile_in_zip_read_info->stream.avail_in==0) && |
| 1718 (pfile_in_zip_read_info->rest_read_compressed>0)) |
| 1719 { |
| 1720 uInt uReadThis = UNZ_BUFSIZE; |
| 1721 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis) |
| 1722 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; |
| 1723 if (uReadThis == 0) |
| 1724 return UNZ_EOF; |
| 1725 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, |
| 1726 pfile_in_zip_read_info->filestream, |
| 1727 pfile_in_zip_read_info->pos_in_zipfile + |
| 1728 pfile_in_zip_read_info->byte_before_the_zipfile, |
| 1729 ZLIB_FILEFUNC_SEEK_SET)!=0) |
| 1730 return UNZ_ERRNO; |
| 1731 if (ZREAD64(pfile_in_zip_read_info->z_filefunc, |
| 1732 pfile_in_zip_read_info->filestream, |
| 1733 pfile_in_zip_read_info->read_buffer, |
| 1734 uReadThis)!=uReadThis) |
| 1735 return UNZ_ERRNO; |
| 1736 |
| 1737 |
| 1738 # ifndef NOUNCRYPT |
| 1739 if(s->encrypted) |
| 1740 { |
| 1741 uInt i; |
| 1742 for(i=0;i<uReadThis;i++) |
| 1743 pfile_in_zip_read_info->read_buffer[i] = |
| 1744 zdecode(s->keys,s->pcrc_32_tab, |
| 1745 pfile_in_zip_read_info->read_buffer[i]); |
| 1746 } |
| 1747 # endif |
| 1748 |
| 1749 |
| 1750 pfile_in_zip_read_info->pos_in_zipfile += uReadThis; |
| 1751 |
| 1752 pfile_in_zip_read_info->rest_read_compressed-=uReadThis; |
| 1753 |
| 1754 pfile_in_zip_read_info->stream.next_in = |
| 1755 (Bytef*)pfile_in_zip_read_info->read_buffer; |
| 1756 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; |
| 1757 } |
| 1758 |
| 1759 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_rea
d_info->raw)) |
| 1760 { |
| 1761 uInt uDoCopy,i ; |
| 1762 |
| 1763 if ((pfile_in_zip_read_info->stream.avail_in == 0) && |
| 1764 (pfile_in_zip_read_info->rest_read_compressed == 0)) |
| 1765 return (iRead==0) ? UNZ_EOF : iRead; |
| 1766 |
| 1767 if (pfile_in_zip_read_info->stream.avail_out < |
| 1768 pfile_in_zip_read_info->stream.avail_in) |
| 1769 uDoCopy = pfile_in_zip_read_info->stream.avail_out ; |
| 1770 else |
| 1771 uDoCopy = pfile_in_zip_read_info->stream.avail_in ; |
| 1772 |
| 1773 for (i=0;i<uDoCopy;i++) |
| 1774 *(pfile_in_zip_read_info->stream.next_out+i) = |
| 1775 *(pfile_in_zip_read_info->stream.next_in+i); |
| 1776 |
| 1777 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total
_out_64 + uDoCopy; |
| 1778 |
| 1779 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, |
| 1780 pfile_in_zip_read_info->stream.next_out, |
| 1781 uDoCopy); |
| 1782 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; |
| 1783 pfile_in_zip_read_info->stream.avail_in -= uDoCopy; |
| 1784 pfile_in_zip_read_info->stream.avail_out -= uDoCopy; |
| 1785 pfile_in_zip_read_info->stream.next_out += uDoCopy; |
| 1786 pfile_in_zip_read_info->stream.next_in += uDoCopy; |
| 1787 pfile_in_zip_read_info->stream.total_out += uDoCopy; |
| 1788 iRead += uDoCopy; |
| 1789 } |
| 1790 else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) |
| 1791 { |
| 1792 #ifdef HAVE_BZIP2 |
| 1793 uLong uTotalOutBefore,uTotalOutAfter; |
| 1794 const Bytef *bufBefore; |
| 1795 uLong uOutThis; |
| 1796 |
| 1797 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip
_read_info->stream.next_in; |
| 1798 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_i
nfo->stream.avail_in; |
| 1799 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_i
nfo->stream.total_in; |
| 1800 pfile_in_zip_read_info->bstream.total_in_hi32 = 0; |
| 1801 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip
_read_info->stream.next_out; |
| 1802 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_i
nfo->stream.avail_out; |
| 1803 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_i
nfo->stream.total_out; |
| 1804 pfile_in_zip_read_info->bstream.total_out_hi32 = 0; |
| 1805 |
| 1806 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; |
| 1807 bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; |
| 1808 |
| 1809 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); |
| 1810 |
| 1811 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; |
| 1812 uOutThis = uTotalOutAfter-uTotalOutBefore; |
| 1813 |
| 1814 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total
_out_64 + uOutThis; |
| 1815 |
| 1816 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
bufBefore, (uInt)(uOutThis)); |
| 1817 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; |
| 1818 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); |
| 1819 |
| 1820 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read
_info->bstream.next_in; |
| 1821 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->b
stream.avail_in; |
| 1822 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->b
stream.total_in_lo32; |
| 1823 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read
_info->bstream.next_out; |
| 1824 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->b
stream.avail_out; |
| 1825 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->b
stream.total_out_lo32; |
| 1826 |
| 1827 if (err==BZ_STREAM_END) |
| 1828 return (iRead==0) ? UNZ_EOF : iRead; |
| 1829 if (err!=BZ_OK) |
| 1830 break; |
| 1831 #endif |
| 1832 } // end Z_BZIP2ED |
| 1833 else |
| 1834 { |
| 1835 ZPOS64_T uTotalOutBefore,uTotalOutAfter; |
| 1836 const Bytef *bufBefore; |
| 1837 ZPOS64_T uOutThis; |
| 1838 int flush=Z_SYNC_FLUSH; |
| 1839 |
| 1840 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; |
| 1841 bufBefore = pfile_in_zip_read_info->stream.next_out; |
| 1842 |
| 1843 /* |
| 1844 if ((pfile_in_zip_read_info->rest_read_uncompressed == |
| 1845 pfile_in_zip_read_info->stream.avail_out) && |
| 1846 (pfile_in_zip_read_info->rest_read_compressed == 0)) |
| 1847 flush = Z_FINISH; |
| 1848 */ |
| 1849 err=inflate(&pfile_in_zip_read_info->stream,flush); |
| 1850 |
| 1851 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) |
| 1852 err = Z_DATA_ERROR; |
| 1853 |
| 1854 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; |
| 1855 uOutThis = uTotalOutAfter-uTotalOutBefore; |
| 1856 |
| 1857 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total
_out_64 + uOutThis; |
| 1858 |
| 1859 pfile_in_zip_read_info->crc32 = |
| 1860 crc32(pfile_in_zip_read_info->crc32,bufBefore, |
| 1861 (uInt)(uOutThis)); |
| 1862 |
| 1863 pfile_in_zip_read_info->rest_read_uncompressed -= |
| 1864 uOutThis; |
| 1865 |
| 1866 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); |
| 1867 |
| 1868 if (err==Z_STREAM_END) |
| 1869 return (iRead==0) ? UNZ_EOF : iRead; |
| 1870 if (err!=Z_OK) |
| 1871 break; |
| 1872 } |
| 1873 } |
| 1874 |
| 1875 if (err==Z_OK) |
| 1876 return iRead; |
| 1877 return err; |
| 1878 } |
| 1879 |
| 1880 |
| 1881 /* |
| 1882 Give the current position in uncompressed data |
| 1883 */ |
| 1884 extern z_off_t ZEXPORT unztell (unzFile file) |
| 1885 { |
| 1886 unz64_s* s; |
| 1887 file_in_zip64_read_info_s* pfile_in_zip_read_info; |
| 1888 if (file==NULL) |
| 1889 return UNZ_PARAMERROR; |
| 1890 s=(unz64_s*)file; |
| 1891 pfile_in_zip_read_info=s->pfile_in_zip_read; |
| 1892 |
| 1893 if (pfile_in_zip_read_info==NULL) |
| 1894 return UNZ_PARAMERROR; |
| 1895 |
| 1896 return (z_off_t)pfile_in_zip_read_info->stream.total_out; |
| 1897 } |
| 1898 |
| 1899 extern ZPOS64_T ZEXPORT unztell64 (unzFile file) |
| 1900 { |
| 1901 |
| 1902 unz64_s* s; |
| 1903 file_in_zip64_read_info_s* pfile_in_zip_read_info; |
| 1904 if (file==NULL) |
| 1905 return (ZPOS64_T)-1; |
| 1906 s=(unz64_s*)file; |
| 1907 pfile_in_zip_read_info=s->pfile_in_zip_read; |
| 1908 |
| 1909 if (pfile_in_zip_read_info==NULL) |
| 1910 return (ZPOS64_T)-1; |
| 1911 |
| 1912 return pfile_in_zip_read_info->total_out_64; |
| 1913 } |
| 1914 |
| 1915 |
| 1916 /* |
| 1917 return 1 if the end of file was reached, 0 elsewhere |
| 1918 */ |
| 1919 extern int ZEXPORT unzeof (unzFile file) |
| 1920 { |
| 1921 unz64_s* s; |
| 1922 file_in_zip64_read_info_s* pfile_in_zip_read_info; |
| 1923 if (file==NULL) |
| 1924 return UNZ_PARAMERROR; |
| 1925 s=(unz64_s*)file; |
| 1926 pfile_in_zip_read_info=s->pfile_in_zip_read; |
| 1927 |
| 1928 if (pfile_in_zip_read_info==NULL) |
| 1929 return UNZ_PARAMERROR; |
| 1930 |
| 1931 if (pfile_in_zip_read_info->rest_read_uncompressed == 0) |
| 1932 return 1; |
| 1933 else |
| 1934 return 0; |
| 1935 } |
| 1936 |
| 1937 |
| 1938 |
| 1939 /* |
| 1940 Read extra field from the current file (opened by unzOpenCurrentFile) |
| 1941 This is the local-header version of the extra field (sometimes, there is |
| 1942 more info in the local-header version than in the central-header) |
| 1943 |
| 1944 if buf==NULL, it return the size of the local extra field that can be read |
| 1945 |
| 1946 if buf!=NULL, len is the size of the buffer, the extra header is copied in |
| 1947 buf. |
| 1948 the return value is the number of bytes copied in buf, or (if <0) |
| 1949 the error code |
| 1950 */ |
| 1951 extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) |
| 1952 { |
| 1953 unz64_s* s; |
| 1954 file_in_zip64_read_info_s* pfile_in_zip_read_info; |
| 1955 uInt read_now; |
| 1956 ZPOS64_T size_to_read; |
| 1957 |
| 1958 if (file==NULL) |
| 1959 return UNZ_PARAMERROR; |
| 1960 s=(unz64_s*)file; |
| 1961 pfile_in_zip_read_info=s->pfile_in_zip_read; |
| 1962 |
| 1963 if (pfile_in_zip_read_info==NULL) |
| 1964 return UNZ_PARAMERROR; |
| 1965 |
| 1966 size_to_read = (pfile_in_zip_read_info->size_local_extrafield - |
| 1967 pfile_in_zip_read_info->pos_local_extrafield); |
| 1968 |
| 1969 if (buf==NULL) |
| 1970 return (int)size_to_read; |
| 1971 |
| 1972 if (len>size_to_read) |
| 1973 read_now = (uInt)size_to_read; |
| 1974 else |
| 1975 read_now = (uInt)len ; |
| 1976 |
| 1977 if (read_now==0) |
| 1978 return 0; |
| 1979 |
| 1980 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, |
| 1981 pfile_in_zip_read_info->filestream, |
| 1982 pfile_in_zip_read_info->offset_local_extrafield + |
| 1983 pfile_in_zip_read_info->pos_local_extrafield, |
| 1984 ZLIB_FILEFUNC_SEEK_SET)!=0) |
| 1985 return UNZ_ERRNO; |
| 1986 |
| 1987 if (ZREAD64(pfile_in_zip_read_info->z_filefunc, |
| 1988 pfile_in_zip_read_info->filestream, |
| 1989 buf,read_now)!=read_now) |
| 1990 return UNZ_ERRNO; |
| 1991 |
| 1992 return (int)read_now; |
| 1993 } |
| 1994 |
| 1995 /* |
| 1996 Close the file in zip opened with unzipOpenCurrentFile |
| 1997 Return UNZ_CRCERROR if all the file was read but the CRC is not good |
| 1998 */ |
| 1999 extern int ZEXPORT unzCloseCurrentFile (unzFile file) |
| 2000 { |
| 2001 int err=UNZ_OK; |
| 2002 |
| 2003 unz64_s* s; |
| 2004 file_in_zip64_read_info_s* pfile_in_zip_read_info; |
| 2005 if (file==NULL) |
| 2006 return UNZ_PARAMERROR; |
| 2007 s=(unz64_s*)file; |
| 2008 pfile_in_zip_read_info=s->pfile_in_zip_read; |
| 2009 |
| 2010 if (pfile_in_zip_read_info==NULL) |
| 2011 return UNZ_PARAMERROR; |
| 2012 |
| 2013 |
| 2014 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && |
| 2015 (!pfile_in_zip_read_info->raw)) |
| 2016 { |
| 2017 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) |
| 2018 err=UNZ_CRCERROR; |
| 2019 } |
| 2020 |
| 2021 |
| 2022 TRYFREE(pfile_in_zip_read_info->read_buffer); |
| 2023 pfile_in_zip_read_info->read_buffer = NULL; |
| 2024 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) |
| 2025 inflateEnd(&pfile_in_zip_read_info->stream); |
| 2026 #ifdef HAVE_BZIP2 |
| 2027 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) |
| 2028 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); |
| 2029 #endif |
| 2030 |
| 2031 |
| 2032 pfile_in_zip_read_info->stream_initialised = 0; |
| 2033 TRYFREE(pfile_in_zip_read_info); |
| 2034 |
| 2035 s->pfile_in_zip_read=NULL; |
| 2036 |
| 2037 return err; |
| 2038 } |
| 2039 |
| 2040 |
| 2041 /* |
| 2042 Get the global comment string of the ZipFile, in the szComment buffer. |
| 2043 uSizeBuf is the size of the szComment buffer. |
| 2044 return the number of byte copied or an error code <0 |
| 2045 */ |
| 2046 extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uS
izeBuf) |
| 2047 { |
| 2048 unz64_s* s; |
| 2049 uLong uReadThis ; |
| 2050 if (file==NULL) |
| 2051 return (int)UNZ_PARAMERROR; |
| 2052 s=(unz64_s*)file; |
| 2053 |
| 2054 uReadThis = uSizeBuf; |
| 2055 if (uReadThis>s->gi.size_comment) |
| 2056 uReadThis = s->gi.size_comment; |
| 2057 |
| 2058 if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK
_SET)!=0) |
| 2059 return UNZ_ERRNO; |
| 2060 |
| 2061 if (uReadThis>0) |
| 2062 { |
| 2063 *szComment='\0'; |
| 2064 if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) |
| 2065 return UNZ_ERRNO; |
| 2066 } |
| 2067 |
| 2068 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) |
| 2069 *(szComment+s->gi.size_comment)='\0'; |
| 2070 return (int)uReadThis; |
| 2071 } |
| 2072 |
| 2073 /* Additions by RX '2004 */ |
| 2074 extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) |
| 2075 { |
| 2076 unz64_s* s; |
| 2077 |
| 2078 if (file==NULL) |
| 2079 return 0; //UNZ_PARAMERROR; |
| 2080 s=(unz64_s*)file; |
| 2081 if (!s->current_file_ok) |
| 2082 return 0; |
| 2083 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) |
| 2084 if (s->num_file==s->gi.number_entry) |
| 2085 return 0; |
| 2086 return s->pos_in_central_dir; |
| 2087 } |
| 2088 |
| 2089 extern uLong ZEXPORT unzGetOffset (unzFile file) |
| 2090 { |
| 2091 ZPOS64_T offset64; |
| 2092 |
| 2093 if (file==NULL) |
| 2094 return 0; //UNZ_PARAMERROR; |
| 2095 offset64 = unzGetOffset64(file); |
| 2096 return (uLong)offset64; |
| 2097 } |
| 2098 |
| 2099 extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) |
| 2100 { |
| 2101 unz64_s* s; |
| 2102 int err; |
| 2103 |
| 2104 if (file==NULL) |
| 2105 return UNZ_PARAMERROR; |
| 2106 s=(unz64_s*)file; |
| 2107 |
| 2108 s->pos_in_central_dir = pos; |
| 2109 s->num_file = s->gi.number_entry; /* hack */ |
| 2110 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, |
| 2111 &s->cur_file_info_internal, |
| 2112 NULL,0,NULL,0,NULL,0); |
| 2113 s->current_file_ok = (err == UNZ_OK); |
| 2114 return err; |
| 2115 } |
| 2116 |
| 2117 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) |
| 2118 { |
| 2119 return unzSetOffset64(file,pos); |
| 2120 } |
OLD | NEW |