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