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 94const 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 110typedef 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 119typedef struct linkedlist_data_s 120{ 121 linkedlist_datablock_internal* first_block; 122 linkedlist_datablock_internal* last_block; 123} linkedlist_data; 124 125 126typedef 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 161typedef 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 185local linkedlist_datablock_internal* allocate_new_datablock(void) 186{ 187 linkedlist_datablock_internal* ldi; 188 ldi = (linkedlist_datablock_internal*) 189 ALLOC(sizeof(linkedlist_datablock_internal)); 190 if (ldi != NULL) 191 { 192 ldi->next_datablock = NULL ; 193 ldi->filled_in_this_block = 0 ; 194 ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; 195 } 196 return ldi; 197} 198 199local void free_datablock(linkedlist_datablock_internal* ldi) 200{ 201 while (ldi != NULL) 202 { 203 linkedlist_datablock_internal* ldinext = ldi->next_datablock; 204 free(ldi); 205 ldi = ldinext; 206 } 207} 208 209local void init_linkedlist(linkedlist_data* ll) 210{ 211 ll->first_block = ll->last_block = NULL; 212} 213 214local void free_linkedlist(linkedlist_data* ll) 215{ 216 free_datablock(ll->first_block); 217 ll->first_block = ll->last_block = NULL; 218} 219 220 221local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) 222{ 223 linkedlist_datablock_internal* ldi; 224 const unsigned char* from_copy; 225 226 if (ll == NULL) 227 { 228 return ZIP_INTERNALERROR; 229 } 230 231 if (ll->last_block == NULL) 232 { 233 ll->first_block = ll->last_block = allocate_new_datablock(); 234 if (ll->first_block == NULL) 235 return ZIP_INTERNALERROR; 236 } 237 238 ldi = ll->last_block; 239 from_copy = (const unsigned char*)buf; 240 241 while (len>0) 242 { 243 uInt copy_this; 244 uInt i; 245 unsigned char* to_copy; 246 247 if (ldi->avail_in_this_block == 0) 248 { 249 ldi->next_datablock = allocate_new_datablock(); 250 if (ldi->next_datablock == NULL) 251 return ZIP_INTERNALERROR; 252 ldi = ldi->next_datablock ; 253 ll->last_block = ldi; 254 } 255 256 if (ldi->avail_in_this_block < len) 257 { 258 copy_this = (uInt)ldi->avail_in_this_block; 259 } 260 else 261 { 262 copy_this = (uInt)len; 263 } 264 265 to_copy = &(ldi->data[ldi->filled_in_this_block]); 266 267 for (i = 0;i < copy_this; i++) { 268 *(to_copy+i) = *(from_copy+i); 269 } 270 271 ldi->filled_in_this_block += copy_this; 272 ldi->avail_in_this_block -= copy_this; 273 from_copy += copy_this ; 274 len -= copy_this; 275 } 276 return ZIP_OK; 277} 278 279 280 281/****************************************************************************/ 282 283#ifndef NO_ADDFILEINEXISTINGZIP 284/* =========================================================================== 285 Inputs a long in LSB order to the given file 286 nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) 287*/ 288 289local int zip64local_putValue(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) 290{ 291 unsigned char buf[8]; 292 int n; 293 for (n = 0; n < nbByte; n++) 294 { 295 buf[n] = (unsigned char)(x & 0xff); 296 x >>= 8; 297 } 298 if (x != 0) 299 { /* data overflow - hack for ZIP64 (X Roche) */ 300 for (n = 0; n < nbByte; n++) { 301 buf[n] = 0xff; 302 } 303 } 304 305 if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,(uLong)nbByte) != (uLong)nbByte) 306 { 307 return ZIP_ERRNO; 308 } 309 else 310 { 311 return ZIP_OK; 312 } 313} 314 315local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) 316{ 317 unsigned char* buf = (unsigned char*)dest; 318 int n; 319 for (n = 0; n < nbByte; n++) { 320 buf[n] = (unsigned char)(x & 0xff); 321 x >>= 8; 322 } 323 324 if (x != 0) 325 { /* data overflow - hack for ZIP64 */ 326 for (n = 0; n < nbByte; n++) 327 { 328 buf[n] = 0xff; 329 } 330 } 331} 332 333/****************************************************************************/ 334 335 336local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) 337{ 338 uLong year = (uLong)ptm->tm_year; 339 if (year >= 1980) 340 { 341 year -= 1980; 342 } 343 else if (year >= 80) 344 { 345 year -= 80; 346 } 347 return 348 (uLong) (((uLong)(ptm->tm_mday) + (32 * (uLong)(ptm->tm_mon + 1)) + (512 * year)) << 16) | 349 (((uLong)ptm->tm_sec / 2) + (32 * (uLong)ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); 350} 351 352 353/****************************************************************************/ 354 355local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int* pi) 356{ 357 unsigned char c; 358 int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); 359 if (err == 1) 360 { 361 *pi = (int)c; 362 return ZIP_OK; 363 } 364 else 365 { 366 if (ZERROR64(*pzlib_filefunc_def,filestream)) 367 { 368 return ZIP_ERRNO; 369 } 370 else 371 { 372 return ZIP_EOF; 373 } 374 } 375} 376 377 378/* =========================================================================== 379 Reads a long in LSB order from the given gz_stream. Sets 380*/ 381local int zip64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) 382{ 383 uLong x ; 384 int i = 0; 385 int err; 386 387 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 388 x = (uLong)i; 389 390 if (err == ZIP_OK) 391 { 392 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 393 } 394 x += ((uLong)i) << 8; 395 396 if (err == ZIP_OK) 397 { 398 *pX = x; 399 } 400 else 401 { 402 *pX = 0; 403 } 404 return err; 405} 406 407local int zip64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) 408{ 409 uLong x ; 410 int i = 0; 411 int err; 412 413 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 414 x = (uLong)i; 415 416 if (err == ZIP_OK) 417 { 418 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 419 } 420 x += ((uLong)i) << 8; 421 422 if (err == ZIP_OK) 423 { 424 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 425 } 426 x += ((uLong)i) << 16; 427 428 if (err == ZIP_OK) 429 { 430 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 431 } 432 x += ((uLong)i) << 24; 433 434 if (err == ZIP_OK) 435 { 436 *pX = x; 437 } 438 else 439 { 440 *pX = 0; 441 } 442 return err; 443} 444 445 446local int zip64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) 447{ 448 ZPOS64_T x; 449 int i = 0; 450 int err; 451 452 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 453 x = (ZPOS64_T)i; 454 455 if (err == ZIP_OK) 456 { 457 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 458 } 459 x += ((ZPOS64_T)i) << 8; 460 461 if (err == ZIP_OK) 462 { 463 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 464 } 465 x += ((ZPOS64_T)i) << 16; 466 467 if (err==ZIP_OK) 468 { 469 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 470 } 471 x += ((ZPOS64_T)i) << 24; 472 473 if (err == ZIP_OK) 474 { 475 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 476 } 477 x += ((ZPOS64_T)i) << 32; 478 479 if (err == ZIP_OK) 480 { 481 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 482 } 483 x += ((ZPOS64_T)i) << 40; 484 485 if (err == ZIP_OK) 486 { 487 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 488 } 489 x += ((ZPOS64_T)i) << 48; 490 491 if (err == ZIP_OK) 492 { 493 err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 494 } 495 x += ((ZPOS64_T)i) << 56; 496 497 if (err == ZIP_OK) 498 { 499 *pX = x; 500 } 501 else 502 { 503 *pX = 0; 504 } 505 506 return err; 507} 508 509#ifndef BUFREADCOMMENT 510#define BUFREADCOMMENT (0x400) 511#endif 512/* 513 Locate the Central directory of a zipfile (at the end, just before 514 the global comment) 515*/ 516local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) 517{ 518 unsigned char* buf; 519 ZPOS64_T uSizeFile; 520 ZPOS64_T uBackRead; 521 ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ 522 ZPOS64_T uPosFound=0; 523 524 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 525 { 526 return 0; 527 } 528 529 530 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); 531 532 if (uMaxBack > uSizeFile) 533 { 534 uMaxBack = uSizeFile; 535 } 536 537 buf = (unsigned char*)ALLOC(BUFREADCOMMENT + 4); 538 if (buf == NULL) 539 { 540 return 0; 541 } 542 543 uBackRead = 4; 544 while (uBackRead<uMaxBack) 545 { 546 uLong uReadSize; 547 ZPOS64_T uReadPos ; 548 int i; 549 if (uBackRead + BUFREADCOMMENT > uMaxBack) 550 { 551 uBackRead = uMaxBack; 552 } 553 else 554 { 555 uBackRead += BUFREADCOMMENT; 556 } 557 uReadPos = uSizeFile - uBackRead ; 558 559 uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? 560 (BUFREADCOMMENT + 4) : (uLong)(uSizeFile-uReadPos); 561 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET) != 0) 562 { 563 break; 564 } 565 566 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize) != uReadSize) 567 { 568 break; 569 } 570 571 for (i = (int)uReadSize - 3; (i--) > 0;) { 572 if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) && 573 ((*(buf + i + 2)) == 0x05) && ((*(buf + i + 3)) == 0x06)) 574 { 575 uPosFound = uReadPos + (unsigned)i; 576 break; 577 } 578 } 579 580 if (uPosFound != 0) 581 { 582 break; 583 } 584 } 585 free(buf); 586 return uPosFound; 587} 588 589/* 590Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before 591the global comment) 592*/ 593local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) 594{ 595 unsigned char* buf; 596 ZPOS64_T uSizeFile; 597 ZPOS64_T uBackRead; 598 ZPOS64_T uMaxBack = 0xffff; /* maximum size of global comment */ 599 ZPOS64_T uPosFound = 0; 600 uLong uL; 601 ZPOS64_T relativeOffset; 602 603 if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 604 { 605 return 0; 606 } 607 608 uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); 609 610 if (uMaxBack > uSizeFile) 611 { 612 uMaxBack = uSizeFile; 613 } 614 615 buf = (unsigned char*)ALLOC(BUFREADCOMMENT + 4); 616 if (buf == NULL) 617 { 618 return 0; 619 } 620 621 uBackRead = 4; 622 while (uBackRead < uMaxBack) 623 { 624 uLong uReadSize; 625 ZPOS64_T uReadPos; 626 int i; 627 if (uBackRead + BUFREADCOMMENT > uMaxBack) 628 { 629 uBackRead = uMaxBack; 630 } 631 else 632 { 633 uBackRead += BUFREADCOMMENT; 634 } 635 uReadPos = uSizeFile - uBackRead ; 636 637 uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? 638 (BUFREADCOMMENT + 4) : (uLong)(uSizeFile - uReadPos); 639 if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET) != 0) 640 { 641 break; 642 } 643 644 if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize) != uReadSize) 645 { 646 break; 647 } 648 649 for (i = (int)uReadSize - 3; (i--) > 0;) 650 { 651 // Signature "0x07064b50" Zip64 end of central directory locater 652 if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) && ((*(buf + i + 2)) == 0x06) && ((*(buf + i + 3)) == 0x07)) 653 { 654 uPosFound = uReadPos + (unsigned)i; 655 break; 656 } 657 } 658 659 if (uPosFound != 0) 660 { 661 break; 662 } 663 } 664 665 free(buf); 666 if (uPosFound == 0) 667 { 668 return 0; 669 } 670 671 /* Zip64 end of central directory locator */ 672 if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET) != 0) 673 { 674 return 0; 675 } 676 677 /* the signature, already checked */ 678 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL) != ZIP_OK) 679 { 680 return 0; 681 } 682 683 /* number of the disk with the start of the zip64 end of central directory */ 684 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL) != ZIP_OK) 685 { 686 return 0; 687 } 688 if (uL != 0) 689 { 690 return 0; 691 } 692 693 /* relative offset of the zip64 end of central directory record */ 694 if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset) != ZIP_OK) 695 { 696 return 0; 697 } 698 699 /* total number of disks */ 700 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL) != ZIP_OK) 701 { 702 return 0; 703 } 704 if (uL != 1) 705 { 706 return 0; 707 } 708 709 /* Goto Zip64 end of central directory record */ 710 if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET) != 0) 711 { 712 return 0; 713 } 714 715 /* the signature */ 716 if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL) != ZIP_OK) 717 { 718 return 0; 719 } 720 721 if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' 722 { 723 return 0; 724 } 725 726 return relativeOffset; 727} 728 729local int LoadCentralDirectoryRecord(zip64_internal* pziinit) 730{ 731 int err = ZIP_OK; 732 ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 733 734 ZPOS64_T size_central_dir; /* size of the central directory */ 735 ZPOS64_T offset_central_dir; /* offset of start of central directory */ 736 ZPOS64_T central_pos; 737 uLong uL; 738 739 uLong number_disk; /* number of the current disk, used for 740 spanning ZIP, unsupported, always 0*/ 741 uLong number_disk_with_CD; /* number of the disk with central dir, used 742 for spanning ZIP, unsupported, always 0*/ 743 ZPOS64_T number_entry; 744 ZPOS64_T number_entry_CD; /* total number of entries in 745 the central dir 746 (same than number_entry on nospan) */ 747 uLong VersionMadeBy; 748 uLong VersionNeeded; 749 uLong size_comment; 750 751 int hasZIP64Record = 0; 752 753 // check first if we find a ZIP64 record 754 central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); 755 if(central_pos > 0) 756 { 757 hasZIP64Record = 1; 758 } 759 else if(central_pos == 0) 760 { 761 central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); 762 } 763 764/* disable to allow appending to empty ZIP archive 765 if (central_pos==0) 766 err=ZIP_ERRNO; 767*/ 768 769 if(hasZIP64Record) 770 { 771 ZPOS64_T sizeEndOfCentralDirectory; 772 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) 773 { 774 err = ZIP_ERRNO; 775 } 776 777 /* the signature, already checked */ 778 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL) != ZIP_OK) 779 { 780 err = ZIP_ERRNO; 781 } 782 783 /* size of zip64 end of central directory record */ 784 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory) != ZIP_OK) 785 { 786 err = ZIP_ERRNO; 787 } 788 789 /* version made by */ 790 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy) != ZIP_OK) 791 { 792 err = ZIP_ERRNO; 793 } 794 795 /* version needed to extract */ 796 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded) != ZIP_OK) 797 { 798 err = ZIP_ERRNO; 799 } 800 801 /* number of this disk */ 802 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk) != ZIP_OK) 803 { 804 err = ZIP_ERRNO; 805 } 806 807 /* number of the disk with the start of the central directory */ 808 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD) != ZIP_OK) 809 { 810 err = ZIP_ERRNO; 811 } 812 813 /* total number of entries in the central directory on this disk */ 814 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry) != ZIP_OK) 815 { 816 err = ZIP_ERRNO; 817 } 818 819 /* total number of entries in the central directory */ 820 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD) != ZIP_OK) 821 { 822 err = ZIP_ERRNO; 823 } 824 825 if ((number_entry_CD != number_entry) || (number_disk_with_CD != 0) || (number_disk != 0)) 826 { 827 err = ZIP_BADZIPFILE; 828 } 829 830 /* size of the central directory */ 831 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir) != ZIP_OK) 832 { 833 err = ZIP_ERRNO; 834 } 835 836 /* offset of start of central directory with respect to the 837 starting disk number */ 838 if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir) != ZIP_OK) 839 { 840 err = ZIP_ERRNO; 841 } 842 843 // TODO.. 844 // read the comment from the standard central header. 845 size_comment = 0; 846 } 847 else 848 { 849 // Read End of central Directory info 850 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET) != 0) 851 { 852 err = ZIP_ERRNO; 853 } 854 855 /* the signature, already checked */ 856 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL) != ZIP_OK) 857 { 858 err = ZIP_ERRNO; 859 } 860 861 /* number of this disk */ 862 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk) != ZIP_OK) 863 { 864 err = ZIP_ERRNO; 865 } 866 867 /* number of the disk with the start of the central directory */ 868 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD) != ZIP_OK) 869 { 870 err = ZIP_ERRNO; 871 } 872 873 /* total number of entries in the central dir on this disk */ 874 number_entry = 0; 875 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL) != ZIP_OK) 876 { 877 err = ZIP_ERRNO; 878 } 879 else 880 { 881 number_entry = uL; 882 } 883 884 /* total number of entries in the central dir */ 885 number_entry_CD = 0; 886 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL) != ZIP_OK) 887 { 888 err = ZIP_ERRNO; 889 } 890 else 891 { 892 number_entry_CD = uL; 893 } 894 895 if ((number_entry_CD != number_entry) || (number_disk_with_CD != 0) || (number_disk != 0)) 896 { 897 err = ZIP_BADZIPFILE; 898 } 899 900 /* size of the central directory */ 901 size_central_dir = 0; 902 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL) != ZIP_OK) 903 { 904 err = ZIP_ERRNO; 905 } 906 else 907 { 908 size_central_dir = uL; 909 } 910 911 /* offset of start of central directory with respect to the starting disk number */ 912 offset_central_dir = 0; 913 if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL) != ZIP_OK) 914 { 915 err = ZIP_ERRNO; 916 } 917 else 918 { 919 offset_central_dir = uL; 920 } 921 922 923 /* zipfile global comment length */ 924 if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment) != ZIP_OK) 925 { 926 err = ZIP_ERRNO; 927 } 928 } 929 930 if ((central_pos<offset_central_dir+size_central_dir) && 931 (err == ZIP_OK)) 932 { 933 err = ZIP_BADZIPFILE; 934 } 935 936 if (err != ZIP_OK) 937 { 938 ZCLOSE64(pziinit->z_filefunc, pziinit->filestream); 939 return ZIP_ERRNO; 940 } 941 942 if (size_comment > 0) 943 { 944 pziinit->globalcomment = (char*)ALLOC(size_comment + 1); 945 if (pziinit->globalcomment) 946 { 947 size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); 948 pziinit->globalcomment[size_comment] = 0; 949 } 950 } 951 952 byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); 953 pziinit->add_position_when_writing_offset = byte_before_the_zipfile; 954 955 { 956 ZPOS64_T size_central_dir_to_read = size_central_dir; 957 size_t buf_size = SIZEDATA_INDATABLOCK; 958 void* buf_read = (void*)ALLOC(buf_size); 959 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) 960 { 961 err = ZIP_ERRNO; 962 } 963 964 while ((size_central_dir_to_read>0) && (err == ZIP_OK)) 965 { 966 ZPOS64_T read_this = SIZEDATA_INDATABLOCK; 967 if (read_this > size_central_dir_to_read) 968 { 969 read_this = size_central_dir_to_read; 970 } 971 972 if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) 973 { 974 err = ZIP_ERRNO; 975 } 976 977 if (err == ZIP_OK) 978 { 979 err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); 980 } 981 982 size_central_dir_to_read -= read_this; 983 } 984 free(buf_read); 985 } 986 pziinit->begin_pos = byte_before_the_zipfile; 987 pziinit->number_entry = number_entry_CD; 988 989 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) 990 { 991 err = ZIP_ERRNO; 992 } 993 994 return err; 995} 996 997 998#endif /* !NO_ADDFILEINEXISTINGZIP*/ 999 1000 1001/************************************************************/ 1002extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) 1003{ 1004 zip64_internal ziinit; 1005 zip64_internal* zi; 1006 int err = ZIP_OK; 1007 1008 ziinit.z_filefunc.zseek32_file = NULL; 1009 ziinit.z_filefunc.ztell32_file = NULL; 1010 if (pzlib_filefunc64_32_def == NULL) 1011 { 1012 fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); 1013 } 1014 else 1015 { 1016 ziinit.z_filefunc = *pzlib_filefunc64_32_def; 1017 } 1018 1019 ziinit.filestream = ZOPEN64(ziinit.z_filefunc, 1020 pathname, 1021 (append == APPEND_STATUS_CREATE) ? 1022 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : 1023 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); 1024 1025 if (ziinit.filestream == NULL) 1026 { 1027 return NULL; 1028 } 1029 1030 if (append == APPEND_STATUS_CREATEAFTER) 1031 { 1032 ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); 1033 } 1034 1035 ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); 1036 ziinit.in_opened_file_inzip = 0; 1037 ziinit.ci.stream_initialised = 0; 1038 ziinit.number_entry = 0; 1039 ziinit.add_position_when_writing_offset = 0; 1040 init_linkedlist(&(ziinit.central_dir)); 1041 1042 1043 1044 zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); 1045 if (zi == NULL) 1046 { 1047 ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); 1048 return NULL; 1049 } 1050 1051 /* now we add file in a zipfile */ 1052# ifndef NO_ADDFILEINEXISTINGZIP 1053 ziinit.globalcomment = NULL; 1054 if (append == APPEND_STATUS_ADDINZIP) 1055 { 1056 // Read and Cache Central Directory Records 1057 err = LoadCentralDirectoryRecord(&ziinit); 1058 } 1059 1060 if (globalcomment) 1061 { 1062 *globalcomment = ziinit.globalcomment; 1063 } 1064# endif /* !NO_ADDFILEINEXISTINGZIP*/ 1065 1066 if (err != ZIP_OK) 1067 { 1068# ifndef NO_ADDFILEINEXISTINGZIP 1069 free(ziinit.globalcomment); 1070# endif /* !NO_ADDFILEINEXISTINGZIP*/ 1071 free(zi); 1072 return NULL; 1073 } 1074 else 1075 { 1076 *zi = ziinit; 1077 return (zipFile)zi; 1078 } 1079} 1080 1081extern zipFile ZEXPORT zipOpen2(const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) 1082{ 1083 if (pzlib_filefunc32_def != NULL) 1084 { 1085 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; 1086 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); 1087 return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); 1088 } 1089 else 1090 { 1091 return zipOpen3(pathname, append, globalcomment, NULL); 1092 } 1093} 1094 1095extern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) 1096{ 1097 if (pzlib_filefunc_def != NULL) 1098 { 1099 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; 1100 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; 1101 zlib_filefunc64_32_def_fill.ztell32_file = NULL; 1102 zlib_filefunc64_32_def_fill.zseek32_file = NULL; 1103 return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); 1104 } 1105 else 1106 { 1107 return zipOpen3(pathname, append, globalcomment, NULL); 1108 } 1109} 1110 1111 1112 1113extern zipFile ZEXPORT zipOpen(const char* pathname, int append) 1114{ 1115 return zipOpen3((const void*)pathname,append,NULL,NULL); 1116} 1117 1118extern zipFile ZEXPORT zipOpen64(const void* pathname, int append) 1119{ 1120 return zipOpen3(pathname,append,NULL,NULL); 1121} 1122 1123local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) 1124{ 1125 /* write the local header */ 1126 int err; 1127 uInt size_filename = (uInt)strlen(filename); 1128 uInt size_extrafield = size_extrafield_local; 1129 1130 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); 1131 1132 if (err == ZIP_OK) 1133 { 1134 if(zi->ci.zip64) 1135 { 1136 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ 1137 } 1138 else 1139 { 1140 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ 1141 } 1142 } 1143 1144 if (err == ZIP_OK) 1145 { 1146 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); 1147 } 1148 1149 if (err == ZIP_OK) 1150 { 1151 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); 1152 } 1153 1154 if (err == ZIP_OK) 1155 { 1156 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); 1157 } 1158 1159 // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later 1160 if (err == ZIP_OK) 1161 { 1162 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ 1163 } 1164 if (err == ZIP_OK) 1165 { 1166 if(zi->ci.zip64) 1167 { 1168 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ 1169 } 1170 else 1171 { 1172 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ 1173 } 1174 } 1175 if (err == ZIP_OK) 1176 { 1177 if(zi->ci.zip64) 1178 { 1179 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ 1180 } 1181 else 1182 { 1183 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ 1184 } 1185 } 1186 1187 if (err == ZIP_OK) 1188 { 1189 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); 1190 } 1191 1192 if(zi->ci.zip64) 1193 { 1194 size_extrafield += 20; 1195 } 1196 1197 if (err == ZIP_OK) 1198 { 1199 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); 1200 } 1201 1202 if ((err == ZIP_OK) && (size_filename > 0)) 1203 { 1204 if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename) != size_filename) 1205 { 1206 err = ZIP_ERRNO; 1207 } 1208 } 1209 1210 if ((err == ZIP_OK) && (size_extrafield_local > 0)) 1211 { 1212 if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) 1213 { 1214 err = ZIP_ERRNO; 1215 } 1216 } 1217 1218 1219 if ((err == ZIP_OK) && (zi->ci.zip64)) 1220 { 1221 // write the Zip64 extended info 1222 short HeaderID = 1; 1223 short DataSize = 16; 1224 ZPOS64_T CompressedSize = 0; 1225 ZPOS64_T UncompressedSize = 0; 1226 1227 // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) 1228 zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); 1229 1230 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)HeaderID,2); 1231 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)DataSize,2); 1232 1233 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); 1234 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); 1235 } 1236 1237 return err; 1238} 1239 1240/* 1241 NOTE. 1242 When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped 1243 before calling this function it can be done with zipRemoveExtraInfoBlock 1244 1245 It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize 1246 unnecessary allocations. 1247 */ 1248extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1249 const void* extrafield_local, uInt size_extrafield_local, 1250 const void* extrafield_global, uInt size_extrafield_global, 1251 const char* comment, int method, int level, int raw, 1252 int windowBits,int memLevel, int strategy, 1253 const char* password, uLong crcForCrypting, 1254 uLong versionMadeBy, uLong flagBase, int zip64) { 1255 zip64_internal* zi; 1256 uInt size_filename; 1257 uInt size_comment; 1258 uInt i; 1259 int err = ZIP_OK; 1260 1261# ifdef NOCRYPT 1262 (crcForCrypting); 1263 if (password != NULL) 1264 { 1265 return ZIP_PARAMERROR; 1266 } 1267# endif 1268 1269 if (file == NULL) 1270 { 1271 return ZIP_PARAMERROR; 1272 } 1273 1274#ifdef HAVE_BZIP2 1275 if ((method != 0) && (method != Z_DEFLATED) && (method != Z_BZIP2ED)) 1276 { 1277 return ZIP_PARAMERROR; 1278 } 1279#else 1280 if ((method != 0) && (method != Z_DEFLATED)) 1281 { 1282 return ZIP_PARAMERROR; 1283 } 1284#endif 1285 1286 // The filename and comment length must fit in 16 bits. 1287 if ((filename != NULL) && (strlen(filename) > 0xffff)) 1288 { 1289 return ZIP_PARAMERROR; 1290 } 1291 if ((comment != NULL) && (strlen(comment) > 0xffff)) 1292 { 1293 return ZIP_PARAMERROR; 1294 } 1295 // The extra field length must fit in 16 bits. If the member also requires 1296 // a Zip64 extra block, that will also need to fit within that 16-bit 1297 // length, but that will be checked for later. 1298 if ((size_extrafield_local > 0xffff) || (size_extrafield_global > 0xffff)) 1299 { 1300 return ZIP_PARAMERROR; 1301 } 1302 1303 zi = (zip64_internal*)file; 1304 1305 if (zi->in_opened_file_inzip == 1) 1306 { 1307 err = zipCloseFileInZip (file); 1308 if (err != ZIP_OK) 1309 { 1310 return err; 1311 } 1312 } 1313 1314 if (filename == NULL) 1315 { 1316 filename = "-"; 1317 } 1318 1319 if (comment == NULL) 1320 { 1321 size_comment = 0; 1322 } 1323 else 1324 { 1325 size_comment = (uInt)strlen(comment); 1326 } 1327 1328 size_filename = (uInt)strlen(filename); 1329 1330 if (zipfi == NULL) 1331 { 1332 zi->ci.dosDate = 0; 1333 } 1334 else 1335 { 1336 if (zipfi->dosDate != 0) 1337 { 1338 zi->ci.dosDate = zipfi->dosDate; 1339 } 1340 else 1341 { 1342 zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); 1343 } 1344 } 1345 1346 zi->ci.flag = flagBase; 1347 if ((level == 8) || (level == 9)) 1348 { 1349 zi->ci.flag |= 2; 1350 } 1351 if (level == 2) 1352 { 1353 zi->ci.flag |= 4; 1354 } 1355 if (level == 1) 1356 { 1357 zi->ci.flag |= 6; 1358 } 1359 if (password != NULL) 1360 { 1361 zi->ci.flag |= 1; 1362 } 1363 1364 zi->ci.crc32 = 0; 1365 zi->ci.method = method; 1366 zi->ci.encrypt = 0; 1367 zi->ci.stream_initialised = 0; 1368 zi->ci.pos_in_buffered_data = 0; 1369 zi->ci.raw = raw; 1370 zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); 1371 1372 zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; 1373 zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data 1374 1375 zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); 1376 1377 zi->ci.size_centralExtra = size_extrafield_global; 1378 zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); 1379 /* version info */ 1380 zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); 1381 zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); 1382 zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); 1383 zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); 1384 zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); 1385 zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ 1386 zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ 1387 zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ 1388 zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); 1389 zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); 1390 zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); 1391 zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ 1392 1393 if (zipfi == NULL) 1394 { 1395 zip64local_putValue_inmemory(zi->ci.central_header + 36,(uLong)0,2); 1396 } 1397 else 1398 { 1399 zip64local_putValue_inmemory(zi->ci.central_header + 36,(uLong)zipfi->internal_fa,2); 1400 } 1401 1402 if (zipfi == NULL) 1403 { 1404 zip64local_putValue_inmemory(zi->ci.central_header + 38,(uLong)0,4); 1405 } 1406 else 1407 { 1408 zip64local_putValue_inmemory(zi->ci.central_header + 38,(uLong)zipfi->external_fa,4); 1409 } 1410 1411 if(zi->ci.pos_local_header >= 0xffffffff) 1412 { 1413 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); 1414 } 1415 else 1416 { 1417 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writing_offset,4); 1418 } 1419 1420 for (i = 0;i < size_filename; i++){ 1421 *(zi->ci.central_header + SIZECENTRALHEADER + i) = *(filename + i); 1422 } 1423 1424 for (i = 0;i < size_extrafield_global; i++){ 1425 *(zi->ci.central_header + SIZECENTRALHEADER + size_filename + i) = 1426 *(((const char*)extrafield_global) + i); 1427 } 1428 1429 for (i = 0;i < size_comment; i++){ 1430 *(zi->ci.central_header + SIZECENTRALHEADER + size_filename + 1431 size_extrafield_global + i) = *(comment + i); 1432 } 1433 if (zi->ci.central_header == NULL) 1434 { 1435 return ZIP_INTERNALERROR; 1436 } 1437 1438 zi->ci.zip64 = zip64; 1439 zi->ci.totalCompressedData = 0; 1440 zi->ci.totalUncompressedData = 0; 1441 zi->ci.pos_zip64extrainfo = 0; 1442 1443 err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); 1444 1445#ifdef HAVE_BZIP2 1446 zi->ci.bstream.avail_in = (uInt)0; 1447 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; 1448 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; 1449 zi->ci.bstream.total_in_hi32 = 0; 1450 zi->ci.bstream.total_in_lo32 = 0; 1451 zi->ci.bstream.total_out_hi32 = 0; 1452 zi->ci.bstream.total_out_lo32 = 0; 1453#endif 1454 1455 zi->ci.stream.avail_in = (uInt)0; 1456 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; 1457 zi->ci.stream.next_out = zi->ci.buffered_data; 1458 zi->ci.stream.total_in = 0; 1459 zi->ci.stream.total_out = 0; 1460 zi->ci.stream.data_type = Z_BINARY; 1461 1462#ifdef HAVE_BZIP2 1463 if ((err == ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) 1464#else 1465 if ((err == ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1466#endif 1467 { 1468 if(zi->ci.method == Z_DEFLATED) 1469 { 1470 zi->ci.stream.zalloc = (alloc_func)0; 1471 zi->ci.stream.zfree = (free_func)0; 1472 zi->ci.stream.opaque = (voidpf)0; 1473 1474 if (windowBits>0) 1475 windowBits = -windowBits; 1476 1477 err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); 1478 1479 if (err == Z_OK) 1480 { 1481 zi->ci.stream_initialised = Z_DEFLATED; 1482 } 1483 } 1484 else if(zi->ci.method == Z_BZIP2ED) 1485 { 1486#ifdef HAVE_BZIP2 1487 // Init BZip stuff here 1488 zi->ci.bstream.bzalloc = 0; 1489 zi->ci.bstream.bzfree = 0; 1490 zi->ci.bstream.opaque = (voidpf)0; 1491 1492 err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); 1493 if(err == BZ_OK) 1494 { 1495 zi->ci.stream_initialised = Z_BZIP2ED; 1496 } 1497#endif 1498 } 1499 1500 } 1501 1502# ifndef NOCRYPT 1503 zi->ci.crypt_header_size = 0; 1504 if ((err == Z_OK) && (password != NULL)) 1505 { 1506 unsigned char bufHead[RAND_HEAD_LEN]; 1507 unsigned int sizeHead; 1508 zi->ci.encrypt = 1; 1509 zi->ci.pcrc_32_tab = get_crc_table(); 1510 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ 1511 1512 sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); 1513 zi->ci.crypt_header_size = sizeHead; 1514 1515 if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) 1516 { 1517 err = ZIP_ERRNO; 1518 } 1519 } 1520# endif 1521 1522 if (err == Z_OK) 1523 { 1524 zi->in_opened_file_inzip = 1; 1525 } 1526 return err; 1527} 1528 1529extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1530 const void* extrafield_local, uInt size_extrafield_local, 1531 const void* extrafield_global, uInt size_extrafield_global, 1532 const char* comment, int method, int level, int raw, 1533 int windowBits,int memLevel, int strategy, 1534 const char* password, uLong crcForCrypting, 1535 uLong versionMadeBy, uLong flagBase) 1536{ 1537 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1538 extrafield_local, size_extrafield_local, 1539 extrafield_global, size_extrafield_global, 1540 comment, method, level, raw, 1541 windowBits, memLevel, strategy, 1542 password, crcForCrypting, versionMadeBy, flagBase, 0); 1543} 1544 1545extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1546 const void* extrafield_local, uInt size_extrafield_local, 1547 const void* extrafield_global, uInt size_extrafield_global, 1548 const char* comment, int method, int level, int raw, 1549 int windowBits,int memLevel, int strategy, 1550 const char* password, uLong crcForCrypting) 1551{ 1552 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1553 extrafield_local, size_extrafield_local, 1554 extrafield_global, size_extrafield_global, 1555 comment, method, level, raw, 1556 windowBits, memLevel, strategy, 1557 password, crcForCrypting, VERSIONMADEBY, 0, 0); 1558} 1559 1560extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1561 const void* extrafield_local, uInt size_extrafield_local, 1562 const void* extrafield_global, uInt size_extrafield_global, 1563 const char* comment, int method, int level, int raw, 1564 int windowBits,int memLevel, int strategy, 1565 const char* password, uLong crcForCrypting, int zip64) 1566{ 1567 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1568 extrafield_local, size_extrafield_local, 1569 extrafield_global, size_extrafield_global, 1570 comment, method, level, raw, 1571 windowBits, memLevel, strategy, 1572 password, crcForCrypting, VERSIONMADEBY, 0, zip64); 1573} 1574 1575extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1576 const void* extrafield_local, uInt size_extrafield_local, 1577 const void* extrafield_global, uInt size_extrafield_global, 1578 const char* comment, int method, int level, int raw) 1579{ 1580 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1581 extrafield_local, size_extrafield_local, 1582 extrafield_global, size_extrafield_global, 1583 comment, method, level, raw, 1584 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 1585 NULL, 0, VERSIONMADEBY, 0, 0); 1586} 1587 1588extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1589 const void* extrafield_local, uInt size_extrafield_local, 1590 const void* extrafield_global, uInt size_extrafield_global, 1591 const char* comment, int method, int level, int raw, int zip64) 1592{ 1593 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1594 extrafield_local, size_extrafield_local, 1595 extrafield_global, size_extrafield_global, 1596 comment, method, level, raw, 1597 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 1598 NULL, 0, VERSIONMADEBY, 0, zip64); 1599} 1600 1601extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1602 const void* extrafield_local, uInt size_extrafield_local, 1603 const void*extrafield_global, uInt size_extrafield_global, 1604 const char* comment, int method, int level, int zip64) 1605{ 1606 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1607 extrafield_local, size_extrafield_local, 1608 extrafield_global, size_extrafield_global, 1609 comment, method, level, 0, 1610 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 1611 NULL, 0, VERSIONMADEBY, 0, zip64); 1612} 1613 1614extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1615 const void* extrafield_local, uInt size_extrafield_local, 1616 const void*extrafield_global, uInt size_extrafield_global, 1617 const char* comment, int method, int level) 1618{ 1619 return zipOpenNewFileInZip4_64(file, filename, zipfi, 1620 extrafield_local, size_extrafield_local, 1621 extrafield_global, size_extrafield_global, 1622 comment, method, level, 0, 1623 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 1624 NULL, 0, VERSIONMADEBY, 0, 0); 1625} 1626 1627local int zip64FlushWriteBuffer(zip64_internal* zi) 1628{ 1629 int err = ZIP_OK; 1630 1631 if (zi->ci.encrypt != 0) 1632 { 1633#ifndef NOCRYPT 1634 uInt i; 1635 int t; 1636 for (i = 0;i < zi->ci.pos_in_buffered_data; i++){ 1637 zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); 1638 } 1639#endif 1640 } 1641 1642 if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) 1643 { 1644 err = ZIP_ERRNO; 1645 } 1646 1647 zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; 1648 1649#ifdef HAVE_BZIP2 1650 if(zi->ci.method == Z_BZIP2ED) 1651 { 1652 zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; 1653 zi->ci.bstream.total_in_lo32 = 0; 1654 zi->ci.bstream.total_in_hi32 = 0; 1655 } 1656 else 1657#endif 1658 { 1659 zi->ci.totalUncompressedData += zi->ci.stream.total_in; 1660 zi->ci.stream.total_in = 0; 1661 } 1662 1663 1664 zi->ci.pos_in_buffered_data = 0; 1665 1666 return err; 1667} 1668 1669extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void* buf, unsigned int len) { 1670 zip64_internal* zi; 1671 int err = ZIP_OK; 1672 1673 if (file == NULL) 1674 { 1675 return ZIP_PARAMERROR; 1676 } 1677 zi = (zip64_internal*)file; 1678 1679 if (zi->in_opened_file_inzip == 0) 1680 { 1681 return ZIP_PARAMERROR; 1682 } 1683 1684 zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); 1685 1686#ifdef HAVE_BZIP2 1687 if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) 1688 { 1689 zi->ci.bstream.next_in = (void*)buf; 1690 zi->ci.bstream.avail_in = len; 1691 err = BZ_RUN_OK; 1692 1693 while ((err == BZ_RUN_OK) && (zi->ci.bstream.avail_in > 0)) 1694 { 1695 if (zi->ci.bstream.avail_out == 0) 1696 { 1697 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1698 { 1699 err = ZIP_ERRNO; 1700 } 1701 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; 1702 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; 1703 } 1704 1705 1706 if(err != BZ_RUN_OK) 1707 { 1708 break; 1709 } 1710 1711 if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) 1712 { 1713 uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; 1714// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; 1715 err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); 1716 1717 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; 1718 } 1719 } 1720 1721 if(err == BZ_RUN_OK) 1722 { 1723 err = ZIP_OK; 1724 } 1725 } 1726 else 1727#endif 1728 { 1729 zi->ci.stream.next_in = (Bytef*)(uintptr_t)buf; 1730 zi->ci.stream.avail_in = len; 1731 1732 while ((err == ZIP_OK) && (zi->ci.stream.avail_in > 0)) 1733 { 1734 if (zi->ci.stream.avail_out == 0) 1735 { 1736 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1737 { 1738 err = ZIP_ERRNO; 1739 } 1740 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; 1741 zi->ci.stream.next_out = zi->ci.buffered_data; 1742 } 1743 1744 1745 if(err != ZIP_OK) 1746 break; 1747 1748 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1749 { 1750 uLong uTotalOutBefore = zi->ci.stream.total_out; 1751 err = deflate(&zi->ci.stream, Z_NO_FLUSH); 1752 1753 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; 1754 } 1755 else 1756 { 1757 uInt copy_this,i; 1758 if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) 1759 copy_this = zi->ci.stream.avail_in; 1760 else 1761 copy_this = zi->ci.stream.avail_out; 1762 1763 for (i = 0; i < copy_this; i++){ 1764 *(((char*)zi->ci.stream.next_out) + i) = 1765 *(((const char*)zi->ci.stream.next_in) + i); 1766 } 1767 { 1768 zi->ci.stream.avail_in -= copy_this; 1769 zi->ci.stream.avail_out -= copy_this; 1770 zi->ci.stream.next_in += copy_this; 1771 zi->ci.stream.next_out += copy_this; 1772 zi->ci.stream.total_in += copy_this; 1773 zi->ci.stream.total_out += copy_this; 1774 zi->ci.pos_in_buffered_data += copy_this; 1775 } 1776 } 1777 }// while(...) 1778 } 1779 1780 return err; 1781} 1782 1783extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uLong uncompressed_size, uLong crc32) 1784{ 1785 return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); 1786} 1787 1788extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_size, uLong crc32) 1789{ 1790 zip64_internal* zi; 1791 ZPOS64_T compressed_size; 1792 uLong invalidValue = 0xffffffff; 1793 unsigned datasize = 0; 1794 int err = ZIP_OK; 1795 1796 if (file == NULL) 1797 { 1798 return ZIP_PARAMERROR; 1799 } 1800 zi = (zip64_internal*)file; 1801 1802 if (zi->in_opened_file_inzip == 0) 1803 { 1804 return ZIP_PARAMERROR; 1805 } 1806 zi->ci.stream.avail_in = 0; 1807 1808 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1809 { 1810 while (err == ZIP_OK) 1811 { 1812 uLong uTotalOutBefore; 1813 if (zi->ci.stream.avail_out == 0) 1814 { 1815 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1816 err = ZIP_ERRNO; 1817 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; 1818 zi->ci.stream.next_out = zi->ci.buffered_data; 1819 } 1820 uTotalOutBefore = zi->ci.stream.total_out; 1821 err=deflate(&zi->ci.stream, Z_FINISH); 1822 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; 1823 } 1824 } 1825 else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) 1826 { 1827#ifdef HAVE_BZIP2 1828 err = BZ_FINISH_OK; 1829 while (err == BZ_FINISH_OK) 1830 { 1831 uLong uTotalOutBefore; 1832 if (zi->ci.bstream.avail_out == 0) 1833 { 1834 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1835 { 1836 err = ZIP_ERRNO; 1837 } 1838 zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; 1839 zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; 1840 } 1841 uTotalOutBefore = zi->ci.bstream.total_out_lo32; 1842 err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); 1843 if(err == BZ_STREAM_END) 1844 { 1845 err = Z_STREAM_END; 1846 } 1847 1848 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); 1849 } 1850 1851 if(err == BZ_FINISH_OK) 1852 { 1853 err = ZIP_OK; 1854 } 1855#endif 1856 } 1857 1858 if (err == Z_STREAM_END) 1859 { 1860 err = ZIP_OK; /* this is normal */ 1861 } 1862 1863 if ((zi->ci.pos_in_buffered_data>0) && (err == ZIP_OK)) 1864 { 1865 if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1866 { 1867 err = ZIP_ERRNO; 1868 } 1869 } 1870 1871 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1872 { 1873 int tmp_err = deflateEnd(&zi->ci.stream); 1874 if (err == ZIP_OK) 1875 { 1876 err = tmp_err; 1877 } 1878 zi->ci.stream_initialised = 0; 1879 } 1880#ifdef HAVE_BZIP2 1881 else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) 1882 { 1883 int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); 1884 if (err == ZIP_OK) 1885 { 1886 err = tmperr; 1887 } 1888 zi->ci.stream_initialised = 0; 1889 } 1890#endif 1891 1892 if (!zi->ci.raw) 1893 { 1894 crc32 = (uLong)zi->ci.crc32; 1895 uncompressed_size = zi->ci.totalUncompressedData; 1896 } 1897 compressed_size = zi->ci.totalCompressedData; 1898 1899# ifndef NOCRYPT 1900 compressed_size += zi->ci.crypt_header_size; 1901# endif 1902 1903 // update Current Item crc and sizes, 1904 if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) 1905 { 1906 /*version Made by*/ 1907 zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); 1908 /*version needed*/ 1909 zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); 1910 1911 } 1912 1913 zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ 1914 1915 1916 if(compressed_size >= 0xffffffff) 1917 { 1918 zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ 1919 } 1920 else 1921 { 1922 zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ 1923 } 1924 1925 /// set internal file attributes field 1926 if (zi->ci.stream.data_type == Z_ASCII) 1927 { 1928 zip64local_putValue_inmemory(zi->ci.central_header + 36,(uLong)Z_ASCII,2); 1929 } 1930 1931 if(uncompressed_size >= 0xffffffff) 1932 { 1933 zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ 1934 } 1935 else 1936 { 1937 zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ 1938 } 1939 1940 // Add ZIP64 extra info field for uncompressed size 1941 if(uncompressed_size >= 0xffffffff) 1942 { 1943 datasize += 8; 1944 } 1945 1946 // Add ZIP64 extra info field for compressed size 1947 if(compressed_size >= 0xffffffff) 1948 { 1949 datasize += 8; 1950 } 1951 1952 // Add ZIP64 extra info field for relative offset to local file header of current file 1953 if(zi->ci.pos_local_header >= 0xffffffff) 1954 { 1955 datasize += 8; 1956 } 1957 1958 if(datasize > 0) 1959 { 1960 char* p = NULL; 1961 1962 if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) 1963 { 1964 // we cannot write more data to the buffer that we have room for. 1965 return ZIP_BADZIPFILE; 1966 } 1967 1968 p = zi->ci.central_header + zi->ci.size_centralheader; 1969 1970 // Add Extra Information Header for 'ZIP64 information' 1971 zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID 1972 p += 2; 1973 zip64local_putValue_inmemory(p, datasize, 2); // DataSize 1974 p += 2; 1975 1976 if(uncompressed_size >= 0xffffffff) 1977 { 1978 zip64local_putValue_inmemory(p, uncompressed_size, 8); 1979 p += 8; 1980 } 1981 1982 if(compressed_size >= 0xffffffff) 1983 { 1984 zip64local_putValue_inmemory(p, compressed_size, 8); 1985 p += 8; 1986 } 1987 1988 if(zi->ci.pos_local_header >= 0xffffffff) 1989 { 1990 zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); 1991 p += 8; 1992 } 1993 1994 // Update how much extra free space we got in the memory buffer 1995 // and increase the centralheader size so the new ZIP64 fields are included 1996 // ( 4 below is the size of HeaderID and DataSize field ) 1997 zi->ci.size_centralExtraFree -= datasize + 4; 1998 zi->ci.size_centralheader += datasize + 4; 1999 2000 // Update the extra info size field 2001 zi->ci.size_centralExtra += datasize + 4; 2002 zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); 2003 } 2004 2005 if (err == ZIP_OK) 2006 { 2007 err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); 2008 } 2009 2010 free(zi->ci.central_header); 2011 2012 if (err == ZIP_OK) 2013 { 2014 // Update the LocalFileHeader with the new values. 2015 2016 ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); 2017 2018 if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET) != 0) 2019 { 2020 err = ZIP_ERRNO; 2021 } 2022 2023 if (err==ZIP_OK) 2024 { 2025 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ 2026 } 2027 2028 if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff ) 2029 { 2030 if(zi->ci.pos_zip64extrainfo > 0) 2031 { 2032 // Update the size in the ZIP64 extended field. 2033 if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) 2034 { 2035 err = ZIP_ERRNO; 2036 } 2037 2038 if (err == ZIP_OK) /* compressed size, unknown */ 2039 { 2040 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); 2041 } 2042 2043 if (err == ZIP_OK) /* uncompressed size, unknown */ 2044 { 2045 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); 2046 } 2047 } 2048 else 2049 { 2050 err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal 2051 } 2052 } 2053 else 2054 { 2055 if (err == ZIP_OK) /* compressed size, unknown */ 2056 { 2057 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); 2058 } 2059 2060 if (err == ZIP_OK) /* uncompressed size, unknown */ 2061 { 2062 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); 2063 } 2064 } 2065 2066 if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET) != 0) 2067 { 2068 err = ZIP_ERRNO; 2069 } 2070 } 2071 2072 zi->number_entry ++; 2073 zi->in_opened_file_inzip = 0; 2074 2075 return err; 2076} 2077 2078extern int ZEXPORT zipCloseFileInZip(zipFile file) 2079{ 2080 return zipCloseFileInZipRaw (file,0,0); 2081} 2082 2083local int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) 2084{ 2085 int err = ZIP_OK; 2086 ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset; 2087 2088 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); 2089 2090 /*num disks*/ 2091 if (err == ZIP_OK) /* number of the disk with the start of the central directory */ 2092 { 2093 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); 2094 } 2095 2096 2097 /*relative offset*/ 2098 if (err == ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ 2099 { 2100 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); 2101 } 2102 2103 /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ 2104 if (err == ZIP_OK) /* number of the disk with the start of the central directory */ 2105 { 2106 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); 2107 } 2108 2109 return err; 2110} 2111 2112local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) 2113{ 2114 int err = ZIP_OK; 2115 2116 uLong Zip64DataSize = 44; 2117 2118 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); 2119 2120 if (err == ZIP_OK) /* size of this 'zip64 end of central directory' */ 2121 { 2122 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? 2123 } 2124 2125 if (err == ZIP_OK) /* version made by */ 2126 { 2127 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); 2128 } 2129 2130 if (err == ZIP_OK) /* version needed */ 2131 { 2132 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); 2133 } 2134 2135 if (err == ZIP_OK) /* number of this disk */ 2136 { 2137 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); 2138 } 2139 2140 if (err == ZIP_OK) /* number of the disk with the start of the central directory */ 2141 { 2142 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); 2143 } 2144 2145 if (err == ZIP_OK) /* total number of entries in the central dir on this disk */ 2146 { 2147 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); 2148 } 2149 2150 if (err == ZIP_OK) /* total number of entries in the central dir */ 2151 { 2152 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); 2153 } 2154 2155 if (err == ZIP_OK) /* size of the central directory */ 2156 { 2157 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); 2158 } 2159 2160 if (err == ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ 2161 { 2162 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; 2163 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); 2164 } 2165 return err; 2166} 2167 2168local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) 2169{ 2170 int err = ZIP_OK; 2171 2172 /*signature*/ 2173 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); 2174 2175 if (err == ZIP_OK) /* number of this disk */ 2176 { 2177 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); 2178 } 2179 2180 if (err == ZIP_OK) /* number of the disk with the start of the central directory */ 2181 { 2182 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); 2183 } 2184 2185 if (err == ZIP_OK) /* total number of entries in the central dir on this disk */ 2186 { 2187 { 2188 if(zi->number_entry >= 0xFFFF) 2189 { 2190 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record 2191 } 2192 else 2193 { 2194 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); 2195 } 2196 } 2197 } 2198 2199 if (err == ZIP_OK) /* total number of entries in the central dir */ 2200 { 2201 if(zi->number_entry >= 0xFFFF) 2202 { 2203 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record 2204 } 2205 else 2206 { 2207 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); 2208 } 2209 } 2210 2211 if (err == ZIP_OK) /* size of the central directory */ 2212 { 2213 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); 2214 } 2215 2216 if (err == ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ 2217 { 2218 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; 2219 if(pos >= 0xffffffff) 2220 { 2221 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); 2222 } 2223 else 2224 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writing_offset),4); 2225 } 2226 2227 return err; 2228} 2229 2230local int Write_GlobalComment(zip64_internal* zi, const char* global_comment) 2231{ 2232 int err = ZIP_OK; 2233 uInt size_global_comment = 0; 2234 2235 if(global_comment != NULL) 2236 { 2237 size_global_comment = (uInt)strlen(global_comment); 2238 } 2239 2240 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); 2241 2242 if (err == ZIP_OK && size_global_comment > 0) 2243 { 2244 if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) 2245 { 2246 err = ZIP_ERRNO; 2247 } 2248 } 2249 return err; 2250} 2251 2252extern int ZEXPORT zipClose(zipFile file, const char* global_comment) 2253{ 2254 zip64_internal* zi; 2255 int err = 0; 2256 uLong size_centraldir = 0; 2257 ZPOS64_T centraldir_pos_inzip; 2258 ZPOS64_T pos; 2259 2260 if (file == NULL) 2261 { 2262 return ZIP_PARAMERROR; 2263 } 2264 2265 zi = (zip64_internal*)file; 2266 2267 if (zi->in_opened_file_inzip == 1) 2268 { 2269 err = zipCloseFileInZip (file); 2270 } 2271 2272#ifndef NO_ADDFILEINEXISTINGZIP 2273 if (global_comment == NULL) 2274 { 2275 global_comment = zi->globalcomment; 2276 } 2277#endif 2278 2279 centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); 2280 2281 if (err == ZIP_OK) 2282 { 2283 linkedlist_datablock_internal* ldi = zi->central_dir.first_block; 2284 while (ldi != NULL) 2285 { 2286 if ((err == ZIP_OK) && (ldi->filled_in_this_block>0)) 2287 { 2288 if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) 2289 { 2290 err = ZIP_ERRNO; 2291 } 2292 } 2293 2294 size_centraldir += ldi->filled_in_this_block; 2295 ldi = ldi->next_datablock; 2296 } 2297 } 2298 free_linkedlist(&(zi->central_dir)); 2299 2300 pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; 2301 if(pos >= 0xffffffff || zi->number_entry >= 0xFFFF) 2302 { 2303 ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); 2304 Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); 2305 2306 Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); 2307 } 2308 2309 if (err == ZIP_OK) 2310 { 2311 err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); 2312 } 2313 2314 if(err == ZIP_OK) 2315 { 2316 err = Write_GlobalComment(zi, global_comment); 2317 } 2318 2319 if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) 2320 { 2321 if (err == ZIP_OK) 2322 { 2323 err = ZIP_ERRNO; 2324 } 2325 } 2326 2327#ifndef NO_ADDFILEINEXISTINGZIP 2328 free(zi->globalcomment); 2329#endif 2330 free(zi); 2331 2332 return err; 2333} 2334 2335extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader) 2336{ 2337 char* p = pData; 2338 int size = 0; 2339 char* pNewHeader; 2340 char* pTmp; 2341 short header; 2342 short dataSize; 2343 2344 int retVal = ZIP_OK; 2345 2346 if(pData == NULL || dataLen == NULL || *dataLen < 4) 2347 { 2348 return ZIP_PARAMERROR; 2349 } 2350 2351 pNewHeader = (char*)ALLOC((unsigned)*dataLen); 2352 pTmp = pNewHeader; 2353 2354 while(p < (pData + *dataLen)) 2355 { 2356 header = *(short*)p; 2357 dataSize = *(((short*)p) + 1); 2358 2359 if( header == sHeader ) // Header found. 2360 { 2361 p += dataSize + 4; // skip it. do not copy to temp buffer 2362 } 2363 else 2364 { 2365 // Extra Info block should not be removed, So copy it to the temp buffer. 2366 memcpy(pTmp, p, dataSize + 4); 2367 p += dataSize + 4; 2368 size += dataSize + 4; 2369 } 2370 2371 } 2372 2373 if(size < *dataLen) 2374 { 2375 // clean old extra info block. 2376 memset(pData,0, *dataLen); 2377 2378 // copy the new extra info block over the old 2379 if(size > 0) 2380 { 2381 memcpy(pData, pNewHeader, size); 2382 } 2383 2384 // set the new extra info size 2385 *dataLen = size; 2386 2387 retVal = ZIP_OK; 2388 } 2389 else 2390 { 2391 retVal = ZIP_ERRNO; 2392 } 2393 2394 free(pNewHeader); 2395 2396 return retVal; 2397} 2398