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