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 )
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
7 Modifications for Zip64 support
8 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
10 For more info read MiniZip_info.txt
13 Oct-2009 - Mathias Svensson - Remove old C style function prototypes
14 Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
15 Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
16 Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
17 It is used when recreting zip archive with RAW when deleting items from a zip.
18 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
19 Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
20 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
29 #include "third_party/zlib/zlib.h"
47 /* compile with -Dlocal if your debugger can't find static symbols */
50 # define VERSIONMADEBY (0x0) /* platform depedent */
54 #define Z_BUFSIZE (64*1024) //(16384)
57 #ifndef Z_MAXFILENAMEINZIP
58 #define Z_MAXFILENAMEINZIP (256)
62 # define ALLOC(size) (malloc(size))
65 # define TRYFREE(p) {if (p) free(p);}
69 #define SIZECENTRALDIRITEM (0x2e)
70 #define SIZEZIPLOCALHEADER (0x1e)
73 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
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))
92 #if MAX_MEM_LEVEL >= 8
93 # define DEF_MEM_LEVEL 8
95 # define DEF_MEM_LEVEL MAX_MEM_LEVEL
98 const char zip_copyright
[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
101 #define SIZEDATA_INDATABLOCK (4096-(4*4))
103 #define LOCALHEADERMAGIC (0x04034b50)
104 #define CENTRALHEADERMAGIC (0x02014b50)
105 #define ENDHEADERMAGIC (0x06054b50)
106 #define ZIP64ENDHEADERMAGIC (0x6064b50)
107 #define ZIP64ENDLOCHEADERMAGIC (0x7064b50)
109 #define FLAG_LOCALHEADER_OFFSET (0x06)
110 #define CRC_LOCALHEADER_OFFSET (0x0e)
112 #define SIZECENTRALHEADER (0x2e) /* 46 */
114 typedef struct linkedlist_datablock_internal_s
116 struct linkedlist_datablock_internal_s
* next_datablock
;
117 uLong avail_in_this_block
;
118 uLong filled_in_this_block
;
119 uLong unused
; /* for future use and alignement */
120 unsigned char data
[SIZEDATA_INDATABLOCK
];
121 } linkedlist_datablock_internal
;
123 typedef struct linkedlist_data_s
125 linkedlist_datablock_internal
* first_block
;
126 linkedlist_datablock_internal
* last_block
;
132 z_stream stream
; /* zLib stream structure for inflate */
134 bz_stream bstream
; /* bzLib stream structure for bziped */
137 int stream_initialised
; /* 1 is stream is initialised */
138 uInt pos_in_buffered_data
; /* last written byte in buffered_data */
140 ZPOS64_T pos_local_header
; /* offset of the local header of the file
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 */
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*/
154 int zip64
; /* Add ZIP64 extened information in the extra field */
155 ZPOS64_T pos_zip64extrainfo
;
156 ZPOS64_T totalCompressedData
;
157 ZPOS64_T totalUncompressedData
;
159 unsigned long keys
[3]; /* keys defining the pseudo-random sequence */
160 const unsigned long* pcrc_32_tab
;
161 int crypt_header_size
;
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 */
173 ZPOS64_T begin_pos
; /* position of the beginning of the zipfile */
174 ZPOS64_T add_position_when_writting_offset
;
175 ZPOS64_T number_entry
;
177 #ifndef NO_ADDFILEINEXISTINGZIP
185 #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
189 local linkedlist_datablock_internal
* allocate_new_datablock()
191 linkedlist_datablock_internal
* ldi
;
192 ldi
= (linkedlist_datablock_internal
*)
193 ALLOC(sizeof(linkedlist_datablock_internal
));
196 ldi
->next_datablock
= NULL
;
197 ldi
->filled_in_this_block
= 0 ;
198 ldi
->avail_in_this_block
= SIZEDATA_INDATABLOCK
;
203 local
void free_datablock(linkedlist_datablock_internal
* ldi
)
207 linkedlist_datablock_internal
* ldinext
= ldi
->next_datablock
;
213 local
void init_linkedlist(linkedlist_data
* ll
)
215 ll
->first_block
= ll
->last_block
= NULL
;
218 local
void free_linkedlist(linkedlist_data
* ll
)
220 free_datablock(ll
->first_block
);
221 ll
->first_block
= ll
->last_block
= NULL
;
225 local
int add_data_in_datablock(linkedlist_data
* ll
, const void* buf
, uLong len
)
227 linkedlist_datablock_internal
* ldi
;
228 const unsigned char* from_copy
;
231 return ZIP_INTERNALERROR
;
233 if (ll
->last_block
== NULL
)
235 ll
->first_block
= ll
->last_block
= allocate_new_datablock();
236 if (ll
->first_block
== NULL
)
237 return ZIP_INTERNALERROR
;
240 ldi
= ll
->last_block
;
241 from_copy
= (unsigned char*)buf
;
247 unsigned char* to_copy
;
249 if (ldi
->avail_in_this_block
==0)
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
;
258 if (ldi
->avail_in_this_block
< len
)
259 copy_this
= (uInt
)ldi
->avail_in_this_block
;
261 copy_this
= (uInt
)len
;
263 to_copy
= &(ldi
->data
[ldi
->filled_in_this_block
]);
265 for (i
=0;i
<copy_this
;i
++)
266 *(to_copy
+i
)=*(from_copy
+i
);
268 ldi
->filled_in_this_block
+= copy_this
;
269 ldi
->avail_in_this_block
-= copy_this
;
270 from_copy
+= copy_this
;
278 /****************************************************************************/
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)
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
)
289 unsigned char buf
[8];
291 for (n
= 0; n
< nbByte
; n
++)
293 buf
[n
] = (unsigned char)(x
& 0xff);
297 { /* data overflow - hack for ZIP64 (X Roche) */
298 for (n
= 0; n
< nbByte
; n
++)
304 if (ZWRITE64(*pzlib_filefunc_def
,filestream
,buf
,nbByte
)!=(uLong
)nbByte
)
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
)
313 unsigned char* buf
=(unsigned char*)dest
;
315 for (n
= 0; n
< nbByte
; n
++) {
316 buf
[n
] = (unsigned char)(x
& 0xff);
321 { /* data overflow - hack for ZIP64 */
322 for (n
= 0; n
< nbByte
; n
++)
329 /****************************************************************************/
332 local uLong
zip64local_TmzDateToDosDate(const tm_zip
* ptm
)
334 uLong year
= (uLong
)ptm
->tm_year
;
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
));
345 /****************************************************************************/
347 local
int zip64local_getByte
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, int *pi
));
349 local
int zip64local_getByte(const zlib_filefunc64_32_def
* pzlib_filefunc_def
,voidpf filestream
,int* pi
)
352 int err
= (int)ZREAD64(*pzlib_filefunc_def
,filestream
,&c
,1);
360 if (ZERROR64(*pzlib_filefunc_def
,filestream
))
368 /* ===========================================================================
369 Reads a long in LSB order from the given gz_stream. Sets
371 local
int zip64local_getShort
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, uLong
*pX
));
373 local
int zip64local_getShort (const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, uLong
* pX
)
379 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
383 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
393 local
int zip64local_getLong
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, uLong
*pX
));
395 local
int zip64local_getLong (const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, uLong
* pX
)
401 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
405 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
409 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
413 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
423 local
int zip64local_getLong64
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, ZPOS64_T
*pX
));
426 local
int zip64local_getLong64 (const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, ZPOS64_T
*pX
)
432 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
436 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
437 x
+= ((ZPOS64_T
)i
)<<8;
440 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
441 x
+= ((ZPOS64_T
)i
)<<16;
444 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
445 x
+= ((ZPOS64_T
)i
)<<24;
448 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
449 x
+= ((ZPOS64_T
)i
)<<32;
452 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
453 x
+= ((ZPOS64_T
)i
)<<40;
456 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
457 x
+= ((ZPOS64_T
)i
)<<48;
460 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
461 x
+= ((ZPOS64_T
)i
)<<56;
471 #ifndef BUFREADCOMMENT
472 #define BUFREADCOMMENT (0x400)
475 Locate the Central directory of a zipfile (at the end, just before
478 local ZPOS64_T zip64local_SearchCentralDir
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
));
480 local ZPOS64_T
zip64local_SearchCentralDir(const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
)
485 ZPOS64_T uMaxBack
=0xffff; /* maximum size of global comment */
486 ZPOS64_T uPosFound
=0;
488 if (ZSEEK64(*pzlib_filefunc_def
,filestream
,0,ZLIB_FILEFUNC_SEEK_END
) != 0)
492 uSizeFile
= ZTELL64(*pzlib_filefunc_def
,filestream
);
494 if (uMaxBack
>uSizeFile
)
495 uMaxBack
= uSizeFile
;
497 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
502 while (uBackRead
<uMaxBack
)
507 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
508 uBackRead
= uMaxBack
;
510 uBackRead
+=BUFREADCOMMENT
;
511 uReadPos
= uSizeFile
-uBackRead
;
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)
518 if (ZREAD64(*pzlib_filefunc_def
,filestream
,buf
,uReadSize
)!=uReadSize
)
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))
525 uPosFound
= uReadPos
+i
;
537 Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
540 local ZPOS64_T zip64local_SearchCentralDir64
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
));
542 local ZPOS64_T
zip64local_SearchCentralDir64(const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
)
547 ZPOS64_T uMaxBack
=0xffff; /* maximum size of global comment */
548 ZPOS64_T uPosFound
=0;
550 ZPOS64_T relativeOffset
;
552 if (ZSEEK64(*pzlib_filefunc_def
,filestream
,0,ZLIB_FILEFUNC_SEEK_END
) != 0)
555 uSizeFile
= ZTELL64(*pzlib_filefunc_def
,filestream
);
557 if (uMaxBack
>uSizeFile
)
558 uMaxBack
= uSizeFile
;
560 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
565 while (uBackRead
<uMaxBack
)
570 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
571 uBackRead
= uMaxBack
;
573 uBackRead
+=BUFREADCOMMENT
;
574 uReadPos
= uSizeFile
-uBackRead
;
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)
581 if (ZREAD64(*pzlib_filefunc_def
,filestream
,buf
,uReadSize
)!=uReadSize
)
584 for (i
=(int)uReadSize
-3; (i
--)>0;)
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))
589 uPosFound
= uReadPos
+i
;
602 /* Zip64 end of central directory locator */
603 if (ZSEEK64(*pzlib_filefunc_def
,filestream
, uPosFound
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
606 /* the signature, already checked */
607 if (zip64local_getLong(pzlib_filefunc_def
,filestream
,&uL
)!=ZIP_OK
)
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
)
616 /* relative offset of the zip64 end of central directory record */
617 if (zip64local_getLong64(pzlib_filefunc_def
,filestream
,&relativeOffset
)!=ZIP_OK
)
620 /* total number of disks */
621 if (zip64local_getLong(pzlib_filefunc_def
,filestream
,&uL
)!=ZIP_OK
)
626 /* Goto Zip64 end of central directory record */
627 if (ZSEEK64(*pzlib_filefunc_def
,filestream
, relativeOffset
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
631 if (zip64local_getLong(pzlib_filefunc_def
,filestream
,&uL
)!=ZIP_OK
)
634 if (uL
!= 0x06064b50) // signature of 'Zip64 end of central directory'
637 return relativeOffset
;
640 int LoadCentralDirectoryRecord(zip64_internal
* pziinit
)
643 ZPOS64_T byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
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
;
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
657 (same than number_entry on nospan) */
662 int hasZIP64Record
= 0;
664 // check first if we find a ZIP64 record
665 central_pos
= zip64local_SearchCentralDir64(&pziinit
->z_filefunc
,pziinit
->filestream
);
670 else if(central_pos
== 0)
672 central_pos
= zip64local_SearchCentralDir(&pziinit
->z_filefunc
,pziinit
->filestream
);
675 /* disable to allow appending to empty ZIP archive
682 ZPOS64_T sizeEndOfCentralDirectory
;
683 if (ZSEEK64(pziinit
->z_filefunc
, pziinit
->filestream
, central_pos
, ZLIB_FILEFUNC_SEEK_SET
) != 0)
686 /* the signature, already checked */
687 if (zip64local_getLong(&pziinit
->z_filefunc
, pziinit
->filestream
,&uL
)!=ZIP_OK
)
690 /* size of zip64 end of central directory record */
691 if (zip64local_getLong64(&pziinit
->z_filefunc
, pziinit
->filestream
, &sizeEndOfCentralDirectory
)!=ZIP_OK
)
694 /* version made by */
695 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
, &VersionMadeBy
)!=ZIP_OK
)
698 /* version needed to extract */
699 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
, &VersionNeeded
)!=ZIP_OK
)
702 /* number of this disk */
703 if (zip64local_getLong(&pziinit
->z_filefunc
, pziinit
->filestream
,&number_disk
)!=ZIP_OK
)
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
)
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
)
714 /* total number of entries in the central directory */
715 if (zip64local_getLong64(&pziinit
->z_filefunc
, pziinit
->filestream
,&number_entry_CD
)!=ZIP_OK
)
718 if ((number_entry_CD
!=number_entry
) || (number_disk_with_CD
!=0) || (number_disk
!=0))
721 /* size of the central directory */
722 if (zip64local_getLong64(&pziinit
->z_filefunc
, pziinit
->filestream
,&size_central_dir
)!=ZIP_OK
)
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
)
731 // read the comment from the standard central header.
736 // Read End of central Directory info
737 if (ZSEEK64(pziinit
->z_filefunc
, pziinit
->filestream
, central_pos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
740 /* the signature, already checked */
741 if (zip64local_getLong(&pziinit
->z_filefunc
, pziinit
->filestream
,&uL
)!=ZIP_OK
)
744 /* number of this disk */
745 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
,&number_disk
)!=ZIP_OK
)
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
)
752 /* total number of entries in the central dir on this disk */
754 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
, &uL
)!=ZIP_OK
)
759 /* total number of entries in the central dir */
761 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
, &uL
)!=ZIP_OK
)
764 number_entry_CD
= uL
;
766 if ((number_entry_CD
!=number_entry
) || (number_disk_with_CD
!=0) || (number_disk
!=0))
769 /* size of the central directory */
770 size_central_dir
= 0;
771 if (zip64local_getLong(&pziinit
->z_filefunc
, pziinit
->filestream
, &uL
)!=ZIP_OK
)
774 size_central_dir
= uL
;
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
)
781 offset_central_dir
= uL
;
784 /* zipfile global comment length */
785 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
, &size_comment
)!=ZIP_OK
)
789 if ((central_pos
<offset_central_dir
+size_central_dir
) &&
795 ZCLOSE64(pziinit
->z_filefunc
, pziinit
->filestream
);
801 pziinit
->globalcomment
= (char*)ALLOC(size_comment
+1);
802 if (pziinit
->globalcomment
)
804 size_comment
= ZREAD64(pziinit
->z_filefunc
, pziinit
->filestream
, pziinit
->globalcomment
,size_comment
);
805 pziinit
->globalcomment
[size_comment
]=0;
809 byte_before_the_zipfile
= central_pos
- (offset_central_dir
+size_central_dir
);
810 pziinit
->add_position_when_writting_offset
= byte_before_the_zipfile
;
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)
819 while ((size_central_dir_to_read
>0) && (err
==ZIP_OK
))
821 ZPOS64_T read_this
= SIZEDATA_INDATABLOCK
;
822 if (read_this
> size_central_dir_to_read
)
823 read_this
= size_central_dir_to_read
;
825 if (ZREAD64(pziinit
->z_filefunc
, pziinit
->filestream
,buf_read
,(uLong
)read_this
) != read_this
)
829 err
= add_data_in_datablock(&pziinit
->central_dir
,buf_read
, (uLong
)read_this
);
831 size_central_dir_to_read
-=read_this
;
835 pziinit
->begin_pos
= byte_before_the_zipfile
;
836 pziinit
->number_entry
= number_entry_CD
;
838 if (ZSEEK64(pziinit
->z_filefunc
, pziinit
->filestream
, offset_central_dir
+byte_before_the_zipfile
,ZLIB_FILEFUNC_SEEK_SET
) != 0)
845 #endif /* !NO_ADDFILEINEXISTINGZIP*/
848 /************************************************************/
849 extern zipFile ZEXPORT
zipOpen3 (const void *pathname
, int append
, zipcharpc
* globalcomment
, zlib_filefunc64_32_def
* pzlib_filefunc64_32_def
)
851 zip64_internal ziinit
;
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
);
860 ziinit
.z_filefunc
= *pzlib_filefunc64_32_def
;
862 ziinit
.filestream
= ZOPEN64(ziinit
.z_filefunc
,
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
));
868 if (ziinit
.filestream
== NULL
)
871 if (append
== APPEND_STATUS_CREATEAFTER
)
872 ZSEEK64(ziinit
.z_filefunc
,ziinit
.filestream
,0,SEEK_END
);
874 ziinit
.begin_pos
= ZTELL64(ziinit
.z_filefunc
,ziinit
.filestream
);
875 ziinit
.in_opened_file_inzip
= 0;
876 ziinit
.ci
.stream_initialised
= 0;
877 ziinit
.number_entry
= 0;
878 ziinit
.add_position_when_writting_offset
= 0;
879 init_linkedlist(&(ziinit
.central_dir
));
883 zi
= (zip64_internal
*)ALLOC(sizeof(zip64_internal
));
886 ZCLOSE64(ziinit
.z_filefunc
,ziinit
.filestream
);
890 /* now we add file in a zipfile */
891 # ifndef NO_ADDFILEINEXISTINGZIP
892 ziinit
.globalcomment
= NULL
;
893 if (append
== APPEND_STATUS_ADDINZIP
)
895 // Read and Cache Central Directory Records
896 err
= LoadCentralDirectoryRecord(&ziinit
);
901 *globalcomment
= ziinit
.globalcomment
;
903 # endif /* !NO_ADDFILEINEXISTINGZIP*/
907 # ifndef NO_ADDFILEINEXISTINGZIP
908 TRYFREE(ziinit
.globalcomment
);
909 # endif /* !NO_ADDFILEINEXISTINGZIP*/
920 extern zipFile ZEXPORT
zipOpen2 (const char *pathname
, int append
, zipcharpc
* globalcomment
, zlib_filefunc_def
* pzlib_filefunc32_def
)
922 if (pzlib_filefunc32_def
!= NULL
)
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
);
929 return zipOpen3(pathname
, append
, globalcomment
, NULL
);
932 extern zipFile ZEXPORT
zipOpen2_64 (const void *pathname
, int append
, zipcharpc
* globalcomment
, zlib_filefunc64_def
* pzlib_filefunc_def
)
934 if (pzlib_filefunc_def
!= NULL
)
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
);
943 return zipOpen3(pathname
, append
, globalcomment
, NULL
);
948 extern zipFile ZEXPORT
zipOpen (const char* pathname
, int append
)
950 return zipOpen3((const void*)pathname
,append
,NULL
,NULL
);
953 extern zipFile ZEXPORT
zipOpen64 (const void* pathname
, int append
)
955 return zipOpen3(pathname
,append
,NULL
,NULL
);
958 int Write_LocalFileHeader(zip64_internal
* zi
, const char* filename
, uInt size_extrafield_local
, const void* extrafield_local
)
960 /* write the local header */
962 uInt size_filename
= (uInt
)strlen(filename
);
963 uInt size_extrafield
= size_extrafield_local
;
965 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)LOCALHEADERMAGIC
, 4);
970 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)45,2);/* version needed to extract */
972 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)20,2);/* version needed to extract */
976 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->ci
.flag
,2);
979 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->ci
.method
,2);
982 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->ci
.dosDate
,4);
984 // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
986 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4); /* crc 32, unknown */
990 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0xFFFFFFFF,4); /* compressed size, unknown */
992 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4); /* compressed size, unknown */
997 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0xFFFFFFFF,4); /* uncompressed size, unknown */
999 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4); /* uncompressed size, unknown */
1003 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_filename
,2);
1007 size_extrafield
+= 20;
1011 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_extrafield
,2);
1013 if ((err
==ZIP_OK
) && (size_filename
> 0))
1015 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
,filename
,size_filename
)!=size_filename
)
1019 if ((err
==ZIP_OK
) && (size_extrafield_local
> 0))
1021 if (ZWRITE64(zi
->z_filefunc
, zi
->filestream
, extrafield_local
, size_extrafield_local
) != size_extrafield_local
)
1026 if ((err
==ZIP_OK
) && (zi
->ci
.zip64
))
1028 // write the Zip64 extended info
1030 short DataSize
= 16;
1031 ZPOS64_T CompressedSize
= 0;
1032 ZPOS64_T UncompressedSize
= 0;
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
);
1037 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, (short)HeaderID
,2);
1038 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, (short)DataSize
,2);
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);
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
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.
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
)
1070 if (password
!= NULL
)
1071 return ZIP_PARAMERROR
;
1075 return ZIP_PARAMERROR
;
1078 if ((method
!=0) && (method
!=Z_DEFLATED
) && (method
!=Z_BZIP2ED
))
1079 return ZIP_PARAMERROR
;
1081 if ((method
!=0) && (method
!=Z_DEFLATED
))
1082 return ZIP_PARAMERROR
;
1085 zi
= (zip64_internal
*)file
;
1087 if (zi
->in_opened_file_inzip
== 1)
1089 err
= zipCloseFileInZip (file
);
1100 size_comment
= (uInt
)strlen(comment
);
1102 size_filename
= (uInt
)strlen(filename
);
1108 if (zipfi
->dosDate
!= 0)
1109 zi
->ci
.dosDate
= zipfi
->dosDate
;
1111 zi
->ci
.dosDate
= zip64local_TmzDateToDosDate(&zipfi
->tmz_date
);
1114 zi
->ci
.flag
= flagBase
;
1115 if ((level
==8) || (level
==9))
1121 if (password
!= NULL
)
1125 zi
->ci
.method
= method
;
1127 zi
->ci
.stream_initialised
= 0;
1128 zi
->ci
.pos_in_buffered_data
= 0;
1130 zi
->ci
.pos_local_header
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1132 zi
->ci
.size_centralheader
= SIZECENTRALHEADER
+ size_filename
+ size_extrafield_global
+ size_comment
;
1133 zi
->ci
.size_centralExtraFree
= 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
1135 zi
->ci
.central_header
= (char*)ALLOC((uInt
)zi
->ci
.size_centralheader
+ zi
->ci
.size_centralExtraFree
);
1137 zi
->ci
.size_centralExtra
= size_extrafield_global
;
1138 zip64local_putValue_inmemory(zi
->ci
.central_header
,(uLong
)CENTRALHEADERMAGIC
,4);
1140 zip64local_putValue_inmemory(zi
->ci
.central_header
+4,(uLong
)versionMadeBy
,2);
1141 zip64local_putValue_inmemory(zi
->ci
.central_header
+6,(uLong
)20,2);
1142 zip64local_putValue_inmemory(zi
->ci
.central_header
+8,(uLong
)zi
->ci
.flag
,2);
1143 zip64local_putValue_inmemory(zi
->ci
.central_header
+10,(uLong
)zi
->ci
.method
,2);
1144 zip64local_putValue_inmemory(zi
->ci
.central_header
+12,(uLong
)zi
->ci
.dosDate
,4);
1145 zip64local_putValue_inmemory(zi
->ci
.central_header
+16,(uLong
)0,4); /*crc*/
1146 zip64local_putValue_inmemory(zi
->ci
.central_header
+20,(uLong
)0,4); /*compr size*/
1147 zip64local_putValue_inmemory(zi
->ci
.central_header
+24,(uLong
)0,4); /*uncompr size*/
1148 zip64local_putValue_inmemory(zi
->ci
.central_header
+28,(uLong
)size_filename
,2);
1149 zip64local_putValue_inmemory(zi
->ci
.central_header
+30,(uLong
)size_extrafield_global
,2);
1150 zip64local_putValue_inmemory(zi
->ci
.central_header
+32,(uLong
)size_comment
,2);
1151 zip64local_putValue_inmemory(zi
->ci
.central_header
+34,(uLong
)0,2); /*disk nm start*/
1154 zip64local_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)0,2);
1156 zip64local_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)zipfi
->internal_fa
,2);
1159 zip64local_putValue_inmemory(zi
->ci
.central_header
+38,(uLong
)0,4);
1161 zip64local_putValue_inmemory(zi
->ci
.central_header
+38,(uLong
)zipfi
->external_fa
,4);
1163 if(zi
->ci
.pos_local_header
>= 0xffffffff)
1164 zip64local_putValue_inmemory(zi
->ci
.central_header
+42,(uLong
)0xffffffff,4);
1166 zip64local_putValue_inmemory(zi
->ci
.central_header
+42,(uLong
)zi
->ci
.pos_local_header
- zi
->add_position_when_writting_offset
,4);
1168 for (i
=0;i
<size_filename
;i
++)
1169 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+i
) = *(filename
+i
);
1171 for (i
=0;i
<size_extrafield_global
;i
++)
1172 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+size_filename
+i
) =
1173 *(((const char*)extrafield_global
)+i
);
1175 for (i
=0;i
<size_comment
;i
++)
1176 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+size_filename
+
1177 size_extrafield_global
+i
) = *(comment
+i
);
1178 if (zi
->ci
.central_header
== NULL
)
1179 return ZIP_INTERNALERROR
;
1181 zi
->ci
.zip64
= zip64
;
1182 zi
->ci
.totalCompressedData
= 0;
1183 zi
->ci
.totalUncompressedData
= 0;
1184 zi
->ci
.pos_zip64extrainfo
= 0;
1186 err
= Write_LocalFileHeader(zi
, filename
, size_extrafield_local
, extrafield_local
);
1189 zi
->ci
.bstream
.avail_in
= (uInt
)0;
1190 zi
->ci
.bstream
.avail_out
= (uInt
)Z_BUFSIZE
;
1191 zi
->ci
.bstream
.next_out
= (char*)zi
->ci
.buffered_data
;
1192 zi
->ci
.bstream
.total_in_hi32
= 0;
1193 zi
->ci
.bstream
.total_in_lo32
= 0;
1194 zi
->ci
.bstream
.total_out_hi32
= 0;
1195 zi
->ci
.bstream
.total_out_lo32
= 0;
1198 zi
->ci
.stream
.avail_in
= (uInt
)0;
1199 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
1200 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
1201 zi
->ci
.stream
.total_in
= 0;
1202 zi
->ci
.stream
.total_out
= 0;
1203 zi
->ci
.stream
.data_type
= Z_BINARY
;
1206 if ((err
==ZIP_OK
) && (zi
->ci
.method
== Z_DEFLATED
|| zi
->ci
.method
== Z_BZIP2ED
) && (!zi
->ci
.raw
))
1208 if ((err
==ZIP_OK
) && (zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1211 if(zi
->ci
.method
== Z_DEFLATED
)
1213 zi
->ci
.stream
.zalloc
= (alloc_func
)0;
1214 zi
->ci
.stream
.zfree
= (free_func
)0;
1215 zi
->ci
.stream
.opaque
= (voidpf
)0;
1218 windowBits
= -windowBits
;
1220 err
= deflateInit2(&zi
->ci
.stream
, level
, Z_DEFLATED
, windowBits
, memLevel
, strategy
);
1223 zi
->ci
.stream_initialised
= Z_DEFLATED
;
1225 else if(zi
->ci
.method
== Z_BZIP2ED
)
1228 // Init BZip stuff here
1229 zi
->ci
.bstream
.bzalloc
= 0;
1230 zi
->ci
.bstream
.bzfree
= 0;
1231 zi
->ci
.bstream
.opaque
= (voidpf
)0;
1233 err
= BZ2_bzCompressInit(&zi
->ci
.bstream
, level
, 0,35);
1235 zi
->ci
.stream_initialised
= Z_BZIP2ED
;
1242 zi
->ci
.crypt_header_size
= 0;
1243 if ((err
==Z_OK
) && (password
!= NULL
))
1245 unsigned char bufHead
[RAND_HEAD_LEN
];
1246 unsigned int sizeHead
;
1248 zi
->ci
.pcrc_32_tab
= get_crc_table();
1249 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
1251 sizeHead
=crypthead(password
,bufHead
,RAND_HEAD_LEN
,zi
->ci
.keys
,zi
->ci
.pcrc_32_tab
,crcForCrypting
);
1252 zi
->ci
.crypt_header_size
= sizeHead
;
1254 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
,bufHead
,sizeHead
) != sizeHead
)
1260 zi
->in_opened_file_inzip
= 1;
1264 extern int ZEXPORT
zipOpenNewFileInZip4 (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1265 const void* extrafield_local
, uInt size_extrafield_local
,
1266 const void* extrafield_global
, uInt size_extrafield_global
,
1267 const char* comment
, int method
, int level
, int raw
,
1268 int windowBits
,int memLevel
, int strategy
,
1269 const char* password
, uLong crcForCrypting
,
1270 uLong versionMadeBy
, uLong flagBase
)
1272 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1273 extrafield_local
, size_extrafield_local
,
1274 extrafield_global
, size_extrafield_global
,
1275 comment
, method
, level
, raw
,
1276 windowBits
, memLevel
, strategy
,
1277 password
, crcForCrypting
, versionMadeBy
, flagBase
, 0);
1280 extern int ZEXPORT
zipOpenNewFileInZip3 (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1281 const void* extrafield_local
, uInt size_extrafield_local
,
1282 const void* extrafield_global
, uInt size_extrafield_global
,
1283 const char* comment
, int method
, int level
, int raw
,
1284 int windowBits
,int memLevel
, int strategy
,
1285 const char* password
, uLong crcForCrypting
)
1287 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1288 extrafield_local
, size_extrafield_local
,
1289 extrafield_global
, size_extrafield_global
,
1290 comment
, method
, level
, raw
,
1291 windowBits
, memLevel
, strategy
,
1292 password
, crcForCrypting
, VERSIONMADEBY
, 0, 0);
1295 extern int ZEXPORT
zipOpenNewFileInZip3_64(zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1296 const void* extrafield_local
, uInt size_extrafield_local
,
1297 const void* extrafield_global
, uInt size_extrafield_global
,
1298 const char* comment
, int method
, int level
, int raw
,
1299 int windowBits
,int memLevel
, int strategy
,
1300 const char* password
, uLong crcForCrypting
, int zip64
)
1302 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1303 extrafield_local
, size_extrafield_local
,
1304 extrafield_global
, size_extrafield_global
,
1305 comment
, method
, level
, raw
,
1306 windowBits
, memLevel
, strategy
,
1307 password
, crcForCrypting
, VERSIONMADEBY
, 0, zip64
);
1310 extern int ZEXPORT
zipOpenNewFileInZip2(zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1311 const void* extrafield_local
, uInt size_extrafield_local
,
1312 const void* extrafield_global
, uInt size_extrafield_global
,
1313 const char* comment
, int method
, int level
, int raw
)
1315 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1316 extrafield_local
, size_extrafield_local
,
1317 extrafield_global
, size_extrafield_global
,
1318 comment
, method
, level
, raw
,
1319 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
1320 NULL
, 0, VERSIONMADEBY
, 0, 0);
1323 extern int ZEXPORT
zipOpenNewFileInZip2_64(zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1324 const void* extrafield_local
, uInt size_extrafield_local
,
1325 const void* extrafield_global
, uInt size_extrafield_global
,
1326 const char* comment
, int method
, int level
, int raw
, int zip64
)
1328 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1329 extrafield_local
, size_extrafield_local
,
1330 extrafield_global
, size_extrafield_global
,
1331 comment
, method
, level
, raw
,
1332 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
1333 NULL
, 0, VERSIONMADEBY
, 0, zip64
);
1336 extern int ZEXPORT
zipOpenNewFileInZip64 (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1337 const void* extrafield_local
, uInt size_extrafield_local
,
1338 const void*extrafield_global
, uInt size_extrafield_global
,
1339 const char* comment
, int method
, int level
, int zip64
)
1341 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1342 extrafield_local
, size_extrafield_local
,
1343 extrafield_global
, size_extrafield_global
,
1344 comment
, method
, level
, 0,
1345 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
1346 NULL
, 0, VERSIONMADEBY
, 0, zip64
);
1349 extern int ZEXPORT
zipOpenNewFileInZip (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1350 const void* extrafield_local
, uInt size_extrafield_local
,
1351 const void*extrafield_global
, uInt size_extrafield_global
,
1352 const char* comment
, int method
, int level
)
1354 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1355 extrafield_local
, size_extrafield_local
,
1356 extrafield_global
, size_extrafield_global
,
1357 comment
, method
, level
, 0,
1358 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
1359 NULL
, 0, VERSIONMADEBY
, 0, 0);
1362 local
int zip64FlushWriteBuffer(zip64_internal
* zi
)
1366 if (zi
->ci
.encrypt
!= 0)
1371 for (i
=0;i
<zi
->ci
.pos_in_buffered_data
;i
++)
1372 zi
->ci
.buffered_data
[i
] = zencode(zi
->ci
.keys
, zi
->ci
.pcrc_32_tab
, zi
->ci
.buffered_data
[i
],t
);
1376 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
,zi
->ci
.buffered_data
,zi
->ci
.pos_in_buffered_data
) != zi
->ci
.pos_in_buffered_data
)
1379 zi
->ci
.totalCompressedData
+= zi
->ci
.pos_in_buffered_data
;
1382 if(zi
->ci
.method
== Z_BZIP2ED
)
1384 zi
->ci
.totalUncompressedData
+= zi
->ci
.bstream
.total_in_lo32
;
1385 zi
->ci
.bstream
.total_in_lo32
= 0;
1386 zi
->ci
.bstream
.total_in_hi32
= 0;
1391 zi
->ci
.totalUncompressedData
+= zi
->ci
.stream
.total_in
;
1392 zi
->ci
.stream
.total_in
= 0;
1396 zi
->ci
.pos_in_buffered_data
= 0;
1401 extern int ZEXPORT
zipWriteInFileInZip (zipFile file
,const void* buf
,unsigned int len
)
1407 return ZIP_PARAMERROR
;
1408 zi
= (zip64_internal
*)file
;
1410 if (zi
->in_opened_file_inzip
== 0)
1411 return ZIP_PARAMERROR
;
1413 zi
->ci
.crc32
= crc32(zi
->ci
.crc32
,buf
,(uInt
)len
);
1416 if(zi
->ci
.method
== Z_BZIP2ED
&& (!zi
->ci
.raw
))
1418 zi
->ci
.bstream
.next_in
= (void*)buf
;
1419 zi
->ci
.bstream
.avail_in
= len
;
1422 while ((err
==BZ_RUN_OK
) && (zi
->ci
.bstream
.avail_in
>0))
1424 if (zi
->ci
.bstream
.avail_out
== 0)
1426 if (zip64FlushWriteBuffer(zi
) == ZIP_ERRNO
)
1428 zi
->ci
.bstream
.avail_out
= (uInt
)Z_BUFSIZE
;
1429 zi
->ci
.bstream
.next_out
= (char*)zi
->ci
.buffered_data
;
1433 if(err
!= BZ_RUN_OK
)
1436 if ((zi
->ci
.method
== Z_BZIP2ED
) && (!zi
->ci
.raw
))
1438 uLong uTotalOutBefore_lo
= zi
->ci
.bstream
.total_out_lo32
;
1439 // uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
1440 err
=BZ2_bzCompress(&zi
->ci
.bstream
, BZ_RUN
);
1442 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.bstream
.total_out_lo32
- uTotalOutBefore_lo
) ;
1446 if(err
== BZ_RUN_OK
)
1452 zi
->ci
.stream
.next_in
= (Bytef
*)buf
;
1453 zi
->ci
.stream
.avail_in
= len
;
1455 while ((err
==ZIP_OK
) && (zi
->ci
.stream
.avail_in
>0))
1457 if (zi
->ci
.stream
.avail_out
== 0)
1459 if (zip64FlushWriteBuffer(zi
) == ZIP_ERRNO
)
1461 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
1462 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
1469 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1471 uLong uTotalOutBefore
= zi
->ci
.stream
.total_out
;
1472 err
=deflate(&zi
->ci
.stream
, Z_NO_FLUSH
);
1473 if(uTotalOutBefore
> zi
->ci
.stream
.total_out
)
1479 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.stream
.total_out
- uTotalOutBefore
) ;
1484 if (zi
->ci
.stream
.avail_in
< zi
->ci
.stream
.avail_out
)
1485 copy_this
= zi
->ci
.stream
.avail_in
;
1487 copy_this
= zi
->ci
.stream
.avail_out
;
1489 for (i
= 0; i
< copy_this
; i
++)
1490 *(((char*)zi
->ci
.stream
.next_out
)+i
) =
1491 *(((const char*)zi
->ci
.stream
.next_in
)+i
);
1493 zi
->ci
.stream
.avail_in
-= copy_this
;
1494 zi
->ci
.stream
.avail_out
-= copy_this
;
1495 zi
->ci
.stream
.next_in
+= copy_this
;
1496 zi
->ci
.stream
.next_out
+= copy_this
;
1497 zi
->ci
.stream
.total_in
+= copy_this
;
1498 zi
->ci
.stream
.total_out
+= copy_this
;
1499 zi
->ci
.pos_in_buffered_data
+= copy_this
;
1508 extern int ZEXPORT
zipCloseFileInZipRaw (zipFile file
, uLong uncompressed_size
, uLong crc32
)
1510 return zipCloseFileInZipRaw64 (file
, uncompressed_size
, crc32
);
1513 extern int ZEXPORT
zipCloseFileInZipRaw64 (zipFile file
, ZPOS64_T uncompressed_size
, uLong crc32
)
1516 ZPOS64_T compressed_size
;
1517 uLong invalidValue
= 0xffffffff;
1522 return ZIP_PARAMERROR
;
1523 zi
= (zip64_internal
*)file
;
1525 if (zi
->in_opened_file_inzip
== 0)
1526 return ZIP_PARAMERROR
;
1527 zi
->ci
.stream
.avail_in
= 0;
1529 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1533 uLong uTotalOutBefore
;
1534 if (zi
->ci
.stream
.avail_out
== 0)
1536 if (zip64FlushWriteBuffer(zi
) == ZIP_ERRNO
)
1538 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
1539 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
1541 uTotalOutBefore
= zi
->ci
.stream
.total_out
;
1542 err
=deflate(&zi
->ci
.stream
, Z_FINISH
);
1543 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.stream
.total_out
- uTotalOutBefore
) ;
1546 else if ((zi
->ci
.method
== Z_BZIP2ED
) && (!zi
->ci
.raw
))
1550 while (err
==BZ_FINISH_OK
)
1552 uLong uTotalOutBefore
;
1553 if (zi
->ci
.bstream
.avail_out
== 0)
1555 if (zip64FlushWriteBuffer(zi
) == ZIP_ERRNO
)
1557 zi
->ci
.bstream
.avail_out
= (uInt
)Z_BUFSIZE
;
1558 zi
->ci
.bstream
.next_out
= (char*)zi
->ci
.buffered_data
;
1560 uTotalOutBefore
= zi
->ci
.bstream
.total_out_lo32
;
1561 err
=BZ2_bzCompress(&zi
->ci
.bstream
, BZ_FINISH
);
1562 if(err
== BZ_STREAM_END
)
1565 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.bstream
.total_out_lo32
- uTotalOutBefore
);
1568 if(err
== BZ_FINISH_OK
)
1573 if (err
==Z_STREAM_END
)
1574 err
=ZIP_OK
; /* this is normal */
1576 if ((zi
->ci
.pos_in_buffered_data
>0) && (err
==ZIP_OK
))
1578 if (zip64FlushWriteBuffer(zi
)==ZIP_ERRNO
)
1582 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1584 int tmp_err
= deflateEnd(&zi
->ci
.stream
);
1587 zi
->ci
.stream_initialised
= 0;
1590 else if((zi
->ci
.method
== Z_BZIP2ED
) && (!zi
->ci
.raw
))
1592 int tmperr
= BZ2_bzCompressEnd(&zi
->ci
.bstream
);
1595 zi
->ci
.stream_initialised
= 0;
1601 crc32
= (uLong
)zi
->ci
.crc32
;
1602 uncompressed_size
= zi
->ci
.totalUncompressedData
;
1604 compressed_size
= zi
->ci
.totalCompressedData
;
1607 compressed_size
+= zi
->ci
.crypt_header_size
;
1610 // update Current Item crc and sizes,
1611 if(compressed_size
>= 0xffffffff || uncompressed_size
>= 0xffffffff || zi
->ci
.pos_local_header
>= 0xffffffff)
1614 zip64local_putValue_inmemory(zi
->ci
.central_header
+4,(uLong
)45,2);
1616 zip64local_putValue_inmemory(zi
->ci
.central_header
+6,(uLong
)45,2);
1620 zip64local_putValue_inmemory(zi
->ci
.central_header
+16,crc32
,4); /*crc*/
1623 if(compressed_size
>= 0xffffffff)
1624 zip64local_putValue_inmemory(zi
->ci
.central_header
+20, invalidValue
,4); /*compr size*/
1626 zip64local_putValue_inmemory(zi
->ci
.central_header
+20, compressed_size
,4); /*compr size*/
1628 /// set internal file attributes field
1629 if (zi
->ci
.stream
.data_type
== Z_ASCII
)
1630 zip64local_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)Z_ASCII
,2);
1632 if(uncompressed_size
>= 0xffffffff)
1633 zip64local_putValue_inmemory(zi
->ci
.central_header
+24, invalidValue
,4); /*uncompr size*/
1635 zip64local_putValue_inmemory(zi
->ci
.central_header
+24, uncompressed_size
,4); /*uncompr size*/
1637 // Add ZIP64 extra info field for uncompressed size
1638 if(uncompressed_size
>= 0xffffffff)
1641 // Add ZIP64 extra info field for compressed size
1642 if(compressed_size
>= 0xffffffff)
1645 // Add ZIP64 extra info field for relative offset to local file header of current file
1646 if(zi
->ci
.pos_local_header
>= 0xffffffff)
1653 if((uLong
)(datasize
+ 4) > zi
->ci
.size_centralExtraFree
)
1655 // we can not write more data to the buffer that we have room for.
1656 return ZIP_BADZIPFILE
;
1659 p
= zi
->ci
.central_header
+ zi
->ci
.size_centralheader
;
1661 // Add Extra Information Header for 'ZIP64 information'
1662 zip64local_putValue_inmemory(p
, 0x0001, 2); // HeaderID
1664 zip64local_putValue_inmemory(p
, datasize
, 2); // DataSize
1667 if(uncompressed_size
>= 0xffffffff)
1669 zip64local_putValue_inmemory(p
, uncompressed_size
, 8);
1673 if(compressed_size
>= 0xffffffff)
1675 zip64local_putValue_inmemory(p
, compressed_size
, 8);
1679 if(zi
->ci
.pos_local_header
>= 0xffffffff)
1681 zip64local_putValue_inmemory(p
, zi
->ci
.pos_local_header
, 8);
1685 // Update how much extra free space we got in the memory buffer
1686 // and increase the centralheader size so the new ZIP64 fields are included
1687 // ( 4 below is the size of HeaderID and DataSize field )
1688 zi
->ci
.size_centralExtraFree
-= datasize
+ 4;
1689 zi
->ci
.size_centralheader
+= datasize
+ 4;
1691 // Update the extra info size field
1692 zi
->ci
.size_centralExtra
+= datasize
+ 4;
1693 zip64local_putValue_inmemory(zi
->ci
.central_header
+30,(uLong
)zi
->ci
.size_centralExtra
,2);
1697 err
= add_data_in_datablock(&zi
->central_dir
, zi
->ci
.central_header
, (uLong
)zi
->ci
.size_centralheader
);
1699 free(zi
->ci
.central_header
);
1703 // Update the LocalFileHeader with the new values.
1705 ZPOS64_T cur_pos_inzip
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1707 if (ZSEEK64(zi
->z_filefunc
,zi
->filestream
, zi
->ci
.pos_local_header
+ 14,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1711 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,crc32
,4); /* crc 32, unknown */
1713 if(uncompressed_size
>= 0xffffffff)
1715 if(zi
->ci
.pos_zip64extrainfo
> 0)
1717 // Update the size in the ZIP64 extended field.
1718 if (ZSEEK64(zi
->z_filefunc
,zi
->filestream
, zi
->ci
.pos_zip64extrainfo
+ 4,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1721 if (err
==ZIP_OK
) /* compressed size, unknown */
1722 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, uncompressed_size
, 8);
1724 if (err
==ZIP_OK
) /* uncompressed size, unknown */
1725 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, compressed_size
, 8);
1730 if (err
==ZIP_OK
) /* compressed size, unknown */
1731 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,compressed_size
,4);
1733 if (err
==ZIP_OK
) /* uncompressed size, unknown */
1734 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,uncompressed_size
,4);
1737 if (ZSEEK64(zi
->z_filefunc
,zi
->filestream
, cur_pos_inzip
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1741 zi
->number_entry
++;
1742 zi
->in_opened_file_inzip
= 0;
1747 extern int ZEXPORT
zipCloseFileInZip (zipFile file
)
1749 return zipCloseFileInZipRaw (file
,0,0);
1752 int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal
* zi
, ZPOS64_T zip64eocd_pos_inzip
)
1755 ZPOS64_T pos
= zip64eocd_pos_inzip
- zi
->add_position_when_writting_offset
;
1757 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)ZIP64ENDLOCHEADERMAGIC
,4);
1760 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1761 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4);
1764 if (err
==ZIP_OK
) /* Relative offset to the Zip64EndOfCentralDirectory */
1765 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
, pos
,8);
1767 /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
1768 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1769 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)1,4);
1774 int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal
* zi
, uLong size_centraldir
, ZPOS64_T centraldir_pos_inzip
)
1778 uLong Zip64DataSize
= 44;
1780 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)ZIP64ENDHEADERMAGIC
,4);
1782 if (err
==ZIP_OK
) /* size of this 'zip64 end of central directory' */
1783 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(ZPOS64_T
)Zip64DataSize
,8); // why ZPOS64_T of this ?
1785 if (err
==ZIP_OK
) /* version made by */
1786 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)45,2);
1788 if (err
==ZIP_OK
) /* version needed */
1789 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)45,2);
1791 if (err
==ZIP_OK
) /* number of this disk */
1792 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4);
1794 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1795 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4);
1797 if (err
==ZIP_OK
) /* total number of entries in the central dir on this disk */
1798 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, zi
->number_entry
, 8);
1800 if (err
==ZIP_OK
) /* total number of entries in the central dir */
1801 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, zi
->number_entry
, 8);
1803 if (err
==ZIP_OK
) /* size of the central directory */
1804 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(ZPOS64_T
)size_centraldir
,8);
1806 if (err
==ZIP_OK
) /* offset of start of central directory with respect to the starting disk number */
1808 ZPOS64_T pos
= centraldir_pos_inzip
- zi
->add_position_when_writting_offset
;
1809 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
, (ZPOS64_T
)pos
,8);
1813 int Write_EndOfCentralDirectoryRecord(zip64_internal
* zi
, uLong size_centraldir
, ZPOS64_T centraldir_pos_inzip
)
1818 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)ENDHEADERMAGIC
,4);
1820 if (err
==ZIP_OK
) /* number of this disk */
1821 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,2);
1823 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1824 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,2);
1826 if (err
==ZIP_OK
) /* total number of entries in the central dir on this disk */
1829 if(zi
->number_entry
>= 0xFFFF)
1830 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0xffff,2); // use value in ZIP64 record
1832 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->number_entry
,2);
1836 if (err
==ZIP_OK
) /* total number of entries in the central dir */
1838 if(zi
->number_entry
>= 0xFFFF)
1839 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0xffff,2); // use value in ZIP64 record
1841 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->number_entry
,2);
1844 if (err
==ZIP_OK
) /* size of the central directory */
1845 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_centraldir
,4);
1847 if (err
==ZIP_OK
) /* offset of start of central directory with respect to the starting disk number */
1849 ZPOS64_T pos
= centraldir_pos_inzip
- zi
->add_position_when_writting_offset
;
1850 if(pos
>= 0xffffffff)
1852 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
, (uLong
)0xffffffff,4);
1855 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
, (uLong
)(centraldir_pos_inzip
- zi
->add_position_when_writting_offset
),4);
1861 int Write_GlobalComment(zip64_internal
* zi
, const char* global_comment
)
1864 uInt size_global_comment
= 0;
1866 if(global_comment
!= NULL
)
1867 size_global_comment
= (uInt
)strlen(global_comment
);
1869 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_global_comment
,2);
1871 if (err
== ZIP_OK
&& size_global_comment
> 0)
1873 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
, global_comment
, size_global_comment
) != size_global_comment
)
1879 extern int ZEXPORT
zipClose (zipFile file
, const char* global_comment
)
1883 uLong size_centraldir
= 0;
1884 ZPOS64_T centraldir_pos_inzip
;
1888 return ZIP_PARAMERROR
;
1890 zi
= (zip64_internal
*)file
;
1892 if (zi
->in_opened_file_inzip
== 1)
1894 err
= zipCloseFileInZip (file
);
1897 #ifndef NO_ADDFILEINEXISTINGZIP
1898 if (global_comment
==NULL
)
1899 global_comment
= zi
->globalcomment
;
1902 centraldir_pos_inzip
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1906 linkedlist_datablock_internal
* ldi
= zi
->central_dir
.first_block
;
1909 if ((err
==ZIP_OK
) && (ldi
->filled_in_this_block
>0))
1911 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
, ldi
->data
, ldi
->filled_in_this_block
) != ldi
->filled_in_this_block
)
1915 size_centraldir
+= ldi
->filled_in_this_block
;
1916 ldi
= ldi
->next_datablock
;
1919 free_linkedlist(&(zi
->central_dir
));
1921 pos
= centraldir_pos_inzip
- zi
->add_position_when_writting_offset
;
1922 if(pos
>= 0xffffffff)
1924 ZPOS64_T Zip64EOCDpos
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1925 Write_Zip64EndOfCentralDirectoryRecord(zi
, size_centraldir
, centraldir_pos_inzip
);
1927 Write_Zip64EndOfCentralDirectoryLocator(zi
, Zip64EOCDpos
);
1931 err
= Write_EndOfCentralDirectoryRecord(zi
, size_centraldir
, centraldir_pos_inzip
);
1934 err
= Write_GlobalComment(zi
, global_comment
);
1936 if (ZCLOSE64(zi
->z_filefunc
,zi
->filestream
) != 0)
1940 #ifndef NO_ADDFILEINEXISTINGZIP
1941 TRYFREE(zi
->globalcomment
);
1948 extern int ZEXPORT
zipRemoveExtraInfoBlock (char* pData
, int* dataLen
, short sHeader
)
1957 int retVal
= ZIP_OK
;
1959 if(pData
== NULL
|| *dataLen
< 4)
1960 return ZIP_PARAMERROR
;
1962 pNewHeader
= (char*)ALLOC(*dataLen
);
1965 while(p
< (pData
+ *dataLen
))
1967 header
= *(short*)p
;
1968 dataSize
= *(((short*)p
)+1);
1970 if( header
== sHeader
) // Header found.
1972 p
+= dataSize
+ 4; // skip it. do not copy to temp buffer
1976 // Extra Info block should not be removed, So copy it to the temp buffer.
1977 memcpy(pTmp
, p
, dataSize
+ 4);
1979 size
+= dataSize
+ 4;
1986 // clean old extra info block.
1987 memset(pData
,0, *dataLen
);
1989 // copy the new extra info block over the old
1991 memcpy(pData
, pNewHeader
, size
);
1993 // set the new extra info size
2001 TRYFREE(pNewHeader
);