(root)/
gcc-13.2.0/
zlib/
contrib/
minizip/
zip.c
       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 automatically added to items that needs it, and existing ZIP64 data need to be removed.
      19     Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
      20     Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
      21  
      22  */
      23  
      24  
      25  #include <stdio.h>
      26  #include <stdlib.h>
      27  #include <string.h>
      28  #include <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 alignment */
     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_writing_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_writing_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_writing_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_writing_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_writing_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_writing_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_writing_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_writing_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_writing_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  }