1 /* unzip.c -- IO for uncompress .zip files using zlib 2 Version 1.01e, February 12th, 2005 3 4 Copyright (C) 1998-2005 Gilles Vollant 5 6 Read unzip.h for more info 7 */ 8 9 /* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of 10 compatibility with older software. The following is from the original crypt.c. Code 11 woven in by Terry Thorsen 1/2003. 12 */ 13 /* 14 Copyright (c) 1990-2000 Info-ZIP. All rights reserved. 15 16 See the accompanying file LICENSE, version 2000-Apr-09 or later 17 (the contents of which are also included in zip.h) for terms of use. 18 If, for some reason, all these files are missing, the Info-ZIP license 19 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html 20 */ 21 /* 22 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] 23 24 The encryption/decryption parts of this source code (as opposed to the 25 non-echoing password parts) were originally written in Europe. The 26 whole source package can be freely distributed, including from the USA. 27 (Prior to January 2000, re-export from the US was a violation of US law.) 28 */ 29 30 /* 31 This encryption code is a direct transcription of the algorithm from 32 Roger Schlafly, described by Phil Katz in the file appnote.txt. This 33 file (appnote.txt) is distributed with the PKZIP program (even in the 34 version without encryption capabilities). 35 */ 36 37 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #if defined(USE_SYSTEM_ZLIB) 42 #include <zlib.h> 43 #else 44 #include "third_party/zlib/zlib.h" 45 #endif 46 #include "unzip.h" 47 48 #ifdef STDC 49 # include <stddef.h> 50 # include <string.h> 51 # include <stdlib.h> 52 #endif 53 #ifdef NO_ERRNO_H 54 extern int errno; 55 #else 56 # include <errno.h> 57 #endif 58 59 60 #ifndef local 61 # define local static 62 #endif 63 /* compile with -Dlocal if your debugger can't find static symbols */ 64 65 66 #ifndef CASESENSITIVITYDEFAULT_NO 67 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) 68 # define CASESENSITIVITYDEFAULT_NO 69 # endif 70 #endif 71 72 73 #ifndef UNZ_BUFSIZE 74 #define UNZ_BUFSIZE (16384) 75 #endif 76 77 #ifndef UNZ_MAXFILENAMEINZIP 78 #define UNZ_MAXFILENAMEINZIP (256) 79 #endif 80 81 #ifndef ALLOC 82 # define ALLOC(size) (malloc(size)) 83 #endif 84 #ifndef TRYFREE 85 # define TRYFREE(p) {if (p) free(p);} 86 #endif 87 88 #define SIZECENTRALDIRITEM (0x2e) 89 #define SIZEZIPLOCALHEADER (0x1e) 90 91 92 93 94 const char unz_copyright[] = 95 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; 96 97 /* unz_file_info_interntal contain internal info about a file in zipfile*/ 98 typedef struct unz_file_info_internal_s 99 { 100 uLong offset_curfile;/* relative offset of local header 4 bytes */ 101 } unz_file_info_internal; 102 103 104 /* file_in_zip_read_info_s contain internal information about a file in zipfile, 105 when reading and decompress it */ 106 typedef struct 107 { 108 char *read_buffer; /* internal buffer for compressed data */ 109 z_stream stream; /* zLib stream structure for inflate */ 110 111 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ 112 uLong stream_initialised; /* flag set if stream structure is initialised*/ 113 114 uLong offset_local_extrafield;/* offset of the local extra field */ 115 uInt size_local_extrafield;/* size of the local extra field */ 116 uLong pos_local_extrafield; /* position in the local extra field in read*/ 117 118 uLong crc32; /* crc32 of all data uncompressed */ 119 uLong crc32_wait; /* crc32 we must obtain after decompress all */ 120 uLong rest_read_compressed; /* number of byte to be decompressed */ 121 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ 122 zlib_filefunc_def z_filefunc; 123 voidpf filestream; /* io structore of the zipfile */ 124 uLong compression_method; /* compression method (0==store) */ 125 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 126 int raw; 127 } file_in_zip_read_info_s; 128 129 130 /* unz_s contain internal information about the zipfile 131 */ 132 typedef struct 133 { 134 zlib_filefunc_def z_filefunc; 135 voidpf filestream; /* io structore of the zipfile */ 136 unz_global_info gi; /* public global information */ 137 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 138 uLong num_file; /* number of the current file in the zipfile*/ 139 uLong pos_in_central_dir; /* pos of the current file in the central dir*/ 140 uLong current_file_ok; /* flag about the usability of the current file*/ 141 uLong central_pos; /* position of the beginning of the central dir*/ 142 143 uLong size_central_dir; /* size of the central directory */ 144 uLong offset_central_dir; /* offset of start of central directory with 145 respect to the starting disk number */ 146 147 unz_file_info cur_file_info; /* public info about the current file in zip*/ 148 unz_file_info_internal cur_file_info_internal; /* private info about it*/ 149 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current 150 file if we are decompressing it */ 151 int encrypted; 152 # ifndef NOUNCRYPT 153 unsigned long keys[3]; /* keys defining the pseudo-random sequence */ 154 const unsigned long* pcrc_32_tab; 155 # endif 156 } unz_s; 157 158 159 #ifndef NOUNCRYPT 160 #include "crypt.h" 161 #endif 162 163 /* =========================================================================== 164 Read a byte from a gz_stream; update next_in and avail_in. Return EOF 165 for end of file. 166 IN assertion: the stream s has been sucessfully opened for reading. 167 */ 168 169 170 local int unzlocal_getByte OF(( 171 const zlib_filefunc_def* pzlib_filefunc_def, 172 voidpf filestream, 173 int *pi)); 174 175 local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) 176 const zlib_filefunc_def* pzlib_filefunc_def; 177 voidpf filestream; 178 int *pi; 179 { 180 unsigned char c; 181 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); 182 if (err==1) 183 { 184 *pi = (int)c; 185 return UNZ_OK; 186 } 187 else 188 { 189 if (ZERROR(*pzlib_filefunc_def,filestream)) 190 return UNZ_ERRNO; 191 else 192 return UNZ_EOF; 193 } 194 } 195 196 197 /* =========================================================================== 198 Reads a long in LSB order from the given gz_stream. Sets 199 */ 200 local int unzlocal_getShort OF(( 201 const zlib_filefunc_def* pzlib_filefunc_def, 202 voidpf filestream, 203 uLong *pX)); 204 205 local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) 206 const zlib_filefunc_def* pzlib_filefunc_def; 207 voidpf filestream; 208 uLong *pX; 209 { 210 uLong x ; 211 int i; 212 int err; 213 214 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); 215 x = (uLong)i; 216 217 if (err==UNZ_OK) 218 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); 219 x += ((uLong)i)<<8; 220 221 if (err==UNZ_OK) 222 *pX = x; 223 else 224 *pX = 0; 225 return err; 226 } 227 228 local int unzlocal_getLong OF(( 229 const zlib_filefunc_def* pzlib_filefunc_def, 230 voidpf filestream, 231 uLong *pX)); 232 233 local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) 234 const zlib_filefunc_def* pzlib_filefunc_def; 235 voidpf filestream; 236 uLong *pX; 237 { 238 uLong x ; 239 int i; 240 int err; 241 242 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); 243 x = (uLong)i; 244 245 if (err==UNZ_OK) 246 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); 247 x += ((uLong)i)<<8; 248 249 if (err==UNZ_OK) 250 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); 251 x += ((uLong)i)<<16; 252 253 if (err==UNZ_OK) 254 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); 255 x += ((uLong)i)<<24; 256 257 if (err==UNZ_OK) 258 *pX = x; 259 else 260 *pX = 0; 261 return err; 262 } 263 264 265 /* My own strcmpi / strcasecmp */ 266 local int strcmpcasenosensitive_internal (fileName1,fileName2) 267 const char* fileName1; 268 const char* fileName2; 269 { 270 for (;;) 271 { 272 char c1=*(fileName1++); 273 char c2=*(fileName2++); 274 if ((c1>='a') && (c1<='z')) 275 c1 -= 0x20; 276 if ((c2>='a') && (c2<='z')) 277 c2 -= 0x20; 278 if (c1=='\0') 279 return ((c2=='\0') ? 0 : -1); 280 if (c2=='\0') 281 return 1; 282 if (c1<c2) 283 return -1; 284 if (c1>c2) 285 return 1; 286 } 287 } 288 289 290 #ifdef CASESENSITIVITYDEFAULT_NO 291 #define CASESENSITIVITYDEFAULTVALUE 2 292 #else 293 #define CASESENSITIVITYDEFAULTVALUE 1 294 #endif 295 296 #ifndef STRCMPCASENOSENTIVEFUNCTION 297 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal 298 #endif 299 300 /* 301 Compare two filename (fileName1,fileName2). 302 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) 303 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi 304 or strcasecmp) 305 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system 306 (like 1 on Unix, 2 on Windows) 307 308 */ 309 extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) 310 const char* fileName1; 311 const char* fileName2; 312 int iCaseSensitivity; 313 { 314 if (iCaseSensitivity==0) 315 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; 316 317 if (iCaseSensitivity==1) 318 return strcmp(fileName1,fileName2); 319 320 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); 321 } 322 323 #ifndef BUFREADCOMMENT 324 #define BUFREADCOMMENT (0x400) 325 #endif 326 327 /* 328 Locate the Central directory of a zipfile (at the end, just before 329 the global comment) 330 */ 331 local uLong unzlocal_SearchCentralDir OF(( 332 const zlib_filefunc_def* pzlib_filefunc_def, 333 voidpf filestream)); 334 335 local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) 336 const zlib_filefunc_def* pzlib_filefunc_def; 337 voidpf filestream; 338 { 339 unsigned char* buf; 340 uLong uSizeFile; 341 uLong uBackRead; 342 uLong uMaxBack=0xffff; /* maximum size of global comment */ 343 uLong uPosFound=0; 344 345 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 346 return 0; 347 348 349 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); 350 351 if (uMaxBack>uSizeFile) 352 uMaxBack = uSizeFile; 353 354 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 355 if (buf==NULL) 356 return 0; 357 358 uBackRead = 4; 359 while (uBackRead<uMaxBack) 360 { 361 uLong uReadSize,uReadPos ; 362 int i; 363 if (uBackRead+BUFREADCOMMENT>uMaxBack) 364 uBackRead = uMaxBack; 365 else 366 uBackRead+=BUFREADCOMMENT; 367 uReadPos = uSizeFile-uBackRead ; 368 369 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 370 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); 371 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 372 break; 373 374 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 375 break; 376 377 for (i=(int)uReadSize-3; (i--)>0;) 378 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 379 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) 380 { 381 uPosFound = uReadPos+i; 382 break; 383 } 384 385 if (uPosFound!=0) 386 break; 387 } 388 TRYFREE(buf); 389 return uPosFound; 390 } 391 392 /* 393 Open a Zip file. path contain the full pathname (by example, 394 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer 395 "zlib/zlib114.zip". 396 If the zipfile cannot be opened (file doesn't exist or in not valid), the 397 return value is NULL. 398 Else, the return value is a unzFile Handle, usable with other function 399 of this unzip package. 400 */ 401 extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) 402 const char *path; 403 zlib_filefunc_def* pzlib_filefunc_def; 404 { 405 unz_s us; 406 unz_s *s; 407 uLong central_pos,uL; 408 409 uLong number_disk; /* number of the current dist, used for 410 spaning ZIP, unsupported, always 0*/ 411 uLong number_disk_with_CD; /* number the the disk with central dir, used 412 for spaning ZIP, unsupported, always 0*/ 413 uLong number_entry_CD; /* total number of entries in 414 the central dir 415 (same than number_entry on nospan) */ 416 417 int err=UNZ_OK; 418 419 if (unz_copyright[0]!=' ') 420 return NULL; 421 422 if (pzlib_filefunc_def==NULL) 423 fill_fopen_filefunc(&us.z_filefunc); 424 else 425 us.z_filefunc = *pzlib_filefunc_def; 426 427 us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, 428 path, 429 ZLIB_FILEFUNC_MODE_READ | 430 ZLIB_FILEFUNC_MODE_EXISTING); 431 if (us.filestream==NULL) 432 return NULL; 433 434 central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); 435 if (central_pos==0) 436 err=UNZ_ERRNO; 437 438 if (ZSEEK(us.z_filefunc, us.filestream, 439 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) 440 err=UNZ_ERRNO; 441 442 /* the signature, already checked */ 443 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) 444 err=UNZ_ERRNO; 445 446 /* number of this disk */ 447 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) 448 err=UNZ_ERRNO; 449 450 /* number of the disk with the start of the central directory */ 451 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) 452 err=UNZ_ERRNO; 453 454 /* total number of entries in the central dir on this disk */ 455 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) 456 err=UNZ_ERRNO; 457 458 /* total number of entries in the central dir */ 459 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) 460 err=UNZ_ERRNO; 461 462 if ((number_entry_CD!=us.gi.number_entry) || 463 (number_disk_with_CD!=0) || 464 (number_disk!=0)) 465 err=UNZ_BADZIPFILE; 466 467 /* size of the central directory */ 468 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) 469 err=UNZ_ERRNO; 470 471 /* offset of start of central directory with respect to the 472 starting disk number */ 473 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) 474 err=UNZ_ERRNO; 475 476 /* zipfile comment length */ 477 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) 478 err=UNZ_ERRNO; 479 480 if ((central_pos<us.offset_central_dir+us.size_central_dir) && 481 (err==UNZ_OK)) 482 err=UNZ_BADZIPFILE; 483 484 if (err!=UNZ_OK) 485 { 486 ZCLOSE(us.z_filefunc, us.filestream); 487 return NULL; 488 } 489 490 us.byte_before_the_zipfile = central_pos - 491 (us.offset_central_dir+us.size_central_dir); 492 us.central_pos = central_pos; 493 us.pfile_in_zip_read = NULL; 494 us.encrypted = 0; 495 496 497 s=(unz_s*)ALLOC(sizeof(unz_s)); 498 *s=us; 499 unzGoToFirstFile((unzFile)s); 500 return (unzFile)s; 501 } 502 503 504 extern unzFile ZEXPORT unzOpen (path) 505 const char *path; 506 { 507 return unzOpen2(path, NULL); 508 } 509 510 /* 511 Close a ZipFile opened with unzipOpen. 512 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), 513 these files MUST be closed with unzipCloseCurrentFile before call unzipClose. 514 return UNZ_OK if there is no problem. */ 515 extern int ZEXPORT unzClose (file) 516 unzFile file; 517 { 518 unz_s* s; 519 if (file==NULL) 520 return UNZ_PARAMERROR; 521 s=(unz_s*)file; 522 523 if (s->pfile_in_zip_read!=NULL) 524 unzCloseCurrentFile(file); 525 526 ZCLOSE(s->z_filefunc, s->filestream); 527 TRYFREE(s); 528 return UNZ_OK; 529 } 530 531 532 /* 533 Write info about the ZipFile in the *pglobal_info structure. 534 No preparation of the structure is needed 535 return UNZ_OK if there is no problem. */ 536 extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) 537 unzFile file; 538 unz_global_info *pglobal_info; 539 { 540 unz_s* s; 541 if (file==NULL) 542 return UNZ_PARAMERROR; 543 s=(unz_s*)file; 544 *pglobal_info=s->gi; 545 return UNZ_OK; 546 } 547 548 549 /* 550 Translate date/time from Dos format to tm_unz (readable more easilty) 551 */ 552 local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) 553 uLong ulDosDate; 554 tm_unz* ptm; 555 { 556 uLong uDate; 557 uDate = (uLong)(ulDosDate>>16); 558 ptm->tm_mday = (uInt)(uDate&0x1f) ; 559 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; 560 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; 561 562 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); 563 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; 564 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; 565 } 566 567 /* 568 Get Info about the current file in the zipfile, with internal only info 569 */ 570 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, 571 unz_file_info *pfile_info, 572 unz_file_info_internal 573 *pfile_info_internal, 574 char *szFileName, 575 uLong fileNameBufferSize, 576 void *extraField, 577 uLong extraFieldBufferSize, 578 char *szComment, 579 uLong commentBufferSize)); 580 581 local int unzlocal_GetCurrentFileInfoInternal (file, 582 pfile_info, 583 pfile_info_internal, 584 szFileName, fileNameBufferSize, 585 extraField, extraFieldBufferSize, 586 szComment, commentBufferSize) 587 unzFile file; 588 unz_file_info *pfile_info; 589 unz_file_info_internal *pfile_info_internal; 590 char *szFileName; 591 uLong fileNameBufferSize; 592 void *extraField; 593 uLong extraFieldBufferSize; 594 char *szComment; 595 uLong commentBufferSize; 596 { 597 unz_s* s; 598 unz_file_info file_info; 599 unz_file_info_internal file_info_internal; 600 int err=UNZ_OK; 601 uLong uMagic; 602 long lSeek=0; 603 604 if (file==NULL) 605 return UNZ_PARAMERROR; 606 s=(unz_s*)file; 607 if (ZSEEK(s->z_filefunc, s->filestream, 608 s->pos_in_central_dir+s->byte_before_the_zipfile, 609 ZLIB_FILEFUNC_SEEK_SET)!=0) 610 err=UNZ_ERRNO; 611 612 613 /* we check the magic */ 614 if (err==UNZ_OK) { 615 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) 616 err=UNZ_ERRNO; 617 else if (uMagic!=0x02014b50) 618 err=UNZ_BADZIPFILE; 619 } 620 621 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) 622 err=UNZ_ERRNO; 623 624 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) 625 err=UNZ_ERRNO; 626 627 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) 628 err=UNZ_ERRNO; 629 630 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) 631 err=UNZ_ERRNO; 632 633 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) 634 err=UNZ_ERRNO; 635 636 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); 637 638 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) 639 err=UNZ_ERRNO; 640 641 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) 642 err=UNZ_ERRNO; 643 644 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) 645 err=UNZ_ERRNO; 646 647 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) 648 err=UNZ_ERRNO; 649 650 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) 651 err=UNZ_ERRNO; 652 653 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) 654 err=UNZ_ERRNO; 655 656 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) 657 err=UNZ_ERRNO; 658 659 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) 660 err=UNZ_ERRNO; 661 662 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) 663 err=UNZ_ERRNO; 664 665 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) 666 err=UNZ_ERRNO; 667 668 lSeek+=file_info.size_filename; 669 if ((err==UNZ_OK) && (szFileName!=NULL)) 670 { 671 uLong uSizeRead ; 672 if (file_info.size_filename<fileNameBufferSize) 673 { 674 *(szFileName+file_info.size_filename)='\0'; 675 uSizeRead = file_info.size_filename; 676 } 677 else 678 uSizeRead = fileNameBufferSize; 679 680 if ((file_info.size_filename>0) && (fileNameBufferSize>0)) 681 if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) 682 err=UNZ_ERRNO; 683 lSeek -= uSizeRead; 684 } 685 686 687 if ((err==UNZ_OK) && (extraField!=NULL)) 688 { 689 uLong uSizeRead ; 690 if (file_info.size_file_extra<extraFieldBufferSize) 691 uSizeRead = file_info.size_file_extra; 692 else 693 uSizeRead = extraFieldBufferSize; 694 695 if (lSeek!=0) { 696 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 697 lSeek=0; 698 else 699 err=UNZ_ERRNO; 700 } 701 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) 702 if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) 703 err=UNZ_ERRNO; 704 lSeek += file_info.size_file_extra - uSizeRead; 705 } 706 else 707 lSeek+=file_info.size_file_extra; 708 709 710 if ((err==UNZ_OK) && (szComment!=NULL)) 711 { 712 uLong uSizeRead ; 713 if (file_info.size_file_comment<commentBufferSize) 714 { 715 *(szComment+file_info.size_file_comment)='\0'; 716 uSizeRead = file_info.size_file_comment; 717 } 718 else 719 uSizeRead = commentBufferSize; 720 721 if (lSeek!=0) { 722 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) 723 lSeek=0; 724 else 725 err=UNZ_ERRNO; 726 } 727 if ((file_info.size_file_comment>0) && (commentBufferSize>0)) 728 if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) 729 err=UNZ_ERRNO; 730 lSeek+=file_info.size_file_comment - uSizeRead; 731 } 732 else 733 lSeek+=file_info.size_file_comment; 734 735 if ((err==UNZ_OK) && (pfile_info!=NULL)) 736 *pfile_info=file_info; 737 738 if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) 739 *pfile_info_internal=file_info_internal; 740 741 return err; 742 } 743 744 745 746 /* 747 Write info about the ZipFile in the *pglobal_info structure. 748 No preparation of the structure is needed 749 return UNZ_OK if there is no problem. 750 */ 751 extern int ZEXPORT unzGetCurrentFileInfo (file, 752 pfile_info, 753 szFileName, fileNameBufferSize, 754 extraField, extraFieldBufferSize, 755 szComment, commentBufferSize) 756 unzFile file; 757 unz_file_info *pfile_info; 758 char *szFileName; 759 uLong fileNameBufferSize; 760 void *extraField; 761 uLong extraFieldBufferSize; 762 char *szComment; 763 uLong commentBufferSize; 764 { 765 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, 766 szFileName,fileNameBufferSize, 767 extraField,extraFieldBufferSize, 768 szComment,commentBufferSize); 769 } 770 771 /* 772 Set the current file of the zipfile to the first file. 773 return UNZ_OK if there is no problem 774 */ 775 extern int ZEXPORT unzGoToFirstFile (file) 776 unzFile file; 777 { 778 int err=UNZ_OK; 779 unz_s* s; 780 if (file==NULL) 781 return UNZ_PARAMERROR; 782 s=(unz_s*)file; 783 s->pos_in_central_dir=s->offset_central_dir; 784 s->num_file=0; 785 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, 786 &s->cur_file_info_internal, 787 NULL,0,NULL,0,NULL,0); 788 s->current_file_ok = (err == UNZ_OK); 789 return err; 790 } 791 792 /* 793 Set the current file of the zipfile to the next file. 794 return UNZ_OK if there is no problem 795 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. 796 */ 797 extern int ZEXPORT unzGoToNextFile (file) 798 unzFile file; 799 { 800 unz_s* s; 801 int err; 802 803 if (file==NULL) 804 return UNZ_PARAMERROR; 805 s=(unz_s*)file; 806 if (!s->current_file_ok) 807 return UNZ_END_OF_LIST_OF_FILE; 808 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ 809 if (s->num_file+1==s->gi.number_entry) 810 return UNZ_END_OF_LIST_OF_FILE; 811 812 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + 813 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; 814 s->num_file++; 815 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, 816 &s->cur_file_info_internal, 817 NULL,0,NULL,0,NULL,0); 818 s->current_file_ok = (err == UNZ_OK); 819 return err; 820 } 821 822 823 /* 824 Try locate the file szFileName in the zipfile. 825 For the iCaseSensitivity signification, see unzipStringFileNameCompare 826 827 return value : 828 UNZ_OK if the file is found. It becomes the current file. 829 UNZ_END_OF_LIST_OF_FILE if the file is not found 830 */ 831 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) 832 unzFile file; 833 const char *szFileName; 834 int iCaseSensitivity; 835 { 836 unz_s* s; 837 int err; 838 839 /* We remember the 'current' position in the file so that we can jump 840 * back there if we fail. 841 */ 842 unz_file_info cur_file_infoSaved; 843 unz_file_info_internal cur_file_info_internalSaved; 844 uLong num_fileSaved; 845 uLong pos_in_central_dirSaved; 846 847 848 if (file==NULL) 849 return UNZ_PARAMERROR; 850 851 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) 852 return UNZ_PARAMERROR; 853 854 s=(unz_s*)file; 855 if (!s->current_file_ok) 856 return UNZ_END_OF_LIST_OF_FILE; 857 858 /* Save the current state */ 859 num_fileSaved = s->num_file; 860 pos_in_central_dirSaved = s->pos_in_central_dir; 861 cur_file_infoSaved = s->cur_file_info; 862 cur_file_info_internalSaved = s->cur_file_info_internal; 863 864 err = unzGoToFirstFile(file); 865 866 while (err == UNZ_OK) 867 { 868 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; 869 err = unzGetCurrentFileInfo(file,NULL, 870 szCurrentFileName,sizeof(szCurrentFileName)-1, 871 NULL,0,NULL,0); 872 if (err == UNZ_OK) 873 { 874 if (unzStringFileNameCompare(szCurrentFileName, 875 szFileName,iCaseSensitivity)==0) 876 return UNZ_OK; 877 err = unzGoToNextFile(file); 878 } 879 } 880 881 /* We failed, so restore the state of the 'current file' to where we 882 * were. 883 */ 884 s->num_file = num_fileSaved ; 885 s->pos_in_central_dir = pos_in_central_dirSaved ; 886 s->cur_file_info = cur_file_infoSaved; 887 s->cur_file_info_internal = cur_file_info_internalSaved; 888 return err; 889 } 890 891 892 /* 893 /////////////////////////////////////////// 894 // Contributed by Ryan Haksi (mailto://cryogen (at) infoserve.net) 895 // I need random access 896 // 897 // Further optimization could be realized by adding an ability 898 // to cache the directory in memory. The goal being a single 899 // comprehensive file read to put the file I need in a memory. 900 */ 901 902 /* 903 typedef struct unz_file_pos_s 904 { 905 uLong pos_in_zip_directory; // offset in file 906 uLong num_of_file; // # of file 907 } unz_file_pos; 908 */ 909 910 extern int ZEXPORT unzGetFilePos(file, file_pos) 911 unzFile file; 912 unz_file_pos* file_pos; 913 { 914 unz_s* s; 915 916 if (file==NULL || file_pos==NULL) 917 return UNZ_PARAMERROR; 918 s=(unz_s*)file; 919 if (!s->current_file_ok) 920 return UNZ_END_OF_LIST_OF_FILE; 921 922 file_pos->pos_in_zip_directory = s->pos_in_central_dir; 923 file_pos->num_of_file = s->num_file; 924 925 return UNZ_OK; 926 } 927 928 extern int ZEXPORT unzGoToFilePos(file, file_pos) 929 unzFile file; 930 unz_file_pos* file_pos; 931 { 932 unz_s* s; 933 int err; 934 935 if (file==NULL || file_pos==NULL) 936 return UNZ_PARAMERROR; 937 s=(unz_s*)file; 938 939 /* jump to the right spot */ 940 s->pos_in_central_dir = file_pos->pos_in_zip_directory; 941 s->num_file = file_pos->num_of_file; 942 943 /* set the current file */ 944 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, 945 &s->cur_file_info_internal, 946 NULL,0,NULL,0,NULL,0); 947 /* return results */ 948 s->current_file_ok = (err == UNZ_OK); 949 return err; 950 } 951 952 /* 953 // Unzip Helper Functions - should be here? 954 /////////////////////////////////////////// 955 */ 956 957 /* 958 Read the local header of the current zipfile 959 Check the coherency of the local header and info in the end of central 960 directory about this file 961 store in *piSizeVar the size of extra info in local header 962 (filename and size of extra field data) 963 */ 964 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, 965 poffset_local_extrafield, 966 psize_local_extrafield) 967 unz_s* s; 968 uInt* piSizeVar; 969 uLong *poffset_local_extrafield; 970 uInt *psize_local_extrafield; 971 { 972 uLong uMagic,uData,uFlags; 973 uLong size_filename; 974 uLong size_extra_field; 975 int err=UNZ_OK; 976 977 *piSizeVar = 0; 978 *poffset_local_extrafield = 0; 979 *psize_local_extrafield = 0; 980 981 if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + 982 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) 983 return UNZ_ERRNO; 984 985 986 if (err==UNZ_OK) { 987 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) 988 err=UNZ_ERRNO; 989 else if (uMagic!=0x04034b50) 990 err=UNZ_BADZIPFILE; 991 } 992 993 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) 994 err=UNZ_ERRNO; 995 /* 996 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) 997 err=UNZ_BADZIPFILE; 998 */ 999 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) 1000 err=UNZ_ERRNO; 1001 1002 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) 1003 err=UNZ_ERRNO; 1004 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) 1005 err=UNZ_BADZIPFILE; 1006 1007 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && 1008 (s->cur_file_info.compression_method!=Z_DEFLATED)) 1009 err=UNZ_BADZIPFILE; 1010 1011 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ 1012 err=UNZ_ERRNO; 1013 1014 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ 1015 err=UNZ_ERRNO; 1016 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && 1017 ((uFlags & 8)==0)) 1018 err=UNZ_BADZIPFILE; 1019 1020 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ 1021 err=UNZ_ERRNO; 1022 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && 1023 ((uFlags & 8)==0)) 1024 err=UNZ_BADZIPFILE; 1025 1026 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ 1027 err=UNZ_ERRNO; 1028 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && 1029 ((uFlags & 8)==0)) 1030 err=UNZ_BADZIPFILE; 1031 1032 1033 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) 1034 err=UNZ_ERRNO; 1035 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) 1036 err=UNZ_BADZIPFILE; 1037 1038 *piSizeVar += (uInt)size_filename; 1039 1040 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) 1041 err=UNZ_ERRNO; 1042 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + 1043 SIZEZIPLOCALHEADER + size_filename; 1044 *psize_local_extrafield = (uInt)size_extra_field; 1045 1046 *piSizeVar += (uInt)size_extra_field; 1047 1048 return err; 1049 } 1050 1051 /* 1052 Open for reading data the current file in the zipfile. 1053 If there is no error and the file is opened, the return value is UNZ_OK. 1054 */ 1055 extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password) 1056 unzFile file; 1057 int* method; 1058 int* level; 1059 int raw; 1060 const char* password; 1061 { 1062 int err=UNZ_OK; 1063 uInt iSizeVar; 1064 unz_s* s; 1065 file_in_zip_read_info_s* pfile_in_zip_read_info; 1066 uLong offset_local_extrafield; /* offset of the local extra field */ 1067 uInt size_local_extrafield; /* size of the local extra field */ 1068 # ifndef NOUNCRYPT 1069 char source[12]; 1070 # else 1071 if (password != NULL) 1072 return UNZ_PARAMERROR; 1073 # endif 1074 1075 if (file==NULL) 1076 return UNZ_PARAMERROR; 1077 s=(unz_s*)file; 1078 if (!s->current_file_ok) 1079 return UNZ_PARAMERROR; 1080 1081 if (s->pfile_in_zip_read != NULL) 1082 unzCloseCurrentFile(file); 1083 1084 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, 1085 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) 1086 return UNZ_BADZIPFILE; 1087 1088 pfile_in_zip_read_info = (file_in_zip_read_info_s*) 1089 ALLOC(sizeof(file_in_zip_read_info_s)); 1090 if (pfile_in_zip_read_info==NULL) 1091 return UNZ_INTERNALERROR; 1092 1093 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); 1094 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; 1095 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; 1096 pfile_in_zip_read_info->pos_local_extrafield=0; 1097 pfile_in_zip_read_info->raw=raw; 1098 1099 if (pfile_in_zip_read_info->read_buffer==NULL) 1100 { 1101 TRYFREE(pfile_in_zip_read_info); 1102 return UNZ_INTERNALERROR; 1103 } 1104 1105 pfile_in_zip_read_info->stream_initialised=0; 1106 1107 if (method!=NULL) 1108 *method = (int)s->cur_file_info.compression_method; 1109 1110 if (level!=NULL) 1111 { 1112 *level = 6; 1113 switch (s->cur_file_info.flag & 0x06) 1114 { 1115 case 6 : *level = 1; break; 1116 case 4 : *level = 2; break; 1117 case 2 : *level = 9; break; 1118 } 1119 } 1120 1121 if ((s->cur_file_info.compression_method!=0) && 1122 (s->cur_file_info.compression_method!=Z_DEFLATED)) 1123 err=UNZ_BADZIPFILE; 1124 1125 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; 1126 pfile_in_zip_read_info->crc32=0; 1127 pfile_in_zip_read_info->compression_method = 1128 s->cur_file_info.compression_method; 1129 pfile_in_zip_read_info->filestream=s->filestream; 1130 pfile_in_zip_read_info->z_filefunc=s->z_filefunc; 1131 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; 1132 1133 pfile_in_zip_read_info->stream.total_out = 0; 1134 1135 if ((s->cur_file_info.compression_method==Z_DEFLATED) && 1136 (!raw)) 1137 { 1138 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; 1139 pfile_in_zip_read_info->stream.zfree = (free_func)0; 1140 pfile_in_zip_read_info->stream.opaque = (voidpf)0; 1141 pfile_in_zip_read_info->stream.next_in = (voidpf)0; 1142 pfile_in_zip_read_info->stream.avail_in = 0; 1143 1144 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); 1145 if (err == Z_OK) 1146 pfile_in_zip_read_info->stream_initialised=1; 1147 else 1148 { 1149 TRYFREE(pfile_in_zip_read_info); 1150 return err; 1151 } 1152 /* windowBits is passed < 0 to tell that there is no zlib header. 1153 * Note that in this case inflate *requires* an extra "dummy" byte 1154 * after the compressed stream in order to complete decompression and 1155 * return Z_STREAM_END. 1156 * In unzip, i don't wait absolutely Z_STREAM_END because I known the 1157 * size of both compressed and uncompressed data 1158 */ 1159 } 1160 pfile_in_zip_read_info->rest_read_compressed = 1161 s->cur_file_info.compressed_size ; 1162 pfile_in_zip_read_info->rest_read_uncompressed = 1163 s->cur_file_info.uncompressed_size ; 1164 1165 1166 pfile_in_zip_read_info->pos_in_zipfile = 1167 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + 1168 iSizeVar; 1169 1170 pfile_in_zip_read_info->stream.avail_in = (uInt)0; 1171 1172 s->pfile_in_zip_read = pfile_in_zip_read_info; 1173 1174 # ifndef NOUNCRYPT 1175 if (password != NULL) 1176 { 1177 int i; 1178 s->pcrc_32_tab = get_crc_table(); 1179 init_keys(password,s->keys,s->pcrc_32_tab); 1180 if (ZSEEK(s->z_filefunc, s->filestream, 1181 s->pfile_in_zip_read->pos_in_zipfile + 1182 s->pfile_in_zip_read->byte_before_the_zipfile, 1183 SEEK_SET)!=0) 1184 return UNZ_INTERNALERROR; 1185 if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12) 1186 return UNZ_INTERNALERROR; 1187 1188 for (i = 0; i<12; i++) 1189 zdecode(s->keys,s->pcrc_32_tab,source[i]); 1190 1191 s->pfile_in_zip_read->pos_in_zipfile+=12; 1192 s->encrypted=1; 1193 } 1194 # endif 1195 1196 1197 return UNZ_OK; 1198 } 1199 1200 extern int ZEXPORT unzOpenCurrentFile (file) 1201 unzFile file; 1202 { 1203 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); 1204 } 1205 1206 extern int ZEXPORT unzOpenCurrentFilePassword (file, password) 1207 unzFile file; 1208 const char* password; 1209 { 1210 return unzOpenCurrentFile3(file, NULL, NULL, 0, password); 1211 } 1212 1213 extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw) 1214 unzFile file; 1215 int* method; 1216 int* level; 1217 int raw; 1218 { 1219 return unzOpenCurrentFile3(file, method, level, raw, NULL); 1220 } 1221 1222 /* 1223 Read bytes from the current file. 1224 buf contain buffer where data must be copied 1225 len the size of buf. 1226 1227 return the number of byte copied if somes bytes are copied 1228 return 0 if the end of file was reached 1229 return <0 with error code if there is an error 1230 (UNZ_ERRNO for IO error, or zLib error for uncompress error) 1231 */ 1232 extern int ZEXPORT unzReadCurrentFile (file, buf, len) 1233 unzFile file; 1234 voidp buf; 1235 unsigned len; 1236 { 1237 int err=UNZ_OK; 1238 uInt iRead = 0; 1239 unz_s* s; 1240 file_in_zip_read_info_s* pfile_in_zip_read_info; 1241 if (file==NULL) 1242 return UNZ_PARAMERROR; 1243 s=(unz_s*)file; 1244 pfile_in_zip_read_info=s->pfile_in_zip_read; 1245 1246 if (pfile_in_zip_read_info==NULL) 1247 return UNZ_PARAMERROR; 1248 1249 1250 if ((pfile_in_zip_read_info->read_buffer == NULL)) 1251 return UNZ_END_OF_LIST_OF_FILE; 1252 if (len==0) 1253 return 0; 1254 1255 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; 1256 1257 pfile_in_zip_read_info->stream.avail_out = (uInt)len; 1258 1259 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && 1260 (!(pfile_in_zip_read_info->raw))) 1261 pfile_in_zip_read_info->stream.avail_out = 1262 (uInt)pfile_in_zip_read_info->rest_read_uncompressed; 1263 1264 if ((len>pfile_in_zip_read_info->rest_read_compressed+ 1265 pfile_in_zip_read_info->stream.avail_in) && 1266 (pfile_in_zip_read_info->raw)) 1267 pfile_in_zip_read_info->stream.avail_out = 1268 (uInt)pfile_in_zip_read_info->rest_read_compressed+ 1269 pfile_in_zip_read_info->stream.avail_in; 1270 1271 while (pfile_in_zip_read_info->stream.avail_out>0) 1272 { 1273 if ((pfile_in_zip_read_info->stream.avail_in==0) && 1274 (pfile_in_zip_read_info->rest_read_compressed>0)) 1275 { 1276 uInt uReadThis = UNZ_BUFSIZE; 1277 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis) 1278 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; 1279 if (uReadThis == 0) 1280 return UNZ_EOF; 1281 if (ZSEEK(pfile_in_zip_read_info->z_filefunc, 1282 pfile_in_zip_read_info->filestream, 1283 pfile_in_zip_read_info->pos_in_zipfile + 1284 pfile_in_zip_read_info->byte_before_the_zipfile, 1285 ZLIB_FILEFUNC_SEEK_SET)!=0) 1286 return UNZ_ERRNO; 1287 if (ZREAD(pfile_in_zip_read_info->z_filefunc, 1288 pfile_in_zip_read_info->filestream, 1289 pfile_in_zip_read_info->read_buffer, 1290 uReadThis)!=uReadThis) 1291 return UNZ_ERRNO; 1292 1293 1294 # ifndef NOUNCRYPT 1295 if(s->encrypted) 1296 { 1297 uInt i; 1298 for(i=0;i<uReadThis;i++) 1299 pfile_in_zip_read_info->read_buffer[i] = 1300 zdecode(s->keys,s->pcrc_32_tab, 1301 pfile_in_zip_read_info->read_buffer[i]); 1302 } 1303 # endif 1304 1305 1306 pfile_in_zip_read_info->pos_in_zipfile += uReadThis; 1307 1308 pfile_in_zip_read_info->rest_read_compressed-=uReadThis; 1309 1310 pfile_in_zip_read_info->stream.next_in = 1311 (Bytef*)pfile_in_zip_read_info->read_buffer; 1312 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; 1313 } 1314 1315 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) 1316 { 1317 uInt uDoCopy,i ; 1318 1319 if ((pfile_in_zip_read_info->stream.avail_in == 0) && 1320 (pfile_in_zip_read_info->rest_read_compressed == 0)) 1321 return (iRead==0) ? UNZ_EOF : iRead; 1322 1323 if (pfile_in_zip_read_info->stream.avail_out < 1324 pfile_in_zip_read_info->stream.avail_in) 1325 uDoCopy = pfile_in_zip_read_info->stream.avail_out ; 1326 else 1327 uDoCopy = pfile_in_zip_read_info->stream.avail_in ; 1328 1329 for (i=0;i<uDoCopy;i++) 1330 *(pfile_in_zip_read_info->stream.next_out+i) = 1331 *(pfile_in_zip_read_info->stream.next_in+i); 1332 1333 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, 1334 pfile_in_zip_read_info->stream.next_out, 1335 uDoCopy); 1336 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; 1337 pfile_in_zip_read_info->stream.avail_in -= uDoCopy; 1338 pfile_in_zip_read_info->stream.avail_out -= uDoCopy; 1339 pfile_in_zip_read_info->stream.next_out += uDoCopy; 1340 pfile_in_zip_read_info->stream.next_in += uDoCopy; 1341 pfile_in_zip_read_info->stream.total_out += uDoCopy; 1342 iRead += uDoCopy; 1343 } 1344 else 1345 { 1346 uLong uTotalOutBefore,uTotalOutAfter; 1347 const Bytef *bufBefore; 1348 uLong uOutThis; 1349 int flush=Z_SYNC_FLUSH; 1350 1351 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; 1352 bufBefore = pfile_in_zip_read_info->stream.next_out; 1353 1354 /* 1355 if ((pfile_in_zip_read_info->rest_read_uncompressed == 1356 pfile_in_zip_read_info->stream.avail_out) && 1357 (pfile_in_zip_read_info->rest_read_compressed == 0)) 1358 flush = Z_FINISH; 1359 */ 1360 err=inflate(&pfile_in_zip_read_info->stream,flush); 1361 1362 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) 1363 err = Z_DATA_ERROR; 1364 1365 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; 1366 uOutThis = uTotalOutAfter-uTotalOutBefore; 1367 1368 pfile_in_zip_read_info->crc32 = 1369 crc32(pfile_in_zip_read_info->crc32,bufBefore, 1370 (uInt)(uOutThis)); 1371 1372 pfile_in_zip_read_info->rest_read_uncompressed -= 1373 uOutThis; 1374 1375 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); 1376 1377 if (err==Z_STREAM_END) 1378 return (iRead==0) ? UNZ_EOF : iRead; 1379 if (err!=Z_OK) 1380 break; 1381 } 1382 } 1383 1384 if (err==Z_OK) 1385 return iRead; 1386 return err; 1387 } 1388 1389 1390 /* 1391 Give the current position in uncompressed data 1392 */ 1393 extern z_off_t ZEXPORT unztell (file) 1394 unzFile file; 1395 { 1396 unz_s* s; 1397 file_in_zip_read_info_s* pfile_in_zip_read_info; 1398 if (file==NULL) 1399 return UNZ_PARAMERROR; 1400 s=(unz_s*)file; 1401 pfile_in_zip_read_info=s->pfile_in_zip_read; 1402 1403 if (pfile_in_zip_read_info==NULL) 1404 return UNZ_PARAMERROR; 1405 1406 return (z_off_t)pfile_in_zip_read_info->stream.total_out; 1407 } 1408 1409 1410 /* 1411 return 1 if the end of file was reached, 0 elsewhere 1412 */ 1413 extern int ZEXPORT unzeof (file) 1414 unzFile file; 1415 { 1416 unz_s* s; 1417 file_in_zip_read_info_s* pfile_in_zip_read_info; 1418 if (file==NULL) 1419 return UNZ_PARAMERROR; 1420 s=(unz_s*)file; 1421 pfile_in_zip_read_info=s->pfile_in_zip_read; 1422 1423 if (pfile_in_zip_read_info==NULL) 1424 return UNZ_PARAMERROR; 1425 1426 if (pfile_in_zip_read_info->rest_read_uncompressed == 0) 1427 return 1; 1428 else 1429 return 0; 1430 } 1431 1432 1433 1434 /* 1435 Read extra field from the current file (opened by unzOpenCurrentFile) 1436 This is the local-header version of the extra field (sometimes, there is 1437 more info in the local-header version than in the central-header) 1438 1439 if buf==NULL, it return the size of the local extra field that can be read 1440 1441 if buf!=NULL, len is the size of the buffer, the extra header is copied in 1442 buf. 1443 the return value is the number of bytes copied in buf, or (if <0) 1444 the error code 1445 */ 1446 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) 1447 unzFile file; 1448 voidp buf; 1449 unsigned len; 1450 { 1451 unz_s* s; 1452 file_in_zip_read_info_s* pfile_in_zip_read_info; 1453 uInt read_now; 1454 uLong size_to_read; 1455 1456 if (file==NULL) 1457 return UNZ_PARAMERROR; 1458 s=(unz_s*)file; 1459 pfile_in_zip_read_info=s->pfile_in_zip_read; 1460 1461 if (pfile_in_zip_read_info==NULL) 1462 return UNZ_PARAMERROR; 1463 1464 size_to_read = (pfile_in_zip_read_info->size_local_extrafield - 1465 pfile_in_zip_read_info->pos_local_extrafield); 1466 1467 if (buf==NULL) 1468 return (int)size_to_read; 1469 1470 if (len>size_to_read) 1471 read_now = (uInt)size_to_read; 1472 else 1473 read_now = (uInt)len ; 1474 1475 if (read_now==0) 1476 return 0; 1477 1478 if (ZSEEK(pfile_in_zip_read_info->z_filefunc, 1479 pfile_in_zip_read_info->filestream, 1480 pfile_in_zip_read_info->offset_local_extrafield + 1481 pfile_in_zip_read_info->pos_local_extrafield, 1482 ZLIB_FILEFUNC_SEEK_SET)!=0) 1483 return UNZ_ERRNO; 1484 1485 if (ZREAD(pfile_in_zip_read_info->z_filefunc, 1486 pfile_in_zip_read_info->filestream, 1487 buf,read_now)!=read_now) 1488 return UNZ_ERRNO; 1489 1490 return (int)read_now; 1491 } 1492 1493 /* 1494 Close the file in zip opened with unzipOpenCurrentFile 1495 Return UNZ_CRCERROR if all the file was read but the CRC is not good 1496 */ 1497 extern int ZEXPORT unzCloseCurrentFile (file) 1498 unzFile file; 1499 { 1500 int err=UNZ_OK; 1501 1502 unz_s* s; 1503 file_in_zip_read_info_s* pfile_in_zip_read_info; 1504 if (file==NULL) 1505 return UNZ_PARAMERROR; 1506 s=(unz_s*)file; 1507 pfile_in_zip_read_info=s->pfile_in_zip_read; 1508 1509 if (pfile_in_zip_read_info==NULL) 1510 return UNZ_PARAMERROR; 1511 1512 1513 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && 1514 (!pfile_in_zip_read_info->raw)) 1515 { 1516 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) 1517 err=UNZ_CRCERROR; 1518 } 1519 1520 1521 TRYFREE(pfile_in_zip_read_info->read_buffer); 1522 pfile_in_zip_read_info->read_buffer = NULL; 1523 if (pfile_in_zip_read_info->stream_initialised) 1524 inflateEnd(&pfile_in_zip_read_info->stream); 1525 1526 pfile_in_zip_read_info->stream_initialised = 0; 1527 TRYFREE(pfile_in_zip_read_info); 1528 1529 s->pfile_in_zip_read=NULL; 1530 1531 return err; 1532 } 1533 1534 1535 /* 1536 Get the global comment string of the ZipFile, in the szComment buffer. 1537 uSizeBuf is the size of the szComment buffer. 1538 return the number of byte copied or an error code <0 1539 */ 1540 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) 1541 unzFile file; 1542 char *szComment; 1543 uLong uSizeBuf; 1544 { 1545 //int err=UNZ_OK; 1546 unz_s* s; 1547 uLong uReadThis ; 1548 if (file==NULL) 1549 return UNZ_PARAMERROR; 1550 s=(unz_s*)file; 1551 1552 uReadThis = uSizeBuf; 1553 if (uReadThis>s->gi.size_comment) 1554 uReadThis = s->gi.size_comment; 1555 1556 if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) 1557 return UNZ_ERRNO; 1558 1559 if (uReadThis>0) 1560 { 1561 *szComment='\0'; 1562 if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) 1563 return UNZ_ERRNO; 1564 } 1565 1566 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) 1567 *(szComment+s->gi.size_comment)='\0'; 1568 return (int)uReadThis; 1569 } 1570 1571 /* Additions by RX '2004 */ 1572 extern uLong ZEXPORT unzGetOffset (file) 1573 unzFile file; 1574 { 1575 unz_s* s; 1576 1577 if (file==NULL) 1578 return UNZ_PARAMERROR; 1579 s=(unz_s*)file; 1580 if (!s->current_file_ok) 1581 return 0; 1582 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) 1583 if (s->num_file==s->gi.number_entry) 1584 return 0; 1585 return s->pos_in_central_dir; 1586 } 1587 1588 extern int ZEXPORT unzSetOffset (file, pos) 1589 unzFile file; 1590 uLong pos; 1591 { 1592 unz_s* s; 1593 int err; 1594 1595 if (file==NULL) 1596 return UNZ_PARAMERROR; 1597 s=(unz_s*)file; 1598 1599 s->pos_in_central_dir = pos; 1600 s->num_file = s->gi.number_entry; /* hack */ 1601 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, 1602 &s->cur_file_info_internal, 1603 NULL,0,NULL,0,NULL,0); 1604 s->current_file_ok = (err == UNZ_OK); 1605 return err; 1606 } 1607