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 unsigned long* 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     if (password != NULL)
   1071         return ZIP_PARAMERROR;
   1072 #    endif
   1073 
   1074     if (file == NULL)
   1075         return ZIP_PARAMERROR;
   1076 
   1077 #ifdef HAVE_BZIP2
   1078     if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
   1079       return ZIP_PARAMERROR;
   1080 #else
   1081     if ((method!=0) && (method!=Z_DEFLATED))
   1082       return ZIP_PARAMERROR;
   1083 #endif
   1084 
   1085     zi = (zip64_internal*)file;
   1086 
   1087     if (zi->in_opened_file_inzip == 1)
   1088     {
   1089         err = zipCloseFileInZip (file);
   1090         if (err != ZIP_OK)
   1091             return err;
   1092     }
   1093 
   1094     if (filename==NULL)
   1095         filename="-";
   1096 
   1097     if (comment==NULL)
   1098         size_comment = 0;
   1099     else
   1100         size_comment = (uInt)strlen(comment);
   1101 
   1102     size_filename = (uInt)strlen(filename);
   1103 
   1104     if (zipfi == NULL)
   1105         zi->ci.dosDate = 0;
   1106     else
   1107     {
   1108         if (zipfi->dosDate != 0)
   1109             zi->ci.dosDate = zipfi->dosDate;
   1110         else
   1111           zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
   1112     }
   1113 
   1114     zi->ci.flag = flagBase;
   1115     if ((level==8) || (level==9))
   1116       zi->ci.flag |= 2;
   1117     if ((level==2))
   1118       zi->ci.flag |= 4;
   1119     if ((level==1))
   1120       zi->ci.flag |= 6;
   1121     if (password != NULL)
   1122       zi->ci.flag |= 1;
   1123 
   1124     zi->ci.crc32 = 0;
   1125     zi->ci.method = method;
   1126     zi->ci.encrypt = 0;
   1127     zi->ci.stream_initialised = 0;
   1128     zi->ci.pos_in_buffered_data = 0;
   1129     zi->ci.raw = raw;
   1130     zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
   1131 
   1132     zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
   1133     zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
   1134 
   1135     zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
   1136 
   1137     zi->ci.size_centralExtra = size_extrafield_global;
   1138     zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
   1139     /* version info */
   1140     zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
   1141     zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
   1142     zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
   1143     zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
   1144     zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
   1145     zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
   1146     zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
   1147     zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
   1148     zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
   1149     zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
   1150     zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
   1151     zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
   1152 
   1153     if (zipfi==NULL)
   1154         zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
   1155     else
   1156         zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
   1157 
   1158     if (zipfi==NULL)
   1159         zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
   1160     else
   1161         zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
   1162 
   1163     if(zi->ci.pos_local_header >= 0xffffffff)
   1164       zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
   1165     else
   1166       zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
   1167 
   1168     for (i=0;i<size_filename;i++)
   1169         *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
   1170 
   1171     for (i=0;i<size_extrafield_global;i++)
   1172         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
   1173               *(((const char*)extrafield_global)+i);
   1174 
   1175     for (i=0;i<size_comment;i++)
   1176         *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
   1177               size_extrafield_global+i) = *(comment+i);
   1178     if (zi->ci.central_header == NULL)
   1179         return ZIP_INTERNALERROR;
   1180 
   1181     zi->ci.zip64 = zip64;
   1182     zi->ci.totalCompressedData = 0;
   1183     zi->ci.totalUncompressedData = 0;
   1184     zi->ci.pos_zip64extrainfo = 0;
   1185 
   1186     err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
   1187 
   1188 #ifdef HAVE_BZIP2
   1189     zi->ci.bstream.avail_in = (uInt)0;
   1190     zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
   1191     zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
   1192     zi->ci.bstream.total_in_hi32 = 0;
   1193     zi->ci.bstream.total_in_lo32 = 0;
   1194     zi->ci.bstream.total_out_hi32 = 0;
   1195     zi->ci.bstream.total_out_lo32 = 0;
   1196 #endif
   1197 
   1198     zi->ci.stream.avail_in = (uInt)0;
   1199     zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
   1200     zi->ci.stream.next_out = zi->ci.buffered_data;
   1201     zi->ci.stream.total_in = 0;
   1202     zi->ci.stream.total_out = 0;
   1203     zi->ci.stream.data_type = Z_BINARY;
   1204 
   1205 #ifdef HAVE_BZIP2
   1206     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
   1207 #else
   1208     if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
   1209 #endif
   1210     {
   1211         if(zi->ci.method == Z_DEFLATED)
   1212         {
   1213           zi->ci.stream.zalloc = (alloc_func)0;
   1214           zi->ci.stream.zfree = (free_func)0;
   1215           zi->ci.stream.opaque = (voidpf)0;
   1216 
   1217           if (windowBits>0)
   1218               windowBits = -windowBits;
   1219 
   1220           err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
   1221 
   1222           if (err==Z_OK)
   1223               zi->ci.stream_initialised = Z_DEFLATED;
   1224         }
   1225         else if(zi->ci.method == Z_BZIP2ED)
   1226         {
   1227 #ifdef HAVE_BZIP2
   1228             // Init BZip stuff here
   1229           zi->ci.bstream.bzalloc = 0;
   1230           zi->ci.bstream.bzfree = 0;
   1231           zi->ci.bstream.opaque = (voidpf)0;
   1232 
   1233           err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
   1234           if(err == BZ_OK)
   1235             zi->ci.stream_initialised = Z_BZIP2ED;
   1236 #endif
   1237         }
   1238 
   1239     }
   1240 
   1241 #    ifndef NOCRYPT
   1242     zi->ci.crypt_header_size = 0;
   1243     if ((err==Z_OK) && (password != NULL))
   1244     {
   1245         unsigned char bufHead[RAND_HEAD_LEN];
   1246         unsigned int sizeHead;
   1247         zi->ci.encrypt = 1;
   1248         zi->ci.pcrc_32_tab = get_crc_table();
   1249         /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
   1250 
   1251         sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
   1252         zi->ci.crypt_header_size = sizeHead;
   1253 
   1254         if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
   1255                 err = ZIP_ERRNO;
   1256     }
   1257 #    endif
   1258 
   1259     if (err==Z_OK)
   1260         zi->in_opened_file_inzip = 1;
   1261     return err;
   1262 }
   1263 
   1264 extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
   1265                                          const void* extrafield_local, uInt size_extrafield_local,
   1266                                          const void* extrafield_global, uInt size_extrafield_global,
   1267                                          const char* comment, int method, int level, int raw,
   1268                                          int windowBits,int memLevel, int strategy,
   1269                                          const char* password, uLong crcForCrypting,
   1270                                          uLong versionMadeBy, uLong flagBase)
   1271 {
   1272     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
   1273                                  extrafield_local, size_extrafield_local,
   1274                                  extrafield_global, size_extrafield_global,
   1275                                  comment, method, level, raw,
   1276                                  windowBits, memLevel, strategy,
   1277                                  password, crcForCrypting, versionMadeBy, flagBase, 0);
   1278 }
   1279 
   1280 extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
   1281                                          const void* extrafield_local, uInt size_extrafield_local,
   1282                                          const void* extrafield_global, uInt size_extrafield_global,
   1283                                          const char* comment, int method, int level, int raw,
   1284                                          int windowBits,int memLevel, int strategy,
   1285                                          const char* password, uLong crcForCrypting)
   1286 {
   1287     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
   1288                                  extrafield_local, size_extrafield_local,
   1289                                  extrafield_global, size_extrafield_global,
   1290                                  comment, method, level, raw,
   1291                                  windowBits, memLevel, strategy,
   1292                                  password, crcForCrypting, VERSIONMADEBY, 0, 0);
   1293 }
   1294 
   1295 extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
   1296                                          const void* extrafield_local, uInt size_extrafield_local,
   1297                                          const void* extrafield_global, uInt size_extrafield_global,
   1298                                          const char* comment, int method, int level, int raw,
   1299                                          int windowBits,int memLevel, int strategy,
   1300                                          const char* password, uLong crcForCrypting, int zip64)
   1301 {
   1302     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
   1303                                  extrafield_local, size_extrafield_local,
   1304                                  extrafield_global, size_extrafield_global,
   1305                                  comment, method, level, raw,
   1306                                  windowBits, memLevel, strategy,
   1307                                  password, crcForCrypting, VERSIONMADEBY, 0, zip64);
   1308 }
   1309 
   1310 extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
   1311                                         const void* extrafield_local, uInt size_extrafield_local,
   1312                                         const void* extrafield_global, uInt size_extrafield_global,
   1313                                         const char* comment, int method, int level, int raw)
   1314 {
   1315     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
   1316                                  extrafield_local, size_extrafield_local,
   1317                                  extrafield_global, size_extrafield_global,
   1318                                  comment, method, level, raw,
   1319                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
   1320                                  NULL, 0, VERSIONMADEBY, 0, 0);
   1321 }
   1322 
   1323 extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
   1324                                         const void* extrafield_local, uInt size_extrafield_local,
   1325                                         const void* extrafield_global, uInt size_extrafield_global,
   1326                                         const char* comment, int method, int level, int raw, int zip64)
   1327 {
   1328     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
   1329                                  extrafield_local, size_extrafield_local,
   1330                                  extrafield_global, size_extrafield_global,
   1331                                  comment, method, level, raw,
   1332                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
   1333                                  NULL, 0, VERSIONMADEBY, 0, zip64);
   1334 }
   1335 
   1336 extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
   1337                                         const void* extrafield_local, uInt size_extrafield_local,
   1338                                         const void*extrafield_global, uInt size_extrafield_global,
   1339                                         const char* comment, int method, int level, int zip64)
   1340 {
   1341     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
   1342                                  extrafield_local, size_extrafield_local,
   1343                                  extrafield_global, size_extrafield_global,
   1344                                  comment, method, level, 0,
   1345                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
   1346                                  NULL, 0, VERSIONMADEBY, 0, zip64);
   1347 }
   1348 
   1349 extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
   1350                                         const void* extrafield_local, uInt size_extrafield_local,
   1351                                         const void*extrafield_global, uInt size_extrafield_global,
   1352                                         const char* comment, int method, int level)
   1353 {
   1354     return zipOpenNewFileInZip4_64 (file, filename, zipfi,
   1355                                  extrafield_local, size_extrafield_local,
   1356                                  extrafield_global, size_extrafield_global,
   1357                                  comment, method, level, 0,
   1358                                  -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
   1359                                  NULL, 0, VERSIONMADEBY, 0, 0);
   1360 }
   1361 
   1362 local int zip64FlushWriteBuffer(zip64_internal* zi)
   1363 {
   1364     int err=ZIP_OK;
   1365 
   1366     if (zi->ci.encrypt != 0)
   1367     {
   1368 #ifndef NOCRYPT
   1369         uInt i;
   1370         int t;
   1371         for (i=0;i<zi->ci.pos_in_buffered_data;i++)
   1372             zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
   1373 #endif
   1374     }
   1375 
   1376     if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
   1377       err = ZIP_ERRNO;
   1378 
   1379     zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
   1380 
   1381 #ifdef HAVE_BZIP2
   1382     if(zi->ci.method == Z_BZIP2ED)
   1383     {
   1384       zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
   1385       zi->ci.bstream.total_in_lo32 = 0;
   1386       zi->ci.bstream.total_in_hi32 = 0;
   1387     }
   1388     else
   1389 #endif
   1390     {
   1391       zi->ci.totalUncompressedData += zi->ci.stream.total_in;
   1392       zi->ci.stream.total_in = 0;
   1393     }
   1394 
   1395 
   1396     zi->ci.pos_in_buffered_data = 0;
   1397 
   1398     return err;
   1399 }
   1400 
   1401 extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
   1402 {
   1403     zip64_internal* zi;
   1404     int err=ZIP_OK;
   1405 
   1406     if (file == NULL)
   1407         return ZIP_PARAMERROR;
   1408     zi = (zip64_internal*)file;
   1409 
   1410     if (zi->in_opened_file_inzip == 0)
   1411         return ZIP_PARAMERROR;
   1412 
   1413     zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
   1414 
   1415 #ifdef HAVE_BZIP2
   1416     if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
   1417     {
   1418       zi->ci.bstream.next_in = (void*)buf;
   1419       zi->ci.bstream.avail_in = len;
   1420       err = BZ_RUN_OK;
   1421 
   1422       while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
   1423       {
   1424         if (zi->ci.bstream.avail_out == 0)
   1425         {
   1426           if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
   1427             err = ZIP_ERRNO;
   1428           zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
   1429           zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
   1430         }
   1431 
   1432 
   1433         if(err != BZ_RUN_OK)
   1434           break;
   1435 
   1436         if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
   1437         {
   1438           uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
   1439 //          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
   1440           err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);
   1441 
   1442           zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
   1443         }
   1444       }
   1445 
   1446       if(err == BZ_RUN_OK)
   1447         err = ZIP_OK;
   1448     }
   1449     else
   1450 #endif
   1451     {
   1452       zi->ci.stream.next_in = (Bytef*)buf;
   1453       zi->ci.stream.avail_in = len;
   1454 
   1455       while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
   1456       {
   1457           if (zi->ci.stream.avail_out == 0)
   1458           {
   1459               if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
   1460                   err = ZIP_ERRNO;
   1461               zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
   1462               zi->ci.stream.next_out = zi->ci.buffered_data;
   1463           }
   1464 
   1465 
   1466           if(err != ZIP_OK)
   1467               break;
   1468 
   1469           if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
   1470           {
   1471               uLong uTotalOutBefore = zi->ci.stream.total_out;
   1472               err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
   1473               if(uTotalOutBefore > zi->ci.stream.total_out)
   1474               {
   1475                 int bBreak = 0;
   1476                 bBreak++;
   1477               }
   1478 
   1479               zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
   1480           }
   1481           else
   1482           {
   1483               uInt copy_this,i;
   1484               if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
   1485                   copy_this = zi->ci.stream.avail_in;
   1486               else
   1487                   copy_this = zi->ci.stream.avail_out;
   1488 
   1489               for (i = 0; i < copy_this; i++)
   1490                   *(((char*)zi->ci.stream.next_out)+i) =
   1491                       *(((const char*)zi->ci.stream.next_in)+i);
   1492               {
   1493                   zi->ci.stream.avail_in -= copy_this;
   1494                   zi->ci.stream.avail_out-= copy_this;
   1495                   zi->ci.stream.next_in+= copy_this;
   1496                   zi->ci.stream.next_out+= copy_this;
   1497                   zi->ci.stream.total_in+= copy_this;
   1498                   zi->ci.stream.total_out+= copy_this;
   1499                   zi->ci.pos_in_buffered_data += copy_this;
   1500               }
   1501           }
   1502       }// while(...)
   1503     }
   1504 
   1505     return err;
   1506 }
   1507 
   1508 extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
   1509 {
   1510     return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
   1511 }
   1512 
   1513 extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
   1514 {
   1515     zip64_internal* zi;
   1516     ZPOS64_T compressed_size;
   1517     uLong invalidValue = 0xffffffff;
   1518     short datasize = 0;
   1519     int err=ZIP_OK;
   1520 
   1521     if (file == NULL)
   1522         return ZIP_PARAMERROR;
   1523     zi = (zip64_internal*)file;
   1524 
   1525     if (zi->in_opened_file_inzip == 0)
   1526         return ZIP_PARAMERROR;
   1527     zi->ci.stream.avail_in = 0;
   1528 
   1529     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
   1530                 {
   1531                         while (err==ZIP_OK)
   1532                         {
   1533                                 uLong uTotalOutBefore;
   1534                                 if (zi->ci.stream.avail_out == 0)
   1535                                 {
   1536                                         if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
   1537                                                 err = ZIP_ERRNO;
   1538                                         zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
   1539                                         zi->ci.stream.next_out = zi->ci.buffered_data;
   1540                                 }
   1541                                 uTotalOutBefore = zi->ci.stream.total_out;
   1542                                 err=deflate(&zi->ci.stream,  Z_FINISH);
   1543                                 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
   1544                         }
   1545                 }
   1546     else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
   1547     {
   1548 #ifdef HAVE_BZIP2
   1549       err = BZ_FINISH_OK;
   1550       while (err==BZ_FINISH_OK)
   1551       {
   1552         uLong uTotalOutBefore;
   1553         if (zi->ci.bstream.avail_out == 0)
   1554         {
   1555           if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
   1556             err = ZIP_ERRNO;
   1557           zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
   1558           zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
   1559         }
   1560         uTotalOutBefore = zi->ci.bstream.total_out_lo32;
   1561         err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);
   1562         if(err == BZ_STREAM_END)
   1563           err = Z_STREAM_END;
   1564 
   1565         zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
   1566       }
   1567 
   1568       if(err == BZ_FINISH_OK)
   1569         err = ZIP_OK;
   1570 #endif
   1571     }
   1572 
   1573     if (err==Z_STREAM_END)
   1574         err=ZIP_OK; /* this is normal */
   1575 
   1576     if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
   1577                 {
   1578         if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
   1579             err = ZIP_ERRNO;
   1580                 }
   1581 
   1582     if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
   1583     {
   1584         int tmp_err = deflateEnd(&zi->ci.stream);
   1585         if (err == ZIP_OK)
   1586             err = tmp_err;
   1587         zi->ci.stream_initialised = 0;
   1588     }
   1589 #ifdef HAVE_BZIP2
   1590     else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
   1591     {
   1592       int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
   1593                         if (err==ZIP_OK)
   1594                                 err = tmperr;
   1595                         zi->ci.stream_initialised = 0;
   1596     }
   1597 #endif
   1598 
   1599     if (!zi->ci.raw)
   1600     {
   1601         crc32 = (uLong)zi->ci.crc32;
   1602         uncompressed_size = zi->ci.totalUncompressedData;
   1603     }
   1604     compressed_size = zi->ci.totalCompressedData;
   1605 
   1606 #    ifndef NOCRYPT
   1607     compressed_size += zi->ci.crypt_header_size;
   1608 #    endif
   1609 
   1610     // update Current Item crc and sizes,
   1611     if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
   1612     {
   1613       /*version Made by*/
   1614       zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
   1615       /*version needed*/
   1616       zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
   1617 
   1618     }
   1619 
   1620     zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
   1621 
   1622 
   1623     if(compressed_size >= 0xffffffff)
   1624       zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
   1625     else
   1626       zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
   1627 
   1628     /// set internal file attributes field
   1629     if (zi->ci.stream.data_type == Z_ASCII)
   1630         zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
   1631 
   1632     if(uncompressed_size >= 0xffffffff)
   1633       zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
   1634     else
   1635       zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
   1636 
   1637     // Add ZIP64 extra info field for uncompressed size
   1638     if(uncompressed_size >= 0xffffffff)
   1639       datasize += 8;
   1640 
   1641     // Add ZIP64 extra info field for compressed size
   1642     if(compressed_size >= 0xffffffff)
   1643       datasize += 8;
   1644 
   1645     // Add ZIP64 extra info field for relative offset to local file header of current file
   1646     if(zi->ci.pos_local_header >= 0xffffffff)
   1647       datasize += 8;
   1648 
   1649     if(datasize > 0)
   1650     {
   1651       char* p = NULL;
   1652 
   1653       if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
   1654       {
   1655         // we can not write more data to the buffer that we have room for.
   1656         return ZIP_BADZIPFILE;
   1657       }
   1658 
   1659       p = zi->ci.central_header + zi->ci.size_centralheader;
   1660 
   1661       // Add Extra Information Header for 'ZIP64 information'
   1662       zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
   1663       p += 2;
   1664       zip64local_putValue_inmemory(p, datasize, 2); // DataSize
   1665       p += 2;
   1666 
   1667       if(uncompressed_size >= 0xffffffff)
   1668       {
   1669         zip64local_putValue_inmemory(p, uncompressed_size, 8);
   1670         p += 8;
   1671       }
   1672 
   1673       if(compressed_size >= 0xffffffff)
   1674       {
   1675         zip64local_putValue_inmemory(p, compressed_size, 8);
   1676         p += 8;
   1677       }
   1678 
   1679       if(zi->ci.pos_local_header >= 0xffffffff)
   1680       {
   1681         zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
   1682         p += 8;
   1683       }
   1684 
   1685       // Update how much extra free space we got in the memory buffer
   1686       // and increase the centralheader size so the new ZIP64 fields are included
   1687       // ( 4 below is the size of HeaderID and DataSize field )
   1688       zi->ci.size_centralExtraFree -= datasize + 4;
   1689       zi->ci.size_centralheader += datasize + 4;
   1690 
   1691       // Update the extra info size field
   1692       zi->ci.size_centralExtra += datasize + 4;
   1693       zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
   1694     }
   1695 
   1696     if (err==ZIP_OK)
   1697         err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
   1698 
   1699     free(zi->ci.central_header);
   1700 
   1701     if (err==ZIP_OK)
   1702     {
   1703         // Update the LocalFileHeader with the new values.
   1704 
   1705         ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
   1706 
   1707         if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
   1708             err = ZIP_ERRNO;
   1709 
   1710         if (err==ZIP_OK)
   1711             err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
   1712 
   1713         if(uncompressed_size >= 0xffffffff)
   1714         {
   1715           if(zi->ci.pos_zip64extrainfo > 0)
   1716           {
   1717             // Update the size in the ZIP64 extended field.
   1718             if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
   1719               err = ZIP_ERRNO;
   1720 
   1721             if (err==ZIP_OK) /* compressed size, unknown */
   1722               err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
   1723 
   1724             if (err==ZIP_OK) /* uncompressed size, unknown */
   1725               err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
   1726           }
   1727         }
   1728         else
   1729         {
   1730           if (err==ZIP_OK) /* compressed size, unknown */
   1731               err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
   1732 
   1733           if (err==ZIP_OK) /* uncompressed size, unknown */
   1734               err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
   1735         }
   1736 
   1737         if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
   1738             err = ZIP_ERRNO;
   1739     }
   1740 
   1741     zi->number_entry ++;
   1742     zi->in_opened_file_inzip = 0;
   1743 
   1744     return err;
   1745 }
   1746 
   1747 extern int ZEXPORT zipCloseFileInZip (zipFile file)
   1748 {
   1749     return zipCloseFileInZipRaw (file,0,0);
   1750 }
   1751 
   1752 int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
   1753 {
   1754   int err = ZIP_OK;
   1755   ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
   1756 
   1757   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
   1758 
   1759   /*num disks*/
   1760     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
   1761       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
   1762 
   1763   /*relative offset*/
   1764     if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
   1765       err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
   1766 
   1767   /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
   1768     if (err==ZIP_OK) /* number of the disk with the start of the central directory */
   1769       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
   1770 
   1771     return err;
   1772 }
   1773 
   1774 int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
   1775 {
   1776   int err = ZIP_OK;
   1777 
   1778   uLong Zip64DataSize = 44;
   1779 
   1780   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
   1781 
   1782   if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
   1783     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
   1784 
   1785   if (err==ZIP_OK) /* version made by */
   1786     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
   1787 
   1788   if (err==ZIP_OK) /* version needed */
   1789     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
   1790 
   1791   if (err==ZIP_OK) /* number of this disk */
   1792     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
   1793 
   1794   if (err==ZIP_OK) /* number of the disk with the start of the central directory */
   1795     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
   1796 
   1797   if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
   1798     err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
   1799 
   1800   if (err==ZIP_OK) /* total number of entries in the central dir */
   1801     err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
   1802 
   1803   if (err==ZIP_OK) /* size of the central directory */
   1804     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
   1805 
   1806   if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
   1807   {
   1808     ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
   1809     err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
   1810   }
   1811   return err;
   1812 }
   1813 int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
   1814 {
   1815   int err = ZIP_OK;
   1816 
   1817   /*signature*/
   1818   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
   1819 
   1820   if (err==ZIP_OK) /* number of this disk */
   1821     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
   1822 
   1823   if (err==ZIP_OK) /* number of the disk with the start of the central directory */
   1824     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
   1825 
   1826   if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
   1827   {
   1828     {
   1829       if(zi->number_entry >= 0xFFFF)
   1830         err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
   1831       else
   1832         err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
   1833     }
   1834   }
   1835 
   1836   if (err==ZIP_OK) /* total number of entries in the central dir */
   1837   {
   1838     if(zi->number_entry >= 0xFFFF)
   1839       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
   1840     else
   1841       err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
   1842   }
   1843 
   1844   if (err==ZIP_OK) /* size of the central directory */
   1845     err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
   1846 
   1847   if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
   1848   {
   1849     ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
   1850     if(pos >= 0xffffffff)
   1851     {
   1852       err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
   1853     }
   1854     else
   1855                   err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
   1856   }
   1857 
   1858    return err;
   1859 }
   1860 
   1861 int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
   1862 {
   1863   int err = ZIP_OK;
   1864   uInt size_global_comment = 0;
   1865 
   1866   if(global_comment != NULL)
   1867     size_global_comment = (uInt)strlen(global_comment);
   1868 
   1869   err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
   1870 
   1871   if (err == ZIP_OK && size_global_comment > 0)
   1872   {
   1873     if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
   1874       err = ZIP_ERRNO;
   1875   }
   1876   return err;
   1877 }
   1878 
   1879 extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
   1880 {
   1881     zip64_internal* zi;
   1882     int err = 0;
   1883     uLong size_centraldir = 0;
   1884     ZPOS64_T centraldir_pos_inzip;
   1885     ZPOS64_T pos;
   1886 
   1887     if (file == NULL)
   1888         return ZIP_PARAMERROR;
   1889 
   1890     zi = (zip64_internal*)file;
   1891 
   1892     if (zi->in_opened_file_inzip == 1)
   1893     {
   1894         err = zipCloseFileInZip (file);
   1895     }
   1896 
   1897 #ifndef NO_ADDFILEINEXISTINGZIP
   1898     if (global_comment==NULL)
   1899         global_comment = zi->globalcomment;
   1900 #endif
   1901 
   1902     centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
   1903 
   1904     if (err==ZIP_OK)
   1905     {
   1906         linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
   1907         while (ldi!=NULL)
   1908         {
   1909             if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
   1910             {
   1911                 if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
   1912                     err = ZIP_ERRNO;
   1913             }
   1914 
   1915             size_centraldir += ldi->filled_in_this_block;
   1916             ldi = ldi->next_datablock;
   1917         }
   1918     }
   1919     free_linkedlist(&(zi->central_dir));
   1920 
   1921     pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
   1922     if(pos >= 0xffffffff)
   1923     {
   1924       ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
   1925       Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
   1926 
   1927       Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
   1928     }
   1929 
   1930     if (err==ZIP_OK)
   1931       err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
   1932 
   1933     if(err == ZIP_OK)
   1934       err = Write_GlobalComment(zi, global_comment);
   1935 
   1936     if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
   1937         if (err == ZIP_OK)
   1938             err = ZIP_ERRNO;
   1939 
   1940 #ifndef NO_ADDFILEINEXISTINGZIP
   1941     TRYFREE(zi->globalcomment);
   1942 #endif
   1943     TRYFREE(zi);
   1944 
   1945     return err;
   1946 }
   1947 
   1948 extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
   1949 {
   1950   char* p = pData;
   1951   int size = 0;
   1952   char* pNewHeader;
   1953   char* pTmp;
   1954   short header;
   1955   short dataSize;
   1956 
   1957   int retVal = ZIP_OK;
   1958 
   1959   if(pData == NULL || *dataLen < 4)
   1960     return ZIP_PARAMERROR;
   1961 
   1962   pNewHeader = (char*)ALLOC(*dataLen);
   1963   pTmp = pNewHeader;
   1964 
   1965   while(p < (pData + *dataLen))
   1966   {
   1967     header = *(short*)p;
   1968     dataSize = *(((short*)p)+1);
   1969 
   1970     if( header == sHeader ) // Header found.
   1971     {
   1972       p += dataSize + 4; // skip it. do not copy to temp buffer
   1973     }
   1974     else
   1975     {
   1976       // Extra Info block should not be removed, So copy it to the temp buffer.
   1977       memcpy(pTmp, p, dataSize + 4);
   1978       p += dataSize + 4;
   1979       size += dataSize + 4;
   1980     }
   1981 
   1982   }
   1983 
   1984   if(size < *dataLen)
   1985   {
   1986     // clean old extra info block.
   1987     memset(pData,0, *dataLen);
   1988 
   1989     // copy the new extra info block over the old
   1990     if(size > 0)
   1991       memcpy(pData, pNewHeader, size);
   1992 
   1993     // set the new extra info size
   1994     *dataLen = size;
   1995 
   1996     retVal = ZIP_OK;
   1997   }
   1998   else
   1999     retVal = ZIP_ERRNO;
   2000 
   2001   TRYFREE(pNewHeader);
   2002 
   2003   return retVal;
   2004 }
   2005