1 /* zip.c -- IO on .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 for Zip64 support 8 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 9 10 For more info read MiniZip_info.txt 11 12 Changes 13 Oct-2009 - Mathias Svensson - Remove old C style function prototypes 14 Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives 15 Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. 16 Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data 17 It is used when recreating zip archive with RAW when deleting items from a zip. 18 ZIP64 data is automatically added to items that needs it, and existing ZIP64 data need to be removed. 19 Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) 20 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer 21 22 */ 23 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <stdint.h> 29 #include <time.h> 30 #include "zlib.h" 31 #include "zip.h" 32 33 #ifdef STDC 34 # include <stddef.h> 35 #endif 36 #ifdef NO_ERRNO_H 37 extern int errno; 38 #else 39 # include <errno.h> 40 #endif 41 42 43 #ifndef local 44 # define local static 45 #endif 46 /* compile with -Dlocal if your debugger can't find static symbols */ 47 48 #ifndef VERSIONMADEBY 49 # define VERSIONMADEBY (0x0) /* platform dependent */ 50 #endif 51 52 #ifndef Z_BUFSIZE 53 #define Z_BUFSIZE (64*1024) //(16384) 54 #endif 55 56 #ifndef Z_MAXFILENAMEINZIP 57 #define Z_MAXFILENAMEINZIP (256) 58 #endif 59 60 #ifndef ALLOC 61 # define ALLOC(size) (malloc(size)) 62 #endif 63 64 /* 65 #define SIZECENTRALDIRITEM (0x2e) 66 #define SIZEZIPLOCALHEADER (0x1e) 67 */ 68 69 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ 70 71 72 // NOT sure that this work on ALL platform 73 #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) 74 75 #ifndef SEEK_CUR 76 #define SEEK_CUR 1 77 #endif 78 79 #ifndef SEEK_END 80 #define SEEK_END 2 81 #endif 82 83 #ifndef SEEK_SET 84 #define SEEK_SET 0 85 #endif 86 87 #ifndef DEF_MEM_LEVEL 88 #if MAX_MEM_LEVEL >= 8 89 # define DEF_MEM_LEVEL 8 90 #else 91 # define DEF_MEM_LEVEL MAX_MEM_LEVEL 92 #endif 93 #endif 94 const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; 95 96 97 #define SIZEDATA_INDATABLOCK (4096-(4*4)) 98 99 #define LOCALHEADERMAGIC (0x04034b50) 100 #define CENTRALHEADERMAGIC (0x02014b50) 101 #define ENDHEADERMAGIC (0x06054b50) 102 #define ZIP64ENDHEADERMAGIC (0x6064b50) 103 #define ZIP64ENDLOCHEADERMAGIC (0x7064b50) 104 105 #define FLAG_LOCALHEADER_OFFSET (0x06) 106 #define CRC_LOCALHEADER_OFFSET (0x0e) 107 108 #define SIZECENTRALHEADER (0x2e) /* 46 */ 109 110 typedef struct linkedlist_datablock_internal_s 111 { 112 struct linkedlist_datablock_internal_s* next_datablock; 113 uLong avail_in_this_block; 114 uLong filled_in_this_block; 115 uLong unused; /* for future use and alignment */ 116 unsigned char data[SIZEDATA_INDATABLOCK]; 117 } linkedlist_datablock_internal; 118 119 typedef struct linkedlist_data_s 120 { 121 linkedlist_datablock_internal* first_block; 122 linkedlist_datablock_internal* last_block; 123 } linkedlist_data; 124 125 126 typedef struct 127 { 128 z_stream stream; /* zLib stream structure for inflate */ 129 #ifdef HAVE_BZIP2 130 bz_stream bstream; /* bzLib stream structure for bziped */ 131 #endif 132 133 int stream_initialised; /* 1 is stream is initialised */ 134 uInt pos_in_buffered_data; /* last written byte in buffered_data */ 135 136 ZPOS64_T pos_local_header; /* offset of the local header of the file 137 currently writing */ 138 char* central_header; /* central header data for the current file */ 139 uLong size_centralExtra; 140 uLong size_centralheader; /* size of the central header for cur file */ 141 uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ 142 uLong flag; /* flag of the file currently writing */ 143 144 int method; /* compression method of file currently wr.*/ 145 int raw; /* 1 for directly writing raw data */ 146 Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ 147 uLong dosDate; 148 uLong crc32; 149 int encrypt; 150 int zip64; /* Add ZIP64 extended information in the extra field */ 151 ZPOS64_T pos_zip64extrainfo; 152 ZPOS64_T totalCompressedData; 153 ZPOS64_T totalUncompressedData; 154 #ifndef NOCRYPT 155 unsigned long keys[3]; /* keys defining the pseudo-random sequence */ 156 const z_crc_t* pcrc_32_tab; 157 unsigned crypt_header_size; 158 #endif 159 } curfile64_info; 160 161 typedef struct 162 { 163 zlib_filefunc64_32_def z_filefunc; 164 voidpf filestream; /* io structure of the zipfile */ 165 linkedlist_data central_dir;/* datablock with central dir in construction*/ 166 int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ 167 curfile64_info ci; /* info on the file currently writing */ 168 169 ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ 170 ZPOS64_T add_position_when_writing_offset; 171 ZPOS64_T number_entry; 172 173 #ifndef NO_ADDFILEINEXISTINGZIP 174 char *globalcomment; 175 #endif 176 177 } zip64_internal; 178 179 180 #ifndef NOCRYPT 181 #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED 182 #include "crypt.h" 183 #endif 184 185 local linkedlist_datablock_internal* allocate_new_datablock(void) { 186 linkedlist_datablock_internal* ldi; 187 ldi = (linkedlist_datablock_internal*) 188 ALLOC(sizeof(linkedlist_datablock_internal)); 189 if (ldi!=NULL) 190 { 191 ldi->next_datablock = NULL ; 192 ldi->filled_in_this_block = 0 ; 193 ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; 194 } 195 return ldi; 196 } 197 198 local void free_datablock(linkedlist_datablock_internal* ldi) { 199 while (ldi!=NULL) 200 { 201 linkedlist_datablock_internal* ldinext = ldi->next_datablock; 202 free(ldi); 203 ldi = ldinext; 204 } 205 } 206 207 local void init_linkedlist(linkedlist_data* ll) { 208 ll->first_block = ll->last_block = NULL; 209 } 210 211 local void free_linkedlist(linkedlist_data* ll) { 212 free_datablock(ll->first_block); 213 ll->first_block = ll->last_block = NULL; 214 } 215 216 217 local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) { 218 linkedlist_datablock_internal* ldi; 219 const unsigned char* from_copy; 220 221 if (ll==NULL) 222 return ZIP_INTERNALERROR; 223 224 if (ll->last_block == NULL) 225 { 226 ll->first_block = ll->last_block = allocate_new_datablock(); 227 if (ll->first_block == NULL) 228 return ZIP_INTERNALERROR; 229 } 230 231 ldi = ll->last_block; 232 from_copy = (const unsigned char*)buf; 233 234 while (len>0) 235 { 236 uInt copy_this; 237 uInt i; 238 unsigned char* to_copy; 239 240 if (ldi->avail_in_this_block==0) 241 { 242 ldi->next_datablock = allocate_new_datablock(); 243 if (ldi->next_datablock == NULL) 244 return ZIP_INTERNALERROR; 245 ldi = ldi->next_datablock ; 246 ll->last_block = ldi; 247 } 248 249 if (ldi->avail_in_this_block < len) 250 copy_this = (uInt)ldi->avail_in_this_block; 251 else 252 copy_this = (uInt)len; 253 254 to_copy = &(ldi->data[ldi->filled_in_this_block]); 255 256 for (i=0;i<copy_this;i++) 257 *(to_copy+i)=*(from_copy+i); 258 259 ldi->filled_in_this_block += copy_this; 260 ldi->avail_in_this_block -= copy_this; 261 from_copy += copy_this ; 262 len -= copy_this; 263 } 264 return ZIP_OK; 265 } 266 267 268 269 /****************************************************************************/ 270 271 #ifndef NO_ADDFILEINEXISTINGZIP 272 /* =========================================================================== 273 Inputs a long in LSB order to the given file 274 nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) 275 */ 276 277 local int zip64local_putValue(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) { 278 unsigned char buf[8]; 279 int n; 280 for (n = 0; n < nbByte; n++) 281 { 282 buf[n] = (unsigned char)(x & 0xff); 283 x >>= 8; 284 } 285 if (x != 0) 286 { /* data overflow - hack for ZIP64 (X Roche) */ 287 for (n = 0; n < nbByte; n++) 288 { 289 buf[n] = 0xff; 290 } 291 } 292 293 if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,(uLong)nbByte)!=(uLong)nbByte) 294 return ZIP_ERRNO; 295 else 296 return ZIP_OK; 297 } 298 299 local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) { 300 unsigned char* buf=(unsigned char*)dest; 301 int n; 302 for (n = 0; n < nbByte; n++) { 303 buf[n] = (unsigned char)(x & 0xff); 304 x >>= 8; 305 } 306 307 if (x != 0) 308 { /* data overflow - hack for ZIP64 */ 309 for (n = 0; n < nbByte; n++) 310 { 311 buf[n] = 0xff; 312 } 313 } 314 } 315 316 /****************************************************************************/ 317 318 319 local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) { 320 uLong year = (uLong)ptm->tm_year; 321 if (year>=1980) 322 year-=1980; 323 else if (year>=80) 324 year-=80; 325 return 326 (uLong) (((uLong)(ptm->tm_mday) + (32 * (uLong)(ptm->tm_mon+1)) + (512 * year)) << 16) | 327 (((uLong)ptm->tm_sec/2) + (32 * (uLong)ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); 328 } 329 330 331 /****************************************************************************/ 332 333 local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int* pi) { 334 unsigned char c; 335 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); 336 if (err==1) 337 { 338 *pi = (int)c; 339 return ZIP_OK; 340 } 341 else 342 { 343 if (ZERROR64(*pzlib_filefunc_def,filestream)) 344 return ZIP_ERRNO; 345 else 346 return ZIP_EOF; 347 } 348 } 349 350 351 /* =========================================================================== 352 Reads a long in LSB order from the given gz_stream. Sets 353 */ 354 local int zip64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) { 355 uLong x ; 356 int i = 0; 357 int err; 358 359 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 360 x = (uLong)i; 361 362 if (err==ZIP_OK) 363 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 364 x += ((uLong)i)<<8; 365 366 if (err==ZIP_OK) 367 *pX = x; 368 else 369 *pX = 0; 370 return err; 371 } 372 373 local int zip64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) { 374 uLong x ; 375 int i = 0; 376 int err; 377 378 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 379 x = (uLong)i; 380 381 if (err==ZIP_OK) 382 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 383 x += ((uLong)i)<<8; 384 385 if (err==ZIP_OK) 386 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 387 x += ((uLong)i)<<16; 388 389 if (err==ZIP_OK) 390 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 391 x += ((uLong)i)<<24; 392 393 if (err==ZIP_OK) 394 *pX = x; 395 else 396 *pX = 0; 397 return err; 398 } 399 400 401 local int zip64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) { 402 ZPOS64_T x; 403 int i = 0; 404 int err; 405 406 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 407 x = (ZPOS64_T)i; 408 409 if (err==ZIP_OK) 410 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 411 x += ((ZPOS64_T)i)<<8; 412 413 if (err==ZIP_OK) 414 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 415 x += ((ZPOS64_T)i)<<16; 416 417 if (err==ZIP_OK) 418 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 419 x += ((ZPOS64_T)i)<<24; 420 421 if (err==ZIP_OK) 422 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 423 x += ((ZPOS64_T)i)<<32; 424 425 if (err==ZIP_OK) 426 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 427 x += ((ZPOS64_T)i)<<40; 428 429 if (err==ZIP_OK) 430 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 431 x += ((ZPOS64_T)i)<<48; 432 433 if (err==ZIP_OK) 434 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 435 x += ((ZPOS64_T)i)<<56; 436 437 if (err==ZIP_OK) 438 *pX = x; 439 else 440 *pX = 0; 441 442 return err; 443 } 444 445 #ifndef BUFREADCOMMENT 446 #define BUFREADCOMMENT (0x400) 447 #endif 448 /* 449 Locate the Central directory of a zipfile (at the end, just before 450 the global comment) 451 */ 452 local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { 453 unsigned char* buf; 454 ZPOS64_T uSizeFile; 455 ZPOS64_T uBackRead; 456 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ 457 ZPOS64_T uPosFound=0; 458 459 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 460 return 0; 461 462 463 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); 464 465 if (uMaxBack>uSizeFile) 466 uMaxBack = uSizeFile; 467 468 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 469 if (buf==NULL) 470 return 0; 471 472 uBackRead = 4; 473 while (uBackRead<uMaxBack) 474 { 475 uLong uReadSize; 476 ZPOS64_T uReadPos ; 477 int i; 478 if (uBackRead+BUFREADCOMMENT>uMaxBack) 479 uBackRead = uMaxBack; 480 else 481 uBackRead+=BUFREADCOMMENT; 482 uReadPos = uSizeFile-uBackRead ; 483 484 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 485 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); 486 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 487 break; 488 489 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 490 break; 491 492 for (i=(int)uReadSize-3; (i--)>0;) 493 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 494 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) 495 { 496 uPosFound = uReadPos+(unsigned)i; 497 break; 498 } 499 500 if (uPosFound!=0) 501 break; 502 } 503 free(buf); 504 return uPosFound; 505 } 506 507 /* 508 Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before 509 the global comment) 510 */ 511 local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { 512 unsigned char* buf; 513 ZPOS64_T uSizeFile; 514 ZPOS64_T uBackRead; 515 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ 516 ZPOS64_T uPosFound=0; 517 uLong uL; 518 ZPOS64_T relativeOffset; 519 520 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 521 return 0; 522 523 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); 524 525 if (uMaxBack>uSizeFile) 526 uMaxBack = uSizeFile; 527 528 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 529 if (buf==NULL) 530 return 0; 531 532 uBackRead = 4; 533 while (uBackRead<uMaxBack) 534 { 535 uLong uReadSize; 536 ZPOS64_T uReadPos; 537 int i; 538 if (uBackRead+BUFREADCOMMENT>uMaxBack) 539 uBackRead = uMaxBack; 540 else 541 uBackRead+=BUFREADCOMMENT; 542 uReadPos = uSizeFile-uBackRead ; 543 544 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 545 (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); 546 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 547 break; 548 549 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 550 break; 551 552 for (i=(int)uReadSize-3; (i--)>0;) 553 { 554 // Signature "0x07064b50" Zip64 end of central directory locater 555 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) 556 { 557 uPosFound = uReadPos+(unsigned)i; 558 break; 559 } 560 } 561 562 if (uPosFound!=0) 563 break; 564 } 565 566 free(buf); 567 if (uPosFound == 0) 568 return 0; 569 570 /* Zip64 end of central directory locator */ 571 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) 572 return 0; 573 574 /* the signature, already checked */ 575 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) 576 return 0; 577 578 /* number of the disk with the start of the zip64 end of central directory */ 579 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) 580 return 0; 581 if (uL != 0) 582 return 0; 583 584 /* relative offset of the zip64 end of central directory record */ 585 if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) 586 return 0; 587 588 /* total number of disks */ 589 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) 590 return 0; 591 if (uL != 1) 592 return 0; 593 594 /* Goto Zip64 end of central directory record */ 595 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) 596 return 0; 597 598 /* the signature */ 599 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) 600 return 0; 601 602 if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' 603 return 0; 604 605 return relativeOffset; 606 } 607 608 local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { 609 int err=ZIP_OK; 610 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 611 612 ZPOS64_T size_central_dir; /* size of the central directory */ 613 ZPOS64_T offset_central_dir; /* offset of start of central directory */ 614 ZPOS64_T central_pos; 615 uLong uL; 616 617 uLong number_disk; /* number of the current disk, used for 618 spanning ZIP, unsupported, always 0*/ 619 uLong number_disk_with_CD; /* number of the disk with central dir, used 620 for spanning ZIP, unsupported, always 0*/ 621 ZPOS64_T number_entry; 622 ZPOS64_T number_entry_CD; /* total number of entries in 623 the central dir 624 (same than number_entry on nospan) */ 625 uLong VersionMadeBy; 626 uLong VersionNeeded; 627 uLong size_comment; 628 629 int hasZIP64Record = 0; 630 631 // check first if we find a ZIP64 record 632 central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); 633 if(central_pos > 0) 634 { 635 hasZIP64Record = 1; 636 } 637 else if(central_pos == 0) 638 { 639 central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); 640 } 641 642 /* disable to allow appending to empty ZIP archive 643 if (central_pos==0) 644 err=ZIP_ERRNO; 645 */ 646 647 if(hasZIP64Record) 648 { 649 ZPOS64_T sizeEndOfCentralDirectory; 650 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) 651 err=ZIP_ERRNO; 652 653 /* the signature, already checked */ 654 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) 655 err=ZIP_ERRNO; 656 657 /* size of zip64 end of central directory record */ 658 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) 659 err=ZIP_ERRNO; 660 661 /* version made by */ 662 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) 663 err=ZIP_ERRNO; 664 665 /* version needed to extract */ 666 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) 667 err=ZIP_ERRNO; 668 669 /* number of this disk */ 670 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) 671 err=ZIP_ERRNO; 672 673 /* number of the disk with the start of the central directory */ 674 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) 675 err=ZIP_ERRNO; 676 677 /* total number of entries in the central directory on this disk */ 678 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) 679 err=ZIP_ERRNO; 680 681 /* total number of entries in the central directory */ 682 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) 683 err=ZIP_ERRNO; 684 685 if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) 686 err=ZIP_BADZIPFILE; 687 688 /* size of the central directory */ 689 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) 690 err=ZIP_ERRNO; 691 692 /* offset of start of central directory with respect to the 693 starting disk number */ 694 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) 695 err=ZIP_ERRNO; 696 697 // TODO.. 698 // read the comment from the standard central header. 699 size_comment = 0; 700 } 701 else 702 { 703 // Read End of central Directory info 704 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) 705 err=ZIP_ERRNO; 706 707 /* the signature, already checked */ 708 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) 709 err=ZIP_ERRNO; 710 711 /* number of this disk */ 712 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) 713 err=ZIP_ERRNO; 714 715 /* number of the disk with the start of the central directory */ 716 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) 717 err=ZIP_ERRNO; 718 719 /* total number of entries in the central dir on this disk */ 720 number_entry = 0; 721 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) 722 err=ZIP_ERRNO; 723 else 724 number_entry = uL; 725 726 /* total number of entries in the central dir */ 727 number_entry_CD = 0; 728 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) 729 err=ZIP_ERRNO; 730 else 731 number_entry_CD = uL; 732 733 if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) 734 err=ZIP_BADZIPFILE; 735 736 /* size of the central directory */ 737 size_central_dir = 0; 738 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) 739 err=ZIP_ERRNO; 740 else 741 size_central_dir = uL; 742 743 /* offset of start of central directory with respect to the starting disk number */ 744 offset_central_dir = 0; 745 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) 746 err=ZIP_ERRNO; 747 else 748 offset_central_dir = uL; 749 750 751 /* zipfile global comment length */ 752 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) 753 err=ZIP_ERRNO; 754 } 755 756 if ((central_pos<offset_central_dir+size_central_dir) && 757 (err==ZIP_OK)) 758 err=ZIP_BADZIPFILE; 759 760 if (err!=ZIP_OK) 761 { 762 ZCLOSE64(pziinit->z_filefunc, pziinit->filestream); 763 return ZIP_ERRNO; 764 } 765 766 if (size_comment>0) 767 { 768 pziinit->globalcomment = (char*)ALLOC(size_comment+1); 769 if (pziinit->globalcomment) 770 { 771 size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); 772 pziinit->globalcomment[size_comment]=0; 773 } 774 } 775 776 byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); 777 pziinit->add_position_when_writing_offset = byte_before_the_zipfile; 778 779 { 780 ZPOS64_T size_central_dir_to_read = size_central_dir; 781 size_t buf_size = SIZEDATA_INDATABLOCK; 782 void* buf_read = (void*)ALLOC(buf_size); 783 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) 784 err=ZIP_ERRNO; 785 786 while ((size_central_dir_to_read>0) && (err==ZIP_OK)) 787 { 788 ZPOS64_T read_this = SIZEDATA_INDATABLOCK; 789 if (read_this > size_central_dir_to_read) 790 read_this = size_central_dir_to_read; 791 792 if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) 793 err=ZIP_ERRNO; 794 795 if (err==ZIP_OK) 796 err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); 797 798 size_central_dir_to_read-=read_this; 799 } 800 free(buf_read); 801 } 802 pziinit->begin_pos = byte_before_the_zipfile; 803 pziinit->number_entry = number_entry_CD; 804 805 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) 806 err=ZIP_ERRNO; 807 808 return err; 809 } 810 811 812 #endif /* !NO_ADDFILEINEXISTINGZIP*/ 813 814 815 /************************************************************/ 816 extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) { 817 zip64_internal ziinit; 818 zip64_internal* zi; 819 int err=ZIP_OK; 820 821 ziinit.z_filefunc.zseek32_file = NULL; 822 ziinit.z_filefunc.ztell32_file = NULL; 823 if (pzlib_filefunc64_32_def==NULL) 824 fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); 825 else 826 ziinit.z_filefunc = *pzlib_filefunc64_32_def; 827 828 ziinit.filestream = ZOPEN64(ziinit.z_filefunc, 829 pathname, 830 (append == APPEND_STATUS_CREATE) ? 831 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : 832 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); 833 834 if (ziinit.filestream == NULL) 835 return NULL; 836 837 if (append == APPEND_STATUS_CREATEAFTER) 838 ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); 839 840 ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); 841 ziinit.in_opened_file_inzip = 0; 842 ziinit.ci.stream_initialised = 0; 843 ziinit.number_entry = 0; 844 ziinit.add_position_when_writing_offset = 0; 845 init_linkedlist(&(ziinit.central_dir)); 846 847 848 849 zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); 850 if (zi==NULL) 851 { 852 ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); 853 return NULL; 854 } 855 856 /* now we add file in a zipfile */ 857 # ifndef NO_ADDFILEINEXISTINGZIP 858 ziinit.globalcomment = NULL; 859 if (append == APPEND_STATUS_ADDINZIP) 860 { 861 // Read and Cache Central Directory Records 862 err = LoadCentralDirectoryRecord(&ziinit); 863 } 864 865 if (globalcomment) 866 { 867 *globalcomment = ziinit.globalcomment; 868 } 869 # endif /* !NO_ADDFILEINEXISTINGZIP*/ 870 871 if (err != ZIP_OK) 872 { 873 # ifndef NO_ADDFILEINEXISTINGZIP 874 free(ziinit.globalcomment); 875 # endif /* !NO_ADDFILEINEXISTINGZIP*/ 876 free(zi); 877 return NULL; 878 } 879 else 880 { 881 *zi = ziinit; 882 return (zipFile)zi; 883 } 884 } 885 886 extern zipFile ZEXPORT zipOpen2(const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) { 887 if (pzlib_filefunc32_def != NULL) 888 { 889 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; 890 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); 891 return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); 892 } 893 else 894 return zipOpen3(pathname, append, globalcomment, NULL); 895 } 896 897 extern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) { 898 if (pzlib_filefunc_def != NULL) 899 { 900 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; 901 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; 902 zlib_filefunc64_32_def_fill.ztell32_file = NULL; 903 zlib_filefunc64_32_def_fill.zseek32_file = NULL; 904 return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); 905 } 906 else 907 return zipOpen3(pathname, append, globalcomment, NULL); 908 } 909 910 911 912 extern zipFile ZEXPORT zipOpen(const char* pathname, int append) { 913 return zipOpen3((const void*)pathname,append,NULL,NULL); 914 } 915 916 extern zipFile ZEXPORT zipOpen64(const void* pathname, int append) { 917 return zipOpen3(pathname,append,NULL,NULL); 918 } 919 920 local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) { 921 /* write the local header */ 922 int err; 923 uInt size_filename = (uInt)strlen(filename); 924 uInt size_extrafield = size_extrafield_local; 925 926 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); 927 928 if (err==ZIP_OK) 929 { 930 if(zi->ci.zip64) 931 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ 932 else 933 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ 934 } 935 936 if (err==ZIP_OK) 937 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); 938 939 if (err==ZIP_OK) 940 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); 941 942 if (err==ZIP_OK) 943 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); 944 945 // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later 946 if (err==ZIP_OK) 947 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ 948 if (err==ZIP_OK) 949 { 950 if(zi->ci.zip64) 951 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ 952 else 953 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ 954 } 955 if (err==ZIP_OK) 956 { 957 if(zi->ci.zip64) 958 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ 959 else 960 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ 961 } 962 963 if (err==ZIP_OK) 964 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); 965 966 if(zi->ci.zip64) 967 { 968 size_extrafield += 20; 969 } 970 971 if (err==ZIP_OK) 972 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); 973 974 if ((err==ZIP_OK) && (size_filename > 0)) 975 { 976 if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) 977 err = ZIP_ERRNO; 978 } 979 980 if ((err==ZIP_OK) && (size_extrafield_local > 0)) 981 { 982 if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) 983 err = ZIP_ERRNO; 984 } 985 986 987 if ((err==ZIP_OK) && (zi->ci.zip64)) 988 { 989 // write the Zip64 extended info 990 short HeaderID = 1; 991 short DataSize = 16; 992 ZPOS64_T CompressedSize = 0; 993 ZPOS64_T UncompressedSize = 0; 994 995 // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) 996 zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); 997 998 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)HeaderID,2); 999 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)DataSize,2); 1000 1001 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); 1002 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); 1003 } 1004 1005 return err; 1006 } 1007 1008 /* 1009 NOTE. 1010 When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped 1011 before calling this function it can be done with zipRemoveExtraInfoBlock 1012 1013 It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize 1014 unnecessary allocations. 1015 */ 1016 extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1017 const void* extrafield_local, uInt size_extrafield_local, 1018 const void* extrafield_global, uInt size_extrafield_global, 1019 const char* comment, int method, int level, int raw, 1020 int windowBits,int memLevel, int strategy, 1021 const char* password, uLong crcForCrypting, 1022 uLong versionMadeBy, uLong flagBase, int zip64) { 1023 zip64_internal* zi; 1024 uInt size_filename; 1025 uInt size_comment; 1026 uInt i; 1027 int err = ZIP_OK; 1028 1029 # ifdef NOCRYPT 1030 (crcForCrypting); 1031 if (password != NULL) 1032 return ZIP_PARAMERROR; 1033 # endif 1034 1035 if (file == NULL) 1036 return ZIP_PARAMERROR; 1037 1038 #ifdef HAVE_BZIP2 1039 if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) 1040 return ZIP_PARAMERROR; 1041 #else 1042 if ((method!=0) && (method!=Z_DEFLATED)) 1043 return ZIP_PARAMERROR; 1044 #endif 1045 1046 // The filename and comment length must fit in 16 bits. 1047 if ((filename!=NULL) && (strlen(filename)>0xffff)) 1048 return ZIP_PARAMERROR; 1049 if ((comment!=NULL) && (strlen(comment)>0xffff)) 1050 return ZIP_PARAMERROR; 1051 // The extra field length must fit in 16 bits. If the member also requires 1052 // a Zip64 extra block, that will also need to fit within that 16-bit 1053 // length, but that will be checked for later. 1054 if ((size_extrafield_local>0xffff) || (size_extrafield_global>0xffff)) 1055 return ZIP_PARAMERROR; 1056 1057 zi = (zip64_internal*)file; 1058 1059 if (zi->in_opened_file_inzip == 1) 1060 { 1061 err = zipCloseFileInZip (file); 1062 if (err != ZIP_OK) 1063 return err; 1064 } 1065 1066 if (filename==NULL) 1067 filename="-"; 1068 1069 if (comment==NULL) 1070 size_comment = 0; 1071 else 1072 size_comment = (uInt)strlen(comment); 1073 1074 size_filename = (uInt)strlen(filename); 1075 1076 if (zipfi == NULL) 1077 zi->ci.dosDate = 0; 1078 else 1079 { 1080 if (zipfi->dosDate != 0) 1081 zi->ci.dosDate = zipfi->dosDate; 1082 else 1083 zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); 1084 } 1085 1086 zi->ci.flag = flagBase; 1087 if ((level==8) || (level==9)) 1088 zi->ci.flag |= 2; 1089 if (level==2) 1090 zi->ci.flag |= 4; 1091 if (level==1) 1092 zi->ci.flag |= 6; 1093 if (password != NULL) 1094 zi->ci.flag |= 1; 1095 1096 zi->ci.crc32 = 0; 1097 zi->ci.method = method; 1098 zi->ci.encrypt = 0; 1099 zi->ci.stream_initialised = 0; 1100 zi->ci.pos_in_buffered_data = 0; 1101 zi->ci.raw = raw; 1102 zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); 1103 1104 zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; 1105 zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data 1106 1107 zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); 1108 1109 zi->ci.size_centralExtra = size_extrafield_global; 1110 zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); 1111 /* version info */ 1112 zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); 1113 zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); 1114 zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); 1115 zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); 1116 zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); 1117 zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ 1118 zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ 1119 zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ 1120 zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); 1121 zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); 1122 zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); 1123 zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ 1124 1125 if (zipfi==NULL) 1126 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); 1127 else 1128 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); 1129 1130 if (zipfi==NULL) 1131 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); 1132 else 1133 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); 1134 1135 if(zi->ci.pos_local_header >= 0xffffffff) 1136 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); 1137 else 1138 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writing_offset,4); 1139 1140 for (i=0;i<size_filename;i++) 1141 *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i); 1142 1143 for (i=0;i<size_extrafield_global;i++) 1144 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) = 1145 *(((const char*)extrafield_global)+i); 1146 1147 for (i=0;i<size_comment;i++) 1148 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+ 1149 size_extrafield_global+i) = *(comment+i); 1150 if (zi->ci.central_header == NULL) 1151 return ZIP_INTERNALERROR; 1152 1153 zi->ci.zip64 = zip64; 1154 zi->ci.totalCompressedData = 0; 1155 zi->ci.totalUncompressedData = 0; 1156 zi->ci.pos_zip64extrainfo = 0; 1157 1158 err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); 1159 1160 #ifdef HAVE_BZIP2 1161 zi->ci.bstream.avail_in = (uInt)0; 1162 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; 1163 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; 1164 zi->ci.bstream.total_in_hi32 = 0; 1165 zi->ci.bstream.total_in_lo32 = 0; 1166 zi->ci.bstream.total_out_hi32 = 0; 1167 zi->ci.bstream.total_out_lo32 = 0; 1168 #endif 1169 1170 zi->ci.stream.avail_in = (uInt)0; 1171 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; 1172 zi->ci.stream.next_out = zi->ci.buffered_data; 1173 zi->ci.stream.total_in = 0; 1174 zi->ci.stream.total_out = 0; 1175 zi->ci.stream.data_type = Z_BINARY; 1176 1177 #ifdef HAVE_BZIP2 1178 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) 1179 #else 1180 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1181 #endif 1182 { 1183 if(zi->ci.method == Z_DEFLATED) 1184 { 1185 zi->ci.stream.zalloc = (alloc_func)0; 1186 zi->ci.stream.zfree = (free_func)0; 1187 zi->ci.stream.opaque = (voidpf)0; 1188 1189 if (windowBits>0) 1190 windowBits = -windowBits; 1191 1192 err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); 1193 1194 if (err==Z_OK) 1195 zi->ci.stream_initialised = Z_DEFLATED; 1196 } 1197 else if(zi->ci.method == Z_BZIP2ED) 1198 { 1199 #ifdef HAVE_BZIP2 1200 // Init BZip stuff here 1201 zi->ci.bstream.bzalloc = 0; 1202 zi->ci.bstream.bzfree = 0; 1203 zi->ci.bstream.opaque = (voidpf)0; 1204 1205 err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); 1206 if(err == BZ_OK) 1207 zi->ci.stream_initialised = Z_BZIP2ED; 1208 #endif 1209 } 1210 1211 } 1212 1213 # ifndef NOCRYPT 1214 zi->ci.crypt_header_size = 0; 1215 if ((err==Z_OK) && (password != NULL)) 1216 { 1217 unsigned char bufHead[RAND_HEAD_LEN]; 1218 unsigned int sizeHead; 1219 zi->ci.encrypt = 1; 1220 zi->ci.pcrc_32_tab = get_crc_table(); 1221 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ 1222 1223 sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); 1224 zi->ci.crypt_header_size = sizeHead; 1225 1226 if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) 1227 err = ZIP_ERRNO; 1228 } 1229 # endif 1230 1231 if (err==Z_OK) 1232 zi->in_opened_file_inzip = 1; 1233 return err; 1234 } 1235 1236 extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1237 const void* extrafield_local, uInt size_extrafield_local, 1238 const void* extrafield_global, uInt size_extrafield_global, 1239 const char* comment, int method, int level, int raw, 1240 int windowBits,int memLevel, int strategy, 1241 const char* password, uLong crcForCrypting, 1242 uLong versionMadeBy, uLong flagBase) { 1243 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1244 extrafield_local, size_extrafield_local, 1245 extrafield_global, size_extrafield_global, 1246 comment, method, level, raw, 1247 windowBits, memLevel, strategy, 1248 password, crcForCrypting, versionMadeBy, flagBase, 0); 1249 } 1250 1251 extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1252 const void* extrafield_local, uInt size_extrafield_local, 1253 const void* extrafield_global, uInt size_extrafield_global, 1254 const char* comment, int method, int level, int raw, 1255 int windowBits,int memLevel, int strategy, 1256 const char* password, uLong crcForCrypting) { 1257 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1258 extrafield_local, size_extrafield_local, 1259 extrafield_global, size_extrafield_global, 1260 comment, method, level, raw, 1261 windowBits, memLevel, strategy, 1262 password, crcForCrypting, VERSIONMADEBY, 0, 0); 1263 } 1264 1265 extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1266 const void* extrafield_local, uInt size_extrafield_local, 1267 const void* extrafield_global, uInt size_extrafield_global, 1268 const char* comment, int method, int level, int raw, 1269 int windowBits,int memLevel, int strategy, 1270 const char* password, uLong crcForCrypting, int zip64) { 1271 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1272 extrafield_local, size_extrafield_local, 1273 extrafield_global, size_extrafield_global, 1274 comment, method, level, raw, 1275 windowBits, memLevel, strategy, 1276 password, crcForCrypting, VERSIONMADEBY, 0, zip64); 1277 } 1278 1279 extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1280 const void* extrafield_local, uInt size_extrafield_local, 1281 const void* extrafield_global, uInt size_extrafield_global, 1282 const char* comment, int method, int level, int raw) { 1283 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1284 extrafield_local, size_extrafield_local, 1285 extrafield_global, size_extrafield_global, 1286 comment, method, level, raw, 1287 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 1288 NULL, 0, VERSIONMADEBY, 0, 0); 1289 } 1290 1291 extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1292 const void* extrafield_local, uInt size_extrafield_local, 1293 const void* extrafield_global, uInt size_extrafield_global, 1294 const char* comment, int method, int level, int raw, int zip64) { 1295 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1296 extrafield_local, size_extrafield_local, 1297 extrafield_global, size_extrafield_global, 1298 comment, method, level, raw, 1299 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 1300 NULL, 0, VERSIONMADEBY, 0, zip64); 1301 } 1302 1303 extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1304 const void* extrafield_local, uInt size_extrafield_local, 1305 const void*extrafield_global, uInt size_extrafield_global, 1306 const char* comment, int method, int level, int zip64) { 1307 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1308 extrafield_local, size_extrafield_local, 1309 extrafield_global, size_extrafield_global, 1310 comment, method, level, 0, 1311 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 1312 NULL, 0, VERSIONMADEBY, 0, zip64); 1313 } 1314 1315 extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1316 const void* extrafield_local, uInt size_extrafield_local, 1317 const void*extrafield_global, uInt size_extrafield_global, 1318 const char* comment, int method, int level) { 1319 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1320 extrafield_local, size_extrafield_local, 1321 extrafield_global, size_extrafield_global, 1322 comment, method, level, 0, 1323 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 1324 NULL, 0, VERSIONMADEBY, 0, 0); 1325 } 1326 1327 local int zip64FlushWriteBuffer(zip64_internal* zi) { 1328 int err=ZIP_OK; 1329 1330 if (zi->ci.encrypt != 0) 1331 { 1332 #ifndef NOCRYPT 1333 uInt i; 1334 int t; 1335 for (i=0;i<zi->ci.pos_in_buffered_data;i++) 1336 zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); 1337 #endif 1338 } 1339 1340 if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) 1341 err = ZIP_ERRNO; 1342 1343 zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; 1344 1345 #ifdef HAVE_BZIP2 1346 if(zi->ci.method == Z_BZIP2ED) 1347 { 1348 zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; 1349 zi->ci.bstream.total_in_lo32 = 0; 1350 zi->ci.bstream.total_in_hi32 = 0; 1351 } 1352 else 1353 #endif 1354 { 1355 zi->ci.totalUncompressedData += zi->ci.stream.total_in; 1356 zi->ci.stream.total_in = 0; 1357 } 1358 1359 1360 zi->ci.pos_in_buffered_data = 0; 1361 1362 return err; 1363 } 1364 1365 extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void* buf, unsigned int len) { 1366 zip64_internal* zi; 1367 int err=ZIP_OK; 1368 1369 if (file == NULL) 1370 return ZIP_PARAMERROR; 1371 zi = (zip64_internal*)file; 1372 1373 if (zi->in_opened_file_inzip == 0) 1374 return ZIP_PARAMERROR; 1375 1376 zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); 1377 1378 #ifdef HAVE_BZIP2 1379 if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) 1380 { 1381 zi->ci.bstream.next_in = (void*)buf; 1382 zi->ci.bstream.avail_in = len; 1383 err = BZ_RUN_OK; 1384 1385 while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) 1386 { 1387 if (zi->ci.bstream.avail_out == 0) 1388 { 1389 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1390 err = ZIP_ERRNO; 1391 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; 1392 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; 1393 } 1394 1395 1396 if(err != BZ_RUN_OK) 1397 break; 1398 1399 if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) 1400 { 1401 uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; 1402 // uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; 1403 err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); 1404 1405 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; 1406 } 1407 } 1408 1409 if(err == BZ_RUN_OK) 1410 err = ZIP_OK; 1411 } 1412 else 1413 #endif 1414 { 1415 zi->ci.stream.next_in = (Bytef*)(uintptr_t)buf; 1416 zi->ci.stream.avail_in = len; 1417 1418 while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) 1419 { 1420 if (zi->ci.stream.avail_out == 0) 1421 { 1422 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1423 err = ZIP_ERRNO; 1424 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; 1425 zi->ci.stream.next_out = zi->ci.buffered_data; 1426 } 1427 1428 1429 if(err != ZIP_OK) 1430 break; 1431 1432 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1433 { 1434 uLong uTotalOutBefore = zi->ci.stream.total_out; 1435 err=deflate(&zi->ci.stream, Z_NO_FLUSH); 1436 1437 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; 1438 } 1439 else 1440 { 1441 uInt copy_this,i; 1442 if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) 1443 copy_this = zi->ci.stream.avail_in; 1444 else 1445 copy_this = zi->ci.stream.avail_out; 1446 1447 for (i = 0; i < copy_this; i++) 1448 *(((char*)zi->ci.stream.next_out)+i) = 1449 *(((const char*)zi->ci.stream.next_in)+i); 1450 { 1451 zi->ci.stream.avail_in -= copy_this; 1452 zi->ci.stream.avail_out-= copy_this; 1453 zi->ci.stream.next_in+= copy_this; 1454 zi->ci.stream.next_out+= copy_this; 1455 zi->ci.stream.total_in+= copy_this; 1456 zi->ci.stream.total_out+= copy_this; 1457 zi->ci.pos_in_buffered_data += copy_this; 1458 } 1459 } 1460 }// while(...) 1461 } 1462 1463 return err; 1464 } 1465 1466 extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uLong uncompressed_size, uLong crc32) { 1467 return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); 1468 } 1469 1470 extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_size, uLong crc32) { 1471 zip64_internal* zi; 1472 ZPOS64_T compressed_size; 1473 uLong invalidValue = 0xffffffff; 1474 unsigned datasize = 0; 1475 int err=ZIP_OK; 1476 1477 if (file == NULL) 1478 return ZIP_PARAMERROR; 1479 zi = (zip64_internal*)file; 1480 1481 if (zi->in_opened_file_inzip == 0) 1482 return ZIP_PARAMERROR; 1483 zi->ci.stream.avail_in = 0; 1484 1485 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1486 { 1487 while (err==ZIP_OK) 1488 { 1489 uLong uTotalOutBefore; 1490 if (zi->ci.stream.avail_out == 0) 1491 { 1492 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1493 err = ZIP_ERRNO; 1494 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; 1495 zi->ci.stream.next_out = zi->ci.buffered_data; 1496 } 1497 uTotalOutBefore = zi->ci.stream.total_out; 1498 err=deflate(&zi->ci.stream, Z_FINISH); 1499 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; 1500 } 1501 } 1502 else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) 1503 { 1504 #ifdef HAVE_BZIP2 1505 err = BZ_FINISH_OK; 1506 while (err==BZ_FINISH_OK) 1507 { 1508 uLong uTotalOutBefore; 1509 if (zi->ci.bstream.avail_out == 0) 1510 { 1511 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1512 err = ZIP_ERRNO; 1513 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; 1514 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; 1515 } 1516 uTotalOutBefore = zi->ci.bstream.total_out_lo32; 1517 err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); 1518 if(err == BZ_STREAM_END) 1519 err = Z_STREAM_END; 1520 1521 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); 1522 } 1523 1524 if(err == BZ_FINISH_OK) 1525 err = ZIP_OK; 1526 #endif 1527 } 1528 1529 if (err==Z_STREAM_END) 1530 err=ZIP_OK; /* this is normal */ 1531 1532 if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) 1533 { 1534 if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) 1535 err = ZIP_ERRNO; 1536 } 1537 1538 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1539 { 1540 int tmp_err = deflateEnd(&zi->ci.stream); 1541 if (err == ZIP_OK) 1542 err = tmp_err; 1543 zi->ci.stream_initialised = 0; 1544 } 1545 #ifdef HAVE_BZIP2 1546 else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) 1547 { 1548 int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); 1549 if (err==ZIP_OK) 1550 err = tmperr; 1551 zi->ci.stream_initialised = 0; 1552 } 1553 #endif 1554 1555 if (!zi->ci.raw) 1556 { 1557 crc32 = (uLong)zi->ci.crc32; 1558 uncompressed_size = zi->ci.totalUncompressedData; 1559 } 1560 compressed_size = zi->ci.totalCompressedData; 1561 1562 # ifndef NOCRYPT 1563 compressed_size += zi->ci.crypt_header_size; 1564 # endif 1565 1566 // update Current Item crc and sizes, 1567 if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) 1568 { 1569 /*version Made by*/ 1570 zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); 1571 /*version needed*/ 1572 zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); 1573 1574 } 1575 1576 zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ 1577 1578 1579 if(compressed_size >= 0xffffffff) 1580 zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ 1581 else 1582 zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ 1583 1584 /// set internal file attributes field 1585 if (zi->ci.stream.data_type == Z_ASCII) 1586 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); 1587 1588 if(uncompressed_size >= 0xffffffff) 1589 zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ 1590 else 1591 zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ 1592 1593 // Add ZIP64 extra info field for uncompressed size 1594 if(uncompressed_size >= 0xffffffff) 1595 datasize += 8; 1596 1597 // Add ZIP64 extra info field for compressed size 1598 if(compressed_size >= 0xffffffff) 1599 datasize += 8; 1600 1601 // Add ZIP64 extra info field for relative offset to local file header of current file 1602 if(zi->ci.pos_local_header >= 0xffffffff) 1603 datasize += 8; 1604 1605 if(datasize > 0) 1606 { 1607 char* p = NULL; 1608 1609 if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) 1610 { 1611 // we cannot write more data to the buffer that we have room for. 1612 return ZIP_BADZIPFILE; 1613 } 1614 1615 p = zi->ci.central_header + zi->ci.size_centralheader; 1616 1617 // Add Extra Information Header for 'ZIP64 information' 1618 zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID 1619 p += 2; 1620 zip64local_putValue_inmemory(p, datasize, 2); // DataSize 1621 p += 2; 1622 1623 if(uncompressed_size >= 0xffffffff) 1624 { 1625 zip64local_putValue_inmemory(p, uncompressed_size, 8); 1626 p += 8; 1627 } 1628 1629 if(compressed_size >= 0xffffffff) 1630 { 1631 zip64local_putValue_inmemory(p, compressed_size, 8); 1632 p += 8; 1633 } 1634 1635 if(zi->ci.pos_local_header >= 0xffffffff) 1636 { 1637 zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); 1638 p += 8; 1639 } 1640 1641 // Update how much extra free space we got in the memory buffer 1642 // and increase the centralheader size so the new ZIP64 fields are included 1643 // ( 4 below is the size of HeaderID and DataSize field ) 1644 zi->ci.size_centralExtraFree -= datasize + 4; 1645 zi->ci.size_centralheader += datasize + 4; 1646 1647 // Update the extra info size field 1648 zi->ci.size_centralExtra += datasize + 4; 1649 zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); 1650 } 1651 1652 if (err==ZIP_OK) 1653 err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); 1654 1655 free(zi->ci.central_header); 1656 1657 if (err==ZIP_OK) 1658 { 1659 // Update the LocalFileHeader with the new values. 1660 1661 ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); 1662 1663 if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) 1664 err = ZIP_ERRNO; 1665 1666 if (err==ZIP_OK) 1667 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ 1668 1669 if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff ) 1670 { 1671 if(zi->ci.pos_zip64extrainfo > 0) 1672 { 1673 // Update the size in the ZIP64 extended field. 1674 if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) 1675 err = ZIP_ERRNO; 1676 1677 if (err==ZIP_OK) /* compressed size, unknown */ 1678 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); 1679 1680 if (err==ZIP_OK) /* uncompressed size, unknown */ 1681 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); 1682 } 1683 else 1684 err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal 1685 } 1686 else 1687 { 1688 if (err==ZIP_OK) /* compressed size, unknown */ 1689 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); 1690 1691 if (err==ZIP_OK) /* uncompressed size, unknown */ 1692 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); 1693 } 1694 1695 if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) 1696 err = ZIP_ERRNO; 1697 } 1698 1699 zi->number_entry ++; 1700 zi->in_opened_file_inzip = 0; 1701 1702 return err; 1703 } 1704 1705 extern int ZEXPORT zipCloseFileInZip(zipFile file) { 1706 return zipCloseFileInZipRaw (file,0,0); 1707 } 1708 1709 local int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) { 1710 int err = ZIP_OK; 1711 ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset; 1712 1713 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); 1714 1715 /*num disks*/ 1716 if (err==ZIP_OK) /* number of the disk with the start of the central directory */ 1717 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); 1718 1719 /*relative offset*/ 1720 if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ 1721 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); 1722 1723 /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ 1724 if (err==ZIP_OK) /* number of the disk with the start of the central directory */ 1725 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); 1726 1727 return err; 1728 } 1729 1730 local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { 1731 int err = ZIP_OK; 1732 1733 uLong Zip64DataSize = 44; 1734 1735 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); 1736 1737 if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ 1738 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? 1739 1740 if (err==ZIP_OK) /* version made by */ 1741 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); 1742 1743 if (err==ZIP_OK) /* version needed */ 1744 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); 1745 1746 if (err==ZIP_OK) /* number of this disk */ 1747 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); 1748 1749 if (err==ZIP_OK) /* number of the disk with the start of the central directory */ 1750 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); 1751 1752 if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ 1753 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); 1754 1755 if (err==ZIP_OK) /* total number of entries in the central dir */ 1756 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); 1757 1758 if (err==ZIP_OK) /* size of the central directory */ 1759 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); 1760 1761 if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ 1762 { 1763 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; 1764 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); 1765 } 1766 return err; 1767 } 1768 1769 local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { 1770 int err = ZIP_OK; 1771 1772 /*signature*/ 1773 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); 1774 1775 if (err==ZIP_OK) /* number of this disk */ 1776 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); 1777 1778 if (err==ZIP_OK) /* number of the disk with the start of the central directory */ 1779 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); 1780 1781 if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ 1782 { 1783 { 1784 if(zi->number_entry >= 0xFFFF) 1785 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record 1786 else 1787 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); 1788 } 1789 } 1790 1791 if (err==ZIP_OK) /* total number of entries in the central dir */ 1792 { 1793 if(zi->number_entry >= 0xFFFF) 1794 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record 1795 else 1796 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); 1797 } 1798 1799 if (err==ZIP_OK) /* size of the central directory */ 1800 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); 1801 1802 if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ 1803 { 1804 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; 1805 if(pos >= 0xffffffff) 1806 { 1807 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); 1808 } 1809 else 1810 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writing_offset),4); 1811 } 1812 1813 return err; 1814 } 1815 1816 local int Write_GlobalComment(zip64_internal* zi, const char* global_comment) { 1817 int err = ZIP_OK; 1818 uInt size_global_comment = 0; 1819 1820 if(global_comment != NULL) 1821 size_global_comment = (uInt)strlen(global_comment); 1822 1823 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); 1824 1825 if (err == ZIP_OK && size_global_comment > 0) 1826 { 1827 if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) 1828 err = ZIP_ERRNO; 1829 } 1830 return err; 1831 } 1832 1833 extern int ZEXPORT zipClose(zipFile file, const char* global_comment) { 1834 zip64_internal* zi; 1835 int err = 0; 1836 uLong size_centraldir = 0; 1837 ZPOS64_T centraldir_pos_inzip; 1838 ZPOS64_T pos; 1839 1840 if (file == NULL) 1841 return ZIP_PARAMERROR; 1842 1843 zi = (zip64_internal*)file; 1844 1845 if (zi->in_opened_file_inzip == 1) 1846 { 1847 err = zipCloseFileInZip (file); 1848 } 1849 1850 #ifndef NO_ADDFILEINEXISTINGZIP 1851 if (global_comment==NULL) 1852 global_comment = zi->globalcomment; 1853 #endif 1854 1855 centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); 1856 1857 if (err==ZIP_OK) 1858 { 1859 linkedlist_datablock_internal* ldi = zi->central_dir.first_block; 1860 while (ldi!=NULL) 1861 { 1862 if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) 1863 { 1864 if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) 1865 err = ZIP_ERRNO; 1866 } 1867 1868 size_centraldir += ldi->filled_in_this_block; 1869 ldi = ldi->next_datablock; 1870 } 1871 } 1872 free_linkedlist(&(zi->central_dir)); 1873 1874 pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; 1875 if(pos >= 0xffffffff || zi->number_entry >= 0xFFFF) 1876 { 1877 ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); 1878 Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); 1879 1880 Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); 1881 } 1882 1883 if (err==ZIP_OK) 1884 err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); 1885 1886 if(err == ZIP_OK) 1887 err = Write_GlobalComment(zi, global_comment); 1888 1889 if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) 1890 if (err == ZIP_OK) 1891 err = ZIP_ERRNO; 1892 1893 #ifndef NO_ADDFILEINEXISTINGZIP 1894 free(zi->globalcomment); 1895 #endif 1896 free(zi); 1897 1898 return err; 1899 } 1900 1901 extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader) { 1902 char* p = pData; 1903 int size = 0; 1904 char* pNewHeader; 1905 char* pTmp; 1906 short header; 1907 short dataSize; 1908 1909 int retVal = ZIP_OK; 1910 1911 if(pData == NULL || dataLen == NULL || *dataLen < 4) 1912 return ZIP_PARAMERROR; 1913 1914 pNewHeader = (char*)ALLOC((unsigned)*dataLen); 1915 pTmp = pNewHeader; 1916 1917 while(p < (pData + *dataLen)) 1918 { 1919 header = *(short*)p; 1920 dataSize = *(((short*)p)+1); 1921 1922 if( header == sHeader ) // Header found. 1923 { 1924 p += dataSize + 4; // skip it. do not copy to temp buffer 1925 } 1926 else 1927 { 1928 // Extra Info block should not be removed, So copy it to the temp buffer. 1929 memcpy(pTmp, p, dataSize + 4); 1930 p += dataSize + 4; 1931 size += dataSize + 4; 1932 } 1933 1934 } 1935 1936 if(size < *dataLen) 1937 { 1938 // clean old extra info block. 1939 memset(pData,0, *dataLen); 1940 1941 // copy the new extra info block over the old 1942 if(size > 0) 1943 memcpy(pData, pNewHeader, size); 1944 1945 // set the new extra info size 1946 *dataLen = size; 1947 1948 retVal = ZIP_OK; 1949 } 1950 else 1951 retVal = ZIP_ERRNO; 1952 1953 free(pNewHeader); 1954 1955 return retVal; 1956 } 1957