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) { 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->read_buffer); 1575 TRYFREE(pfile_in_zip_read_info); 1576 return err; 1577 } 1578 #else 1579 pfile_in_zip_read_info->raw=1; 1580 #endif 1581 } 1582 else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) 1583 { 1584 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; 1585 pfile_in_zip_read_info->stream.zfree = (free_func)0; 1586 pfile_in_zip_read_info->stream.opaque = (voidpf)0; 1587 pfile_in_zip_read_info->stream.next_in = 0; 1588 pfile_in_zip_read_info->stream.avail_in = 0; 1589 1590 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); 1591 if (err == Z_OK) 1592 pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; 1593 else 1594 { 1595 TRYFREE(pfile_in_zip_read_info->read_buffer); 1596 TRYFREE(pfile_in_zip_read_info); 1597 return err; 1598 } 1599 /* windowBits is passed < 0 to tell that there is no zlib header. 1600 * Note that in this case inflate *requires* an extra "dummy" byte 1601 * after the compressed stream in order to complete decompression and 1602 * return Z_STREAM_END. 1603 * In unzip, i don't wait absolutely Z_STREAM_END because I known the 1604 * size of both compressed and uncompressed data 1605 */ 1606 } 1607 pfile_in_zip_read_info->rest_read_compressed = 1608 s->cur_file_info.compressed_size ; 1609 pfile_in_zip_read_info->rest_read_uncompressed = 1610 s->cur_file_info.uncompressed_size ; 1611 1612 1613 pfile_in_zip_read_info->pos_in_zipfile = 1614 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + 1615 iSizeVar; 1616 1617 pfile_in_zip_read_info->stream.avail_in = (uInt)0; 1618 1619 s->pfile_in_zip_read = pfile_in_zip_read_info; 1620 s->encrypted = 0; 1621 1622 # ifndef NOUNCRYPT 1623 if (password != NULL) 1624 { 1625 int i; 1626 s->pcrc_32_tab = get_crc_table(); 1627 init_keys(password,s->keys,s->pcrc_32_tab); 1628 if (ZSEEK64(s->z_filefunc, s->filestream, 1629 s->pfile_in_zip_read->pos_in_zipfile + 1630 s->pfile_in_zip_read->byte_before_the_zipfile, 1631 SEEK_SET)!=0) 1632 return UNZ_INTERNALERROR; 1633 if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) 1634 return UNZ_INTERNALERROR; 1635 1636 for (i = 0; i<12; i++) 1637 zdecode(s->keys,s->pcrc_32_tab,source[i]); 1638 1639 s->pfile_in_zip_read->pos_in_zipfile+=12; 1640 s->encrypted=1; 1641 } 1642 # endif 1643 1644 1645 return UNZ_OK; 1646 } 1647 1648 extern int ZEXPORT unzOpenCurrentFile (unzFile file) 1649 { 1650 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); 1651 } 1652 1653 extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) 1654 { 1655 return unzOpenCurrentFile3(file, NULL, NULL, 0, password); 1656 } 1657 1658 extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) 1659 { 1660 return unzOpenCurrentFile3(file, method, level, raw, NULL); 1661 } 1662 1663 /** Addition for GDAL : START */ 1664 1665 extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) 1666 { 1667 unz64_s* s; 1668 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1669 s=(unz64_s*)file; 1670 if (file==NULL) 1671 return 0; //UNZ_PARAMERROR; 1672 pfile_in_zip_read_info=s->pfile_in_zip_read; 1673 if (pfile_in_zip_read_info==NULL) 1674 return 0; //UNZ_PARAMERROR; 1675 return pfile_in_zip_read_info->pos_in_zipfile + 1676 pfile_in_zip_read_info->byte_before_the_zipfile; 1677 } 1678 1679 /** Addition for GDAL : END */ 1680 1681 /* 1682 Read bytes from the current file. 1683 buf contain buffer where data must be copied 1684 len the size of buf. 1685 1686 return the number of byte copied if somes bytes are copied 1687 return 0 if the end of file was reached 1688 return <0 with error code if there is an error 1689 (UNZ_ERRNO for IO error, or zLib error for uncompress error) 1690 */ 1691 extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) 1692 { 1693 int err=UNZ_OK; 1694 uInt iRead = 0; 1695 unz64_s* s; 1696 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1697 if (file==NULL) 1698 return UNZ_PARAMERROR; 1699 s=(unz64_s*)file; 1700 pfile_in_zip_read_info=s->pfile_in_zip_read; 1701 1702 if (pfile_in_zip_read_info==NULL) 1703 return UNZ_PARAMERROR; 1704 1705 1706 if (pfile_in_zip_read_info->read_buffer == NULL) 1707 return UNZ_END_OF_LIST_OF_FILE; 1708 if (len==0) 1709 return 0; 1710 1711 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; 1712 1713 pfile_in_zip_read_info->stream.avail_out = (uInt)len; 1714 1715 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && 1716 (!(pfile_in_zip_read_info->raw))) 1717 pfile_in_zip_read_info->stream.avail_out = 1718 (uInt)pfile_in_zip_read_info->rest_read_uncompressed; 1719 1720 if ((len>pfile_in_zip_read_info->rest_read_compressed+ 1721 pfile_in_zip_read_info->stream.avail_in) && 1722 (pfile_in_zip_read_info->raw)) 1723 pfile_in_zip_read_info->stream.avail_out = 1724 (uInt)pfile_in_zip_read_info->rest_read_compressed+ 1725 pfile_in_zip_read_info->stream.avail_in; 1726 1727 while (pfile_in_zip_read_info->stream.avail_out>0) 1728 { 1729 if ((pfile_in_zip_read_info->stream.avail_in==0) && 1730 (pfile_in_zip_read_info->rest_read_compressed>0)) 1731 { 1732 uInt uReadThis = UNZ_BUFSIZE; 1733 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis) 1734 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; 1735 if (uReadThis == 0) 1736 return UNZ_EOF; 1737 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, 1738 pfile_in_zip_read_info->filestream, 1739 pfile_in_zip_read_info->pos_in_zipfile + 1740 pfile_in_zip_read_info->byte_before_the_zipfile, 1741 ZLIB_FILEFUNC_SEEK_SET)!=0) 1742 return UNZ_ERRNO; 1743 if (ZREAD64(pfile_in_zip_read_info->z_filefunc, 1744 pfile_in_zip_read_info->filestream, 1745 pfile_in_zip_read_info->read_buffer, 1746 uReadThis)!=uReadThis) 1747 return UNZ_ERRNO; 1748 1749 1750 # ifndef NOUNCRYPT 1751 if(s->encrypted) 1752 { 1753 uInt i; 1754 for(i=0;i<uReadThis;i++) 1755 pfile_in_zip_read_info->read_buffer[i] = 1756 zdecode(s->keys,s->pcrc_32_tab, 1757 pfile_in_zip_read_info->read_buffer[i]); 1758 } 1759 # endif 1760 1761 1762 pfile_in_zip_read_info->pos_in_zipfile += uReadThis; 1763 1764 pfile_in_zip_read_info->rest_read_compressed-=uReadThis; 1765 1766 pfile_in_zip_read_info->stream.next_in = 1767 (Bytef*)pfile_in_zip_read_info->read_buffer; 1768 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; 1769 } 1770 1771 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) 1772 { 1773 uInt uDoCopy,i ; 1774 1775 if ((pfile_in_zip_read_info->stream.avail_in == 0) && 1776 (pfile_in_zip_read_info->rest_read_compressed == 0)) 1777 return (iRead==0) ? UNZ_EOF : (int)iRead; 1778 1779 if (pfile_in_zip_read_info->stream.avail_out < 1780 pfile_in_zip_read_info->stream.avail_in) 1781 uDoCopy = pfile_in_zip_read_info->stream.avail_out ; 1782 else 1783 uDoCopy = pfile_in_zip_read_info->stream.avail_in ; 1784 1785 for (i=0;i<uDoCopy;i++) 1786 *(pfile_in_zip_read_info->stream.next_out+i) = 1787 *(pfile_in_zip_read_info->stream.next_in+i); 1788 1789 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; 1790 1791 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, 1792 pfile_in_zip_read_info->stream.next_out, 1793 uDoCopy); 1794 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; 1795 pfile_in_zip_read_info->stream.avail_in -= uDoCopy; 1796 pfile_in_zip_read_info->stream.avail_out -= uDoCopy; 1797 pfile_in_zip_read_info->stream.next_out += uDoCopy; 1798 pfile_in_zip_read_info->stream.next_in += uDoCopy; 1799 pfile_in_zip_read_info->stream.total_out += uDoCopy; 1800 iRead += uDoCopy; 1801 } 1802 else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) 1803 { 1804 #ifdef HAVE_BZIP2 1805 uLong uTotalOutBefore,uTotalOutAfter; 1806 const Bytef *bufBefore; 1807 uLong uOutThis; 1808 1809 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; 1810 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; 1811 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; 1812 pfile_in_zip_read_info->bstream.total_in_hi32 = 0; 1813 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; 1814 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; 1815 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; 1816 pfile_in_zip_read_info->bstream.total_out_hi32 = 0; 1817 1818 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; 1819 bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; 1820 1821 err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); 1822 1823 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; 1824 uOutThis = uTotalOutAfter-uTotalOutBefore; 1825 1826 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; 1827 1828 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); 1829 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; 1830 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); 1831 1832 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; 1833 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; 1834 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; 1835 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; 1836 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; 1837 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; 1838 1839 if (err==BZ_STREAM_END) 1840 return (iRead==0) ? UNZ_EOF : iRead; 1841 if (err!=BZ_OK) 1842 break; 1843 #endif 1844 } // end Z_BZIP2ED 1845 else 1846 { 1847 ZPOS64_T uTotalOutBefore,uTotalOutAfter; 1848 const Bytef *bufBefore; 1849 ZPOS64_T uOutThis; 1850 int flush=Z_SYNC_FLUSH; 1851 1852 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; 1853 bufBefore = pfile_in_zip_read_info->stream.next_out; 1854 1855 /* 1856 if ((pfile_in_zip_read_info->rest_read_uncompressed == 1857 pfile_in_zip_read_info->stream.avail_out) && 1858 (pfile_in_zip_read_info->rest_read_compressed == 0)) 1859 flush = Z_FINISH; 1860 */ 1861 err=inflate(&pfile_in_zip_read_info->stream,flush); 1862 1863 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) 1864 err = Z_DATA_ERROR; 1865 1866 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; 1867 /* Detect overflow, because z_stream.total_out is uLong (32 bits) */ 1868 if (uTotalOutAfter<uTotalOutBefore) 1869 uTotalOutAfter += 1LL << 32; /* Add maximum value of uLong + 1 */ 1870 uOutThis = uTotalOutAfter-uTotalOutBefore; 1871 1872 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; 1873 1874 pfile_in_zip_read_info->crc32 = 1875 crc32(pfile_in_zip_read_info->crc32,bufBefore, 1876 (uInt)(uOutThis)); 1877 1878 pfile_in_zip_read_info->rest_read_uncompressed -= 1879 uOutThis; 1880 1881 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); 1882 1883 if (err==Z_STREAM_END) 1884 return (iRead==0) ? UNZ_EOF : (int)iRead; 1885 if (err!=Z_OK) 1886 break; 1887 } 1888 } 1889 1890 if (err==Z_OK) 1891 return (int)iRead; 1892 return err; 1893 } 1894 1895 1896 /* 1897 Give the current position in uncompressed data 1898 */ 1899 extern z_off_t ZEXPORT unztell (unzFile file) 1900 { 1901 unz64_s* s; 1902 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1903 if (file==NULL) 1904 return UNZ_PARAMERROR; 1905 s=(unz64_s*)file; 1906 pfile_in_zip_read_info=s->pfile_in_zip_read; 1907 1908 if (pfile_in_zip_read_info==NULL) 1909 return UNZ_PARAMERROR; 1910 1911 return (z_off_t)pfile_in_zip_read_info->stream.total_out; 1912 } 1913 1914 extern ZPOS64_T ZEXPORT unztell64 (unzFile file) 1915 { 1916 1917 unz64_s* s; 1918 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1919 if (file==NULL) 1920 return (ZPOS64_T)-1; 1921 s=(unz64_s*)file; 1922 pfile_in_zip_read_info=s->pfile_in_zip_read; 1923 1924 if (pfile_in_zip_read_info==NULL) 1925 return (ZPOS64_T)-1; 1926 1927 return pfile_in_zip_read_info->total_out_64; 1928 } 1929 1930 1931 /* 1932 return 1 if the end of file was reached, 0 elsewhere 1933 */ 1934 extern int ZEXPORT unzeof (unzFile file) 1935 { 1936 unz64_s* s; 1937 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1938 if (file==NULL) 1939 return UNZ_PARAMERROR; 1940 s=(unz64_s*)file; 1941 pfile_in_zip_read_info=s->pfile_in_zip_read; 1942 1943 if (pfile_in_zip_read_info==NULL) 1944 return UNZ_PARAMERROR; 1945 1946 if (pfile_in_zip_read_info->rest_read_uncompressed == 0) 1947 return 1; 1948 else 1949 return 0; 1950 } 1951 1952 1953 1954 /* 1955 Read extra field from the current file (opened by unzOpenCurrentFile) 1956 This is the local-header version of the extra field (sometimes, there is 1957 more info in the local-header version than in the central-header) 1958 1959 if buf==NULL, it return the size of the local extra field that can be read 1960 1961 if buf!=NULL, len is the size of the buffer, the extra header is copied in 1962 buf. 1963 the return value is the number of bytes copied in buf, or (if <0) 1964 the error code 1965 */ 1966 extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) 1967 { 1968 unz64_s* s; 1969 file_in_zip64_read_info_s* pfile_in_zip_read_info; 1970 uInt read_now; 1971 ZPOS64_T size_to_read; 1972 1973 if (file==NULL) 1974 return UNZ_PARAMERROR; 1975 s=(unz64_s*)file; 1976 pfile_in_zip_read_info=s->pfile_in_zip_read; 1977 1978 if (pfile_in_zip_read_info==NULL) 1979 return UNZ_PARAMERROR; 1980 1981 size_to_read = (pfile_in_zip_read_info->size_local_extrafield - 1982 pfile_in_zip_read_info->pos_local_extrafield); 1983 1984 if (buf==NULL) 1985 return (int)size_to_read; 1986 1987 if (len>size_to_read) 1988 read_now = (uInt)size_to_read; 1989 else 1990 read_now = (uInt)len ; 1991 1992 if (read_now==0) 1993 return 0; 1994 1995 if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, 1996 pfile_in_zip_read_info->filestream, 1997 pfile_in_zip_read_info->offset_local_extrafield + 1998 pfile_in_zip_read_info->pos_local_extrafield, 1999 ZLIB_FILEFUNC_SEEK_SET)!=0) 2000 return UNZ_ERRNO; 2001 2002 if (ZREAD64(pfile_in_zip_read_info->z_filefunc, 2003 pfile_in_zip_read_info->filestream, 2004 buf,read_now)!=read_now) 2005 return UNZ_ERRNO; 2006 2007 return (int)read_now; 2008 } 2009 2010 /* 2011 Close the file in zip opened with unzOpenCurrentFile 2012 Return UNZ_CRCERROR if all the file was read but the CRC is not good 2013 */ 2014 extern int ZEXPORT unzCloseCurrentFile (unzFile file) 2015 { 2016 int err=UNZ_OK; 2017 2018 unz64_s* s; 2019 file_in_zip64_read_info_s* pfile_in_zip_read_info; 2020 if (file==NULL) 2021 return UNZ_PARAMERROR; 2022 s=(unz64_s*)file; 2023 pfile_in_zip_read_info=s->pfile_in_zip_read; 2024 2025 if (pfile_in_zip_read_info==NULL) 2026 return UNZ_PARAMERROR; 2027 2028 2029 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && 2030 (!pfile_in_zip_read_info->raw)) 2031 { 2032 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) 2033 err=UNZ_CRCERROR; 2034 } 2035 2036 2037 TRYFREE(pfile_in_zip_read_info->read_buffer); 2038 pfile_in_zip_read_info->read_buffer = NULL; 2039 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) 2040 inflateEnd(&pfile_in_zip_read_info->stream); 2041 #ifdef HAVE_BZIP2 2042 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) 2043 BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); 2044 #endif 2045 2046 2047 pfile_in_zip_read_info->stream_initialised = 0; 2048 TRYFREE(pfile_in_zip_read_info); 2049 2050 s->pfile_in_zip_read=NULL; 2051 2052 return err; 2053 } 2054 2055 2056 /* 2057 Get the global comment string of the ZipFile, in the szComment buffer. 2058 uSizeBuf is the size of the szComment buffer. 2059 return the number of byte copied or an error code <0 2060 */ 2061 extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) 2062 { 2063 unz64_s* s; 2064 uLong uReadThis ; 2065 if (file==NULL) 2066 return (int)UNZ_PARAMERROR; 2067 s=(unz64_s*)file; 2068 2069 uReadThis = uSizeBuf; 2070 if (uReadThis>s->gi.size_comment) 2071 uReadThis = s->gi.size_comment; 2072 2073 if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) 2074 return UNZ_ERRNO; 2075 2076 if (uReadThis>0) 2077 { 2078 *szComment='\0'; 2079 if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) 2080 return UNZ_ERRNO; 2081 } 2082 2083 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) 2084 *(szComment+s->gi.size_comment)='\0'; 2085 return (int)uReadThis; 2086 } 2087 2088 /* Additions by RX '2004 */ 2089 extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) 2090 { 2091 unz64_s* s; 2092 2093 if (file==NULL) 2094 return 0; //UNZ_PARAMERROR; 2095 s=(unz64_s*)file; 2096 if (!s->current_file_ok) 2097 return 0; 2098 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) 2099 if (s->num_file==s->gi.number_entry) 2100 return 0; 2101 return s->pos_in_central_dir; 2102 } 2103 2104 extern uLong ZEXPORT unzGetOffset (unzFile file) 2105 { 2106 ZPOS64_T offset64; 2107 2108 if (file==NULL) 2109 return 0; //UNZ_PARAMERROR; 2110 offset64 = unzGetOffset64(file); 2111 return (uLong)offset64; 2112 } 2113 2114 extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) 2115 { 2116 unz64_s* s; 2117 int err; 2118 2119 if (file==NULL) 2120 return UNZ_PARAMERROR; 2121 s=(unz64_s*)file; 2122 2123 s->pos_in_central_dir = pos; 2124 s->num_file = s->gi.number_entry; /* hack */ 2125 err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, 2126 &s->cur_file_info_internal, 2127 NULL,0,NULL,0,NULL,0); 2128 s->current_file_ok = (err == UNZ_OK); 2129 return err; 2130 } 2131 2132 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) 2133 { 2134 return unzSetOffset64(file,pos); 2135 } 2136