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