Modifications for Zip64 support Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
For more info read MiniZip_info.txt
Changes Oct-2009 - Mathias Svensson - Remove old C style function prototypes Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data It is used when recreating zip archive with RAW when deleting items from a zip. ZIP64 data is automatically added to items that needs it, and existing ZIP64 data need to be removed. Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
int stream_initialised; /* 1 is stream is initialised */
uInt pos_in_buffered_data; /* last written byte in buffered_data */
ZPOS64_T pos_local_header; /* offset of the local header of the file
currently writing */ char* central_header; /* central header data for the current file */
uLong size_centralExtra;
uLong size_centralheader; /* size of the central header for cur file */
uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
uLong flag; /* flag of the file currently writing */
int method; /* compression method of file currently wr.*/ int raw; /* 1 for directly writing raw data */
Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
uLong dosDate;
uLong crc32; int encrypt; int zip64; /* Add ZIP64 extended information in the extra field */
ZPOS64_T pos_zip64extrainfo;
ZPOS64_T totalCompressedData;
ZPOS64_T totalUncompressedData; #ifndef NOCRYPT unsignedlong keys[3]; /* keys defining the pseudo-random sequence */ const z_crc_t* pcrc_32_tab; unsigned crypt_header_size; #endif
} curfile64_info;
typedefstruct
{
zlib_filefunc64_32_def z_filefunc;
voidpf filestream; /* io structure of the zipfile */
linkedlist_data central_dir;/* datablock with central dir in construction*/ int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
curfile64_info ci; /* info on the file currently writing */
ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
ZPOS64_T add_position_when_writing_offset;
ZPOS64_T number_entry;
#ifndef NO_ADDFILEINEXISTINGZIP /* =========================================================================== Inputs a long in LSB order to the given file nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
*/
local int zip64local_putValue(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) { unsignedchar buf[8]; int n; for (n = 0; n < nbByte; n++)
{
buf[n] = (unsignedchar)(x & 0xff);
x >>= 8;
} if (x != 0)
{ /* data overflow - hack for ZIP64 (X Roche) */ for (n = 0; n < nbByte; n++)
{
buf[n] = 0xff;
}
}
if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,(uLong)nbByte)!=(uLong)nbByte) return ZIP_ERRNO; else return ZIP_OK;
}
local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) { unsignedchar* buf=(unsignedchar*)dest; int n; for (n = 0; n < nbByte; n++) {
buf[n] = (unsignedchar)(x & 0xff);
x >>= 8;
}
if (x != 0)
{ /* data overflow - hack for ZIP64 */ for (n = 0; n < nbByte; n++)
{
buf[n] = 0xff;
}
}
}
local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int* pi) { unsignedchar c; int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); if (err==1)
{
*pi = (int)c; return ZIP_OK;
} else
{ if (ZERROR64(*pzlib_filefunc_def,filestream)) return ZIP_ERRNO; else return ZIP_EOF;
}
}
/* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets
*/
local int zip64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) {
uLong x ; int i = 0; int err;
err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
x = (uLong)i;
if (err==ZIP_OK)
err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
x += ((uLong)i)<<8;
local int zip64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) {
ZPOS64_T x; int i = 0; int err;
err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
x = (ZPOS64_T)i;
if (err==ZIP_OK)
err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
x += ((ZPOS64_T)i)<<8;
if (err==ZIP_OK)
err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
x += ((ZPOS64_T)i)<<16;
if (err==ZIP_OK)
err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
x += ((ZPOS64_T)i)<<24;
if (err==ZIP_OK)
err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
x += ((ZPOS64_T)i)<<32;
if (err==ZIP_OK)
err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
x += ((ZPOS64_T)i)<<40;
if (err==ZIP_OK)
err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
x += ((ZPOS64_T)i)<<48;
if (err==ZIP_OK)
err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
x += ((ZPOS64_T)i)<<56;
if (err==ZIP_OK)
*pX = x; else
*pX = 0;
return err;
}
#ifndef BUFREADCOMMENT #define BUFREADCOMMENT (0x400) #endif /* Locate the Central directory of a zipfile (at the end, just before the global comment)
*/
local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsignedchar* buf;
ZPOS64_T uSizeFile;
ZPOS64_T uBackRead;
ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
ZPOS64_T uPosFound=0;
if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) return 0;
if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break;
for (i=(int)uReadSize-3; (i--)>0;) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
{
uPosFound = uReadPos+(unsigned)i; break;
}
if (uPosFound!=0) break;
}
free(buf); return uPosFound;
}
/* Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before the global comment)
*/
local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsignedchar* buf;
ZPOS64_T uSizeFile;
ZPOS64_T uBackRead;
ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
ZPOS64_T uPosFound=0;
uLong uL;
ZPOS64_T relativeOffset;
if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) return 0;
if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break;
for (i=(int)uReadSize-3; (i--)>0;)
{ // Signature "0x07064b50" Zip64 end of central directory locater if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
{
uPosFound = uReadPos+(unsigned)i; break;
}
}
if (uPosFound!=0) break;
}
free(buf); if (uPosFound == 0) return 0;
/* Zip64 end of central directory locator */ if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) return 0;
/* the signature, already checked */ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0;
/* number of the disk with the start of the zip64 end of central directory */ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0; if (uL != 0) return 0;
/* relative offset of the zip64 end of central directory record */ if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) return 0;
/* total number of disks */ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0; if (uL != 1) return 0;
/* Goto Zip64 end of central directory record */ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) return 0;
/* the signature */ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0;
if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' return 0;
return relativeOffset;
}
local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { int err=ZIP_OK;
ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
ZPOS64_T size_central_dir; /* size of the central directory */
ZPOS64_T offset_central_dir; /* offset of start of central directory */
ZPOS64_T central_pos;
uLong uL;
uLong number_disk; /* number of the current dist, used for
spanning ZIP, unsupported, always 0*/
uLong number_disk_with_CD; /* number the the disk with central dir, used
for spanning ZIP, unsupported, always 0*/
ZPOS64_T number_entry;
ZPOS64_T number_entry_CD; /* total number of entries in the central dir
(same than number_entry on nospan) */
uLong VersionMadeBy;
uLong VersionNeeded;
uLong size_comment;
int hasZIP64Record = 0;
// check first if we find a ZIP64 record
central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); if(central_pos > 0)
{
hasZIP64Record = 1;
} elseif(central_pos == 0)
{
central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
}
/* disable to allow appending to empty ZIP archive if (central_pos==0) err=ZIP_ERRNO;
*/
/* the signature, already checked */ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
err=ZIP_ERRNO;
/* size of zip64 end of central directory record */ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
err=ZIP_ERRNO;
/* version made by */ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
err=ZIP_ERRNO;
/* version needed to extract */ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
err=ZIP_ERRNO;
/* number of this disk */ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
err=ZIP_ERRNO;
/* number of the disk with the start of the central directory */ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
err=ZIP_ERRNO;
/* total number of entries in the central directory on this disk */ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
err=ZIP_ERRNO;
/* total number of entries in the central directory */ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
err=ZIP_ERRNO;
if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
err=ZIP_BADZIPFILE;
/* size of the central directory */ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
err=ZIP_ERRNO;
/* offset of start of central directory with respect to the
starting disk number */ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
err=ZIP_ERRNO;
// TODO.. // read the comment from the standard central header.
size_comment = 0;
} else
{ // Read End of central Directory info if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
err=ZIP_ERRNO;
/* the signature, already checked */ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
err=ZIP_ERRNO;
/* number of this disk */ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
err=ZIP_ERRNO;
/* number of the disk with the start of the central directory */ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
err=ZIP_ERRNO;
/* total number of entries in the central dir on this disk */
number_entry = 0; if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
err=ZIP_ERRNO; else
number_entry = uL;
/* total number of entries in the central dir */
number_entry_CD = 0; if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
err=ZIP_ERRNO; else
number_entry_CD = uL;
if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
err=ZIP_BADZIPFILE;
/* size of the central directory */
size_central_dir = 0; if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
err=ZIP_ERRNO; else
size_central_dir = uL;
/* offset of start of central directory with respect to the starting disk number */
offset_central_dir = 0; if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
err=ZIP_ERRNO; else
offset_central_dir = uL;
/* zipfile global comment length */ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
err=ZIP_ERRNO;
}
if ((central_pos<offset_central_dir+size_central_dir) &&
(err==ZIP_OK))
err=ZIP_BADZIPFILE;
if (err!=ZIP_OK)
{
ZCLOSE64(pziinit->z_filefunc, pziinit->filestream); return ZIP_ERRNO;
}
if (size_comment>0)
{
pziinit->globalcomment = (char*)ALLOC(size_comment+1); if (pziinit->globalcomment)
{
size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
pziinit->globalcomment[size_comment]=0;
}
}
zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); if (zi==NULL)
{
ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); return NULL;
}
/* now we add file in a zipfile */ # ifndef NO_ADDFILEINEXISTINGZIP
ziinit.globalcomment = NULL; if (append == APPEND_STATUS_ADDINZIP)
{ // Read and Cache Central Directory Records
err = LoadCentralDirectoryRecord(&ziinit);
}
if (err==ZIP_OK)
{ if(zi->ci.zip64)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ else
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
}
if (err==ZIP_OK)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
if (err==ZIP_OK)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
if (err==ZIP_OK)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
// CRC / Compressed size / Uncompressed size will be filled in later and rewritten later if (err==ZIP_OK)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ if (err==ZIP_OK)
{ if(zi->ci.zip64)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ else
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
} if (err==ZIP_OK)
{ if(zi->ci.zip64)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ else
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
}
if (err==ZIP_OK)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
if(zi->ci.zip64)
{
size_extrafield += 20;
}
if (err==ZIP_OK)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
if ((err==ZIP_OK) && (size_filename > 0))
{ if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
err = ZIP_ERRNO;
}
if ((err==ZIP_OK) && (size_extrafield_local > 0))
{ if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
err = ZIP_ERRNO;
}
if ((err==ZIP_OK) && (zi->ci.zip64))
{ // write the Zip64 extended info short HeaderID = 1; short DataSize = 16;
ZPOS64_T CompressedSize = 0;
ZPOS64_T UncompressedSize = 0;
// Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
/* NOTE. When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped before calling this function it can be done with zipRemoveExtraInfoBlock
It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize unnecessary allocations.
*/ externint ZEXPORT zipOpenNewFileInZip4_64(zipFile file, constchar* filename, const zip_fileinfo* zipfi, constvoid* extrafield_local, uInt size_extrafield_local, constvoid* extrafield_global, uInt size_extrafield_global, constchar* comment, int method, int level, int raw, int windowBits,int memLevel, int strategy, constchar* password, uLong crcForCrypting,
uLong versionMadeBy, uLong flagBase, int zip64) {
zip64_internal* zi;
uInt size_filename;
uInt size_comment;
uInt i; int err = ZIP_OK;
zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
if (zipfi==NULL)
zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); else
zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
if (zipfi==NULL)
zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); else
zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
/// set internal file attributes field if (zi->ci.stream.data_type == Z_ASCII)
zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
// Add ZIP64 extra info field for uncompressed size if(uncompressed_size >= 0xffffffff)
datasize += 8;
// Add ZIP64 extra info field for compressed size if(compressed_size >= 0xffffffff)
datasize += 8;
// Add ZIP64 extra info field for relative offset to local file header of current file if(zi->ci.pos_local_header >= 0xffffffff)
datasize += 8;
if(datasize > 0)
{ char* p = NULL;
if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
{ // we can not write more data to the buffer that we have room for. return ZIP_BADZIPFILE;
}
p = zi->ci.central_header + zi->ci.size_centralheader;
// Add Extra Information Header for 'ZIP64 information'
zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
p += 2;
zip64local_putValue_inmemory(p, datasize, 2); // DataSize
p += 2;
// Update how much extra free space we got in the memory buffer // and increase the centralheader size so the new ZIP64 fields are included // ( 4 below is the size of HeaderID and DataSize field )
zi->ci.size_centralExtraFree -= datasize + 4;
zi->ci.size_centralheader += datasize + 4;
// Update the extra info size field
zi->ci.size_centralExtra += datasize + 4;
zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
}
if (err==ZIP_OK)
err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
free(zi->ci.central_header);
if (err==ZIP_OK)
{ // Update the LocalFileHeader with the new values.
/*num disks*/ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
/*relative offset*/ if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
/*total disks*/ /* Do not support spawning of disk so always say 1 here*/ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
return err;
}
local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { int err = ZIP_OK;
if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
if (err==ZIP_OK) /* version made by */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
if (err==ZIP_OK) /* version needed */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
if (err==ZIP_OK) /* number of this disk */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
if (err==ZIP_OK) /* number of the disk with the start of the central directory */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
if (err==ZIP_OK) /* total number of entries in the central dir */
err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
if (err==ZIP_OK) /* size of the central directory */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
{
ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
} return err;
}
local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { int err = ZIP_OK;
if (err==ZIP_OK) /* number of this disk */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
if (err==ZIP_OK) /* number of the disk with the start of the central directory */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
{
{ if(zi->number_entry >= 0xFFFF)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record else
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
}
}
if (err==ZIP_OK) /* total number of entries in the central dir */
{ if(zi->number_entry >= 0xFFFF)
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record else
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
}
if (err==ZIP_OK) /* size of the central directory */
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
{
ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; if(pos >= 0xffffffff)
{
err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
} else
err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writing_offset),4);
}
return err;
}
local int Write_GlobalComment(zip64_internal* zi, constchar* global_comment) { int err = ZIP_OK;
uInt size_global_comment = 0;
externint ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader) { char* p = pData; int size = 0; char* pNewHeader; char* pTmp; short header; short dataSize;
if( header == sHeader ) // Header found.
{
p += dataSize + 4; // skip it. do not copy to temp buffer
} else
{ // Extra Info block should not be removed, So copy it to the temp buffer.
memcpy(pTmp, p, dataSize + 4);
p += dataSize + 4;
size += dataSize + 4;
}
}
if(size < *dataLen)
{ // clean old extra info block.
memset(pData,0, *dataLen);
// copy the new extra info block over the old if(size > 0)
memcpy(pData, pNewHeader, size);
// set the new extra info size
*dataLen = size;
retVal = ZIP_OK;
} else
retVal = ZIP_ERRNO;
free(pNewHeader);
return retVal;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.23 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.