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 Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). 53 Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G 54 should only read the compressed/uncompressed size from the Zip64 format if 55 the size from normal header was 0xFFFFFFFF 56 Oct-2009 - Mathias Svensson - Applied some bug fixes from patches received from Gilles Vollant 57 Oct-2009 - Mathias Svensson - Applied support to unzip files with compression method BZIP2 (bzip2 lib is required) 58 Patch created by Daniel Borca 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 "zlib.h" 76 #include "unzip.h" 77 78 #ifdef STDC 79 # include <stddef.h> 80 #endif 81 #ifdef NO_ERRNO_H 82 extern int errno; 83 #else 84 # include <errno.h> 85 #endif 86 87 88 #ifndef local 89 # define local static 90 #endif 91 /* compile with -Dlocal if your debugger can't find static symbols */ 92 93 94 #ifndef CASESENSITIVITYDEFAULT_NO 95 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) 96 # define CASESENSITIVITYDEFAULT_NO 97 # endif 98 #endif 99 100 101 #ifndef UNZ_BUFSIZE 102 #define UNZ_BUFSIZE (16384) 103 #endif 104 105 #ifndef UNZ_MAXFILENAMEINZIP 106 #define UNZ_MAXFILENAMEINZIP (256) 107 #endif 108 109 #ifndef ALLOC 110 # define ALLOC(size) (malloc(size)) 111 #endif 112 113 #define SIZECENTRALDIRITEM (0x2e) 114 #define SIZEZIPLOCALHEADER (0x1e) 115 116 117 const char unz_copyright[] = 118 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; 119 120 /* unz_file_info64_internal contain internal info about a file in zipfile*/ 121 typedef struct unz_file_info64_internal_s 122 { 123 ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ 124 } unz_file_info64_internal; 125 126 127 /* file_in_zip_read_info_s contain internal information about a file in zipfile, 128 when reading and decompress it */ 129 typedef struct 130 { 131 char *read_buffer; /* internal buffer for compressed data */ 132 z_stream stream; /* zLib stream structure for inflate */ 133 134 #ifdef HAVE_BZIP2 135 bz_stream bstream; /* bzLib stream structure for bziped */ 136 #endif 137 138 ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ 139 uLong stream_initialised; /* flag set if stream structure is initialised*/ 140 141 ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ 142 uInt size_local_extrafield;/* size of the local extra field */ 143 ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ 144 ZPOS64_T total_out_64; 145 146 uLong crc32; /* crc32 of all data uncompressed */ 147 uLong crc32_wait; /* crc32 we must obtain after decompress all */ 148 ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ 149 ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ 150 zlib_filefunc64_32_def z_filefunc; 151 voidpf filestream; /* io structure of the zipfile */ 152 uLong compression_method; /* compression method (0==store) */ 153 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 154 int raw; 155 } file_in_zip64_read_info_s; 156 157 158 /* unz64_s contain internal information about the zipfile 159 */ 160 typedef struct 161 { 162 zlib_filefunc64_32_def z_filefunc; 163 int is64bitOpenFunction; 164 voidpf filestream; /* io structure of the zipfile */ 165 unz_global_info64 gi; /* public global information */ 166 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 167 ZPOS64_T num_file; /* number of the current file in the zipfile*/ 168 ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ 169 ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ 170 ZPOS64_T central_pos; /* position of the beginning of the central dir*/ 171 172 ZPOS64_T size_central_dir; /* size of the central directory */ 173 ZPOS64_T offset_central_dir; /* offset of start of central directory with 174 respect to the starting disk number */ 175 176 unz_file_info64 cur_file_info; /* public info about the current file in zip*/ 177 unz_file_info64_internal cur_file_info_internal; /* private info about it*/ 178 file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current 179 file if we are decompressing it */ 180 int encrypted; 181 182 int isZip64; 183 184 # ifndef NOUNCRYPT 185 unsigned long keys[3]; /* keys defining the pseudo-random sequence */ 186 const z_crc_t* pcrc_32_tab; 187 # endif 188 } unz64_s; 189 190 191 #ifndef NOUNCRYPT 192 #include "crypt.h" 193 #endif 194 195 196 /* =========================================================================== 197 Reads a long in LSB order from the given gz_stream. Sets 198 */ 199 200 local int unz64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, 201 voidpf filestream, 202 uLong *pX) { 203 unsigned char c[2]; 204 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,2); 205 if (err==2) 206 { 207 *pX = c[0] | ((uLong)c[1] << 8); 208 return UNZ_OK; 209 } 210 else 211 { 212 *pX = 0; 213 if (ZERROR64(*pzlib_filefunc_def,filestream)) 214 return UNZ_ERRNO; 215 else 216 return UNZ_EOF; 217 } 218 } 219 220 local int unz64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def, 221 voidpf filestream, 222 uLong *pX) { 223 unsigned char c[4]; 224 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,4); 225 if (err==4) 226 { 227 *pX = c[0] | ((uLong)c[1] << 8) | ((uLong)c[2] << 16) | ((uLong)c[3] << 24); 228 return UNZ_OK; 229 } 230 else 231 { 232 *pX = 0; 233 if (ZERROR64(*pzlib_filefunc_def,filestream)) 234 return UNZ_ERRNO; 235 else 236 return UNZ_EOF; 237 } 238 } 239 240 241 local int unz64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def, 242 voidpf filestream, 243 ZPOS64_T *pX) { 244 unsigned char c[8]; 245 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,8); 246 if (err==8) 247 { 248 *pX = c[0] | ((ZPOS64_T)c[1] << 8) | ((ZPOS64_T)c[2] << 16) | ((ZPOS64_T)c[3] << 24) 249 | ((ZPOS64_T)c[4] << 32) | ((ZPOS64_T)c[5] << 40) | ((ZPOS64_T)c[6] << 48) | ((ZPOS64_T)c[7] << 56); 250 return UNZ_OK; 251 } 252 else 253 { 254 *pX = 0; 255 if (ZERROR64(*pzlib_filefunc_def,filestream)) 256 return UNZ_ERRNO; 257 else 258 return UNZ_EOF; 259 } 260 } 261 262 /* My own strcmpi / strcasecmp */ 263 local int strcmpcasenosensitive_internal(const char* fileName1, const char* fileName2) { 264 for (;;) 265 { 266 char c1=*(fileName1++); 267 char c2=*(fileName2++); 268 if ((c1>='a') && (c1<='z')) 269 c1 -= 0x20; 270 if ((c2>='a') && (c2<='z')) 271 c2 -= 0x20; 272 if (c1=='\0') 273 return ((c2=='\0') ? 0 : -1); 274 if (c2=='\0') 275 return 1; 276 if (c1<c2) 277 return -1; 278 if (c1>c2) 279 return 1; 280 } 281 } 282 283 284 #ifdef CASESENSITIVITYDEFAULT_NO 285 #define CASESENSITIVITYDEFAULTVALUE 2 286 #else 287 #define CASESENSITIVITYDEFAULTVALUE 1 288 #endif 289 290 #ifndef STRCMPCASENOSENTIVEFUNCTION 291 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal 292 #endif 293 294 /* 295 Compare two filenames (fileName1,fileName2). 296 If iCaseSensitivity = 1, comparison is case sensitive (like strcmp) 297 If iCaseSensitivity = 2, comparison is not case sensitive (like strcmpi 298 or strcasecmp) 299 If iCaseSensitivity = 0, case sensitivity is default of your operating system 300 (like 1 on Unix, 2 on Windows) 301 302 */ 303 extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, 304 const char* fileName2, 305 int iCaseSensitivity) { 306 if (iCaseSensitivity==0) 307 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; 308 309 if (iCaseSensitivity==1) 310 return strcmp(fileName1,fileName2); 311 312 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); 313 } 314 315 #ifndef BUFREADCOMMENT 316 #define BUFREADCOMMENT (0x400) 317 #endif 318 319 #ifndef CENTRALDIRINVALID 320 #define CENTRALDIRINVALID ((ZPOS64_T)(-1)) 321 #endif 322 323 /* 324 Locate the Central directory of a zipfile (at the end, just before 325 the global comment) 326 */ 327 local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { 328 unsigned char* buf; 329 ZPOS64_T uSizeFile; 330 ZPOS64_T uBackRead; 331 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ 332 ZPOS64_T uPosFound=CENTRALDIRINVALID; 333 334 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 335 return CENTRALDIRINVALID; 336 337 338 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); 339 340 if (uMaxBack>uSizeFile) 341 uMaxBack = uSizeFile; 342 343 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 344 if (buf==NULL) 345 return CENTRALDIRINVALID; 346 347 uBackRead = 4; 348 while (uBackRead<uMaxBack) 349 { 350 uLong uReadSize; 351 ZPOS64_T uReadPos ; 352 int i; 353 if (uBackRead+BUFREADCOMMENT>uMaxBack) 354 uBackRead = uMaxBack; 355 else 356 uBackRead+=BUFREADCOMMENT; 357 uReadPos = uSizeFile-uBackRead ; 358 359 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 360 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); 361 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 362 break; 363 364 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 365 break; 366 367 for (i=(int)uReadSize-3; (i--)>0;) 368 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 369 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) 370 { 371 uPosFound = uReadPos+(unsigned)i; 372 break; 373 } 374 375 if (uPosFound!=CENTRALDIRINVALID) 376 break; 377 } 378 free(buf); 379 return uPosFound; 380 } 381 382 383 /* 384 Locate the Central directory 64 of a zipfile (at the end, just before 385 the global comment) 386 */ 387 local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, 388 voidpf filestream) { 389 unsigned char* buf; 390 ZPOS64_T uSizeFile; 391 ZPOS64_T uBackRead; 392 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ 393 ZPOS64_T uPosFound=CENTRALDIRINVALID; 394 uLong uL; 395 ZPOS64_T relativeOffset; 396 397 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 398 return CENTRALDIRINVALID; 399 400 401 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); 402 403 if (uMaxBack>uSizeFile) 404 uMaxBack = uSizeFile; 405 406 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 407 if (buf==NULL) 408 return CENTRALDIRINVALID; 409 410 uBackRead = 4; 411 while (uBackRead<uMaxBack) 412 { 413 uLong uReadSize; 414 ZPOS64_T uReadPos; 415 int i; 416 if (uBackRead+BUFREADCOMMENT>uMaxBack) 417 uBackRead = uMaxBack; 418 else 419 uBackRead+=BUFREADCOMMENT; 420 uReadPos = uSizeFile-uBackRead ; 421 422 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 423 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); 424 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 425 break; 426 427 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 428 break; 429 430 for (i=(int)uReadSize-3; (i--)>0;) 431 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 432 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) 433 { 434 uPosFound = uReadPos+(unsigned)i; 435 break; 436 } 437 438 if (uPosFound!=CENTRALDIRINVALID) 439 break; 440 } 441 free(buf); 442 if (uPosFound == CENTRALDIRINVALID) 443 return CENTRALDIRINVALID; 444 445 /* Zip64 end of central directory locator */ 446 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) 447 return CENTRALDIRINVALID; 448 449 /* the signature, already checked */ 450 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 451 return CENTRALDIRINVALID; 452 453 /* number of the disk with the start of the zip64 end of central directory */ 454 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 455 return CENTRALDIRINVALID; 456 if (uL != 0) 457 return CENTRALDIRINVALID; 458 459 /* relative offset of the zip64 end of central directory record */ 460 if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) 461 return CENTRALDIRINVALID; 462 463 /* total number of disks */ 464 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 465 return CENTRALDIRINVALID; 466 if (uL != 1) 467 return CENTRALDIRINVALID; 468 469 /* Goto end of central directory record */ 470 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) 471 return CENTRALDIRINVALID; 472 473 /* the signature */ 474 if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) 475 return CENTRALDIRINVALID; 476 477 if (uL != 0x06064b50) 478 return CENTRALDIRINVALID; 479 480 return relativeOffset; 481 } 482 483 /* 484 Open a Zip file. path contain the full pathname (by example, 485 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer 486 "zlib/zlib114.zip". 487 If the zipfile cannot be opened (file doesn't exist or in not valid), the 488 return value is NULL. 489 Else, the return value is a unzFile Handle, usable with other function 490 of this unzip package. 491 */ 492 local unzFile unzOpenInternal(const void *path, 493 zlib_filefunc64_32_def* pzlib_filefunc64_32_def, 494 int is64bitOpenFunction) { 495 unz64_s us; 496 unz64_s *s; 497 ZPOS64_T central_pos; 498 uLong uL; 499 500 uLong number_disk; /* number of the current disk, used for 501 spanning ZIP, unsupported, always 0*/ 502 uLong number_disk_with_CD; /* number the disk with central dir, used 503 for spanning ZIP, unsupported, always 0*/ 504 ZPOS64_T number_entry_CD; /* total number of entries in 505 the central dir 506 (same than number_entry on nospan) */ 507 508 int err=UNZ_OK; 509 510 if (unz_copyright[0]!=' ') 511 return NULL; 512 513 us.z_filefunc.zseek32_file = NULL; 514 us.z_filefunc.ztell32_file = NULL; 515 if (pzlib_filefunc64_32_def==NULL) 516 fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); 517 else 518 us.z_filefunc = *pzlib_filefunc64_32_def; 519 us.is64bitOpenFunction = is64bitOpenFunction; 520 521 522 523 us.filestream = ZOPEN64(us.z_filefunc, 524 path, 525 ZLIB_FILEFUNC_MODE_READ | 526 ZLIB_FILEFUNC_MODE_EXISTING); 527 if (us.filestream==NULL) 528 return NULL; 529 530 central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); 531 if (central_pos!=CENTRALDIRINVALID) 532 { 533 uLong uS; 534 ZPOS64_T uL64; 535 536 us.isZip64 = 1; 537 538 if (ZSEEK64(us.z_filefunc, us.filestream, 539 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) 540 err=UNZ_ERRNO; 541 542 /* the signature, already checked */ 543 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 544 err=UNZ_ERRNO; 545 546 /* size of zip64 end of central directory record */ 547 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) 548 err=UNZ_ERRNO; 549 550 /* version made by */ 551 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) 552 err=UNZ_ERRNO; 553 554 /* version needed to extract */ 555 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) 556 err=UNZ_ERRNO; 557 558 /* number of this disk */ 559 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) 560 err=UNZ_ERRNO; 561 562 /* number of the disk with the start of the central directory */ 563 if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) 564 err=UNZ_ERRNO; 565 566 /* total number of entries in the central directory on this disk */ 567 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) 568 err=UNZ_ERRNO; 569 570 /* total number of entries in the central directory */ 571 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) 572 err=UNZ_ERRNO; 573 574 if ((number_entry_CD!=us.gi.number_entry) || 575 (number_disk_with_CD!=0) || 576 (number_disk!=0)) 577 err=UNZ_BADZIPFILE; 578 579 /* size of the central directory */ 580 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) 581 err=UNZ_ERRNO; 582 583 /* offset of start of central directory with respect to the 584 starting disk number */ 585 if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) 586 err=UNZ_ERRNO; 587 588 us.gi.size_comment = 0; 589 } 590 else 591 { 592 central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); 593 if (central_pos==CENTRALDIRINVALID) 594 err=UNZ_ERRNO; 595 596 us.isZip64 = 0; 597 598 if (ZSEEK64(us.z_filefunc, us.filestream, 599 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) 600 err=UNZ_ERRNO; 601 602 /* the signature, already checked */ 603 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 604 err=UNZ_ERRNO; 605 606 /* number of this disk */ 607 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) 608 err=UNZ_ERRNO; 609 610 /* number of the disk with the start of the central directory */ 611 if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) 612 err=UNZ_ERRNO; 613 614 /* total number of entries in the central dir on this disk */ 615 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 616 err=UNZ_ERRNO; 617 us.gi.number_entry = uL; 618 619 /* total number of entries in the central dir */ 620 if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 621 err=UNZ_ERRNO; 622 number_entry_CD = uL; 623 624 if ((number_entry_CD!=us.gi.number_entry) || 625 (number_disk_with_CD!=0) || 626 (number_disk!=0)) 627 err=UNZ_BADZIPFILE; 628 629 /* size of the central directory */ 630 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 631 err=UNZ_ERRNO; 632 us.size_central_dir = uL; 633 634 /* offset of start of central directory with respect to the 635 starting disk number */ 636 if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 637 err=UNZ_ERRNO; 638 us.offset_central_dir = uL; 639 640 /* zipfile comment length */ 641 if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) 642 err=UNZ_ERRNO; 643 } 644 645 if ((central_pos<us.offset_central_dir+us.size_central_dir) && 646 (err==UNZ_OK)) 647 err=UNZ_BADZIPFILE; 648 649 if (err!=UNZ_OK) 650 { 651 ZCLOSE64(us.z_filefunc, us.filestream); 652 return NULL; 653 } 654 655 us.byte_before_the_zipfile = central_pos - 656 (us.offset_central_dir+us.size_central_dir); 657 us.central_pos = central_pos; 658 us.pfile_in_zip_read = NULL; 659 us.encrypted = 0; 660 661 662 s=(unz64_s*)ALLOC(sizeof(unz64_s)); 663 if( s != NULL) 664 { 665 *s=us; 666 unzGoToFirstFile((unzFile)s); 667 } 668 return (unzFile)s; 669 } 670 671 672 extern unzFile ZEXPORT unzOpen2(const char *path, 673 zlib_filefunc_def* pzlib_filefunc32_def) { 674 if (pzlib_filefunc32_def != NULL) 675 { 676 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; 677 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); 678 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0); 679 } 680 else 681 return unzOpenInternal(path, NULL, 0); 682 } 683 684 extern unzFile ZEXPORT unzOpen2_64(const void *path, 685 zlib_filefunc64_def* pzlib_filefunc_def) { 686 if (pzlib_filefunc_def != NULL) 687 { 688 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; 689 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; 690 zlib_filefunc64_32_def_fill.ztell32_file = NULL; 691 zlib_filefunc64_32_def_fill.zseek32_file = NULL; 692 return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1); 693 } 694 else 695 return unzOpenInternal(path, NULL, 1); 696 } 697 698 extern unzFile ZEXPORT unzOpen(const char *path) { 699 return unzOpenInternal(path, NULL, 0); 700 } 701 702 extern unzFile ZEXPORT unzOpen64(const void *path) { 703 return unzOpenInternal(path, NULL, 1); 704 } 705 706 /* 707 Close a ZipFile opened with unzOpen. 708 If there is files inside the .Zip opened with unzOpenCurrentFile (see later), 709 these files MUST be closed with unzCloseCurrentFile before call unzClose. 710 return UNZ_OK if there is no problem. */ 711 extern int ZEXPORT unzClose(unzFile file) { 712 unz64_s* s; 713 if (file==NULL) 714 return UNZ_PARAMERROR; 715 s=(unz64_s*)file; 716 717 if (s->pfile_in_zip_read!=NULL) 718 unzCloseCurrentFile(file); 719 720 ZCLOSE64(s->z_filefunc, s->filestream); 721 free(s); 722 return UNZ_OK; 723 } 724 725 726 /* 727 Write info about the ZipFile in the *pglobal_info structure. 728 No preparation of the structure is needed 729 return UNZ_OK if there is no problem. */ 730 extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64* pglobal_info) { 731 unz64_s* s; 732 if (file==NULL) 733 return UNZ_PARAMERROR; 734 s=(unz64_s*)file; 735 *pglobal_info=s->gi; 736 return UNZ_OK; 737 } 738 739 extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32) { 740 unz64_s* s; 741 if (file==NULL) 742 return UNZ_PARAMERROR; 743 s=(unz64_s*)file; 744 /* to do : check if number_entry is not truncated */ 745 pglobal_info32->number_entry = (uLong)s->gi.number_entry; 746 pglobal_info32->size_comment = s->gi.size_comment; 747 return UNZ_OK; 748 } 749 /* 750 Translate date/time from Dos format to tm_unz (readable more easily) 751 */ 752 local void unz64local_DosDateToTmuDate(ZPOS64_T ulDosDate, tm_unz* ptm) { 753 ZPOS64_T uDate; 754 uDate = (ZPOS64_T)(ulDosDate>>16); 755 ptm->tm_mday = (int)(uDate&0x1f) ; 756 ptm->tm_mon = (int)((((uDate)&0x1E0)/0x20)-1) ; 757 ptm->tm_year = (int)(((uDate&0x0FE00)/0x0200)+1980) ; 758 759 ptm->tm_hour = (int) ((ulDosDate &0xF800)/0x800); 760 ptm->tm_min = (int) ((ulDosDate&0x7E0)/0x20) ; 761 ptm->tm_sec = (int) (2*(ulDosDate&0x1f)) ; 762 } 763 764 /* 765 Get Info about the current file in the zipfile, with internal only info 766 */ 767 local int unz64local_GetCurrentFileInfoInternal(unzFile file, 768 unz_file_info64 *pfile_info, 769 unz_file_info64_internal 770 *pfile_info_internal, 771 char *szFileName, 772 uLong fileNameBufferSize, 773 void *extraField, 774 uLong extraFieldBufferSize, 775 char *szComment, 776 uLong commentBufferSize) { 777 unz64_s* s; 778 unz_file_info64 file_info; 779 unz_file_info64_internal file_info_internal; 780 int err=UNZ_OK; 781 uLong uMagic; 782 long lSeek=0; 783 uLong uL; 784 785 if (file==NULL) 786 return UNZ_PARAMERROR; 787 s=(unz64_s*)file; 788 if (ZSEEK64(s->z_filefunc, s->filestream, 789 s->pos_in_central_dir+s->byte_before_the_zipfile, 790 ZLIB_FILEFUNC_SEEK_SET)!=0) 791 err=UNZ_ERRNO; 792 793 794 /* we check the magic */ 795 if (err==UNZ_OK) 796 { 797 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) 798 err=UNZ_ERRNO; 799 else if (uMagic!=0x02014b50) 800 err=UNZ_BADZIPFILE; 801 } 802 803 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) 804 err=UNZ_ERRNO; 805 806 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) 807 err=UNZ_ERRNO; 808 809 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) 810 err=UNZ_ERRNO; 811 812 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) 813 err=UNZ_ERRNO; 814 815 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) 816 err=UNZ_ERRNO; 817 818 unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); 819 820 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) 821 err=UNZ_ERRNO; 822 823 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) 824 err=UNZ_ERRNO; 825 file_info.compressed_size = uL; 826 827 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) 828 err=UNZ_ERRNO; 829 file_info.uncompressed_size = uL; 830 831 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) 832 err=UNZ_ERRNO; 833 834 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) 835 err=UNZ_ERRNO; 836 837 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) 838 err=UNZ_ERRNO; 839 840 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) 841 err=UNZ_ERRNO; 842 843 if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) 844 err=UNZ_ERRNO; 845 846 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) 847 err=UNZ_ERRNO; 848 849 // relative offset of local header 850 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) 851 err=UNZ_ERRNO; 852 file_info_internal.offset_curfile = uL; 853 854 lSeek+=file_info.size_filename; 855 if ((err==UNZ_OK) && (szFileName!=NULL)) 856 { 857 uLong uSizeRead ; 858 if (file_info.size_filename<fileNameBufferSize) 859 { 860 *(szFileName+file_info.size_filename)='\0'; 861 uSizeRead = file_info.size_filename; 862 } 863 else 864 uSizeRead = fileNameBufferSize; 865 866 if ((file_info.size_filename>0) && (fileNameBufferSize>0)) 867 if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) 868 err=UNZ_ERRNO; 869 lSeek -= uSizeRead; 870 } 871 872 // Read extrafield 873 if ((err==UNZ_OK) && (extraField!=NULL)) 874 { 875 ZPOS64_T uSizeRead ; 876 if (file_info.size_file_extra<extraFieldBufferSize) 877 uSizeRead = file_info.size_file_extra; 878 else 879 uSizeRead = extraFieldBufferSize; 880 881 if (lSeek!=0) 882 { 883 if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 884 lSeek=0; 885 else 886 err=UNZ_ERRNO; 887 } 888 889 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) 890 if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) 891 err=UNZ_ERRNO; 892 893 lSeek += file_info.size_file_extra - (uLong)uSizeRead; 894 } 895 else 896 lSeek += file_info.size_file_extra; 897 898 899 if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) 900 { 901 uLong acc = 0; 902 903 // since lSeek now points to after the extra field we need to move back 904 lSeek -= file_info.size_file_extra; 905 906 if (lSeek!=0) 907 { 908 if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 909 lSeek=0; 910 else 911 err=UNZ_ERRNO; 912 } 913 914 while(acc < file_info.size_file_extra) 915 { 916 uLong headerId; 917 uLong dataSize; 918 919 if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) 920 err=UNZ_ERRNO; 921 922 if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) 923 err=UNZ_ERRNO; 924 925 /* ZIP64 extra fields */ 926 if (headerId == 0x0001) 927 { 928 if(file_info.uncompressed_size == MAXU32) 929 { 930 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) 931 err=UNZ_ERRNO; 932 } 933 934 if(file_info.compressed_size == MAXU32) 935 { 936 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) 937 err=UNZ_ERRNO; 938 } 939 940 if(file_info_internal.offset_curfile == MAXU32) 941 { 942 /* Relative Header offset */ 943 if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) 944 err=UNZ_ERRNO; 945 } 946 947 if(file_info.disk_num_start == 0xffff) 948 { 949 /* Disk Start Number */ 950 if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) 951 err=UNZ_ERRNO; 952 } 953 954 } 955 else 956 { 957 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) 958 err=UNZ_ERRNO; 959 } 960 961 acc += 2 + 2 + dataSize; 962 } 963 } 964 965 if ((err==UNZ_OK) && (szComment!=NULL)) 966 { 967 uLong uSizeRead ; 968 if (file_info.size_file_comment<commentBufferSize) 969 { 970 *(szComment+file_info.size_file_comment)='\0'; 971 uSizeRead = file_info.size_file_comment; 972 } 973 else 974 uSizeRead = commentBufferSize; 975 976 if (lSeek!=0) 977 { 978 if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 979 lSeek=0; 980 else 981 err=UNZ_ERRNO; 982 } 983 984 if ((file_info.size_file_comment>0) && (commentBufferSize>0)) 985 if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) 986 err=UNZ_ERRNO; 987 lSeek+=file_info.size_file_comment - uSizeRead; 988 } 989 else 990 lSeek+=file_info.size_file_comment; 991 992 993 if ((err==UNZ_OK) && (pfile_info!=NULL)) 994 *pfile_info=file_info; 995 996 if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) 997 *pfile_info_internal=file_info_internal; 998 999 return err; 1000 } 1001 1002 1003 1004 /* 1005 Write info about the ZipFile in the *pglobal_info structure. 1006 No preparation of the structure is needed 1007 return UNZ_OK if there is no problem. 1008 */ 1009 extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, 1010 unz_file_info64 * pfile_info, 1011 char * szFileName, uLong fileNameBufferSize, 1012 void *extraField, uLong extraFieldBufferSize, 1013 char* szComment, uLong commentBufferSize) { 1014 return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, 1015 szFileName,fileNameBufferSize, 1016 extraField,extraFieldBufferSize, 1017 szComment,commentBufferSize); 1018 } 1019 1020 extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, 1021 unz_file_info * pfile_info, 1022 char * szFileName, uLong fileNameBufferSize, 1023 void *extraField, uLong extraFieldBufferSize, 1024 char* szComment, uLong commentBufferSize) { 1025 int err; 1026 unz_file_info64 file_info64; 1027 err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, 1028 szFileName,fileNameBufferSize, 1029 extraField,extraFieldBufferSize, 1030 szComment,commentBufferSize); 1031 if ((err==UNZ_OK) && (pfile_info != NULL)) 1032 { 1033 pfile_info->version = file_info64.version; 1034 pfile_info->version_needed = file_info64.version_needed; 1035 pfile_info->flag = file_info64.flag; 1036 pfile_info->compression_method = file_info64.compression_method; 1037 pfile_info->dosDate = file_info64.dosDate; 1038 pfile_info->crc = file_info64.crc; 1039 1040 pfile_info->size_filename = file_info64.size_filename; 1041 pfile_info->size_file_extra = file_info64.size_file_extra; 1042 pfile_info->size_file_comment = file_info64.size_file_comment; 1043 1044 pfile_info->disk_num_start = file_info64.disk_num_start; 1045 pfile_info->internal_fa = file_info64.internal_fa; 1046 pfile_info->external_fa = file_info64.external_fa; 1047 1048 pfile_info->tmu_date = file_info64.tmu_date; 1049 1050 1051 pfile_info->compressed_size = (uLong)file_info64.compressed_size; 1052 pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; 1053 1054 } 1055 return err; 1056 } 1057 /* 1058 Set the current file of the zipfile to the first file. 1059 return UNZ_OK if there is no problem 1060 */ 1061 extern int ZEXPORT unzGoToFirstFile(unzFile file) { 1062 int err=UNZ_OK; 1063 unz64_s* s; 1064 if (file==NULL) 1065 return UNZ_PARAMERROR; 1066 s=(unz64_s*)file; 1067 s->pos_in_central_dir=s->offset_central_dir; 1068 s->num_file=0; 1069 err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, 1070 &s->cur_file_info_internal, 1071 NULL,0,NULL,0,NULL,0); 1072 s->current_file_ok = (err == UNZ_OK); 1073 return err; 1074 } 1075 1076 /* 1077 Set the current file of the zipfile to the next file. 1078 return UNZ_OK if there is no problem 1079 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. 1080 */ 1081 extern int ZEXPORT unzGoToNextFile(unzFile file) { 1082 unz64_s* s; 1083 int err; 1084 1085 if (file==NULL) 1086 return UNZ_PARAMERROR; 1087 s=(unz64_s*)file; 1088 if (!s->current_file_ok) 1089 return UNZ_END_OF_LIST_OF_FILE; 1090 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ 1091 if (s->num_file+1==s->gi.number_entry) 1092 return UNZ_END_OF_LIST_OF_FILE; 1093 1094 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + 1095 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; 1096 s->num_file++; 1097 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, 1098 &s->cur_file_info_internal, 1099 NULL,0,NULL,0,NULL,0); 1100 s->current_file_ok = (err == UNZ_OK); 1101 return err; 1102 } 1103 1104 1105 /* 1106 Try locate the file szFileName in the zipfile. 1107 For the iCaseSensitivity signification, see unzStringFileNameCompare 1108 1109 return value : 1110 UNZ_OK if the file is found. It becomes the current file. 1111 UNZ_END_OF_LIST_OF_FILE if the file is not found 1112 */ 1113 extern int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity) { 1114 unz64_s* s; 1115 int err; 1116 1117 /* We remember the 'current' position in the file so that we can jump 1118 * back there if we fail. 1119 */ 1120 unz_file_info64 cur_file_infoSaved; 1121 unz_file_info64_internal cur_file_info_internalSaved; 1122 ZPOS64_T num_fileSaved; 1123 ZPOS64_T pos_in_central_dirSaved; 1124 1125 1126 if (file==NULL) 1127 return UNZ_PARAMERROR; 1128 1129 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) 1130 return UNZ_PARAMERROR; 1131 1132 s=(unz64_s*)file; 1133 if (!s->current_file_ok) 1134 return UNZ_END_OF_LIST_OF_FILE; 1135 1136 /* Save the current state */ 1137 num_fileSaved = s->num_file; 1138 pos_in_central_dirSaved = s->pos_in_central_dir; 1139 cur_file_infoSaved = s->cur_file_info; 1140 cur_file_info_internalSaved = s->cur_file_info_internal; 1141 1142 err = unzGoToFirstFile(file); 1143 1144 while (err == UNZ_OK) 1145 { 1146 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; 1147 err = unzGetCurrentFileInfo64(file,NULL, 1148 szCurrentFileName,sizeof(szCurrentFileName)-1, 1149 NULL,0,NULL,0); 1150 if (err == UNZ_OK) 1151 { 1152 if (unzStringFileNameCompare(szCurrentFileName, 1153 szFileName,iCaseSensitivity)==0) 1154 return UNZ_OK; 1155 err = unzGoToNextFile(file); 1156 } 1157 } 1158 1159 /* We failed, so restore the state of the 'current file' to where we 1160 * were. 1161 */ 1162 s->num_file = num_fileSaved ; 1163 s->pos_in_central_dir = pos_in_central_dirSaved ; 1164 s->cur_file_info = cur_file_infoSaved; 1165 s->cur_file_info_internal = cur_file_info_internalSaved; 1166 return err; 1167 } 1168 1169 1170 /* 1171 /////////////////////////////////////////// 1172 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) 1173 // I need random access 1174 // 1175 // Further optimization could be realized by adding an ability 1176 // to cache the directory in memory. The goal being a single 1177 // comprehensive file read to put the file I need in a memory. 1178 */ 1179 1180 /* 1181 typedef struct unz_file_pos_s 1182 { 1183 ZPOS64_T pos_in_zip_directory; // offset in file 1184 ZPOS64_T num_of_file; // # of file 1185 } unz_file_pos; 1186 */ 1187 1188 extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) { 1189 unz64_s* s; 1190 1191 if (file==NULL || file_pos==NULL) 1192 return UNZ_PARAMERROR; 1193 s=(unz64_s*)file; 1194 if (!s->current_file_ok) 1195 return UNZ_END_OF_LIST_OF_FILE; 1196 1197 file_pos->pos_in_zip_directory = s->pos_in_central_dir; 1198 file_pos->num_of_file = s->num_file; 1199 1200 return UNZ_OK; 1201 } 1202 1203 extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos* file_pos) { 1204 unz64_file_pos file_pos64; 1205 int err = unzGetFilePos64(file,&file_pos64); 1206 if (err==UNZ_OK) 1207 { 1208 file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; 1209 file_pos->num_of_file = (uLong)file_pos64.num_of_file; 1210 } 1211 return err; 1212 } 1213 1214 extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) { 1215 unz64_s* s; 1216 int err; 1217 1218 if (file==NULL || file_pos==NULL) 1219 return UNZ_PARAMERROR; 1220 s=(unz64_s*)file; 1221 1222 /* jump to the right spot */ 1223 s->pos_in_central_dir = file_pos->pos_in_zip_directory; 1224 s->num_file = file_pos->num_of_file; 1225 1226 /* set the current file */ 1227 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, 1228 &s->cur_file_info_internal, 1229 NULL,0,NULL,0,NULL,0); 1230 /* return results */ 1231 s->current_file_ok = (err == UNZ_OK); 1232 return err; 1233 } 1234 1235 extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos* file_pos) { 1236 unz64_file_pos file_pos64; 1237 if (file_pos == NULL) 1238 return UNZ_PARAMERROR; 1239 1240 file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; 1241 file_pos64.num_of_file = file_pos->num_of_file; 1242 return unzGoToFilePos64(file,&file_pos64); 1243 } 1244 1245 /* 1246 // Unzip Helper Functions - should be here? 1247 /////////////////////////////////////////// 1248 */ 1249 1250 /* 1251 Read the local header of the current zipfile 1252 Check the coherency of the local header and info in the end of central 1253 directory about this file 1254 store in *piSizeVar the size of extra info in local header 1255 (filename and size of extra field data) 1256 */ 1257 local int unz64local_CheckCurrentFileCoherencyHeader(unz64_s* s, uInt* piSizeVar, 1258 ZPOS64_T * poffset_local_extrafield, 1259 uInt * psize_local_extrafield) { 1260 uLong uMagic,uData,uFlags; 1261 uLong size_filename; 1262 uLong size_extra_field; 1263 int err=UNZ_OK; 1264 1265 *piSizeVar = 0; 1266 *poffset_local_extrafield = 0; 1267 *psize_local_extrafield = 0; 1268 1269 if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + 1270 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) 1271 return UNZ_ERRNO; 1272 1273 1274 if (err==UNZ_OK) 1275 { 1276 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) 1277 err=UNZ_ERRNO; 1278 else if (uMagic!=0x04034b50) 1279 err=UNZ_BADZIPFILE; 1280 } 1281 1282 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) 1283 err=UNZ_ERRNO; 1284 /* 1285 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) 1286 err=UNZ_BADZIPFILE; 1287 */ 1288 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) 1289 err=UNZ_ERRNO; 1290 1291 if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) 1292 err=UNZ_ERRNO; 1293 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) 1294 err=UNZ_BADZIPFILE; 1295 1296 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && 1297 /* #ifdef HAVE_BZIP2 */ 1298 (s->cur_file_info.compression_method!=Z_BZIP2ED) && 1299 /* #endif */ 1300 (s->cur_file_info.compression_method!=Z_DEFLATED)) 1301 err=UNZ_BADZIPFILE; 1302 1303 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ 1304 err=UNZ_ERRNO; 1305 1306 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ 1307 err=UNZ_ERRNO; 1308 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) 1309 err=UNZ_BADZIPFILE; 1310 1311 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ 1312 err=UNZ_ERRNO; 1313 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) 1314 err=UNZ_BADZIPFILE; 1315 1316 if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ 1317 err=UNZ_ERRNO; 1318 else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) 1319 err=UNZ_BADZIPFILE; 1320 1321 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) 1322 err=UNZ_ERRNO; 1323 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) 1324 err=UNZ_BADZIPFILE; 1325 1326 *piSizeVar += (uInt)size_filename; 1327 1328 if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) 1329 err=UNZ_ERRNO; 1330 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + 1331 SIZEZIPLOCALHEADER + size_filename; 1332 *psize_local_extrafield = (uInt)size_extra_field; 1333 1334 *piSizeVar += (uInt)size_extra_field; 1335 1336 return err; 1337 } 1338 1339 /* 1340 Open for reading data the current file in the zipfile. 1341 If there is no error and the file is opened, the return value is UNZ_OK. 1342 */ 1343 extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method, 1344 int* level, int raw, const char* password) { 1345 int err=UNZ_OK; 1346 uInt iSizeVar; 1347 unz64_s* s; 1348 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1349 ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ 1350 uInt size_local_extrafield; /* size of the local extra field */ 1351 # ifndef NOUNCRYPT 1352 char source[12]; 1353 # else 1354 if (password != NULL) 1355 return UNZ_PARAMERROR; 1356 # endif 1357 1358 if (file==NULL) 1359 return UNZ_PARAMERROR; 1360 s=(unz64_s*)file; 1361 if (!s->current_file_ok) 1362 return UNZ_PARAMERROR; 1363 1364 if (s->pfile_in_zip_read != NULL) 1365 unzCloseCurrentFile(file); 1366 1367 if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) 1368 return UNZ_BADZIPFILE; 1369 1370 pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); 1371 if (pfile_in_zip_read_info==NULL) 1372 return UNZ_INTERNALERROR; 1373 1374 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); 1375 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; 1376 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; 1377 pfile_in_zip_read_info->pos_local_extrafield=0; 1378 pfile_in_zip_read_info->raw=raw; 1379 1380 if (pfile_in_zip_read_info->read_buffer==NULL) 1381 { 1382 free(pfile_in_zip_read_info); 1383 return UNZ_INTERNALERROR; 1384 } 1385 1386 pfile_in_zip_read_info->stream_initialised=0; 1387 1388 if (method!=NULL) 1389 *method = (int)s->cur_file_info.compression_method; 1390 1391 if (level!=NULL) 1392 { 1393 *level = 6; 1394 switch (s->cur_file_info.flag & 0x06) 1395 { 1396 case 6 : *level = 1; break; 1397 case 4 : *level = 2; break; 1398 case 2 : *level = 9; break; 1399 } 1400 } 1401 1402 if ((s->cur_file_info.compression_method!=0) && 1403 /* #ifdef HAVE_BZIP2 */ 1404 (s->cur_file_info.compression_method!=Z_BZIP2ED) && 1405 /* #endif */ 1406 (s->cur_file_info.compression_method!=Z_DEFLATED)) 1407 1408 err=UNZ_BADZIPFILE; 1409 1410 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; 1411 pfile_in_zip_read_info->crc32=0; 1412 pfile_in_zip_read_info->total_out_64=0; 1413 pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; 1414 pfile_in_zip_read_info->filestream=s->filestream; 1415 pfile_in_zip_read_info->z_filefunc=s->z_filefunc; 1416 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; 1417 1418 pfile_in_zip_read_info->stream.total_out = 0; 1419 1420 if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) 1421 { 1422 #ifdef HAVE_BZIP2 1423 pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; 1424 pfile_in_zip_read_info->bstream.bzfree = (free_func)0; 1425 pfile_in_zip_read_info->bstream.opaque = (voidpf)0; 1426 pfile_in_zip_read_info->bstream.state = (voidpf)0; 1427 1428 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; 1429 pfile_in_zip_read_info->stream.zfree = (free_func)0; 1430 pfile_in_zip_read_info->stream.opaque = (voidpf)0; 1431 pfile_in_zip_read_info->stream.next_in = (voidpf)0; 1432 pfile_in_zip_read_info->stream.avail_in = 0; 1433 1434 err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); 1435 if (err == Z_OK) 1436 pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; 1437 else 1438 { 1439 free(pfile_in_zip_read_info->read_buffer); 1440 free(pfile_in_zip_read_info); 1441 return err; 1442 } 1443 #else 1444 pfile_in_zip_read_info->raw=1; 1445 #endif 1446 } 1447 else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) 1448 { 1449 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; 1450 pfile_in_zip_read_info->stream.zfree = (free_func)0; 1451 pfile_in_zip_read_info->stream.opaque = (voidpf)0; 1452 pfile_in_zip_read_info->stream.next_in = 0; 1453 pfile_in_zip_read_info->stream.avail_in = 0; 1454 1455 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); 1456 if (err == Z_OK) 1457 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; 1458 else 1459 { 1460 free(pfile_in_zip_read_info->read_buffer); 1461 free(pfile_in_zip_read_info); 1462 return err; 1463 } 1464 /* windowBits is passed < 0 to tell that there is no zlib header. 1465 * Note that in this case inflate *requires* an extra "dummy" byte 1466 * after the compressed stream in order to complete decompression and 1467 * return Z_STREAM_END. 1468 * In unzip, i don't wait absolutely Z_STREAM_END because I known the 1469 * size of both compressed and uncompressed data 1470 */ 1471 } 1472 pfile_in_zip_read_info->rest_read_compressed = 1473 s->cur_file_info.compressed_size ; 1474 pfile_in_zip_read_info->rest_read_uncompressed = 1475 s->cur_file_info.uncompressed_size ; 1476 1477 1478 pfile_in_zip_read_info->pos_in_zipfile = 1479 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + 1480 iSizeVar; 1481 1482 pfile_in_zip_read_info->stream.avail_in = (uInt)0; 1483 1484 s->pfile_in_zip_read = pfile_in_zip_read_info; 1485 s->encrypted = 0; 1486 1487 # ifndef NOUNCRYPT 1488 if (password != NULL) 1489 { 1490 int i; 1491 s->pcrc_32_tab = get_crc_table(); 1492 init_keys(password,s->keys,s->pcrc_32_tab); 1493 if (ZSEEK64(s->z_filefunc, s->filestream, 1494 s->pfile_in_zip_read->pos_in_zipfile + 1495 s->pfile_in_zip_read->byte_before_the_zipfile, 1496 SEEK_SET)!=0) 1497 return UNZ_INTERNALERROR; 1498 if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) 1499 return UNZ_INTERNALERROR; 1500 1501 for (i = 0; i<12; i++) 1502 zdecode(s->keys,s->pcrc_32_tab,source[i]); 1503 1504 s->pfile_in_zip_read->pos_in_zipfile+=12; 1505 s->encrypted=1; 1506 } 1507 # endif 1508 1509 1510 return UNZ_OK; 1511 } 1512 1513 extern int ZEXPORT unzOpenCurrentFile(unzFile file) { 1514 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); 1515 } 1516 1517 extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char* password) { 1518 return unzOpenCurrentFile3(file, NULL, NULL, 0, password); 1519 } 1520 1521 extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int* method, int* level, int raw) { 1522 return unzOpenCurrentFile3(file, method, level, raw, NULL); 1523 } 1524 1525 /** Addition for GDAL : START */ 1526 1527 extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file) { 1528 unz64_s* s; 1529 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1530 s=(unz64_s*)file; 1531 if (file==NULL) 1532 return 0; //UNZ_PARAMERROR; 1533 pfile_in_zip_read_info=s->pfile_in_zip_read; 1534 if (pfile_in_zip_read_info==NULL) 1535 return 0; //UNZ_PARAMERROR; 1536 return pfile_in_zip_read_info->pos_in_zipfile + 1537 pfile_in_zip_read_info->byte_before_the_zipfile; 1538 } 1539 1540 /** Addition for GDAL : END */ 1541 1542 /* 1543 Read bytes from the current file. 1544 buf contain buffer where data must be copied 1545 len the size of buf. 1546 1547 return the number of byte copied if some bytes are copied 1548 return 0 if the end of file was reached 1549 return <0 with error code if there is an error 1550 (UNZ_ERRNO for IO error, or zLib error for uncompress error) 1551 */ 1552 extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len) { 1553 int err=UNZ_OK; 1554 uInt iRead = 0; 1555 unz64_s* s; 1556 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1557 if (file==NULL) 1558 return UNZ_PARAMERROR; 1559 s=(unz64_s*)file; 1560 pfile_in_zip_read_info=s->pfile_in_zip_read; 1561 1562 if (pfile_in_zip_read_info==NULL) 1563 return UNZ_PARAMERROR; 1564 1565 1566 if (pfile_in_zip_read_info->read_buffer == NULL) 1567 return UNZ_END_OF_LIST_OF_FILE; 1568 if (len==0) 1569 return 0; 1570 1571 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; 1572 1573 pfile_in_zip_read_info->stream.avail_out = (uInt)len; 1574 1575 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && 1576 (!(pfile_in_zip_read_info->raw))) 1577 pfile_in_zip_read_info->stream.avail_out = 1578 (uInt)pfile_in_zip_read_info->rest_read_uncompressed; 1579 1580 if ((len>pfile_in_zip_read_info->rest_read_compressed+ 1581 pfile_in_zip_read_info->stream.avail_in) && 1582 (pfile_in_zip_read_info->raw)) 1583 pfile_in_zip_read_info->stream.avail_out = 1584 (uInt)pfile_in_zip_read_info->rest_read_compressed+ 1585 pfile_in_zip_read_info->stream.avail_in; 1586 1587 while (pfile_in_zip_read_info->stream.avail_out>0) 1588 { 1589 if ((pfile_in_zip_read_info->stream.avail_in==0) && 1590 (pfile_in_zip_read_info->rest_read_compressed>0)) 1591 { 1592 uInt uReadThis = UNZ_BUFSIZE; 1593 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis) 1594 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; 1595 if (uReadThis == 0) 1596 return UNZ_EOF; 1597 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, 1598 pfile_in_zip_read_info->filestream, 1599 pfile_in_zip_read_info->pos_in_zipfile + 1600 pfile_in_zip_read_info->byte_before_the_zipfile, 1601 ZLIB_FILEFUNC_SEEK_SET)!=0) 1602 return UNZ_ERRNO; 1603 if (ZREAD64(pfile_in_zip_read_info->z_filefunc, 1604 pfile_in_zip_read_info->filestream, 1605 pfile_in_zip_read_info->read_buffer, 1606 uReadThis)!=uReadThis) 1607 return UNZ_ERRNO; 1608 1609 1610 # ifndef NOUNCRYPT 1611 if(s->encrypted) 1612 { 1613 uInt i; 1614 for(i=0;i<uReadThis;i++) 1615 pfile_in_zip_read_info->read_buffer[i] = 1616 zdecode(s->keys,s->pcrc_32_tab, 1617 pfile_in_zip_read_info->read_buffer[i]); 1618 } 1619 # endif 1620 1621 1622 pfile_in_zip_read_info->pos_in_zipfile += uReadThis; 1623 1624 pfile_in_zip_read_info->rest_read_compressed-=uReadThis; 1625 1626 pfile_in_zip_read_info->stream.next_in = 1627 (Bytef*)pfile_in_zip_read_info->read_buffer; 1628 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; 1629 } 1630 1631 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) 1632 { 1633 uInt uDoCopy,i ; 1634 1635 if ((pfile_in_zip_read_info->stream.avail_in == 0) && 1636 (pfile_in_zip_read_info->rest_read_compressed == 0)) 1637 return (iRead==0) ? UNZ_EOF : (int)iRead; 1638 1639 if (pfile_in_zip_read_info->stream.avail_out < 1640 pfile_in_zip_read_info->stream.avail_in) 1641 uDoCopy = pfile_in_zip_read_info->stream.avail_out ; 1642 else 1643 uDoCopy = pfile_in_zip_read_info->stream.avail_in ; 1644 1645 for (i=0;i<uDoCopy;i++) 1646 *(pfile_in_zip_read_info->stream.next_out+i) = 1647 *(pfile_in_zip_read_info->stream.next_in+i); 1648 1649 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; 1650 1651 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, 1652 pfile_in_zip_read_info->stream.next_out, 1653 uDoCopy); 1654 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; 1655 pfile_in_zip_read_info->stream.avail_in -= uDoCopy; 1656 pfile_in_zip_read_info->stream.avail_out -= uDoCopy; 1657 pfile_in_zip_read_info->stream.next_out += uDoCopy; 1658 pfile_in_zip_read_info->stream.next_in += uDoCopy; 1659 pfile_in_zip_read_info->stream.total_out += uDoCopy; 1660 iRead += uDoCopy; 1661 } 1662 else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) 1663 { 1664 #ifdef HAVE_BZIP2 1665 uLong uTotalOutBefore,uTotalOutAfter; 1666 const Bytef *bufBefore; 1667 uLong uOutThis; 1668 1669 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; 1670 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; 1671 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; 1672 pfile_in_zip_read_info->bstream.total_in_hi32 = 0; 1673 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; 1674 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; 1675 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; 1676 pfile_in_zip_read_info->bstream.total_out_hi32 = 0; 1677 1678 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; 1679 bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; 1680 1681 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); 1682 1683 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; 1684 uOutThis = uTotalOutAfter-uTotalOutBefore; 1685 1686 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; 1687 1688 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); 1689 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; 1690 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); 1691 1692 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; 1693 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; 1694 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; 1695 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; 1696 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; 1697 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; 1698 1699 if (err==BZ_STREAM_END) 1700 return (iRead==0) ? UNZ_EOF : iRead; 1701 if (err!=BZ_OK) 1702 break; 1703 #endif 1704 } // end Z_BZIP2ED 1705 else 1706 { 1707 ZPOS64_T uTotalOutBefore,uTotalOutAfter; 1708 const Bytef *bufBefore; 1709 ZPOS64_T uOutThis; 1710 int flush=Z_SYNC_FLUSH; 1711 1712 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; 1713 bufBefore = pfile_in_zip_read_info->stream.next_out; 1714 1715 /* 1716 if ((pfile_in_zip_read_info->rest_read_uncompressed == 1717 pfile_in_zip_read_info->stream.avail_out) && 1718 (pfile_in_zip_read_info->rest_read_compressed == 0)) 1719 flush = Z_FINISH; 1720 */ 1721 err=inflate(&pfile_in_zip_read_info->stream,flush); 1722 1723 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) 1724 err = Z_DATA_ERROR; 1725 1726 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; 1727 /* Detect overflow, because z_stream.total_out is uLong (32 bits) */ 1728 if (uTotalOutAfter<uTotalOutBefore) 1729 uTotalOutAfter += 1LL << 32; /* Add maximum value of uLong + 1 */ 1730 uOutThis = uTotalOutAfter-uTotalOutBefore; 1731 1732 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; 1733 1734 pfile_in_zip_read_info->crc32 = 1735 crc32(pfile_in_zip_read_info->crc32,bufBefore, 1736 (uInt)(uOutThis)); 1737 1738 pfile_in_zip_read_info->rest_read_uncompressed -= 1739 uOutThis; 1740 1741 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); 1742 1743 if (err==Z_STREAM_END) 1744 return (iRead==0) ? UNZ_EOF : (int)iRead; 1745 if (err!=Z_OK) 1746 break; 1747 } 1748 } 1749 1750 if (err==Z_OK) 1751 return (int)iRead; 1752 return err; 1753 } 1754 1755 1756 /* 1757 Give the current position in uncompressed data 1758 */ 1759 extern z_off_t ZEXPORT unztell(unzFile file) { 1760 unz64_s* s; 1761 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1762 if (file==NULL) 1763 return UNZ_PARAMERROR; 1764 s=(unz64_s*)file; 1765 pfile_in_zip_read_info=s->pfile_in_zip_read; 1766 1767 if (pfile_in_zip_read_info==NULL) 1768 return UNZ_PARAMERROR; 1769 1770 return (z_off_t)pfile_in_zip_read_info->stream.total_out; 1771 } 1772 1773 extern ZPOS64_T ZEXPORT unztell64(unzFile file) { 1774 1775 unz64_s* s; 1776 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1777 if (file==NULL) 1778 return (ZPOS64_T)-1; 1779 s=(unz64_s*)file; 1780 pfile_in_zip_read_info=s->pfile_in_zip_read; 1781 1782 if (pfile_in_zip_read_info==NULL) 1783 return (ZPOS64_T)-1; 1784 1785 return pfile_in_zip_read_info->total_out_64; 1786 } 1787 1788 1789 /* 1790 return 1 if the end of file was reached, 0 elsewhere 1791 */ 1792 extern int ZEXPORT unzeof(unzFile file) { 1793 unz64_s* s; 1794 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1795 if (file==NULL) 1796 return UNZ_PARAMERROR; 1797 s=(unz64_s*)file; 1798 pfile_in_zip_read_info=s->pfile_in_zip_read; 1799 1800 if (pfile_in_zip_read_info==NULL) 1801 return UNZ_PARAMERROR; 1802 1803 if (pfile_in_zip_read_info->rest_read_uncompressed == 0) 1804 return 1; 1805 else 1806 return 0; 1807 } 1808 1809 1810 1811 /* 1812 Read extra field from the current file (opened by unzOpenCurrentFile) 1813 This is the local-header version of the extra field (sometimes, there is 1814 more info in the local-header version than in the central-header) 1815 1816 if buf==NULL, it return the size of the local extra field that can be read 1817 1818 if buf!=NULL, len is the size of the buffer, the extra header is copied in 1819 buf. 1820 the return value is the number of bytes copied in buf, or (if <0) 1821 the error code 1822 */ 1823 extern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len) { 1824 unz64_s* s; 1825 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1826 uInt read_now; 1827 ZPOS64_T size_to_read; 1828 1829 if (file==NULL) 1830 return UNZ_PARAMERROR; 1831 s=(unz64_s*)file; 1832 pfile_in_zip_read_info=s->pfile_in_zip_read; 1833 1834 if (pfile_in_zip_read_info==NULL) 1835 return UNZ_PARAMERROR; 1836 1837 size_to_read = (pfile_in_zip_read_info->size_local_extrafield - 1838 pfile_in_zip_read_info->pos_local_extrafield); 1839 1840 if (buf==NULL) 1841 return (int)size_to_read; 1842 1843 if (len>size_to_read) 1844 read_now = (uInt)size_to_read; 1845 else 1846 read_now = (uInt)len ; 1847 1848 if (read_now==0) 1849 return 0; 1850 1851 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, 1852 pfile_in_zip_read_info->filestream, 1853 pfile_in_zip_read_info->offset_local_extrafield + 1854 pfile_in_zip_read_info->pos_local_extrafield, 1855 ZLIB_FILEFUNC_SEEK_SET)!=0) 1856 return UNZ_ERRNO; 1857 1858 if (ZREAD64(pfile_in_zip_read_info->z_filefunc, 1859 pfile_in_zip_read_info->filestream, 1860 buf,read_now)!=read_now) 1861 return UNZ_ERRNO; 1862 1863 return (int)read_now; 1864 } 1865 1866 /* 1867 Close the file in zip opened with unzOpenCurrentFile 1868 Return UNZ_CRCERROR if all the file was read but the CRC is not good 1869 */ 1870 extern int ZEXPORT unzCloseCurrentFile(unzFile file) { 1871 int err=UNZ_OK; 1872 1873 unz64_s* s; 1874 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1875 if (file==NULL) 1876 return UNZ_PARAMERROR; 1877 s=(unz64_s*)file; 1878 pfile_in_zip_read_info=s->pfile_in_zip_read; 1879 1880 if (pfile_in_zip_read_info==NULL) 1881 return UNZ_PARAMERROR; 1882 1883 1884 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && 1885 (!pfile_in_zip_read_info->raw)) 1886 { 1887 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) 1888 err=UNZ_CRCERROR; 1889 } 1890 1891 1892 free(pfile_in_zip_read_info->read_buffer); 1893 pfile_in_zip_read_info->read_buffer = NULL; 1894 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) 1895 inflateEnd(&pfile_in_zip_read_info->stream); 1896 #ifdef HAVE_BZIP2 1897 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) 1898 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); 1899 #endif 1900 1901 1902 pfile_in_zip_read_info->stream_initialised = 0; 1903 free(pfile_in_zip_read_info); 1904 1905 s->pfile_in_zip_read=NULL; 1906 1907 return err; 1908 } 1909 1910 1911 /* 1912 Get the global comment string of the ZipFile, in the szComment buffer. 1913 uSizeBuf is the size of the szComment buffer. 1914 return the number of byte copied or an error code <0 1915 */ 1916 extern int ZEXPORT unzGetGlobalComment(unzFile file, char * szComment, uLong uSizeBuf) { 1917 unz64_s* s; 1918 uLong uReadThis ; 1919 if (file==NULL) 1920 return (int)UNZ_PARAMERROR; 1921 s=(unz64_s*)file; 1922 1923 uReadThis = uSizeBuf; 1924 if (uReadThis>s->gi.size_comment) 1925 uReadThis = s->gi.size_comment; 1926 1927 if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) 1928 return UNZ_ERRNO; 1929 1930 if (uReadThis>0) 1931 { 1932 *szComment='\0'; 1933 if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) 1934 return UNZ_ERRNO; 1935 } 1936 1937 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) 1938 *(szComment+s->gi.size_comment)='\0'; 1939 return (int)uReadThis; 1940 } 1941 1942 /* Additions by RX '2004 */ 1943 extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) { 1944 unz64_s* s; 1945 1946 if (file==NULL) 1947 return 0; //UNZ_PARAMERROR; 1948 s=(unz64_s*)file; 1949 if (!s->current_file_ok) 1950 return 0; 1951 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) 1952 if (s->num_file==s->gi.number_entry) 1953 return 0; 1954 return s->pos_in_central_dir; 1955 } 1956 1957 extern uLong ZEXPORT unzGetOffset(unzFile file) { 1958 ZPOS64_T offset64; 1959 1960 if (file==NULL) 1961 return 0; //UNZ_PARAMERROR; 1962 offset64 = unzGetOffset64(file); 1963 return (uLong)offset64; 1964 } 1965 1966 extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) { 1967 unz64_s* s; 1968 int err; 1969 1970 if (file==NULL) 1971 return UNZ_PARAMERROR; 1972 s=(unz64_s*)file; 1973 1974 s->pos_in_central_dir = pos; 1975 s->num_file = s->gi.number_entry; /* hack */ 1976 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, 1977 &s->cur_file_info_internal, 1978 NULL,0,NULL,0,NULL,0); 1979 s->current_file_ok = (err == UNZ_OK); 1980 return err; 1981 } 1982 1983 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) { 1984 return unzSetOffset64(file,pos); 1985 } 1986