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
43 #if !defined(NOCRYPT) && !defined(WANTCRYPT)
50 /* compile with -Dlocal if your debugger can't find static symbols */
53 # define VERSIONMADEBY (0x0) /* platform depedent */
57 #define Z_BUFSIZE (64*1024) //(16384)
60 #ifndef Z_MAXFILENAMEINZIP
61 #define Z_MAXFILENAMEINZIP (256)
65 # define ALLOC(size) (malloc(size))
68 # define TRYFREE(p) {if (p) free(p);}
72 #define SIZECENTRALDIRITEM (0x2e)
73 #define SIZEZIPLOCALHEADER (0x1e)
76 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
79 // NOT sure that this work on ALL platform
80 #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
95 #if MAX_MEM_LEVEL >= 8
96 # define DEF_MEM_LEVEL 8
98 # define DEF_MEM_LEVEL MAX_MEM_LEVEL
101 const char zip_copyright
[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
104 #define SIZEDATA_INDATABLOCK (4096-(4*4))
106 #define LOCALHEADERMAGIC (0x04034b50)
107 #define CENTRALHEADERMAGIC (0x02014b50)
108 #define ENDHEADERMAGIC (0x06054b50)
109 #define ZIP64ENDHEADERMAGIC (0x6064b50)
110 #define ZIP64ENDLOCHEADERMAGIC (0x7064b50)
112 #define FLAG_LOCALHEADER_OFFSET (0x06)
113 #define CRC_LOCALHEADER_OFFSET (0x0e)
115 #define SIZECENTRALHEADER (0x2e) /* 46 */
117 typedef struct linkedlist_datablock_internal_s
119 struct linkedlist_datablock_internal_s
* next_datablock
;
120 uLong avail_in_this_block
;
121 uLong filled_in_this_block
;
122 uLong unused
; /* for future use and alignement */
123 unsigned char data
[SIZEDATA_INDATABLOCK
];
124 } linkedlist_datablock_internal
;
126 typedef struct linkedlist_data_s
128 linkedlist_datablock_internal
* first_block
;
129 linkedlist_datablock_internal
* last_block
;
135 z_stream stream
; /* zLib stream structure for inflate */
137 bz_stream bstream
; /* bzLib stream structure for bziped */
140 int stream_initialised
; /* 1 is stream is initialised */
141 uInt pos_in_buffered_data
; /* last written byte in buffered_data */
143 ZPOS64_T pos_local_header
; /* offset of the local header of the file
145 char* central_header
; /* central header data for the current file */
146 uLong size_centralExtra
;
147 uLong size_centralheader
; /* size of the central header for cur file */
148 uLong size_centralExtraFree
; /* Extra bytes allocated to the centralheader but that are not used */
149 uLong flag
; /* flag of the file currently writing */
151 int method
; /* compression method of file currenty wr.*/
152 int raw
; /* 1 for directly writing raw data */
153 Byte buffered_data
[Z_BUFSIZE
];/* buffer contain compressed data to be writ*/
157 int zip64
; /* Add ZIP64 extened information in the extra field */
158 ZPOS64_T pos_zip64extrainfo
;
159 ZPOS64_T totalCompressedData
;
160 ZPOS64_T totalUncompressedData
;
162 unsigned long keys
[3]; /* keys defining the pseudo-random sequence */
163 const z_crc_t
* pcrc_32_tab
;
164 int crypt_header_size
;
170 zlib_filefunc64_32_def z_filefunc
;
171 voidpf filestream
; /* io structore of the zipfile */
172 linkedlist_data central_dir
;/* datablock with central dir in construction*/
173 int in_opened_file_inzip
; /* 1 if a file in the zip is currently writ.*/
174 curfile64_info ci
; /* info on the file curretly writing */
176 ZPOS64_T begin_pos
; /* position of the beginning of the zipfile */
177 ZPOS64_T add_position_when_writting_offset
;
178 ZPOS64_T number_entry
;
180 #ifndef NO_ADDFILEINEXISTINGZIP
188 #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
192 local linkedlist_datablock_internal
* allocate_new_datablock()
194 linkedlist_datablock_internal
* ldi
;
195 ldi
= (linkedlist_datablock_internal
*)
196 ALLOC(sizeof(linkedlist_datablock_internal
));
199 ldi
->next_datablock
= NULL
;
200 ldi
->filled_in_this_block
= 0 ;
201 ldi
->avail_in_this_block
= SIZEDATA_INDATABLOCK
;
206 local
void free_datablock(linkedlist_datablock_internal
* ldi
)
210 linkedlist_datablock_internal
* ldinext
= ldi
->next_datablock
;
216 local
void init_linkedlist(linkedlist_data
* ll
)
218 ll
->first_block
= ll
->last_block
= NULL
;
221 local
void free_linkedlist(linkedlist_data
* ll
)
223 free_datablock(ll
->first_block
);
224 ll
->first_block
= ll
->last_block
= NULL
;
228 local
int add_data_in_datablock(linkedlist_data
* ll
, const void* buf
, uLong len
)
230 linkedlist_datablock_internal
* ldi
;
231 const unsigned char* from_copy
;
234 return ZIP_INTERNALERROR
;
236 if (ll
->last_block
== NULL
)
238 ll
->first_block
= ll
->last_block
= allocate_new_datablock();
239 if (ll
->first_block
== NULL
)
240 return ZIP_INTERNALERROR
;
243 ldi
= ll
->last_block
;
244 from_copy
= (unsigned char*)buf
;
250 unsigned char* to_copy
;
252 if (ldi
->avail_in_this_block
==0)
254 ldi
->next_datablock
= allocate_new_datablock();
255 if (ldi
->next_datablock
== NULL
)
256 return ZIP_INTERNALERROR
;
257 ldi
= ldi
->next_datablock
;
258 ll
->last_block
= ldi
;
261 if (ldi
->avail_in_this_block
< len
)
262 copy_this
= (uInt
)ldi
->avail_in_this_block
;
264 copy_this
= (uInt
)len
;
266 to_copy
= &(ldi
->data
[ldi
->filled_in_this_block
]);
268 for (i
=0;i
<copy_this
;i
++)
269 *(to_copy
+i
)=*(from_copy
+i
);
271 ldi
->filled_in_this_block
+= copy_this
;
272 ldi
->avail_in_this_block
-= copy_this
;
273 from_copy
+= copy_this
;
281 /****************************************************************************/
283 #ifndef NO_ADDFILEINEXISTINGZIP
284 /* ===========================================================================
285 Inputs a long in LSB order to the given file
286 nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
289 local
int zip64local_putValue
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, ZPOS64_T x
, int nbByte
));
290 local
int zip64local_putValue (const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, ZPOS64_T x
, int nbByte
)
292 unsigned char buf
[8];
294 for (n
= 0; n
< nbByte
; n
++)
296 buf
[n
] = (unsigned char)(x
& 0xff);
300 { /* data overflow - hack for ZIP64 (X Roche) */
301 for (n
= 0; n
< nbByte
; n
++)
307 if (ZWRITE64(*pzlib_filefunc_def
,filestream
,buf
,nbByte
)!=(uLong
)nbByte
)
313 local
void zip64local_putValue_inmemory
OF((void* dest
, ZPOS64_T x
, int nbByte
));
314 local
void zip64local_putValue_inmemory (void* dest
, ZPOS64_T x
, int nbByte
)
316 unsigned char* buf
=(unsigned char*)dest
;
318 for (n
= 0; n
< nbByte
; n
++) {
319 buf
[n
] = (unsigned char)(x
& 0xff);
324 { /* data overflow - hack for ZIP64 */
325 for (n
= 0; n
< nbByte
; n
++)
332 /****************************************************************************/
335 local uLong
zip64local_TmzDateToDosDate(const tm_zip
* ptm
)
337 uLong year
= (uLong
)ptm
->tm_year
;
343 (uLong
) (((ptm
->tm_mday
) + (32 * (ptm
->tm_mon
+1)) + (512 * year
)) << 16) |
344 ((ptm
->tm_sec
/2) + (32* ptm
->tm_min
) + (2048 * (uLong
)ptm
->tm_hour
));
348 /****************************************************************************/
350 local
int zip64local_getByte
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, int *pi
));
352 local
int zip64local_getByte(const zlib_filefunc64_32_def
* pzlib_filefunc_def
,voidpf filestream
,int* pi
)
355 int err
= (int)ZREAD64(*pzlib_filefunc_def
,filestream
,&c
,1);
363 if (ZERROR64(*pzlib_filefunc_def
,filestream
))
371 /* ===========================================================================
372 Reads a long in LSB order from the given gz_stream. Sets
374 local
int zip64local_getShort
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, uLong
*pX
));
376 local
int zip64local_getShort (const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, uLong
* pX
)
382 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
386 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
396 local
int zip64local_getLong
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, uLong
*pX
));
398 local
int zip64local_getLong (const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, uLong
* pX
)
404 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
408 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
412 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
416 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
426 local
int zip64local_getLong64
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, ZPOS64_T
*pX
));
429 local
int zip64local_getLong64 (const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
, ZPOS64_T
*pX
)
435 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
439 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
440 x
+= ((ZPOS64_T
)i
)<<8;
443 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
444 x
+= ((ZPOS64_T
)i
)<<16;
447 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
448 x
+= ((ZPOS64_T
)i
)<<24;
451 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
452 x
+= ((ZPOS64_T
)i
)<<32;
455 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
456 x
+= ((ZPOS64_T
)i
)<<40;
459 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
460 x
+= ((ZPOS64_T
)i
)<<48;
463 err
= zip64local_getByte(pzlib_filefunc_def
,filestream
,&i
);
464 x
+= ((ZPOS64_T
)i
)<<56;
474 #ifndef BUFREADCOMMENT
475 #define BUFREADCOMMENT (0x400)
478 Locate the Central directory of a zipfile (at the end, just before
481 local ZPOS64_T zip64local_SearchCentralDir
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
));
483 local ZPOS64_T
zip64local_SearchCentralDir(const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
)
488 ZPOS64_T uMaxBack
=0xffff; /* maximum size of global comment */
489 ZPOS64_T uPosFound
=0;
491 if (ZSEEK64(*pzlib_filefunc_def
,filestream
,0,ZLIB_FILEFUNC_SEEK_END
) != 0)
495 uSizeFile
= ZTELL64(*pzlib_filefunc_def
,filestream
);
497 if (uMaxBack
>uSizeFile
)
498 uMaxBack
= uSizeFile
;
500 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
505 while (uBackRead
<uMaxBack
)
510 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
511 uBackRead
= uMaxBack
;
513 uBackRead
+=BUFREADCOMMENT
;
514 uReadPos
= uSizeFile
-uBackRead
;
516 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
517 (BUFREADCOMMENT
+4) : (uLong
)(uSizeFile
-uReadPos
);
518 if (ZSEEK64(*pzlib_filefunc_def
,filestream
,uReadPos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
521 if (ZREAD64(*pzlib_filefunc_def
,filestream
,buf
,uReadSize
)!=uReadSize
)
524 for (i
=(int)uReadSize
-3; (i
--)>0;)
525 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
526 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
528 uPosFound
= uReadPos
+i
;
540 Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
543 local ZPOS64_T zip64local_SearchCentralDir64
OF((const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
));
545 local ZPOS64_T
zip64local_SearchCentralDir64(const zlib_filefunc64_32_def
* pzlib_filefunc_def
, voidpf filestream
)
550 ZPOS64_T uMaxBack
=0xffff; /* maximum size of global comment */
551 ZPOS64_T uPosFound
=0;
553 ZPOS64_T relativeOffset
;
555 if (ZSEEK64(*pzlib_filefunc_def
,filestream
,0,ZLIB_FILEFUNC_SEEK_END
) != 0)
558 uSizeFile
= ZTELL64(*pzlib_filefunc_def
,filestream
);
560 if (uMaxBack
>uSizeFile
)
561 uMaxBack
= uSizeFile
;
563 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
568 while (uBackRead
<uMaxBack
)
573 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
574 uBackRead
= uMaxBack
;
576 uBackRead
+=BUFREADCOMMENT
;
577 uReadPos
= uSizeFile
-uBackRead
;
579 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
580 (BUFREADCOMMENT
+4) : (uLong
)(uSizeFile
-uReadPos
);
581 if (ZSEEK64(*pzlib_filefunc_def
,filestream
,uReadPos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
584 if (ZREAD64(*pzlib_filefunc_def
,filestream
,buf
,uReadSize
)!=uReadSize
)
587 for (i
=(int)uReadSize
-3; (i
--)>0;)
589 // Signature "0x07064b50" Zip64 end of central directory locater
590 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) && ((*(buf
+i
+2))==0x06) && ((*(buf
+i
+3))==0x07))
592 uPosFound
= uReadPos
+i
;
605 /* Zip64 end of central directory locator */
606 if (ZSEEK64(*pzlib_filefunc_def
,filestream
, uPosFound
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
609 /* the signature, already checked */
610 if (zip64local_getLong(pzlib_filefunc_def
,filestream
,&uL
)!=ZIP_OK
)
613 /* number of the disk with the start of the zip64 end of central directory */
614 if (zip64local_getLong(pzlib_filefunc_def
,filestream
,&uL
)!=ZIP_OK
)
619 /* relative offset of the zip64 end of central directory record */
620 if (zip64local_getLong64(pzlib_filefunc_def
,filestream
,&relativeOffset
)!=ZIP_OK
)
623 /* total number of disks */
624 if (zip64local_getLong(pzlib_filefunc_def
,filestream
,&uL
)!=ZIP_OK
)
629 /* Goto Zip64 end of central directory record */
630 if (ZSEEK64(*pzlib_filefunc_def
,filestream
, relativeOffset
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
634 if (zip64local_getLong(pzlib_filefunc_def
,filestream
,&uL
)!=ZIP_OK
)
637 if (uL
!= 0x06064b50) // signature of 'Zip64 end of central directory'
640 return relativeOffset
;
643 int LoadCentralDirectoryRecord(zip64_internal
* pziinit
)
646 ZPOS64_T byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
648 ZPOS64_T size_central_dir
; /* size of the central directory */
649 ZPOS64_T offset_central_dir
; /* offset of start of central directory */
650 ZPOS64_T central_pos
;
653 uLong number_disk
; /* number of the current dist, used for
654 spaning ZIP, unsupported, always 0*/
655 uLong number_disk_with_CD
; /* number the the disk with central dir, used
656 for spaning ZIP, unsupported, always 0*/
657 ZPOS64_T number_entry
;
658 ZPOS64_T number_entry_CD
; /* total number of entries in
660 (same than number_entry on nospan) */
665 int hasZIP64Record
= 0;
667 // check first if we find a ZIP64 record
668 central_pos
= zip64local_SearchCentralDir64(&pziinit
->z_filefunc
,pziinit
->filestream
);
673 else if(central_pos
== 0)
675 central_pos
= zip64local_SearchCentralDir(&pziinit
->z_filefunc
,pziinit
->filestream
);
678 /* disable to allow appending to empty ZIP archive
685 ZPOS64_T sizeEndOfCentralDirectory
;
686 if (ZSEEK64(pziinit
->z_filefunc
, pziinit
->filestream
, central_pos
, ZLIB_FILEFUNC_SEEK_SET
) != 0)
689 /* the signature, already checked */
690 if (zip64local_getLong(&pziinit
->z_filefunc
, pziinit
->filestream
,&uL
)!=ZIP_OK
)
693 /* size of zip64 end of central directory record */
694 if (zip64local_getLong64(&pziinit
->z_filefunc
, pziinit
->filestream
, &sizeEndOfCentralDirectory
)!=ZIP_OK
)
697 /* version made by */
698 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
, &VersionMadeBy
)!=ZIP_OK
)
701 /* version needed to extract */
702 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
, &VersionNeeded
)!=ZIP_OK
)
705 /* number of this disk */
706 if (zip64local_getLong(&pziinit
->z_filefunc
, pziinit
->filestream
,&number_disk
)!=ZIP_OK
)
709 /* number of the disk with the start of the central directory */
710 if (zip64local_getLong(&pziinit
->z_filefunc
, pziinit
->filestream
,&number_disk_with_CD
)!=ZIP_OK
)
713 /* total number of entries in the central directory on this disk */
714 if (zip64local_getLong64(&pziinit
->z_filefunc
, pziinit
->filestream
, &number_entry
)!=ZIP_OK
)
717 /* total number of entries in the central directory */
718 if (zip64local_getLong64(&pziinit
->z_filefunc
, pziinit
->filestream
,&number_entry_CD
)!=ZIP_OK
)
721 if ((number_entry_CD
!=number_entry
) || (number_disk_with_CD
!=0) || (number_disk
!=0))
724 /* size of the central directory */
725 if (zip64local_getLong64(&pziinit
->z_filefunc
, pziinit
->filestream
,&size_central_dir
)!=ZIP_OK
)
728 /* offset of start of central directory with respect to the
729 starting disk number */
730 if (zip64local_getLong64(&pziinit
->z_filefunc
, pziinit
->filestream
,&offset_central_dir
)!=ZIP_OK
)
734 // read the comment from the standard central header.
739 // Read End of central Directory info
740 if (ZSEEK64(pziinit
->z_filefunc
, pziinit
->filestream
, central_pos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
743 /* the signature, already checked */
744 if (zip64local_getLong(&pziinit
->z_filefunc
, pziinit
->filestream
,&uL
)!=ZIP_OK
)
747 /* number of this disk */
748 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
,&number_disk
)!=ZIP_OK
)
751 /* number of the disk with the start of the central directory */
752 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
,&number_disk_with_CD
)!=ZIP_OK
)
755 /* total number of entries in the central dir on this disk */
757 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
, &uL
)!=ZIP_OK
)
762 /* total number of entries in the central dir */
764 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
, &uL
)!=ZIP_OK
)
767 number_entry_CD
= uL
;
769 if ((number_entry_CD
!=number_entry
) || (number_disk_with_CD
!=0) || (number_disk
!=0))
772 /* size of the central directory */
773 size_central_dir
= 0;
774 if (zip64local_getLong(&pziinit
->z_filefunc
, pziinit
->filestream
, &uL
)!=ZIP_OK
)
777 size_central_dir
= uL
;
779 /* offset of start of central directory with respect to the starting disk number */
780 offset_central_dir
= 0;
781 if (zip64local_getLong(&pziinit
->z_filefunc
, pziinit
->filestream
, &uL
)!=ZIP_OK
)
784 offset_central_dir
= uL
;
787 /* zipfile global comment length */
788 if (zip64local_getShort(&pziinit
->z_filefunc
, pziinit
->filestream
, &size_comment
)!=ZIP_OK
)
792 if ((central_pos
<offset_central_dir
+size_central_dir
) &&
798 ZCLOSE64(pziinit
->z_filefunc
, pziinit
->filestream
);
804 pziinit
->globalcomment
= (char*)ALLOC(size_comment
+1);
805 if (pziinit
->globalcomment
)
807 size_comment
= ZREAD64(pziinit
->z_filefunc
, pziinit
->filestream
, pziinit
->globalcomment
,size_comment
);
808 pziinit
->globalcomment
[size_comment
]=0;
812 byte_before_the_zipfile
= central_pos
- (offset_central_dir
+size_central_dir
);
813 pziinit
->add_position_when_writting_offset
= byte_before_the_zipfile
;
816 ZPOS64_T size_central_dir_to_read
= size_central_dir
;
817 size_t buf_size
= SIZEDATA_INDATABLOCK
;
818 void* buf_read
= (void*)ALLOC(buf_size
);
819 if (ZSEEK64(pziinit
->z_filefunc
, pziinit
->filestream
, offset_central_dir
+ byte_before_the_zipfile
, ZLIB_FILEFUNC_SEEK_SET
) != 0)
822 while ((size_central_dir_to_read
>0) && (err
==ZIP_OK
))
824 ZPOS64_T read_this
= SIZEDATA_INDATABLOCK
;
825 if (read_this
> size_central_dir_to_read
)
826 read_this
= size_central_dir_to_read
;
828 if (ZREAD64(pziinit
->z_filefunc
, pziinit
->filestream
,buf_read
,(uLong
)read_this
) != read_this
)
832 err
= add_data_in_datablock(&pziinit
->central_dir
,buf_read
, (uLong
)read_this
);
834 size_central_dir_to_read
-=read_this
;
838 pziinit
->begin_pos
= byte_before_the_zipfile
;
839 pziinit
->number_entry
= number_entry_CD
;
841 if (ZSEEK64(pziinit
->z_filefunc
, pziinit
->filestream
, offset_central_dir
+byte_before_the_zipfile
,ZLIB_FILEFUNC_SEEK_SET
) != 0)
848 #endif /* !NO_ADDFILEINEXISTINGZIP*/
851 /************************************************************/
852 extern zipFile ZEXPORT
zipOpen3 (const void *pathname
, int append
, zipcharpc
* globalcomment
, zlib_filefunc64_32_def
* pzlib_filefunc64_32_def
)
854 zip64_internal ziinit
;
858 ziinit
.z_filefunc
.zseek32_file
= NULL
;
859 ziinit
.z_filefunc
.ztell32_file
= NULL
;
860 if (pzlib_filefunc64_32_def
==NULL
)
861 fill_fopen64_filefunc(&ziinit
.z_filefunc
.zfile_func64
);
863 ziinit
.z_filefunc
= *pzlib_filefunc64_32_def
;
865 ziinit
.filestream
= ZOPEN64(ziinit
.z_filefunc
,
867 (append
== APPEND_STATUS_CREATE
) ?
868 (ZLIB_FILEFUNC_MODE_READ
| ZLIB_FILEFUNC_MODE_WRITE
| ZLIB_FILEFUNC_MODE_CREATE
) :
869 (ZLIB_FILEFUNC_MODE_READ
| ZLIB_FILEFUNC_MODE_WRITE
| ZLIB_FILEFUNC_MODE_EXISTING
));
871 if (ziinit
.filestream
== NULL
)
874 if (append
== APPEND_STATUS_CREATEAFTER
)
875 ZSEEK64(ziinit
.z_filefunc
,ziinit
.filestream
,0,SEEK_END
);
877 ziinit
.begin_pos
= ZTELL64(ziinit
.z_filefunc
,ziinit
.filestream
);
878 ziinit
.in_opened_file_inzip
= 0;
879 ziinit
.ci
.stream_initialised
= 0;
880 ziinit
.number_entry
= 0;
881 ziinit
.add_position_when_writting_offset
= 0;
882 init_linkedlist(&(ziinit
.central_dir
));
886 zi
= (zip64_internal
*)ALLOC(sizeof(zip64_internal
));
889 ZCLOSE64(ziinit
.z_filefunc
,ziinit
.filestream
);
893 /* now we add file in a zipfile */
894 # ifndef NO_ADDFILEINEXISTINGZIP
895 ziinit
.globalcomment
= NULL
;
896 if (append
== APPEND_STATUS_ADDINZIP
)
898 // Read and Cache Central Directory Records
899 err
= LoadCentralDirectoryRecord(&ziinit
);
904 *globalcomment
= ziinit
.globalcomment
;
906 # endif /* !NO_ADDFILEINEXISTINGZIP*/
910 # ifndef NO_ADDFILEINEXISTINGZIP
911 TRYFREE(ziinit
.globalcomment
);
912 # endif /* !NO_ADDFILEINEXISTINGZIP*/
923 extern zipFile ZEXPORT
zipOpen2 (const char *pathname
, int append
, zipcharpc
* globalcomment
, zlib_filefunc_def
* pzlib_filefunc32_def
)
925 if (pzlib_filefunc32_def
!= NULL
)
927 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill
;
928 fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill
,pzlib_filefunc32_def
);
929 return zipOpen3(pathname
, append
, globalcomment
, &zlib_filefunc64_32_def_fill
);
932 return zipOpen3(pathname
, append
, globalcomment
, NULL
);
935 extern zipFile ZEXPORT
zipOpen2_64 (const void *pathname
, int append
, zipcharpc
* globalcomment
, zlib_filefunc64_def
* pzlib_filefunc_def
)
937 if (pzlib_filefunc_def
!= NULL
)
939 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill
;
940 zlib_filefunc64_32_def_fill
.zfile_func64
= *pzlib_filefunc_def
;
941 zlib_filefunc64_32_def_fill
.ztell32_file
= NULL
;
942 zlib_filefunc64_32_def_fill
.zseek32_file
= NULL
;
943 return zipOpen3(pathname
, append
, globalcomment
, &zlib_filefunc64_32_def_fill
);
946 return zipOpen3(pathname
, append
, globalcomment
, NULL
);
951 extern zipFile ZEXPORT
zipOpen (const char* pathname
, int append
)
953 return zipOpen3((const void*)pathname
,append
,NULL
,NULL
);
956 extern zipFile ZEXPORT
zipOpen64 (const void* pathname
, int append
)
958 return zipOpen3(pathname
,append
,NULL
,NULL
);
961 int Write_LocalFileHeader(zip64_internal
* zi
, const char* filename
, uInt size_extrafield_local
, const void* extrafield_local
)
963 /* write the local header */
965 uInt size_filename
= (uInt
)strlen(filename
);
966 uInt size_extrafield
= size_extrafield_local
;
968 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)LOCALHEADERMAGIC
, 4);
973 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)45,2);/* version needed to extract */
975 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)20,2);/* version needed to extract */
979 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->ci
.flag
,2);
982 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->ci
.method
,2);
985 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->ci
.dosDate
,4);
987 // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
989 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4); /* crc 32, unknown */
993 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0xFFFFFFFF,4); /* compressed size, unknown */
995 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4); /* compressed size, unknown */
1000 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0xFFFFFFFF,4); /* uncompressed size, unknown */
1002 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4); /* uncompressed size, unknown */
1006 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_filename
,2);
1010 size_extrafield
+= 20;
1014 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_extrafield
,2);
1016 if ((err
==ZIP_OK
) && (size_filename
> 0))
1018 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
,filename
,size_filename
)!=size_filename
)
1022 if ((err
==ZIP_OK
) && (size_extrafield_local
> 0))
1024 if (ZWRITE64(zi
->z_filefunc
, zi
->filestream
, extrafield_local
, size_extrafield_local
) != size_extrafield_local
)
1029 if ((err
==ZIP_OK
) && (zi
->ci
.zip64
))
1031 // write the Zip64 extended info
1033 short DataSize
= 16;
1034 ZPOS64_T CompressedSize
= 0;
1035 ZPOS64_T UncompressedSize
= 0;
1037 // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
1038 zi
->ci
.pos_zip64extrainfo
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1040 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, (short)HeaderID
,2);
1041 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, (short)DataSize
,2);
1043 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, (ZPOS64_T
)UncompressedSize
,8);
1044 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, (ZPOS64_T
)CompressedSize
,8);
1052 When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
1053 before calling this function it can be done with zipRemoveExtraInfoBlock
1055 It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
1056 unnecessary allocations.
1058 extern int ZEXPORT
zipOpenNewFileInZip4_64 (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1059 const void* extrafield_local
, uInt size_extrafield_local
,
1060 const void* extrafield_global
, uInt size_extrafield_global
,
1061 const char* comment
, int method
, int level
, int raw
,
1062 int windowBits
,int memLevel
, int strategy
,
1063 const char* password
, uLong crcForCrypting
,
1064 uLong versionMadeBy
, uLong flagBase
, int zip64
)
1073 // (crcForCrypting);
1074 if (password
!= NULL
)
1075 return ZIP_PARAMERROR
;
1079 return ZIP_PARAMERROR
;
1082 if ((method
!=0) && (method
!=Z_DEFLATED
) && (method
!=Z_BZIP2ED
))
1083 return ZIP_PARAMERROR
;
1085 if ((method
!=0) && (method
!=Z_DEFLATED
))
1086 return ZIP_PARAMERROR
;
1089 zi
= (zip64_internal
*)file
;
1091 if (zi
->in_opened_file_inzip
== 1)
1093 err
= zipCloseFileInZip (file
);
1104 size_comment
= (uInt
)strlen(comment
);
1106 size_filename
= (uInt
)strlen(filename
);
1112 if (zipfi
->dosDate
!= 0)
1113 zi
->ci
.dosDate
= zipfi
->dosDate
;
1115 zi
->ci
.dosDate
= zip64local_TmzDateToDosDate(&zipfi
->tmz_date
);
1118 zi
->ci
.flag
= flagBase
;
1119 if ((level
==8) || (level
==9))
1125 if (password
!= NULL
)
1129 zi
->ci
.method
= method
;
1131 zi
->ci
.stream_initialised
= 0;
1132 zi
->ci
.pos_in_buffered_data
= 0;
1134 zi
->ci
.pos_local_header
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1136 zi
->ci
.size_centralheader
= SIZECENTRALHEADER
+ size_filename
+ size_extrafield_global
+ size_comment
;
1137 zi
->ci
.size_centralExtraFree
= 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
1139 zi
->ci
.central_header
= (char*)ALLOC((uInt
)zi
->ci
.size_centralheader
+ zi
->ci
.size_centralExtraFree
);
1141 zi
->ci
.size_centralExtra
= size_extrafield_global
;
1142 zip64local_putValue_inmemory(zi
->ci
.central_header
,(uLong
)CENTRALHEADERMAGIC
,4);
1144 zip64local_putValue_inmemory(zi
->ci
.central_header
+4,(uLong
)versionMadeBy
,2);
1145 zip64local_putValue_inmemory(zi
->ci
.central_header
+6,(uLong
)20,2);
1146 zip64local_putValue_inmemory(zi
->ci
.central_header
+8,(uLong
)zi
->ci
.flag
,2);
1147 zip64local_putValue_inmemory(zi
->ci
.central_header
+10,(uLong
)zi
->ci
.method
,2);
1148 zip64local_putValue_inmemory(zi
->ci
.central_header
+12,(uLong
)zi
->ci
.dosDate
,4);
1149 zip64local_putValue_inmemory(zi
->ci
.central_header
+16,(uLong
)0,4); /*crc*/
1150 zip64local_putValue_inmemory(zi
->ci
.central_header
+20,(uLong
)0,4); /*compr size*/
1151 zip64local_putValue_inmemory(zi
->ci
.central_header
+24,(uLong
)0,4); /*uncompr size*/
1152 zip64local_putValue_inmemory(zi
->ci
.central_header
+28,(uLong
)size_filename
,2);
1153 zip64local_putValue_inmemory(zi
->ci
.central_header
+30,(uLong
)size_extrafield_global
,2);
1154 zip64local_putValue_inmemory(zi
->ci
.central_header
+32,(uLong
)size_comment
,2);
1155 zip64local_putValue_inmemory(zi
->ci
.central_header
+34,(uLong
)0,2); /*disk nm start*/
1158 zip64local_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)0,2);
1160 zip64local_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)zipfi
->internal_fa
,2);
1163 zip64local_putValue_inmemory(zi
->ci
.central_header
+38,(uLong
)0,4);
1165 zip64local_putValue_inmemory(zi
->ci
.central_header
+38,(uLong
)zipfi
->external_fa
,4);
1167 if(zi
->ci
.pos_local_header
>= 0xffffffff)
1168 zip64local_putValue_inmemory(zi
->ci
.central_header
+42,(uLong
)0xffffffff,4);
1170 zip64local_putValue_inmemory(zi
->ci
.central_header
+42,(uLong
)zi
->ci
.pos_local_header
- zi
->add_position_when_writting_offset
,4);
1172 for (i
=0;i
<size_filename
;i
++)
1173 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+i
) = *(filename
+i
);
1175 for (i
=0;i
<size_extrafield_global
;i
++)
1176 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+size_filename
+i
) =
1177 *(((const char*)extrafield_global
)+i
);
1179 for (i
=0;i
<size_comment
;i
++)
1180 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+size_filename
+
1181 size_extrafield_global
+i
) = *(comment
+i
);
1182 if (zi
->ci
.central_header
== NULL
)
1183 return ZIP_INTERNALERROR
;
1185 zi
->ci
.zip64
= zip64
;
1186 zi
->ci
.totalCompressedData
= 0;
1187 zi
->ci
.totalUncompressedData
= 0;
1188 zi
->ci
.pos_zip64extrainfo
= 0;
1190 err
= Write_LocalFileHeader(zi
, filename
, size_extrafield_local
, extrafield_local
);
1193 zi
->ci
.bstream
.avail_in
= (uInt
)0;
1194 zi
->ci
.bstream
.avail_out
= (uInt
)Z_BUFSIZE
;
1195 zi
->ci
.bstream
.next_out
= (char*)zi
->ci
.buffered_data
;
1196 zi
->ci
.bstream
.total_in_hi32
= 0;
1197 zi
->ci
.bstream
.total_in_lo32
= 0;
1198 zi
->ci
.bstream
.total_out_hi32
= 0;
1199 zi
->ci
.bstream
.total_out_lo32
= 0;
1202 zi
->ci
.stream
.avail_in
= (uInt
)0;
1203 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
1204 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
1205 zi
->ci
.stream
.total_in
= 0;
1206 zi
->ci
.stream
.total_out
= 0;
1207 zi
->ci
.stream
.data_type
= Z_BINARY
;
1210 if ((err
==ZIP_OK
) && (zi
->ci
.method
== Z_DEFLATED
|| zi
->ci
.method
== Z_BZIP2ED
) && (!zi
->ci
.raw
))
1212 if ((err
==ZIP_OK
) && (zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1215 if(zi
->ci
.method
== Z_DEFLATED
)
1217 zi
->ci
.stream
.zalloc
= (alloc_func
)0;
1218 zi
->ci
.stream
.zfree
= (free_func
)0;
1219 zi
->ci
.stream
.opaque
= (voidpf
)0;
1222 windowBits
= -windowBits
;
1224 err
= deflateInit2(&zi
->ci
.stream
, level
, Z_DEFLATED
, windowBits
, memLevel
, strategy
);
1227 zi
->ci
.stream_initialised
= Z_DEFLATED
;
1229 else if(zi
->ci
.method
== Z_BZIP2ED
)
1232 // Init BZip stuff here
1233 zi
->ci
.bstream
.bzalloc
= 0;
1234 zi
->ci
.bstream
.bzfree
= 0;
1235 zi
->ci
.bstream
.opaque
= (voidpf
)0;
1237 err
= BZ2_bzCompressInit(&zi
->ci
.bstream
, level
, 0,35);
1239 zi
->ci
.stream_initialised
= Z_BZIP2ED
;
1246 zi
->ci
.crypt_header_size
= 0;
1247 if ((err
==Z_OK
) && (password
!= NULL
))
1249 unsigned char bufHead
[RAND_HEAD_LEN
];
1250 unsigned int sizeHead
;
1252 zi
->ci
.pcrc_32_tab
= get_crc_table();
1253 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
1255 sizeHead
=crypthead(password
,bufHead
,RAND_HEAD_LEN
,zi
->ci
.keys
,zi
->ci
.pcrc_32_tab
,crcForCrypting
);
1256 zi
->ci
.crypt_header_size
= sizeHead
;
1258 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
,bufHead
,sizeHead
) != sizeHead
)
1264 zi
->in_opened_file_inzip
= 1;
1268 extern int ZEXPORT
zipOpenNewFileInZip4 (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1269 const void* extrafield_local
, uInt size_extrafield_local
,
1270 const void* extrafield_global
, uInt size_extrafield_global
,
1271 const char* comment
, int method
, int level
, int raw
,
1272 int windowBits
,int memLevel
, int strategy
,
1273 const char* password
, uLong crcForCrypting
,
1274 uLong versionMadeBy
, uLong flagBase
)
1276 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1277 extrafield_local
, size_extrafield_local
,
1278 extrafield_global
, size_extrafield_global
,
1279 comment
, method
, level
, raw
,
1280 windowBits
, memLevel
, strategy
,
1281 password
, crcForCrypting
, versionMadeBy
, flagBase
, 0);
1284 extern int ZEXPORT
zipOpenNewFileInZip3 (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1285 const void* extrafield_local
, uInt size_extrafield_local
,
1286 const void* extrafield_global
, uInt size_extrafield_global
,
1287 const char* comment
, int method
, int level
, int raw
,
1288 int windowBits
,int memLevel
, int strategy
,
1289 const char* password
, uLong crcForCrypting
)
1291 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1292 extrafield_local
, size_extrafield_local
,
1293 extrafield_global
, size_extrafield_global
,
1294 comment
, method
, level
, raw
,
1295 windowBits
, memLevel
, strategy
,
1296 password
, crcForCrypting
, VERSIONMADEBY
, 0, 0);
1299 extern int ZEXPORT
zipOpenNewFileInZip3_64(zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1300 const void* extrafield_local
, uInt size_extrafield_local
,
1301 const void* extrafield_global
, uInt size_extrafield_global
,
1302 const char* comment
, int method
, int level
, int raw
,
1303 int windowBits
,int memLevel
, int strategy
,
1304 const char* password
, uLong crcForCrypting
, int zip64
)
1306 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1307 extrafield_local
, size_extrafield_local
,
1308 extrafield_global
, size_extrafield_global
,
1309 comment
, method
, level
, raw
,
1310 windowBits
, memLevel
, strategy
,
1311 password
, crcForCrypting
, VERSIONMADEBY
, 0, zip64
);
1314 extern int ZEXPORT
zipOpenNewFileInZip2(zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1315 const void* extrafield_local
, uInt size_extrafield_local
,
1316 const void* extrafield_global
, uInt size_extrafield_global
,
1317 const char* comment
, int method
, int level
, int raw
)
1319 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1320 extrafield_local
, size_extrafield_local
,
1321 extrafield_global
, size_extrafield_global
,
1322 comment
, method
, level
, raw
,
1323 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
1324 NULL
, 0, VERSIONMADEBY
, 0, 0);
1327 extern int ZEXPORT
zipOpenNewFileInZip2_64(zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1328 const void* extrafield_local
, uInt size_extrafield_local
,
1329 const void* extrafield_global
, uInt size_extrafield_global
,
1330 const char* comment
, int method
, int level
, int raw
, int zip64
)
1332 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1333 extrafield_local
, size_extrafield_local
,
1334 extrafield_global
, size_extrafield_global
,
1335 comment
, method
, level
, raw
,
1336 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
1337 NULL
, 0, VERSIONMADEBY
, 0, zip64
);
1340 extern int ZEXPORT
zipOpenNewFileInZip64 (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1341 const void* extrafield_local
, uInt size_extrafield_local
,
1342 const void*extrafield_global
, uInt size_extrafield_global
,
1343 const char* comment
, int method
, int level
, int zip64
)
1345 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1346 extrafield_local
, size_extrafield_local
,
1347 extrafield_global
, size_extrafield_global
,
1348 comment
, method
, level
, 0,
1349 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
1350 NULL
, 0, VERSIONMADEBY
, 0, zip64
);
1353 extern int ZEXPORT
zipOpenNewFileInZip (zipFile file
, const char* filename
, const zip_fileinfo
* zipfi
,
1354 const void* extrafield_local
, uInt size_extrafield_local
,
1355 const void*extrafield_global
, uInt size_extrafield_global
,
1356 const char* comment
, int method
, int level
)
1358 return zipOpenNewFileInZip4_64 (file
, filename
, zipfi
,
1359 extrafield_local
, size_extrafield_local
,
1360 extrafield_global
, size_extrafield_global
,
1361 comment
, method
, level
, 0,
1362 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
1363 NULL
, 0, VERSIONMADEBY
, 0, 0);
1366 local
int zip64FlushWriteBuffer(zip64_internal
* zi
)
1370 if (zi
->ci
.encrypt
!= 0)
1375 for (i
=0;i
<zi
->ci
.pos_in_buffered_data
;i
++)
1376 zi
->ci
.buffered_data
[i
] = zencode(zi
->ci
.keys
, zi
->ci
.pcrc_32_tab
, zi
->ci
.buffered_data
[i
],t
);
1380 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
,zi
->ci
.buffered_data
,zi
->ci
.pos_in_buffered_data
) != zi
->ci
.pos_in_buffered_data
)
1383 zi
->ci
.totalCompressedData
+= zi
->ci
.pos_in_buffered_data
;
1386 if(zi
->ci
.method
== Z_BZIP2ED
)
1388 zi
->ci
.totalUncompressedData
+= zi
->ci
.bstream
.total_in_lo32
;
1389 zi
->ci
.bstream
.total_in_lo32
= 0;
1390 zi
->ci
.bstream
.total_in_hi32
= 0;
1395 zi
->ci
.totalUncompressedData
+= zi
->ci
.stream
.total_in
;
1396 zi
->ci
.stream
.total_in
= 0;
1400 zi
->ci
.pos_in_buffered_data
= 0;
1405 extern int ZEXPORT
zipWriteInFileInZip (zipFile file
,const void* buf
,unsigned int len
)
1411 return ZIP_PARAMERROR
;
1412 zi
= (zip64_internal
*)file
;
1414 if (zi
->in_opened_file_inzip
== 0)
1415 return ZIP_PARAMERROR
;
1417 zi
->ci
.crc32
= crc32(zi
->ci
.crc32
,buf
,(uInt
)len
);
1420 if(zi
->ci
.method
== Z_BZIP2ED
&& (!zi
->ci
.raw
))
1422 zi
->ci
.bstream
.next_in
= (void*)buf
;
1423 zi
->ci
.bstream
.avail_in
= len
;
1426 while ((err
==BZ_RUN_OK
) && (zi
->ci
.bstream
.avail_in
>0))
1428 if (zi
->ci
.bstream
.avail_out
== 0)
1430 if (zip64FlushWriteBuffer(zi
) == ZIP_ERRNO
)
1432 zi
->ci
.bstream
.avail_out
= (uInt
)Z_BUFSIZE
;
1433 zi
->ci
.bstream
.next_out
= (char*)zi
->ci
.buffered_data
;
1437 if(err
!= BZ_RUN_OK
)
1440 if ((zi
->ci
.method
== Z_BZIP2ED
) && (!zi
->ci
.raw
))
1442 uLong uTotalOutBefore_lo
= zi
->ci
.bstream
.total_out_lo32
;
1443 // uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
1444 err
=BZ2_bzCompress(&zi
->ci
.bstream
, BZ_RUN
);
1446 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.bstream
.total_out_lo32
- uTotalOutBefore_lo
) ;
1450 if(err
== BZ_RUN_OK
)
1456 zi
->ci
.stream
.next_in
= (Bytef
*)buf
;
1457 zi
->ci
.stream
.avail_in
= len
;
1459 while ((err
==ZIP_OK
) && (zi
->ci
.stream
.avail_in
>0))
1461 if (zi
->ci
.stream
.avail_out
== 0)
1463 if (zip64FlushWriteBuffer(zi
) == ZIP_ERRNO
)
1465 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
1466 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
1473 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1475 uLong uTotalOutBefore
= zi
->ci
.stream
.total_out
;
1476 err
=deflate(&zi
->ci
.stream
, Z_NO_FLUSH
);
1477 if(uTotalOutBefore
> zi
->ci
.stream
.total_out
)
1483 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.stream
.total_out
- uTotalOutBefore
) ;
1488 if (zi
->ci
.stream
.avail_in
< zi
->ci
.stream
.avail_out
)
1489 copy_this
= zi
->ci
.stream
.avail_in
;
1491 copy_this
= zi
->ci
.stream
.avail_out
;
1493 for (i
= 0; i
< copy_this
; i
++)
1494 *(((char*)zi
->ci
.stream
.next_out
)+i
) =
1495 *(((const char*)zi
->ci
.stream
.next_in
)+i
);
1497 zi
->ci
.stream
.avail_in
-= copy_this
;
1498 zi
->ci
.stream
.avail_out
-= copy_this
;
1499 zi
->ci
.stream
.next_in
+= copy_this
;
1500 zi
->ci
.stream
.next_out
+= copy_this
;
1501 zi
->ci
.stream
.total_in
+= copy_this
;
1502 zi
->ci
.stream
.total_out
+= copy_this
;
1503 zi
->ci
.pos_in_buffered_data
+= copy_this
;
1512 extern int ZEXPORT
zipCloseFileInZipRaw (zipFile file
, uLong uncompressed_size
, uLong crc32
)
1514 return zipCloseFileInZipRaw64 (file
, uncompressed_size
, crc32
);
1517 extern int ZEXPORT
zipCloseFileInZipRaw64 (zipFile file
, ZPOS64_T uncompressed_size
, uLong crc32
)
1520 ZPOS64_T compressed_size
;
1521 uLong invalidValue
= 0xffffffff;
1526 return ZIP_PARAMERROR
;
1527 zi
= (zip64_internal
*)file
;
1529 if (zi
->in_opened_file_inzip
== 0)
1530 return ZIP_PARAMERROR
;
1531 zi
->ci
.stream
.avail_in
= 0;
1533 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1537 uLong uTotalOutBefore
;
1538 if (zi
->ci
.stream
.avail_out
== 0)
1540 if (zip64FlushWriteBuffer(zi
) == ZIP_ERRNO
)
1542 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
1543 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
1545 uTotalOutBefore
= zi
->ci
.stream
.total_out
;
1546 err
=deflate(&zi
->ci
.stream
, Z_FINISH
);
1547 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.stream
.total_out
- uTotalOutBefore
) ;
1550 else if ((zi
->ci
.method
== Z_BZIP2ED
) && (!zi
->ci
.raw
))
1554 while (err
==BZ_FINISH_OK
)
1556 uLong uTotalOutBefore
;
1557 if (zi
->ci
.bstream
.avail_out
== 0)
1559 if (zip64FlushWriteBuffer(zi
) == ZIP_ERRNO
)
1561 zi
->ci
.bstream
.avail_out
= (uInt
)Z_BUFSIZE
;
1562 zi
->ci
.bstream
.next_out
= (char*)zi
->ci
.buffered_data
;
1564 uTotalOutBefore
= zi
->ci
.bstream
.total_out_lo32
;
1565 err
=BZ2_bzCompress(&zi
->ci
.bstream
, BZ_FINISH
);
1566 if(err
== BZ_STREAM_END
)
1569 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.bstream
.total_out_lo32
- uTotalOutBefore
);
1572 if(err
== BZ_FINISH_OK
)
1577 if (err
==Z_STREAM_END
)
1578 err
=ZIP_OK
; /* this is normal */
1580 if ((zi
->ci
.pos_in_buffered_data
>0) && (err
==ZIP_OK
))
1582 if (zip64FlushWriteBuffer(zi
)==ZIP_ERRNO
)
1586 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1588 int tmp_err
= deflateEnd(&zi
->ci
.stream
);
1591 zi
->ci
.stream_initialised
= 0;
1594 else if((zi
->ci
.method
== Z_BZIP2ED
) && (!zi
->ci
.raw
))
1596 int tmperr
= BZ2_bzCompressEnd(&zi
->ci
.bstream
);
1599 zi
->ci
.stream_initialised
= 0;
1605 crc32
= (uLong
)zi
->ci
.crc32
;
1606 uncompressed_size
= zi
->ci
.totalUncompressedData
;
1608 compressed_size
= zi
->ci
.totalCompressedData
;
1611 compressed_size
+= zi
->ci
.crypt_header_size
;
1614 // update Current Item crc and sizes,
1615 if(compressed_size
>= 0xffffffff || uncompressed_size
>= 0xffffffff || zi
->ci
.pos_local_header
>= 0xffffffff)
1618 zip64local_putValue_inmemory(zi
->ci
.central_header
+4,(uLong
)45,2);
1620 zip64local_putValue_inmemory(zi
->ci
.central_header
+6,(uLong
)45,2);
1624 zip64local_putValue_inmemory(zi
->ci
.central_header
+16,crc32
,4); /*crc*/
1627 if(compressed_size
>= 0xffffffff)
1628 zip64local_putValue_inmemory(zi
->ci
.central_header
+20, invalidValue
,4); /*compr size*/
1630 zip64local_putValue_inmemory(zi
->ci
.central_header
+20, compressed_size
,4); /*compr size*/
1632 /// set internal file attributes field
1633 if (zi
->ci
.stream
.data_type
== Z_ASCII
)
1634 zip64local_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)Z_ASCII
,2);
1636 if(uncompressed_size
>= 0xffffffff)
1637 zip64local_putValue_inmemory(zi
->ci
.central_header
+24, invalidValue
,4); /*uncompr size*/
1639 zip64local_putValue_inmemory(zi
->ci
.central_header
+24, uncompressed_size
,4); /*uncompr size*/
1641 // Add ZIP64 extra info field for uncompressed size
1642 if(uncompressed_size
>= 0xffffffff)
1645 // Add ZIP64 extra info field for compressed size
1646 if(compressed_size
>= 0xffffffff)
1649 // Add ZIP64 extra info field for relative offset to local file header of current file
1650 if(zi
->ci
.pos_local_header
>= 0xffffffff)
1657 if((uLong
)(datasize
+ 4) > zi
->ci
.size_centralExtraFree
)
1659 // we can not write more data to the buffer that we have room for.
1660 return ZIP_BADZIPFILE
;
1663 p
= zi
->ci
.central_header
+ zi
->ci
.size_centralheader
;
1665 // Add Extra Information Header for 'ZIP64 information'
1666 zip64local_putValue_inmemory(p
, 0x0001, 2); // HeaderID
1668 zip64local_putValue_inmemory(p
, datasize
, 2); // DataSize
1671 if(uncompressed_size
>= 0xffffffff)
1673 zip64local_putValue_inmemory(p
, uncompressed_size
, 8);
1677 if(compressed_size
>= 0xffffffff)
1679 zip64local_putValue_inmemory(p
, compressed_size
, 8);
1683 if(zi
->ci
.pos_local_header
>= 0xffffffff)
1685 zip64local_putValue_inmemory(p
, zi
->ci
.pos_local_header
, 8);
1689 // Update how much extra free space we got in the memory buffer
1690 // and increase the centralheader size so the new ZIP64 fields are included
1691 // ( 4 below is the size of HeaderID and DataSize field )
1692 zi
->ci
.size_centralExtraFree
-= datasize
+ 4;
1693 zi
->ci
.size_centralheader
+= datasize
+ 4;
1695 // Update the extra info size field
1696 zi
->ci
.size_centralExtra
+= datasize
+ 4;
1697 zip64local_putValue_inmemory(zi
->ci
.central_header
+30,(uLong
)zi
->ci
.size_centralExtra
,2);
1701 err
= add_data_in_datablock(&zi
->central_dir
, zi
->ci
.central_header
, (uLong
)zi
->ci
.size_centralheader
);
1703 free(zi
->ci
.central_header
);
1707 // Update the LocalFileHeader with the new values.
1709 ZPOS64_T cur_pos_inzip
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1711 if (ZSEEK64(zi
->z_filefunc
,zi
->filestream
, zi
->ci
.pos_local_header
+ 14,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1715 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,crc32
,4); /* crc 32, unknown */
1717 if(uncompressed_size
>= 0xffffffff || compressed_size
>= 0xffffffff )
1719 if(zi
->ci
.pos_zip64extrainfo
> 0)
1721 // Update the size in the ZIP64 extended field.
1722 if (ZSEEK64(zi
->z_filefunc
,zi
->filestream
, zi
->ci
.pos_zip64extrainfo
+ 4,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1725 if (err
==ZIP_OK
) /* compressed size, unknown */
1726 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, uncompressed_size
, 8);
1728 if (err
==ZIP_OK
) /* uncompressed size, unknown */
1729 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, compressed_size
, 8);
1732 err
= ZIP_BADZIPFILE
; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
1736 if (err
==ZIP_OK
) /* compressed size, unknown */
1737 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,compressed_size
,4);
1739 if (err
==ZIP_OK
) /* uncompressed size, unknown */
1740 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,uncompressed_size
,4);
1743 if (ZSEEK64(zi
->z_filefunc
,zi
->filestream
, cur_pos_inzip
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1747 zi
->number_entry
++;
1748 zi
->in_opened_file_inzip
= 0;
1753 extern int ZEXPORT
zipCloseFileInZip (zipFile file
)
1755 return zipCloseFileInZipRaw (file
,0,0);
1758 int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal
* zi
, ZPOS64_T zip64eocd_pos_inzip
)
1761 ZPOS64_T pos
= zip64eocd_pos_inzip
- zi
->add_position_when_writting_offset
;
1763 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)ZIP64ENDLOCHEADERMAGIC
,4);
1766 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1767 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4);
1770 if (err
==ZIP_OK
) /* Relative offset to the Zip64EndOfCentralDirectory */
1771 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
, pos
,8);
1773 /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
1774 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1775 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)1,4);
1780 int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal
* zi
, uLong size_centraldir
, ZPOS64_T centraldir_pos_inzip
)
1784 uLong Zip64DataSize
= 44;
1786 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)ZIP64ENDHEADERMAGIC
,4);
1788 if (err
==ZIP_OK
) /* size of this 'zip64 end of central directory' */
1789 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(ZPOS64_T
)Zip64DataSize
,8); // why ZPOS64_T of this ?
1791 if (err
==ZIP_OK
) /* version made by */
1792 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)45,2);
1794 if (err
==ZIP_OK
) /* version needed */
1795 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)45,2);
1797 if (err
==ZIP_OK
) /* number of this disk */
1798 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4);
1800 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1801 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4);
1803 if (err
==ZIP_OK
) /* total number of entries in the central dir on this disk */
1804 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, zi
->number_entry
, 8);
1806 if (err
==ZIP_OK
) /* total number of entries in the central dir */
1807 err
= zip64local_putValue(&zi
->z_filefunc
, zi
->filestream
, zi
->number_entry
, 8);
1809 if (err
==ZIP_OK
) /* size of the central directory */
1810 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(ZPOS64_T
)size_centraldir
,8);
1812 if (err
==ZIP_OK
) /* offset of start of central directory with respect to the starting disk number */
1814 ZPOS64_T pos
= centraldir_pos_inzip
- zi
->add_position_when_writting_offset
;
1815 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
, (ZPOS64_T
)pos
,8);
1819 int Write_EndOfCentralDirectoryRecord(zip64_internal
* zi
, uLong size_centraldir
, ZPOS64_T centraldir_pos_inzip
)
1824 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)ENDHEADERMAGIC
,4);
1826 if (err
==ZIP_OK
) /* number of this disk */
1827 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,2);
1829 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1830 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,2);
1832 if (err
==ZIP_OK
) /* total number of entries in the central dir on this disk */
1835 if(zi
->number_entry
>= 0xFFFF)
1836 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0xffff,2); // use value in ZIP64 record
1838 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->number_entry
,2);
1842 if (err
==ZIP_OK
) /* total number of entries in the central dir */
1844 if(zi
->number_entry
>= 0xFFFF)
1845 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0xffff,2); // use value in ZIP64 record
1847 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->number_entry
,2);
1850 if (err
==ZIP_OK
) /* size of the central directory */
1851 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_centraldir
,4);
1853 if (err
==ZIP_OK
) /* offset of start of central directory with respect to the starting disk number */
1855 ZPOS64_T pos
= centraldir_pos_inzip
- zi
->add_position_when_writting_offset
;
1856 if(pos
>= 0xffffffff)
1858 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
, (uLong
)0xffffffff,4);
1861 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
, (uLong
)(centraldir_pos_inzip
- zi
->add_position_when_writting_offset
),4);
1867 int Write_GlobalComment(zip64_internal
* zi
, const char* global_comment
)
1870 uInt size_global_comment
= 0;
1872 if(global_comment
!= NULL
)
1873 size_global_comment
= (uInt
)strlen(global_comment
);
1875 err
= zip64local_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_global_comment
,2);
1877 if (err
== ZIP_OK
&& size_global_comment
> 0)
1879 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
, global_comment
, size_global_comment
) != size_global_comment
)
1885 extern int ZEXPORT
zipClose (zipFile file
, const char* global_comment
)
1889 uLong size_centraldir
= 0;
1890 ZPOS64_T centraldir_pos_inzip
;
1894 return ZIP_PARAMERROR
;
1896 zi
= (zip64_internal
*)file
;
1898 if (zi
->in_opened_file_inzip
== 1)
1900 err
= zipCloseFileInZip (file
);
1903 #ifndef NO_ADDFILEINEXISTINGZIP
1904 if (global_comment
==NULL
)
1905 global_comment
= zi
->globalcomment
;
1908 centraldir_pos_inzip
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1912 linkedlist_datablock_internal
* ldi
= zi
->central_dir
.first_block
;
1915 if ((err
==ZIP_OK
) && (ldi
->filled_in_this_block
>0))
1917 if (ZWRITE64(zi
->z_filefunc
,zi
->filestream
, ldi
->data
, ldi
->filled_in_this_block
) != ldi
->filled_in_this_block
)
1921 size_centraldir
+= ldi
->filled_in_this_block
;
1922 ldi
= ldi
->next_datablock
;
1925 free_linkedlist(&(zi
->central_dir
));
1927 pos
= centraldir_pos_inzip
- zi
->add_position_when_writting_offset
;
1928 if(pos
>= 0xffffffff || zi
->number_entry
> 0xFFFF)
1930 ZPOS64_T Zip64EOCDpos
= ZTELL64(zi
->z_filefunc
,zi
->filestream
);
1931 Write_Zip64EndOfCentralDirectoryRecord(zi
, size_centraldir
, centraldir_pos_inzip
);
1933 Write_Zip64EndOfCentralDirectoryLocator(zi
, Zip64EOCDpos
);
1937 err
= Write_EndOfCentralDirectoryRecord(zi
, size_centraldir
, centraldir_pos_inzip
);
1940 err
= Write_GlobalComment(zi
, global_comment
);
1942 if (ZCLOSE64(zi
->z_filefunc
,zi
->filestream
) != 0)
1946 #ifndef NO_ADDFILEINEXISTINGZIP
1947 TRYFREE(zi
->globalcomment
);
1954 extern int ZEXPORT
zipRemoveExtraInfoBlock (char* pData
, int* dataLen
, short sHeader
)
1963 int retVal
= ZIP_OK
;
1965 if(pData
== NULL
|| *dataLen
< 4)
1966 return ZIP_PARAMERROR
;
1968 pNewHeader
= (char*)ALLOC(*dataLen
);
1971 while(p
< (pData
+ *dataLen
))
1973 header
= *(short*)p
;
1974 dataSize
= *(((short*)p
)+1);
1976 if( header
== sHeader
) // Header found.
1978 p
+= dataSize
+ 4; // skip it. do not copy to temp buffer
1982 // Extra Info block should not be removed, So copy it to the temp buffer.
1983 memcpy(pTmp
, p
, dataSize
+ 4);
1985 size
+= dataSize
+ 4;
1992 // clean old extra info block.
1993 memset(pData
,0, *dataLen
);
1995 // copy the new extra info block over the old
1997 memcpy(pData
, pNewHeader
, size
);
1999 // set the new extra info size
2007 TRYFREE(pNewHeader
);