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