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 automatically added to items that needs it, and existing ZIP64 data need to be removed.
19 Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
20 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
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 alignment */
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 z_crc_t
* 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_writing_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_writing_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_writing_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
)
1071 if (password
!= NULL
)
1072 return ZIP_PARAMERROR
;
1076 return ZIP_PARAMERROR
;
1079 if ((method
!=0) && (method
!=Z_DEFLATED
) && (method
!=Z_BZIP2ED
))
1080 return ZIP_PARAMERROR
;
1082 if ((method
!=0) && (method
!=Z_DEFLATED
))
1083 return ZIP_PARAMERROR
;
1086 zi
= (zip64_internal
*)file
;
1088 if (zi
->in_opened_file_inzip
== 1)
1090 err
= zipCloseFileInZip (file
);
1101 size_comment
= (uInt
)strlen(comment
);
1103 size_filename
= (uInt
)strlen(filename
);
1109 if (zipfi
->dosDate
!= 0)
1110 zi
->ci
.dosDate
= zipfi
->dosDate
;
1112 zi
->ci
.dosDate
= zip64local_TmzDateToDosDate(&zipfi
->tmz_date
);
1115 zi
->ci
.flag
= flagBase
;
1116 if ((level
==8) || (level
==9))
1122 if (password
!= NULL
)
1126 zi
->ci
.method
= method
;
1128 zi
->ci
.stream_initialised
= 0;
1129 zi
->ci
.pos_in_buffered_data
= 0;
1131 zi
->ci
.pos_local_header
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1133 zi
->ci
.size_centralheader
= SIZECENTRALHEADER
+ size_filename
+ size_extrafield_global
+ size_comment
;
1134 zi
->ci
.size_centralExtraFree
= 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
1136 zi
->ci
.central_header
= (char*)ALLOC((uInt
)zi
->ci
.size_centralheader
+ zi
->ci
.size_centralExtraFree
);
1138 zi
->ci
.size_centralExtra
= size_extrafield_global
;
1139 zip64local_putValue_inmemory(zi
->ci
.central_header
,(uLong
)CENTRALHEADERMAGIC
,4);
1141 zip64local_putValue_inmemory(zi
->ci
.central_header
+4,(uLong
)versionMadeBy
,2);
1142 zip64local_putValue_inmemory(zi
->ci
.central_header
+6,(uLong
)20,2);
1143 zip64local_putValue_inmemory(zi
->ci
.central_header
+8,(uLong
)zi
->ci
.flag
,2);
1144 zip64local_putValue_inmemory(zi
->ci
.central_header
+10,(uLong
)zi
->ci
.method
,2);
1145 zip64local_putValue_inmemory(zi
->ci
.central_header
+12,(uLong
)zi
->ci
.dosDate
,4);
1146 zip64local_putValue_inmemory(zi
->ci
.central_header
+16,(uLong
)0,4); /*crc*/
1147 zip64local_putValue_inmemory(zi
->ci
.central_header
+20,(uLong
)0,4); /*compr size*/
1148 zip64local_putValue_inmemory(zi
->ci
.central_header
+24,(uLong
)0,4); /*uncompr size*/
1149 zip64local_putValue_inmemory(zi
->ci
.central_header
+28,(uLong
)size_filename
,2);
1150 zip64local_putValue_inmemory(zi
->ci
.central_header
+30,(uLong
)size_extrafield_global
,2);
1151 zip64local_putValue_inmemory(zi
->ci
.central_header
+32,(uLong
)size_comment
,2);
1152 zip64local_putValue_inmemory(zi
->ci
.central_header
+34,(uLong
)0,2); /*disk nm start*/
1155 zip64local_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)0,2);
1157 zip64local_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)zipfi
->internal_fa
,2);
1160 zip64local_putValue_inmemory(zi
->ci
.central_header
+38,(uLong
)0,4);
1162 zip64local_putValue_inmemory(zi
->ci
.central_header
+38,(uLong
)zipfi
->external_fa
,4);
1164 if(zi
->ci
.pos_local_header
>= 0xffffffff)
1165 zip64local_putValue_inmemory(zi
->ci
.central_header
+42,(uLong
)0xffffffff,4);
1167 zip64local_putValue_inmemory(zi
->ci
.central_header
+42,(uLong
)zi
->ci
.pos_local_header
- zi
->add_position_when_writing_offset
,4);
1169 for (i
=0;i
<size_filename
;i
++)
1170 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+i
) = *(filename
+i
);
1172 for (i
=0;i
<size_extrafield_global
;i
++)
1173 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+size_filename
+i
) =
1174 *(((const char*)extrafield_global
)+i
);
1176 for (i
=0;i
<size_comment
;i
++)
1177 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+size_filename
+
1178 size_extrafield_global
+i
) = *(comment
+i
);
1179 if (zi
->ci
.central_header
== NULL
)
1180 return ZIP_INTERNALERROR
;
1182 zi
->ci
.zip64
= zip64
;
1183 zi
->ci
.totalCompressedData
= 0;
1184 zi
->ci
.totalUncompressedData
= 0;
1185 zi
->ci
.pos_zip64extrainfo
= 0;
1187 err
= Write_LocalFileHeader(zi
, filename
, size_extrafield_local
, extrafield_local
);
1190 zi
->ci
.bstream
.avail_in
= (uInt
)0;
1191 zi
->ci
.bstream
.avail_out
= (uInt
)Z_BUFSIZE
;
1192 zi
->ci
.bstream
.next_out
= (char*)zi
->ci
.buffered_data
;
1193 zi
->ci
.bstream
.total_in_hi32
= 0;
1194 zi
->ci
.bstream
.total_in_lo32
= 0;
1195 zi
->ci
.bstream
.total_out_hi32
= 0;
1196 zi
->ci
.bstream
.total_out_lo32
= 0;
1199 zi
->ci
.stream
.avail_in
= (uInt
)0;
1200 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
1201 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
1202 zi
->ci
.stream
.total_in
= 0;
1203 zi
->ci
.stream
.total_out
= 0;
1204 zi
->ci
.stream
.data_type
= Z_BINARY
;
1207 if ((err
==ZIP_OK
) && (zi
->ci
.method
== Z_DEFLATED
|| zi
->ci
.method
== Z_BZIP2ED
) && (!zi
->ci
.raw
))
1209 if ((err
==ZIP_OK
) && (zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1212 if(zi
->ci
.method
== Z_DEFLATED
)
1214 zi
->ci
.stream
.zalloc
= (alloc_func
)0;
1215 zi
->ci
.stream
.zfree
= (free_func
)0;
1216 zi
->ci
.stream
.opaque
= (voidpf
)0;
1219 windowBits
= -windowBits
;
1221 err
= deflateInit2(&zi
->ci
.stream
, level
, Z_DEFLATED
, windowBits
, memLevel
, strategy
);
1224 zi
->ci
.stream_initialised
= Z_DEFLATED
;
1226 else if(zi
->ci
.method
== Z_BZIP2ED
)
1229 // Init BZip stuff here
1230 zi
->ci
.bstream
.bzalloc
= 0;
1231 zi
->ci
.bstream
.bzfree
= 0;
1232 zi
->ci
.bstream
.opaque
= (voidpf
)0;
1234 err
= BZ2_bzCompressInit(&zi
->ci
.bstream
, level
, 0,35);
1236 zi
->ci
.stream_initialised
= Z_BZIP2ED
;
1243 zi
->ci
.crypt_header_size
= 0;
1244 if ((err
==Z_OK
) && (password
!= NULL
))
1246 unsigned char bufHead
[RAND_HEAD_LEN
];
1247 unsigned int sizeHead
;
1249 zi
->ci
.pcrc_32_tab
= get_crc_table();
1250 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
1252 sizeHead
=crypthead(password
,bufHead
,RAND_HEAD_LEN
,zi
->ci
.keys
,zi
->ci
.pcrc_32_tab
,crcForCrypting
);
1253 zi
->ci
.crypt_header_size
= sizeHead
;
1255 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
,bufHead
,sizeHead
) != sizeHead
)
1261 zi
->in_opened_file_inzip
= 1;
1265 extern int ZEXPORT
zipOpenNewFileInZip4 (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1266 const void* extrafield_local
, uInt size_extrafield_local
,
1267 const void* extrafield_global
, uInt size_extrafield_global
,
1268 const char* comment
, int method
, int level
, int raw
,
1269 int windowBits
,int memLevel
, int strategy
,
1270 const char* password
, uLong crcForCrypting
,
1271 uLong versionMadeBy
, uLong flagBase
)
1273 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1274 extrafield_local
, size_extrafield_local
,
1275 extrafield_global
, size_extrafield_global
,
1276 comment
, method
, level
, raw
,
1277 windowBits
, memLevel
, strategy
,
1278 password
, crcForCrypting
, versionMadeBy
, flagBase
, 0);
1281 extern int ZEXPORT
zipOpenNewFileInZip3 (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1282 const void* extrafield_local
, uInt size_extrafield_local
,
1283 const void* extrafield_global
, uInt size_extrafield_global
,
1284 const char* comment
, int method
, int level
, int raw
,
1285 int windowBits
,int memLevel
, int strategy
,
1286 const char* password
, uLong crcForCrypting
)
1288 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1289 extrafield_local
, size_extrafield_local
,
1290 extrafield_global
, size_extrafield_global
,
1291 comment
, method
, level
, raw
,
1292 windowBits
, memLevel
, strategy
,
1293 password
, crcForCrypting
, VERSIONMADEBY
, 0, 0);
1296 extern int ZEXPORT
zipOpenNewFileInZip3_64(zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1297 const void* extrafield_local
, uInt size_extrafield_local
,
1298 const void* extrafield_global
, uInt size_extrafield_global
,
1299 const char* comment
, int method
, int level
, int raw
,
1300 int windowBits
,int memLevel
, int strategy
,
1301 const char* password
, uLong crcForCrypting
, int zip64
)
1303 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1304 extrafield_local
, size_extrafield_local
,
1305 extrafield_global
, size_extrafield_global
,
1306 comment
, method
, level
, raw
,
1307 windowBits
, memLevel
, strategy
,
1308 password
, crcForCrypting
, VERSIONMADEBY
, 0, zip64
);
1311 extern int ZEXPORT
zipOpenNewFileInZip2(zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1312 const void* extrafield_local
, uInt size_extrafield_local
,
1313 const void* extrafield_global
, uInt size_extrafield_global
,
1314 const char* comment
, int method
, int level
, int raw
)
1316 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1317 extrafield_local
, size_extrafield_local
,
1318 extrafield_global
, size_extrafield_global
,
1319 comment
, method
, level
, raw
,
1320 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
1321 NULL
, 0, VERSIONMADEBY
, 0, 0);
1324 extern int ZEXPORT
zipOpenNewFileInZip2_64(zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1325 const void* extrafield_local
, uInt size_extrafield_local
,
1326 const void* extrafield_global
, uInt size_extrafield_global
,
1327 const char* comment
, int method
, int level
, int raw
, int zip64
)
1329 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1330 extrafield_local
, size_extrafield_local
,
1331 extrafield_global
, size_extrafield_global
,
1332 comment
, method
, level
, raw
,
1333 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
1334 NULL
, 0, VERSIONMADEBY
, 0, zip64
);
1337 extern int ZEXPORT
zipOpenNewFileInZip64 (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1338 const void* extrafield_local
, uInt size_extrafield_local
,
1339 const void*extrafield_global
, uInt size_extrafield_global
,
1340 const char* comment
, int method
, int level
, int zip64
)
1342 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1343 extrafield_local
, size_extrafield_local
,
1344 extrafield_global
, size_extrafield_global
,
1345 comment
, method
, level
, 0,
1346 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
1347 NULL
, 0, VERSIONMADEBY
, 0, zip64
);
1350 extern int ZEXPORT
zipOpenNewFileInZip (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1351 const void* extrafield_local
, uInt size_extrafield_local
,
1352 const void*extrafield_global
, uInt size_extrafield_global
,
1353 const char* comment
, int method
, int level
)
1355 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1356 extrafield_local
, size_extrafield_local
,
1357 extrafield_global
, size_extrafield_global
,
1358 comment
, method
, level
, 0,
1359 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
1360 NULL
, 0, VERSIONMADEBY
, 0, 0);
1363 local
int zip64FlushWriteBuffer(zip64_internal
* zi
)
1367 if (zi
->ci
.encrypt
!= 0)
1372 for (i
=0;i
<zi
->ci
.pos_in_buffered_data
;i
++)
1373 zi
->ci
.buffered_data
[i
] = zencode(zi
->ci
.keys
, zi
->ci
.pcrc_32_tab
, zi
->ci
.buffered_data
[i
],t
);
1377 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
,zi
->ci
.buffered_data
,zi
->ci
.pos_in_buffered_data
) != zi
->ci
.pos_in_buffered_data
)
1380 zi
->ci
.totalCompressedData
+= zi
->ci
.pos_in_buffered_data
;
1383 if(zi
->ci
.method
== Z_BZIP2ED
)
1385 zi
->ci
.totalUncompressedData
+= zi
->ci
.bstream
.total_in_lo32
;
1386 zi
->ci
.bstream
.total_in_lo32
= 0;
1387 zi
->ci
.bstream
.total_in_hi32
= 0;
1392 zi
->ci
.totalUncompressedData
+= zi
->ci
.stream
.total_in
;
1393 zi
->ci
.stream
.total_in
= 0;
1397 zi
->ci
.pos_in_buffered_data
= 0;
1402 extern int ZEXPORT
zipWriteInFileInZip (zipFile file
,const void* buf
,unsigned int len
)
1408 return ZIP_PARAMERROR
;
1409 zi
= (zip64_internal
*)file
;
1411 if (zi
->in_opened_file_inzip
== 0)
1412 return ZIP_PARAMERROR
;
1414 zi
->ci
.crc32
= crc32(zi
->ci
.crc32
,buf
,(uInt
)len
);
1417 if(zi
->ci
.method
== Z_BZIP2ED
&& (!zi
->ci
.raw
))
1419 zi
->ci
.bstream
.next_in
= (void*)buf
;
1420 zi
->ci
.bstream
.avail_in
= len
;
1423 while ((err
==BZ_RUN_OK
) && (zi
->ci
.bstream
.avail_in
>0))
1425 if (zi
->ci
.bstream
.avail_out
== 0)
1427 if (zip64FlushWriteBuffer(zi
) == ZIP_ERRNO
)
1429 zi
->ci
.bstream
.avail_out
= (uInt
)Z_BUFSIZE
;
1430 zi
->ci
.bstream
.next_out
= (char*)zi
->ci
.buffered_data
;
1434 if(err
!= BZ_RUN_OK
)
1437 if ((zi
->ci
.method
== Z_BZIP2ED
) && (!zi
->ci
.raw
))
1439 uLong uTotalOutBefore_lo
= zi
->ci
.bstream
.total_out_lo32
;
1440 // uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
1441 err
=BZ2_bzCompress(&zi
->ci
.bstream
, BZ_RUN
);
1443 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.bstream
.total_out_lo32
- uTotalOutBefore_lo
) ;
1447 if(err
== BZ_RUN_OK
)
1453 zi
->ci
.stream
.next_in
= (Bytef
*)buf
;
1454 zi
->ci
.stream
.avail_in
= len
;
1456 while ((err
==ZIP_OK
) && (zi
->ci
.stream
.avail_in
>0))
1458 if (zi
->ci
.stream
.avail_out
== 0)
1460 if (zip64FlushWriteBuffer(zi
) == ZIP_ERRNO
)
1462 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
1463 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
1470 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1472 uLong uTotalOutBefore
= zi
->ci
.stream
.total_out
;
1473 err
=deflate(&zi
->ci
.stream
, Z_NO_FLUSH
);
1474 if(uTotalOutBefore
> zi
->ci
.stream
.total_out
)
1480 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.stream
.total_out
- uTotalOutBefore
) ;
1485 if (zi
->ci
.stream
.avail_in
< zi
->ci
.stream
.avail_out
)
1486 copy_this
= zi
->ci
.stream
.avail_in
;
1488 copy_this
= zi
->ci
.stream
.avail_out
;
1490 for (i
= 0; i
< copy_this
; i
++)
1491 *(((char*)zi
->ci
.stream
.next_out
)+i
) =
1492 *(((const char*)zi
->ci
.stream
.next_in
)+i
);
1494 zi
->ci
.stream
.avail_in
-= copy_this
;
1495 zi
->ci
.stream
.avail_out
-= copy_this
;
1496 zi
->ci
.stream
.next_in
+= copy_this
;
1497 zi
->ci
.stream
.next_out
+= copy_this
;
1498 zi
->ci
.stream
.total_in
+= copy_this
;
1499 zi
->ci
.stream
.total_out
+= copy_this
;
1500 zi
->ci
.pos_in_buffered_data
+= copy_this
;
1509 extern int ZEXPORT
zipCloseFileInZipRaw (zipFile file
, uLong uncompressed_size
, uLong crc32
)
1511 return zipCloseFileInZipRaw64 (file
, uncompressed_size
, crc32
);
1514 extern int ZEXPORT
zipCloseFileInZipRaw64 (zipFile file
, ZPOS64_T uncompressed_size
, uLong crc32
)
1517 ZPOS64_T compressed_size
;
1518 uLong invalidValue
= 0xffffffff;
1523 return ZIP_PARAMERROR
;
1524 zi
= (zip64_internal
*)file
;
1526 if (zi
->in_opened_file_inzip
== 0)
1527 return ZIP_PARAMERROR
;
1528 zi
->ci
.stream
.avail_in
= 0;
1530 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1534 uLong uTotalOutBefore
;
1535 if (zi
->ci
.stream
.avail_out
== 0)
1537 if (zip64FlushWriteBuffer(zi
) == ZIP_ERRNO
)
1539 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
1540 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
1542 uTotalOutBefore
= zi
->ci
.stream
.total_out
;
1543 err
=deflate(&zi
->ci
.stream
, Z_FINISH
);
1544 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.stream
.total_out
- uTotalOutBefore
) ;
1547 else if ((zi
->ci
.method
== Z_BZIP2ED
) && (!zi
->ci
.raw
))
1551 while (err
==BZ_FINISH_OK
)
1553 uLong uTotalOutBefore
;
1554 if (zi
->ci
.bstream
.avail_out
== 0)
1556 if (zip64FlushWriteBuffer(zi
) == ZIP_ERRNO
)
1558 zi
->ci
.bstream
.avail_out
= (uInt
)Z_BUFSIZE
;
1559 zi
->ci
.bstream
.next_out
= (char*)zi
->ci
.buffered_data
;
1561 uTotalOutBefore
= zi
->ci
.bstream
.total_out_lo32
;
1562 err
=BZ2_bzCompress(&zi
->ci
.bstream
, BZ_FINISH
);
1563 if(err
== BZ_STREAM_END
)
1566 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.bstream
.total_out_lo32
- uTotalOutBefore
);
1569 if(err
== BZ_FINISH_OK
)
1574 if (err
==Z_STREAM_END
)
1575 err
=ZIP_OK
; /* this is normal */
1577 if ((zi
->ci
.pos_in_buffered_data
>0) && (err
==ZIP_OK
))
1579 if (zip64FlushWriteBuffer(zi
)==ZIP_ERRNO
)
1583 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1585 int tmp_err
= deflateEnd(&zi
->ci
.stream
);
1588 zi
->ci
.stream_initialised
= 0;
1591 else if((zi
->ci
.method
== Z_BZIP2ED
) && (!zi
->ci
.raw
))
1593 int tmperr
= BZ2_bzCompressEnd(&zi
->ci
.bstream
);
1596 zi
->ci
.stream_initialised
= 0;
1602 crc32
= (uLong
)zi
->ci
.crc32
;
1603 uncompressed_size
= zi
->ci
.totalUncompressedData
;
1605 compressed_size
= zi
->ci
.totalCompressedData
;
1608 compressed_size
+= zi
->ci
.crypt_header_size
;
1611 // update Current Item crc and sizes,
1612 if(compressed_size
>= 0xffffffff || uncompressed_size
>= 0xffffffff || zi
->ci
.pos_local_header
>= 0xffffffff)
1615 zip64local_putValue_inmemory(zi
->ci
.central_header
+4,(uLong
)45,2);
1617 zip64local_putValue_inmemory(zi
->ci
.central_header
+6,(uLong
)45,2);
1621 zip64local_putValue_inmemory(zi
->ci
.central_header
+16,crc32
,4); /*crc*/
1624 if(compressed_size
>= 0xffffffff)
1625 zip64local_putValue_inmemory(zi
->ci
.central_header
+20, invalidValue
,4); /*compr size*/
1627 zip64local_putValue_inmemory(zi
->ci
.central_header
+20, compressed_size
,4); /*compr size*/
1629 /// set internal file attributes field
1630 if (zi
->ci
.stream
.data_type
== Z_ASCII
)
1631 zip64local_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)Z_ASCII
,2);
1633 if(uncompressed_size
>= 0xffffffff)
1634 zip64local_putValue_inmemory(zi
->ci
.central_header
+24, invalidValue
,4); /*uncompr size*/
1636 zip64local_putValue_inmemory(zi
->ci
.central_header
+24, uncompressed_size
,4); /*uncompr size*/
1638 // Add ZIP64 extra info field for uncompressed size
1639 if(uncompressed_size
>= 0xffffffff)
1642 // Add ZIP64 extra info field for compressed size
1643 if(compressed_size
>= 0xffffffff)
1646 // Add ZIP64 extra info field for relative offset to local file header of current file
1647 if(zi
->ci
.pos_local_header
>= 0xffffffff)
1654 if((uLong
)(datasize
+ 4) > zi
->ci
.size_centralExtraFree
)
1656 // we can not write more data to the buffer that we have room for.
1657 return ZIP_BADZIPFILE
;
1660 p
= zi
->ci
.central_header
+ zi
->ci
.size_centralheader
;
1662 // Add Extra Information Header for 'ZIP64 information'
1663 zip64local_putValue_inmemory(p
, 0x0001, 2); // HeaderID
1665 zip64local_putValue_inmemory(p
, datasize
, 2); // DataSize
1668 if(uncompressed_size
>= 0xffffffff)
1670 zip64local_putValue_inmemory(p
, uncompressed_size
, 8);
1674 if(compressed_size
>= 0xffffffff)
1676 zip64local_putValue_inmemory(p
, compressed_size
, 8);
1680 if(zi
->ci
.pos_local_header
>= 0xffffffff)
1682 zip64local_putValue_inmemory(p
, zi
->ci
.pos_local_header
, 8);
1686 // Update how much extra free space we got in the memory buffer
1687 // and increase the centralheader size so the new ZIP64 fields are included
1688 // ( 4 below is the size of HeaderID and DataSize field )
1689 zi
->ci
.size_centralExtraFree
-= datasize
+ 4;
1690 zi
->ci
.size_centralheader
+= datasize
+ 4;
1692 // Update the extra info size field
1693 zi
->ci
.size_centralExtra
+= datasize
+ 4;
1694 zip64local_putValue_inmemory(zi
->ci
.central_header
+30,(uLong
)zi
->ci
.size_centralExtra
,2);
1698 err
= add_data_in_datablock(&zi
->central_dir
, zi
->ci
.central_header
, (uLong
)zi
->ci
.size_centralheader
);
1700 free(zi
->ci
.central_header
);
1704 // Update the LocalFileHeader with the new values.
1706 ZPOS64_T cur_pos_inzip
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1708 if (ZSEEK64(zi
->z_filefunc
,zi
->filestream
, zi
->ci
.pos_local_header
+ 14,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1712 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,crc32
,4); /* crc 32, unknown */
1714 if(uncompressed_size
>= 0xffffffff || compressed_size
>= 0xffffffff )
1716 if(zi
->ci
.pos_zip64extrainfo
> 0)
1718 // Update the size in the ZIP64 extended field.
1719 if (ZSEEK64(zi
->z_filefunc
,zi
->filestream
, zi
->ci
.pos_zip64extrainfo
+ 4,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1722 if (err
==ZIP_OK
) /* compressed size, unknown */
1723 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, uncompressed_size
, 8);
1725 if (err
==ZIP_OK
) /* uncompressed size, unknown */
1726 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, compressed_size
, 8);
1729 err
= ZIP_BADZIPFILE
; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
1733 if (err
==ZIP_OK
) /* compressed size, unknown */
1734 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,compressed_size
,4);
1736 if (err
==ZIP_OK
) /* uncompressed size, unknown */
1737 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,uncompressed_size
,4);
1740 if (ZSEEK64(zi
->z_filefunc
,zi
->filestream
, cur_pos_inzip
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1744 zi
->number_entry
++;
1745 zi
->in_opened_file_inzip
= 0;
1750 extern int ZEXPORT
zipCloseFileInZip (zipFile file
)
1752 return zipCloseFileInZipRaw (file
,0,0);
1755 int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal
* zi
, ZPOS64_T zip64eocd_pos_inzip
)
1758 ZPOS64_T pos
= zip64eocd_pos_inzip
- zi
->add_position_when_writing_offset
;
1760 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)ZIP64ENDLOCHEADERMAGIC
,4);
1763 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1764 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4);
1767 if (err
==ZIP_OK
) /* Relative offset to the Zip64EndOfCentralDirectory */
1768 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
, pos
,8);
1770 /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
1771 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1772 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)1,4);
1777 int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal
* zi
, uLong size_centraldir
, ZPOS64_T centraldir_pos_inzip
)
1781 uLong Zip64DataSize
= 44;
1783 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)ZIP64ENDHEADERMAGIC
,4);
1785 if (err
==ZIP_OK
) /* size of this 'zip64 end of central directory' */
1786 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(ZPOS64_T
)Zip64DataSize
,8); // why ZPOS64_T of this ?
1788 if (err
==ZIP_OK
) /* version made by */
1789 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)45,2);
1791 if (err
==ZIP_OK
) /* version needed */
1792 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)45,2);
1794 if (err
==ZIP_OK
) /* number of this disk */
1795 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4);
1797 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1798 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4);
1800 if (err
==ZIP_OK
) /* total number of entries in the central dir on this disk */
1801 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, zi
->number_entry
, 8);
1803 if (err
==ZIP_OK
) /* total number of entries in the central dir */
1804 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, zi
->number_entry
, 8);
1806 if (err
==ZIP_OK
) /* size of the central directory */
1807 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(ZPOS64_T
)size_centraldir
,8);
1809 if (err
==ZIP_OK
) /* offset of start of central directory with respect to the starting disk number */
1811 ZPOS64_T pos
= centraldir_pos_inzip
- zi
->add_position_when_writing_offset
;
1812 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
, (ZPOS64_T
)pos
,8);
1816 int Write_EndOfCentralDirectoryRecord(zip64_internal
* zi
, uLong size_centraldir
, ZPOS64_T centraldir_pos_inzip
)
1821 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)ENDHEADERMAGIC
,4);
1823 if (err
==ZIP_OK
) /* number of this disk */
1824 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,2);
1826 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1827 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,2);
1829 if (err
==ZIP_OK
) /* total number of entries in the central dir on this disk */
1832 if(zi
->number_entry
>= 0xFFFF)
1833 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0xffff,2); // use value in ZIP64 record
1835 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->number_entry
,2);
1839 if (err
==ZIP_OK
) /* total number of entries in the central dir */
1841 if(zi
->number_entry
>= 0xFFFF)
1842 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0xffff,2); // use value in ZIP64 record
1844 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->number_entry
,2);
1847 if (err
==ZIP_OK
) /* size of the central directory */
1848 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_centraldir
,4);
1850 if (err
==ZIP_OK
) /* offset of start of central directory with respect to the starting disk number */
1852 ZPOS64_T pos
= centraldir_pos_inzip
- zi
->add_position_when_writing_offset
;
1853 if(pos
>= 0xffffffff)
1855 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
, (uLong
)0xffffffff,4);
1858 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
, (uLong
)(centraldir_pos_inzip
- zi
->add_position_when_writing_offset
),4);
1864 int Write_GlobalComment(zip64_internal
* zi
, const char* global_comment
)
1867 uInt size_global_comment
= 0;
1869 if(global_comment
!= NULL
)
1870 size_global_comment
= (uInt
)strlen(global_comment
);
1872 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_global_comment
,2);
1874 if (err
== ZIP_OK
&& size_global_comment
> 0)
1876 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
, global_comment
, size_global_comment
) != size_global_comment
)
1882 extern int ZEXPORT
zipClose (zipFile file
, const char* global_comment
)
1886 uLong size_centraldir
= 0;
1887 ZPOS64_T centraldir_pos_inzip
;
1891 return ZIP_PARAMERROR
;
1893 zi
= (zip64_internal
*)file
;
1895 if (zi
->in_opened_file_inzip
== 1)
1897 err
= zipCloseFileInZip (file
);
1900 #ifndef NO_ADDFILEINEXISTINGZIP
1901 if (global_comment
==NULL
)
1902 global_comment
= zi
->globalcomment
;
1905 centraldir_pos_inzip
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1909 linkedlist_datablock_internal
* ldi
= zi
->central_dir
.first_block
;
1912 if ((err
==ZIP_OK
) && (ldi
->filled_in_this_block
>0))
1914 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
, ldi
->data
, ldi
->filled_in_this_block
) != ldi
->filled_in_this_block
)
1918 size_centraldir
+= ldi
->filled_in_this_block
;
1919 ldi
= ldi
->next_datablock
;
1922 free_linkedlist(&(zi
->central_dir
));
1924 pos
= centraldir_pos_inzip
- zi
->add_position_when_writing_offset
;
1925 if(pos
>= 0xffffffff || zi
->number_entry
> 0xFFFF)
1927 ZPOS64_T Zip64EOCDpos
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1928 Write_Zip64EndOfCentralDirectoryRecord(zi
, size_centraldir
, centraldir_pos_inzip
);
1930 Write_Zip64EndOfCentralDirectoryLocator(zi
, Zip64EOCDpos
);
1934 err
= Write_EndOfCentralDirectoryRecord(zi
, size_centraldir
, centraldir_pos_inzip
);
1937 err
= Write_GlobalComment(zi
, global_comment
);
1939 if (ZCLOSE64(zi
->z_filefunc
,zi
->filestream
) != 0)
1943 #ifndef NO_ADDFILEINEXISTINGZIP
1944 TRYFREE(zi
->globalcomment
);
1951 extern int ZEXPORT
zipRemoveExtraInfoBlock (char* pData
, int* dataLen
, short sHeader
)
1960 int retVal
= ZIP_OK
;
1962 if(pData
== NULL
|| *dataLen
< 4)
1963 return ZIP_PARAMERROR
;
1965 pNewHeader
= (char*)ALLOC(*dataLen
);
1968 while(p
< (pData
+ *dataLen
))
1970 header
= *(short*)p
;
1971 dataSize
= *(((short*)p
)+1);
1973 if( header
== sHeader
) // Header found.
1975 p
+= dataSize
+ 4; // skip it. do not copy to temp buffer
1979 // Extra Info block should not be removed, So copy it to the temp buffer.
1980 memcpy(pTmp
, p
, dataSize
+ 4);
1982 size
+= dataSize
+ 4;
1989 // clean old extra info block.
1990 memset(pData
,0, *dataLen
);
1992 // copy the new extra info block over the old
1994 memcpy(pData
, pNewHeader
, size
);
1996 // set the new extra info size
2004 TRYFREE(pNewHeader
);