From 66ed216ad8ff2625e3a157aa644aa11b42fbae94 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Wed, 2 Jan 2013 02:56:31 +0100 Subject: [PATCH] Update zip code to minizip 1.1 .. from zlib-1.2.7/contrib/minizip/ It resides next to the unzip code in framework/minizip/ This updates makes the code a bit cleaner and creating zip64 with the idZipBuilder is now more feasible and update to future minizip versions should be easier as I didn't change the original files from minizip 1.1 very much. --- neo/framework/Zip.cpp | 1355 +------------- neo/framework/Zip.h | 227 +-- neo/framework/minizip/MiniZip64_info.txt | 4 +- neo/framework/minizip/zip.cpp | 2036 ++++++++++++++++++++++ neo/framework/minizip/zip.h | 362 ++++ 5 files changed, 2419 insertions(+), 1565 deletions(-) create mode 100644 neo/framework/minizip/zip.cpp create mode 100644 neo/framework/minizip/zip.h diff --git a/neo/framework/Zip.cpp b/neo/framework/Zip.cpp index afcc28a8..f08c49a0 100644 --- a/neo/framework/Zip.cpp +++ b/neo/framework/Zip.cpp @@ -36,1350 +36,29 @@ Contains external code for building ZipFiles. */ #include "Zip.h" -#include "Unzip.h" -#undef STDC -#include "../libs/zlib/zutil.h" - -/* zip.c -- IO on .zip files using zlib - Version 1.01e, February 12th, 2005 - - 27 Dec 2004 Rolf Kalbermatter - Modification to zipOpen2 to support globalComment retrieval. - - Copyright (C) 1998-2005 Gilles Vollant - - This unzip package allow creates .ZIP file, compatible with PKZip 2.04g - WinZip, InfoZip tools and compatible. - Multi volume ZipFile (span) are not supported. - Encryption compatible with pkzip 2.04g only supported - Old compressions used by old PKZip 1.x are not supported - - For uncompress .zip file, look at unzip.h - - I WAIT FEEDBACK at mail info@winimage.com - Visit also http://www.winimage.com/zLibDll/unzip.html for evolution - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - For more info about .ZIP format, see - http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip - http://www.info-zip.org/pub/infozip/doc/ - PkWare has also a specification at : - ftp://ftp.pkware.com/probdesc.zip - -*/ - -#ifndef Z_MAXFILENAMEINZIP -#define Z_MAXFILENAMEINZIP (256) -#endif - -#ifndef ALLOC -#define ALLOC( size ) ( Mem_Alloc( size, TAG_ZIP ) ) -#endif -#ifndef TRYFREE -#define TRYFREE( p ) { if (p) { Mem_Free(p); } } -#endif - -/* -#define SIZECENTRALDIRITEM (0x2e) -#define SIZEZIPLOCALHEADER (0x1e) -*/ - -const char zip_copyright[] = - " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; - -#define LOCALHEADERMAGIC (0x04034b50) -#define CENTRALHEADERMAGIC (0x02014b50) -#define ENDHEADERMAGIC (0x06054b50) - -#define FLAG_LOCALHEADER_OFFSET (0x06) -#define CRC_LOCALHEADER_OFFSET (0x0e) - -#define SIZECENTRALHEADER (0x2e) /* 46 */ +// #undef STDC +idCVar zip_verbosity( "zip_verbosity", "0", CVAR_BOOL, "1 = verbose logging when building zip files" ); #define DEFAULT_COMPRESSION_LEVEL (5) /* 1 == Compress faster, 9 == Compress better */ #define DEFAULT_WRITEBUFFERSIZE (16384) -#ifndef NOCRYPT -#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED -#include "crypt.h" -#endif - -idCVar zip_verbosity( "zip_verbosity", "0", CVAR_BOOL, "1 = verbose logging when building zip files" ); - /* -======================== -allocate_new_datablock -======================== -*/ -linkedlist_datablock_internal* allocate_new_datablock() -{ - linkedlist_datablock_internal* ldi = NULL; - ldi = ( linkedlist_datablock_internal* ) ALLOC( sizeof( linkedlist_datablock_internal ) ); - if( ldi != NULL ) - { - ldi->next_datablock = NULL; - ldi->filled_in_this_block = 0; - ldi->avail_in_this_block = SIZEDATA_INDATABLOCK; - } - return ldi; -} - -/* -======================== -free_datablock -======================== -*/ -void free_datablock( linkedlist_datablock_internal* ldi ) -{ - while( ldi != NULL ) - { - linkedlist_datablock_internal* ldinext = ldi->next_datablock; - TRYFREE( ldi ); - ldi = ldinext; - } -} - -/* -======================== -init_linkedlist -======================== -*/ -void init_linkedlist( linkedlist_data* ll ) -{ - ll->first_block = ll->last_block = NULL; -} - -/* -======================== -free_linkedlist -======================== -*/ -void free_linkedlist( linkedlist_data* ll ) -{ - free_datablock( ll->first_block ); - ll->first_block = ll->last_block = NULL; -} - -/* -======================== -add_data_in_datablock -======================== -*/ -int add_data_in_datablock( linkedlist_data* ll, const void* buf, unsigned long len ) -{ - linkedlist_datablock_internal* ldi; - const unsigned char* from_copy; - - if( ll == NULL ) - { - return ZIP_INTERNALERROR; - } - - if( ll->last_block == NULL ) - { - ll->first_block = ll->last_block = allocate_new_datablock(); - if( ll->first_block == NULL ) - { - return ZIP_INTERNALERROR; - } - } - - ldi = ll->last_block; - from_copy = ( unsigned char* )buf; - - while( len > 0 ) - { - unsigned int copy_this; - unsigned char* to_copy; - - if( ldi->avail_in_this_block == 0 ) - { - ldi->next_datablock = allocate_new_datablock(); - if( ldi->next_datablock == NULL ) - { - return ZIP_INTERNALERROR; - } - ldi = ldi->next_datablock; - ll->last_block = ldi; - } - - if( ldi->avail_in_this_block < len ) - { - copy_this = ( unsigned int )ldi->avail_in_this_block; - } - else - { - copy_this = ( unsigned int )len; - } - - to_copy = &( ldi->data[ ldi->filled_in_this_block ] ); - - for( unsigned int i = 0; i < copy_this; i++ ) - { - *( to_copy + i ) = * ( from_copy + i ); - } - - ldi->filled_in_this_block += copy_this; - ldi->avail_in_this_block -= copy_this; - from_copy += copy_this; - len -= copy_this; - } - - return ZIP_OK; -} - -#ifndef NO_ADDFILEINEXISTINGZIP - -/* -======================== -ziplocal_putValue - -Inputs a long in LSB order to the given file -nbByte == 1, 2 or 4 (byte, short or long) -======================== -*/ -int ziplocal_putValue( idFile* filestream, unsigned long x, int nbByte ) -{ - unsigned char buf[4]; - for( int n = 0; n < nbByte; n++ ) - { - buf[n] = ( unsigned char )( x & 0xff ); - x >>= 8; - } - if( x != 0 ) - { - /* data overflow - hack for ZIP64 (X Roche) */ - for( int n = 0; n < nbByte; n++ ) - { - buf[n] = 0xff; - } - } - if( filestream->Write( buf, nbByte ) != nbByte ) - { - return ZIP_ERRNO; - } - else - { - return ZIP_OK; - } -} - -/* -======================== -ziplocal_putValue_inmemory -======================== -*/ -void ziplocal_putValue_inmemory( void* dest, unsigned long x, int nbByte ) -{ - unsigned char* buf = ( unsigned char* )dest; - for( int n = 0; n < nbByte; n++ ) - { - buf[n] = ( unsigned char )( x & 0xff ); - x >>= 8; - } - - if( x != 0 ) - { - /* data overflow - hack for ZIP64 */ - for( int n = 0; n < nbByte; n++ ) - { - buf[n] = 0xff; - } - } -} - -/* -======================== -ziplocal_TmzDateToDosDate -======================== -*/ -unsigned long ziplocal_TmzDateToDosDate( const tm_zip* ptm, unsigned long dosDate ) -{ - unsigned long year = ( unsigned long )ptm->tm_year; - if( year > 1980 ) - { - year -= 1980; - } - else if( year > 80 ) - { - year -= 80; - } - return ( unsigned long )( ( ( ptm->tm_mday ) + ( 32 * ( ptm->tm_mon + 1 ) ) + ( 512 * year ) ) << 16 ) | - ( ( ptm->tm_sec / 2 ) + ( 32 * ptm->tm_min ) + ( 2048 * ( unsigned long )ptm->tm_hour ) ); -} - -/* -======================== -ziplocal_getByte -======================== -*/ -int ziplocal_getByte( idFile* filestream, int* pi ) -{ - unsigned char c; - int err = ( int )filestream->Read( &c, 1 ); - if( err == 1 ) - { - *pi = ( int )c; - return ZIP_OK; - } - else - { - return ZIP_ERRNO; - } - /* - unsigned char c; - int err = (int)ZREAD( filestream, &c, 1 ); - - if ( err == 1 ) { - *pi = (int)c; - return ZIP_OK; - } else { - if ( ZERROR( filestream ) ) { - return ZIP_ERRNO; - } else { - return ZIP_EOF; - } - } - */ -} - -/* -======================== -ziplocal_getShort - -Reads a long in LSB order from the given gz_stream. Sets -======================== -*/ -int ziplocal_getShort( idFile* filestream, unsigned long* pX ) -{ - short v; - if( filestream->Read( &v, sizeof( v ) ) == sizeof( v ) ) - { - idSwap::Little( v ); - *pX = v; - return ZIP_OK; - } - else - { - return ZIP_ERRNO; - } - /* - unsigned long x ; - int i; - int err; - - err = ziplocal_getByte( filestream, &i ); - x = (unsigned long)i; - - if ( err == ZIP_OK ) { - err = ziplocal_getByte( filestream, &i ); - } - x += ( (unsigned long)i ) << 8; - - if ( err == ZIP_OK ) { - *pX = x; - } else { - *pX = 0; - } - return err; - */ -} - -/* -======================== -ziplocal_getLong -======================== -*/ -int ziplocal_getLong( idFile* filestream, unsigned long* pX ) -{ - int v; - if( filestream->Read( &v, sizeof( v ) ) == sizeof( v ) ) - { - idSwap::Little( v ); - *pX = v; - return ZIP_OK; - } - else - { - return ZIP_ERRNO; - } - /* - unsigned long x ; - int i; - int err; - - err = ziplocal_getByte( filestream, &i ); - x = (unsigned long)i; - - if ( err == ZIP_OK ) { - err = ziplocal_getByte( filestream, &i ); - } - x += ( (unsigned long)i ) << 8; - - if ( err == ZIP_OK ) { - err = ziplocal_getByte( filestream, &i ); - } - x += ( (unsigned long)i) << 16; - - if ( err == ZIP_OK ) { - err = ziplocal_getByte( filestream, &i ); - } - x += ( (unsigned long)i ) << 24; - - if ( err == ZIP_OK ) { - *pX = x; - } else { - *pX = 0; - } - return err; - */ -} - -#ifndef BUFREADCOMMENT -#define BUFREADCOMMENT (0x400) -#endif - -/* -======================== -ziplocal_SearchCentralDir - -Locate the Central directory of a zipfile (at the end, just before -the global comment) -======================== -*/ -unsigned long ziplocal_SearchCentralDir( idFile* filestream ) -{ - unsigned char* buf; - unsigned long uSizeFile; - unsigned long uBackRead; - unsigned long uMaxBack = 0xffff; /* maximum size of global comment */ - unsigned long uPosFound = 0; - - if( filestream->Seek( 0, FS_SEEK_END ) != 0 ) - { - return 0; - } - - uSizeFile = ( unsigned long )filestream->Tell(); - - if( uMaxBack > uSizeFile ) - { - uMaxBack = uSizeFile; - } - - buf = ( unsigned char* )ALLOC( BUFREADCOMMENT + 4 ); - if( buf == NULL ) - { - return 0; - } - - uBackRead = 4; - while( uBackRead < uMaxBack ) - { - unsigned long uReadSize, uReadPos; - if( uBackRead + BUFREADCOMMENT > uMaxBack ) - { - uBackRead = uMaxBack; - } - else - { - uBackRead += BUFREADCOMMENT; - } - uReadPos = uSizeFile - uBackRead ; - - uReadSize = ( ( BUFREADCOMMENT + 4 ) < ( uSizeFile - uReadPos ) ) ? ( BUFREADCOMMENT + 4 ) : ( uSizeFile - uReadPos ); - if( filestream->Seek( uReadPos, FS_SEEK_SET ) != 0 ) - { - break; - } - - if( filestream->Read( buf, uReadSize ) != ( int )uReadSize ) - { - break; - } - - for( int i = ( int )uReadSize - 3; ( i -- ) > 0; ) - { - if( ( ( *( buf + i ) ) == 0x50 ) && ( ( *( buf + i + 1 ) ) == 0x4b ) && ( ( *( buf + i + 2 ) ) == 0x05 ) && ( ( *( buf + i + 3 ) ) == 0x06 ) ) - { - uPosFound = uReadPos + i; - break; - } - } - - if( uPosFound != 0 ) - { - break; - } - } - TRYFREE( buf ); - return uPosFound; -} -#endif /* !NO_ADDFILEINEXISTINGZIP*/ - -/* -======================== -zipOpen2 -======================== -*/ -zipFile zipOpen2( const char* pathname, int append, char* globalcomment ) -{ - zip_internal ziinit; - zip_internal* zi; - int err = ZIP_OK; - - ziinit.filestream = fileSystem->OpenExplicitFileWrite( pathname ); - /* - ziinit.filestream = ZOPEN( pathname, ( append == APPEND_STATUS_CREATE ) ? - ( ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE ) : - ( ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING ) ); - */ - if( ziinit.filestream == NULL ) - { - return NULL; - } - ziinit.begin_pos = ( unsigned long )ziinit.filestream->Tell(); - ziinit.in_opened_file_inzip = 0; - ziinit.ci.stream_initialised = 0; - ziinit.number_entry = 0; - ziinit.add_position_when_writting_offset = 0; - init_linkedlist( &( ziinit.central_dir ) ); - - zi = ( zip_internal* )ALLOC( sizeof( zip_internal ) ); - if( zi == NULL ) - { - delete ziinit.filestream; - ziinit.filestream = NULL; - return NULL; - } - - /* now we add file in a zipfile */ -#ifndef NO_ADDFILEINEXISTINGZIP - ziinit.globalcomment = NULL; - if( append == APPEND_STATUS_ADDINZIP ) - { - unsigned long byte_before_the_zipfile; // byte before the zipfile, ( > 0 for sfx ) - unsigned long size_central_dir; // size of the central directory - unsigned long offset_central_dir; // offset of start of central directory - unsigned long central_pos, uL; - unsigned long number_disk; // number of the current dist, used for spaning ZIP, unsupported, always 0 - unsigned long number_disk_with_CD; // number the the disk with central dir, used for spaning ZIP, unsupported, always 0 - unsigned long number_entry; - unsigned long number_entry_CD; // total number of entries in the central dir ( same than number_entry on nospan ) - unsigned long size_comment; - - central_pos = ziplocal_SearchCentralDir( ziinit.filestream ); - if( central_pos == 0 ) - { - err = ZIP_ERRNO; - } - - if( ziinit.filestream->Seek( central_pos, FS_SEEK_SET ) != 0 ) - { - err = ZIP_ERRNO; - } - - /* the signature, already checked */ - if( ziplocal_getLong( ziinit.filestream, &uL ) != ZIP_OK ) - { - err = ZIP_ERRNO; - } - - /* number of this disk */ - if( ziplocal_getShort( ziinit.filestream, &number_disk ) != ZIP_OK ) - { - err = ZIP_ERRNO; - } - - /* number of the disk with the start of the central directory */ - if( ziplocal_getShort( ziinit.filestream, &number_disk_with_CD ) != ZIP_OK ) - { - err = ZIP_ERRNO; - } - - /* total number of entries in the central dir on this disk */ - if( ziplocal_getShort( ziinit.filestream, &number_entry ) != ZIP_OK ) - { - err = ZIP_ERRNO; - } - - /* total number of entries in the central dir */ - if( ziplocal_getShort( ziinit.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( ziplocal_getLong( ziinit.filestream, &size_central_dir ) != ZIP_OK ) - { - err = ZIP_ERRNO; - } - - /* offset of start of central directory with respect to the starting disk number */ - if( ziplocal_getLong( ziinit.filestream, &offset_central_dir ) != ZIP_OK ) - { - err = ZIP_ERRNO; - } - - /* zipfile global comment length */ - if( ziplocal_getShort( ziinit.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 ) - { - delete ziinit.filestream; - ziinit.filestream = NULL; - return NULL; - } - - if( size_comment > 0 ) - { - ziinit.globalcomment = ( char* )ALLOC( size_comment + 1 ); - if( ziinit.globalcomment ) - { - size_comment = ( unsigned long )ziinit.filestream->Read( ziinit.globalcomment, size_comment ); - ziinit.globalcomment[size_comment] = 0; - } - } - - byte_before_the_zipfile = central_pos - ( offset_central_dir + size_central_dir ); - ziinit.add_position_when_writting_offset = byte_before_the_zipfile; - { - unsigned long size_central_dir_to_read = size_central_dir; - size_t buf_size = SIZEDATA_INDATABLOCK; - void* buf_read = ( void* )ALLOC( buf_size ); - if( ziinit.filestream->Seek( offset_central_dir + byte_before_the_zipfile, FS_SEEK_SET ) != 0 ) - { - err = ZIP_ERRNO; - } - - while( ( size_central_dir_to_read > 0 ) && ( err == ZIP_OK ) ) - { - unsigned long read_this = SIZEDATA_INDATABLOCK; - if( read_this > size_central_dir_to_read ) - { - read_this = size_central_dir_to_read; - } - if( ziinit.filestream->Read( buf_read, read_this ) != ( int )read_this ) - { - err = ZIP_ERRNO; - } - if( err == ZIP_OK ) - { - err = add_data_in_datablock( &ziinit.central_dir, buf_read, ( unsigned long )read_this ); - } - size_central_dir_to_read -= read_this; - } - TRYFREE( buf_read ); - } - ziinit.begin_pos = byte_before_the_zipfile; - ziinit.number_entry = number_entry_CD; - - if( ziinit.filestream->Seek( offset_central_dir + byte_before_the_zipfile, FS_SEEK_SET ) != 0 ) - { - err = ZIP_ERRNO; - } - } - - if( globalcomment ) - { - /// ?? - globalcomment = ziinit.globalcomment; - } -#endif /* !NO_ADDFILEINEXISTINGZIP*/ - - if( err != ZIP_OK ) - { -#ifndef NO_ADDFILEINEXISTINGZIP - TRYFREE( ziinit.globalcomment ); -#endif /* !NO_ADDFILEINEXISTINGZIP*/ - TRYFREE( zi ); - return NULL; - } - else - { - *zi = ziinit; - return ( zipFile )zi; - } -} - -/* -======================== -zipOpen -======================== -*/ -zipFile zipOpen( const char* pathname, int append ) -{ - return zipOpen2( pathname, append, NULL ); -} - -/* -======================== -zipOpenNewFileInZip3 -======================== -*/ -int zipOpenNewFileInZip3( zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, unsigned int size_extrafield_local, const void* extrafield_global, - unsigned int size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, int strategy, const char* password, unsigned long crcForCrypting ) -{ - unsigned int size_filename; - unsigned int size_comment; - int err = ZIP_OK; - -#ifdef NOCRYPT - if( password != NULL ) - { - return ZIP_PARAMERROR; - } -#endif - - if( file == NULL ) - { - return ZIP_PARAMERROR; - } - if( ( method != 0 ) && ( method != Z_DEFLATED ) ) - { - return ZIP_PARAMERROR; - } - - zip_internal* zi = ( zip_internal* )file; - - if( zi->in_opened_file_inzip == 1 ) - { - err = zipCloseFileInZip( file ); - if( err != ZIP_OK ) - { - return err; - } - } - - if( filename == NULL ) - { - filename = "-"; - } - - if( comment == NULL ) - { - size_comment = 0; - } - else - { - size_comment = ( unsigned int )idStr::Length( comment ); - } - - size_filename = ( unsigned int )idStr::Length( filename ); - - if( zipfi == NULL ) - { - zi->ci.dosDate = 0; - } - else - { - if( zipfi->dosDate != 0 ) - { - zi->ci.dosDate = zipfi->dosDate; - } - else - { - zi->ci.dosDate = ziplocal_TmzDateToDosDate( &zipfi->tmz_date, zipfi->dosDate ); - } - } - - zi->ci.flag = 0; - if( ( level == 8 ) || ( level == 9 ) ) - { - zi->ci.flag |= 2; - } - if( level == 2 ) // DG: remove unnecessary parenthesis - { - zi->ci.flag |= 4; - } - if( level == 1 ) // DG: remove unnecessary parenthesis - { - zi->ci.flag |= 6; - } - if( password != NULL ) - { - zi->ci.flag |= 1; - } - - zi->ci.crc32 = 0; - zi->ci.method = method; - zi->ci.encrypt = 0; - zi->ci.stream_initialised = 0; - zi->ci.pos_in_buffered_data = 0; - zi->ci.raw = raw; - zi->ci.pos_local_header = ( unsigned long )zi->filestream->Tell(); - zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; - zi->ci.central_header = ( char* )ALLOC( ( unsigned int )zi->ci.size_centralheader ); - - ziplocal_putValue_inmemory( zi->ci.central_header, ( unsigned long )CENTRALHEADERMAGIC, 4 ); - /* version info */ - ziplocal_putValue_inmemory( zi->ci.central_header + 4, ( unsigned long )0, 2 ); - ziplocal_putValue_inmemory( zi->ci.central_header + 6, ( unsigned long )20, 2 ); - ziplocal_putValue_inmemory( zi->ci.central_header + 8, ( unsigned long )zi->ci.flag, 2 ); - ziplocal_putValue_inmemory( zi->ci.central_header + 10, ( unsigned long )zi->ci.method, 2 ); - ziplocal_putValue_inmemory( zi->ci.central_header + 12, ( unsigned long )zi->ci.dosDate, 4 ); - ziplocal_putValue_inmemory( zi->ci.central_header + 16, ( unsigned long )0, 4 ); /*crc*/ - ziplocal_putValue_inmemory( zi->ci.central_header + 20, ( unsigned long )0, 4 ); /*compr size*/ - ziplocal_putValue_inmemory( zi->ci.central_header + 24, ( unsigned long )0, 4 ); /*uncompr size*/ - ziplocal_putValue_inmemory( zi->ci.central_header + 28, ( unsigned long )size_filename, 2 ); - ziplocal_putValue_inmemory( zi->ci.central_header + 30, ( unsigned long )size_extrafield_global, 2 ); - ziplocal_putValue_inmemory( zi->ci.central_header + 32, ( unsigned long )size_comment, 2 ); - ziplocal_putValue_inmemory( zi->ci.central_header + 34, ( unsigned long )0, 2 ); /*disk nm start*/ - - if( zipfi == NULL ) - { - ziplocal_putValue_inmemory( zi->ci.central_header + 36, ( unsigned long )0, 2 ); - } - else - { - ziplocal_putValue_inmemory( zi->ci.central_header + 36, ( unsigned long )zipfi->internal_fa, 2 ); - } - - if( zipfi == NULL ) - { - ziplocal_putValue_inmemory( zi->ci.central_header + 38, ( unsigned long )0, 4 ); - } - else - { - ziplocal_putValue_inmemory( zi->ci.central_header + 38, ( unsigned long )zipfi->external_fa, 4 ); - } - - ziplocal_putValue_inmemory( zi->ci.central_header + 42, ( unsigned long )zi->ci.pos_local_header - zi->add_position_when_writting_offset, 4 ); - - for( unsigned int i = 0; i < size_filename; i++ ) - { - *( zi->ci.central_header + SIZECENTRALHEADER + i ) = *( filename + i ); - } - - for( unsigned int i = 0; i < size_extrafield_global; i++ ) - { - *( zi->ci.central_header + SIZECENTRALHEADER + size_filename + i ) = *( ( ( const char* )extrafield_global ) + i ); - } - - for( unsigned int i = 0; i < size_comment; i++ ) - { - *( zi->ci.central_header + SIZECENTRALHEADER + size_filename + size_extrafield_global + i ) = *( comment + i ); - } - - if( zi->ci.central_header == NULL ) - { - return ZIP_INTERNALERROR; - } - - /* write the local header */ - err = ziplocal_putValue( zi->filestream, ( unsigned long )LOCALHEADERMAGIC, 4 ); - - if( err == ZIP_OK ) - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )20, 2 ); /* version needed to extract */ - } - if( err == ZIP_OK ) - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )zi->ci.flag, 2 ); - } - - if( err == ZIP_OK ) - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )zi->ci.method, 2 ); - } - - if( err == ZIP_OK ) - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )zi->ci.dosDate, 4 ); - } - - if( err == ZIP_OK ) - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )0, 4 ); /* crc 32, unknown */ - } - - if( err == ZIP_OK ) - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )0, 4 ); /* compressed size, unknown */ - } - - if( err == ZIP_OK ) - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )0, 4 ); /* uncompressed size, unknown */ - } - - if( err == ZIP_OK ) - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )size_filename, 2 ); - } - - if( err == ZIP_OK ) - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )size_extrafield_local, 2 ); - } - - if( ( err == ZIP_OK ) && ( size_filename > 0 ) ) - { - if( zi->filestream->Write( filename, size_filename ) != ( int )size_filename ) - { - err = ZIP_ERRNO; - } - } - - if( ( err == ZIP_OK ) && ( size_extrafield_local > 0 ) ) - { - if( zi->filestream->Write( extrafield_local, size_extrafield_local ) != ( int )size_extrafield_local ) - { - err = ZIP_ERRNO; - } - } - - zi->ci.stream.avail_in = ( unsigned int )0; - zi->ci.stream.avail_out = ( unsigned int )Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - zi->ci.stream.total_in = 0; - zi->ci.stream.total_out = 0; - - if( ( err == ZIP_OK ) && ( zi->ci.method == Z_DEFLATED ) && ( !zi->ci.raw ) ) - { - zi->ci.stream.zalloc = ( alloc_func )0; - zi->ci.stream.zfree = ( free_func )0; - zi->ci.stream.opaque = ( voidpf )0; - - if( windowBits > 0 ) - { - windowBits = -windowBits; - } - - err = deflateInit2( &zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy ); - - if( err == Z_OK ) - { - zi->ci.stream_initialised = 1; - } - } -#ifndef NOCRYPT - zi->ci.crypt_header_size = 0; - if( ( err == Z_OK ) && ( password != NULL ) ) - { - unsigned char bufHead[RAND_HEAD_LEN]; - unsigned int sizeHead; - zi->ci.encrypt = 1; - zi->ci.pcrc_32_tab = get_crc_table(); - /*init_keys( password, zi->ci.keys, zi->ci.pcrc_32_tab );*/ - - sizeHead = crypthead( password, bufHead, RAND_HEAD_LEN, zi->ci.keys, zi->ci.pcrc_32_tab, crcForCrypting ); - zi->ci.crypt_header_size = sizeHead; - if( ZWRITE( zi->z_filefunc, zi->filestream, bufHead, sizeHead ) != sizeHead ) - { - err = ZIP_ERRNO; - } - } -#endif - - if( err == Z_OK ) - { - zi->in_opened_file_inzip = 1; - } - return err; -} - -/* -======================== -zipOpenNewFileInZip2 -======================== -*/ -int zipOpenNewFileInZip2( zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, unsigned int size_extrafield_local, - const void* extrafield_global, unsigned int size_extrafield_global, const char* comment, int method, int level, int raw ) -{ - return zipOpenNewFileInZip3( file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, - comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0 ); -} - -/* -======================== -zipOpenNewFileInZip -======================== -*/ -int zipOpenNewFileInZip( zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, unsigned int size_extrafield_local, const void* extrafield_global, - unsigned int size_extrafield_global, const char* comment, int method, int level ) -{ - return zipOpenNewFileInZip2( file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, 0 ); -} - -/* -======================== -zipFlushWriteBuffer -======================== -*/ -int zipFlushWriteBuffer( zip_internal* zi ) -{ - int err = ZIP_OK; - if( zi->ci.encrypt != 0 ) - { -#ifndef NOCRYPT - int t; - for( int i = 0; i < zi->ci.pos_in_buffered_data; i++ ) - { - zi->ci.buffered_data[i] = zencode( zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i], t ); - } -#endif - } - if( zi->filestream->Write( zi->ci.buffered_data, zi->ci.pos_in_buffered_data ) != ( int )zi->ci.pos_in_buffered_data ) - { - err = ZIP_ERRNO; - } - zi->ci.pos_in_buffered_data = 0; - return err; -} - -/* -======================== -zipWriteInFileInZip -======================== -*/ -int zipWriteInFileInZip( zipFile file, const void* buf, unsigned int len ) -{ - zip_internal* zi; - int err = ZIP_OK; - - if( file == NULL ) - { - return ZIP_PARAMERROR; - } - zi = ( zip_internal* )file; - - if( zi->in_opened_file_inzip == 0 ) - { - return ZIP_PARAMERROR; - } - zi->ci.stream.next_in = ( Bytef* )buf; - zi->ci.stream.avail_in = len; - zi->ci.crc32 = crc32( zi->ci.crc32, ( byte* )buf, len ); - - while( ( err == ZIP_OK ) && ( zi->ci.stream.avail_in > 0 ) ) - { - if( zi->ci.stream.avail_out == 0 ) - { - if( zipFlushWriteBuffer( zi ) == ZIP_ERRNO ) - { - err = ZIP_ERRNO; - } - zi->ci.stream.avail_out = ( unsigned int )Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - } - - if( err != ZIP_OK ) - { - break; - } - - if( ( zi->ci.method == Z_DEFLATED ) && ( !zi->ci.raw ) ) - { - unsigned long uTotalOutBefore = zi->ci.stream.total_out; - err = deflate( &zi->ci.stream, Z_NO_FLUSH ); - zi->ci.pos_in_buffered_data += ( unsigned int )( zi->ci.stream.total_out - uTotalOutBefore ); - } - else - { - unsigned int copy_this; - if( zi->ci.stream.avail_in < zi->ci.stream.avail_out ) - { - copy_this = zi->ci.stream.avail_in; - } - else - { - copy_this = zi->ci.stream.avail_out; - } - for( unsigned int i = 0; i < copy_this; i++ ) - { - *( ( ( char* )zi->ci.stream.next_out ) + i ) = *( ( ( const char* )zi->ci.stream.next_in ) + i ); - } - - zi->ci.stream.avail_in -= copy_this; - zi->ci.stream.avail_out -= copy_this; - zi->ci.stream.next_in += copy_this; - zi->ci.stream.next_out += copy_this; - zi->ci.stream.total_in += copy_this; - zi->ci.stream.total_out += copy_this; - zi->ci.pos_in_buffered_data += copy_this; - } - } - - return err; -} - -/* -======================== -zipCloseFileInZipRaw -======================== -*/ -int zipCloseFileInZipRaw( zipFile file, unsigned long uncompressed_size, unsigned long crc32 ) -{ - zip_internal* zi; - unsigned long compressed_size; - int err = ZIP_OK; - - if( file == NULL ) - { - return ZIP_PARAMERROR; - } - zi = ( zip_internal* )file; - - if( zi->in_opened_file_inzip == 0 ) - { - return ZIP_PARAMERROR; - } - zi->ci.stream.avail_in = 0; - - if( ( zi->ci.method == Z_DEFLATED ) && !zi->ci.raw ) - { - while( err == ZIP_OK ) - { - unsigned long uTotalOutBefore; - if( zi->ci.stream.avail_out == 0 ) - { - if( zipFlushWriteBuffer( zi ) == ZIP_ERRNO ) - { - err = ZIP_ERRNO; - } - zi->ci.stream.avail_out = ( unsigned int )Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - } - uTotalOutBefore = zi->ci.stream.total_out; - err = deflate( &zi->ci.stream, Z_FINISH ); - zi->ci.pos_in_buffered_data += ( unsigned int )( zi->ci.stream.total_out - uTotalOutBefore ); - } - } - - if( err == Z_STREAM_END ) - { - err = ZIP_OK; /* this is normal */ - } - - if( ( zi->ci.pos_in_buffered_data > 0 ) && ( err == ZIP_OK ) ) - { - if( zipFlushWriteBuffer( zi ) == ZIP_ERRNO ) - { - err = ZIP_ERRNO; - } - } - - if( ( zi->ci.method == Z_DEFLATED ) && !zi->ci.raw ) - { - err = deflateEnd( &zi->ci.stream ); - zi->ci.stream_initialised = 0; - } - - if( !zi->ci.raw ) - { - crc32 = ( unsigned long )zi->ci.crc32; - uncompressed_size = ( unsigned long )zi->ci.stream.total_in; - } - compressed_size = ( unsigned long )zi->ci.stream.total_out; -#ifndef NOCRYPT - compressed_size += zi->ci.crypt_header_size; -#endif - - ziplocal_putValue_inmemory( zi->ci.central_header + 16, crc32, 4 ); /*crc*/ - ziplocal_putValue_inmemory( zi->ci.central_header + 20, compressed_size, 4 ); /*compr size*/ - if( zi->ci.stream.data_type == Z_ASCII ) - { - ziplocal_putValue_inmemory( zi->ci.central_header + 36, ( unsigned long )Z_ASCII, 2 ); - } - ziplocal_putValue_inmemory( zi->ci.central_header + 24, uncompressed_size, 4 ); /*uncompr size*/ - - if( err == ZIP_OK ) - { - err = add_data_in_datablock( &zi->central_dir, zi->ci.central_header, ( unsigned long )zi->ci.size_centralheader ); - } - TRYFREE( zi->ci.central_header ); - - if( err == ZIP_OK ) - { - long cur_pos_inzip = ( long )zi->filestream->Tell(); - if( zi->filestream->Seek( zi->ci.pos_local_header + 14, FS_SEEK_SET ) != 0 ) - { - err = ZIP_ERRNO; - } - - if( err == ZIP_OK ) - { - err = ziplocal_putValue( zi->filestream, crc32, 4 ); /* crc 32, unknown */ - } - - if( err == ZIP_OK ) /* compressed size, unknown */ - { - err = ziplocal_putValue( zi->filestream, compressed_size, 4 ); - } - - if( err == ZIP_OK ) /* uncompressed size, unknown */ - { - err = ziplocal_putValue( zi->filestream, uncompressed_size, 4 ); - } - - if( zi->filestream->Seek( cur_pos_inzip, FS_SEEK_SET ) != 0 ) - { - err = ZIP_ERRNO; - } - } - zi->number_entry++; - zi->in_opened_file_inzip = 0; - - return err; -} - -/* -======================== -zipCloseFileInZip -======================== -*/ -int zipCloseFileInZip( zipFile file ) -{ - return zipCloseFileInZipRaw( file, 0, 0 ); -} - -/* -======================== -zipClose -======================== -*/ -int zipClose( zipFile file, const char* global_comment ) -{ - zip_internal* zi; - int err = 0; - unsigned long size_centraldir = 0; - unsigned long centraldir_pos_inzip; - unsigned int size_global_comment; - if( file == NULL ) - { - return ZIP_PARAMERROR; - } - zi = ( zip_internal* )file; - - if( zi->in_opened_file_inzip == 1 ) - { - err = zipCloseFileInZip( file ); - } - -#ifndef NO_ADDFILEINEXISTINGZIP - if( global_comment == NULL ) - { - global_comment = zi->globalcomment; - } -#endif - if( global_comment == NULL ) - { - size_global_comment = 0; - } - else - { - size_global_comment = ( unsigned int )idStr::Length( global_comment ); - } - - centraldir_pos_inzip = ( unsigned long )zi->filestream->Tell(); - if( err == ZIP_OK ) - { - linkedlist_datablock_internal* ldi = zi->central_dir.first_block; - while( ldi != NULL ) - { - if( ( err == ZIP_OK ) && ( ldi->filled_in_this_block > 0 ) ) - { - if( zi->filestream->Write( ldi->data, ldi->filled_in_this_block ) != ( int )ldi->filled_in_this_block ) - { - err = ZIP_ERRNO; - } - } - size_centraldir += ldi->filled_in_this_block; - ldi = ldi->next_datablock; - } - } - free_datablock( zi->central_dir.first_block ); - - if( err == ZIP_OK ) /* Magic End */ - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )ENDHEADERMAGIC, 4 ); - } - - if( err == ZIP_OK ) /* number of this disk */ - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )0, 2 ); - } - - if( err == ZIP_OK ) /* number of the disk with the start of the central directory */ - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )0, 2 ); - } - - if( err == ZIP_OK ) /* total number of entries in the central dir on this disk */ - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )zi->number_entry, 2 ); - } - - if( err == ZIP_OK ) /* total number of entries in the central dir */ - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )zi->number_entry, 2 ); - } - - if( err == ZIP_OK ) /* size of the central directory */ - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )size_centraldir, 4 ); - } - - if( err == ZIP_OK ) /* offset of start of central directory with respect to the starting disk number */ - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )( centraldir_pos_inzip - zi->add_position_when_writting_offset ), 4 ); - } - - if( err == ZIP_OK ) /* zipfile comment length */ - { - err = ziplocal_putValue( zi->filestream, ( unsigned long )size_global_comment, 2 ); - } - - if( ( err == ZIP_OK ) && ( size_global_comment > 0 ) ) - { - if( zi->filestream->Write( global_comment, size_global_comment ) != ( int )size_global_comment ) - { - err = ZIP_ERRNO; - } - } - - delete zi->filestream; - zi->filestream = NULL; - -#ifndef NO_ADDFILEINEXISTINGZIP - TRYFREE( zi->globalcomment ); -#endif - TRYFREE( zi ); - - return err; -} + * DG: all the zip implementation has been updated to minizip 1.1 and is in framework/minizip/zip.cpp + * In the D3 BFG implementation there were some things specific to Doom3: + * * FILE was replaced by idFile, thus + * - fseek(), fread(), fwrite(), ftell() were replaced by idFile functions + * - fopen() was replaced by fileSystem->OpenExplicitFileWrite() + * - fclose() was replaced by fileSystem->CloseFile() + * + * As this isn't important for the code to work I haven't done these changes, but using the + * Doom3 specific functions could be quite easily done by using zipOpen2() with an appropriate + * zlib_filefunc_def. + * + * TODO: Doom3 should already support zip64 for unzipping, maybe it would make sense to use the + * corresponding functions here as well.. but then we can't use idFile, because it only + * supports files up to 2GB (Length() and Tell() return ints) + */ /* ======================== diff --git a/neo/framework/Zip.h b/neo/framework/Zip.h index 2dd1e2c6..2a90f9db 100644 --- a/neo/framework/Zip.h +++ b/neo/framework/Zip.h @@ -30,231 +30,8 @@ If you have questions concerning this license or the applicable additional terms #include "../libs/zlib/zlib.h" -/* -================================================================================================ - -Contains external code for building ZipFiles. - -The Unzip Package allows extraction of a file from .ZIP file, compatible with -PKZip 2.04g, !WinZip, !InfoZip tools and compatibles. Encryption and multi-volume ZipFiles -(span) are not supported. Old compressions used by old PKZip 1.x are not supported. - -================================================================================================ -*/ -#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagzipFile__ -{ - int unused; -} zipFile__; -typedef zipFile__* zipFile; -#else -typedef void* zipFile; -#endif - -#define ZIP_OK (0) -#define ZIP_EOF (0) -#define ZIP_ERRNO (Z_ERRNO) -#define ZIP_PARAMERROR (-102) -#define ZIP_BADZIPFILE (-103) -#define ZIP_INTERNALERROR (-104) - -#ifndef Z_BUFSIZE -#define Z_BUFSIZE (16384) -#endif - -/* -======================== -tm_zip -contains date/time info -======================== -*/ -typedef struct tm_zip_s -{ - unsigned int tm_sec; /* seconds after the minute - [0,59] */ - unsigned int tm_min; /* minutes after the hour - [0,59] */ - unsigned int tm_hour; /* hours since midnight - [0,23] */ - unsigned int tm_mday; /* day of the month - [1,31] */ - unsigned int tm_mon; /* months since January - [0,11] */ - unsigned int tm_year; /* years - [1980..2044] */ -} tm_zip; - -/* -======================== -zip_fileinfo -======================== -*/ -typedef struct -{ - tm_zip tmz_date; /* date in understandable format */ - unsigned long dosDate; /* if dos_date == 0, tmu_date is used */ -// unsigned long flag; /* general purpose bit flag 2 bytes */ - - unsigned long internal_fa; /* internal file attributes 2 bytes */ - unsigned long external_fa; /* external file attributes 4 bytes */ -} zip_fileinfo; - -#define NOCRYPT // ignore passwords -#define SIZEDATA_INDATABLOCK (4096-(4*4)) - -/* -======================== -linkedlist_datablock_internal -======================== -*/ -typedef struct linkedlist_datablock_internal_s -{ - struct linkedlist_datablock_internal_s* next_datablock; - unsigned long avail_in_this_block; - unsigned long filled_in_this_block; - unsigned long unused; /* for future use and alignement */ - unsigned char data[SIZEDATA_INDATABLOCK]; -} linkedlist_datablock_internal; - -/* -======================== -linkedlist_data -======================== -*/ -typedef struct linkedlist_data_s -{ - linkedlist_datablock_internal* first_block; - linkedlist_datablock_internal* last_block; -} linkedlist_data; - -/* -======================== -curfile_info -======================== -*/ -typedef struct -{ - z_stream stream; /* zLib stream structure for inflate */ - int stream_initialised; /* 1 is stream is initialised */ - unsigned int pos_in_buffered_data; /* last written byte in buffered_data */ - - unsigned long pos_local_header; /* offset of the local header of the file currenty writing */ - char* central_header; /* central header data for the current file */ - unsigned long size_centralheader; /* size of the central header for cur file */ - unsigned long flag; /* flag of the file currently writing */ - - int method; /* compression method of file currenty wr.*/ - int raw; /* 1 for directly writing raw data */ - byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ - unsigned long dosDate; - unsigned long crc32; - int encrypt; -#ifndef NOCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ - const unsigned long* pcrc_32_tab; - int crypt_header_size; -#endif -} curfile_info; - -//#define NO_ADDFILEINEXISTINGZIP -/* -======================== -zip_internal -======================== -*/ -typedef struct -{ - idFile* filestream; /* io structore 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.*/ - curfile_info ci; /* info on the file curretly writing */ - - unsigned long begin_pos; /* position of the beginning of the zipfile */ - unsigned long add_position_when_writting_offset; - unsigned long number_entry; -#ifndef NO_ADDFILEINEXISTINGZIP - char* globalcomment; -#endif -} zip_internal; - -#define APPEND_STATUS_CREATE (0) -#define APPEND_STATUS_CREATEAFTER (1) -#define APPEND_STATUS_ADDINZIP (2) - -/* - Create a zipfile. - pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on - an Unix computer "zlib/zlib113.zip". - if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip - will be created at the end of the file. - (useful if the file contain a self extractor code) - if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will - add files in existing zip (be sure you don't add file that doesn't exist) - If the zipfile cannot be opened, the return value is NULL. - Else, the return value is a zipFile Handle, usable with other function - of this zip package. -*/ - -/* Note : there is no delete function into a zipfile. - If you want delete file into a zipfile, you must open a zipfile, and create another - Of couse, you can use RAW reading and writing to copy the file you did not want delte -*/ -extern zipFile zipOpen( const char* pathname, int append ); - -/* - Open a file in the ZIP for writing. - filename : the filename in zip (if NULL, '-' without quote will be used - *zipfi contain supplemental information - if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local - contains the extrafield data the the local header - if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global - contains the extrafield data the the local header - if comment != NULL, comment contain the comment string - method contain the compression method (0 for store, Z_DEFLATED for deflate) - level contain the level of compression (can be Z_DEFAULT_COMPRESSION) -*/ -extern zipFile zipOpen2( const char* pathname, int append, char* globalcomment ); - -extern int zipOpenNewFileInZip( zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, - uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, - int method, int level ); - -/* - Same than zipOpenNewFileInZip, except if raw=1, we write raw file -*/ -extern int zipOpenNewFileInZip2( zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw ); - -/* - Same than zipOpenNewFileInZip2, except - windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 - password : crypting password (NULL for no crypting) - crcForCtypting : crc of file to compress (needed for crypting) -*/ -extern int zipOpenNewFileInZip3( zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, - int memLevel, int strategy, const char* password, uLong crcForCtypting ); - -/* - Write data in the zipfile -*/ -extern int zipWriteInFileInZip( zipFile file, const void* buf, unsigned int len ); - - -/* - Close the current file in the zipfile -*/ -extern int zipCloseFileInZip( zipFile file ); - - -/* - Close the current file in the zipfile, for fiel opened with - parameter raw=1 in zipOpenNewFileInZip2 - uncompressed_size and crc32 are value for the uncompressed size -*/ -extern int zipCloseFileInZipRaw( zipFile file, uLong uncompressed_size, uLong crc32 ); - - -/* - Close the zipfile -*/ -extern int zipClose( zipFile file, const char* global_comment ); +// DG: all the zip access stuff from minizip is now in minizip/zip.h +#include "minizip/zip.h" /* diff --git a/neo/framework/minizip/MiniZip64_info.txt b/neo/framework/minizip/MiniZip64_info.txt index 09513213..78c06059 100644 --- a/neo/framework/minizip/MiniZip64_info.txt +++ b/neo/framework/minizip/MiniZip64_info.txt @@ -1,7 +1,7 @@ NOTE from Daniel Gibson: -These are parts of MiniZip (the unzip-parts), taken from zlib-1.2.7/contrib/minizip/ -and adjusted for doom3 by making small adjustments foor doom3 (doom3-specific allocator) +These are parts of MiniZip, taken from zlib-1.2.7/contrib/minizip/ +and adjusted for doom3 by making small adjustments for doom3 (doom3-specific allocator) and adding a function (unzReOpen()) from the original Doom3 GPL release by id Software that used MiniZip 0.15beta. It was adjusted by Daniel Gibson for MiniZip 1.1 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. diff --git a/neo/framework/minizip/zip.cpp b/neo/framework/minizip/zip.cpp new file mode 100644 index 00000000..a97d02cd --- /dev/null +++ b/neo/framework/minizip/zip.cpp @@ -0,0 +1,2036 @@ +/* + this is from zlib-1.2.7/contrib/minizip/ + + zip.c -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + 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 recreting zip archive with RAW when deleting items from a zip. + ZIP64 data is automaticly 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 + + #################################################################################### + +DG: The file was renamed from zip.c to zip.cpp so we can use C++ functions from Doom3, furthermore we use doom3 headers + instead of system headers and Doom3's Mem_Alloc() and Mem_Free() instead of malloc() and free() + Other than that, there are no real changes to the original file. + +*/ + +// DG: add the precompiled.h beast.. +#include "precompiled.h" +#pragma hdrstop +// DG end + +#if 0 // we don't really want system includes here +#include +#include +#include +#include +#include "zlib.h" +#include "zip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + +#else // 0 + +// we don't need crypt support +#define NOCRYPT 1 + +#include "zip.h" +#endif // 0 + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef VERSIONMADEBY +# define VERSIONMADEBY (0x0) /* platform depedent */ +#endif + +#ifndef Z_BUFSIZE +#define Z_BUFSIZE (64*1024) //(16384) +#endif + +#ifndef Z_MAXFILENAMEINZIP +#define Z_MAXFILENAMEINZIP (256) +#endif + +#if 0 // don't use system malloc but doom3's allocator +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif +#else // 0 +#define ALLOC(size) (Mem_Alloc(size, TAG_IDFILE)) +#define TRYFREE(p) {Mem_Free(p);} // Mem_Free - as well as free() - check for NULL themselves, no need to do it here +#endif // 0 + +/* +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) +*/ + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + + +// NOT sure that this work on ALL platform +#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#ifndef DEF_MEM_LEVEL +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +#endif +const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + + +#define SIZEDATA_INDATABLOCK (4096-(4*4)) + +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) +#define ZIP64ENDHEADERMAGIC (0x6064b50) +#define ZIP64ENDLOCHEADERMAGIC (0x7064b50) + +#define FLAG_LOCALHEADER_OFFSET (0x06) +#define CRC_LOCALHEADER_OFFSET (0x0e) + +#define SIZECENTRALHEADER (0x2e) /* 46 */ + +typedef struct linkedlist_datablock_internal_s +{ + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignement */ + unsigned char data[SIZEDATA_INDATABLOCK]; +} linkedlist_datablock_internal; + +typedef struct linkedlist_data_s +{ + linkedlist_datablock_internal* first_block; + linkedlist_datablock_internal* last_block; +} linkedlist_data; + + +typedef struct +{ + z_stream stream; /* zLib stream structure for inflate */ +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + 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 + currenty 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 currenty 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 extened information in the extra field */ + ZPOS64_T pos_zip64extrainfo; + ZPOS64_T totalCompressedData; + ZPOS64_T totalUncompressedData; +#ifndef NOCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; + int crypt_header_size; +#endif +} curfile64_info; + +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore 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 curretly writing */ + + ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ + ZPOS64_T add_position_when_writting_offset; + ZPOS64_T number_entry; + +#ifndef NO_ADDFILEINEXISTINGZIP + char *globalcomment; +#endif + +} zip64_internal; + + +#ifndef NOCRYPT +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED +#include "crypt.h" +#endif + +local linkedlist_datablock_internal* allocate_new_datablock() +{ + linkedlist_datablock_internal* ldi; + ldi = (linkedlist_datablock_internal*) + ALLOC(sizeof(linkedlist_datablock_internal)); + if (ldi!=NULL) + { + ldi->next_datablock = NULL ; + ldi->filled_in_this_block = 0 ; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; + } + return ldi; +} + +local void free_datablock(linkedlist_datablock_internal* ldi) +{ + while (ldi!=NULL) + { + linkedlist_datablock_internal* ldinext = ldi->next_datablock; + TRYFREE(ldi); + ldi = ldinext; + } +} + +local void init_linkedlist(linkedlist_data* ll) +{ + ll->first_block = ll->last_block = NULL; +} + +local void free_linkedlist(linkedlist_data* ll) +{ + free_datablock(ll->first_block); + ll->first_block = ll->last_block = NULL; +} + + +local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) +{ + linkedlist_datablock_internal* ldi; + const unsigned char* from_copy; + + if (ll==NULL) + return ZIP_INTERNALERROR; + + if (ll->last_block == NULL) + { + ll->first_block = ll->last_block = allocate_new_datablock(); + if (ll->first_block == NULL) + return ZIP_INTERNALERROR; + } + + ldi = ll->last_block; + from_copy = (unsigned char*)buf; + + while (len>0) + { + uInt copy_this; + uInt i; + unsigned char* to_copy; + + if (ldi->avail_in_this_block==0) + { + ldi->next_datablock = allocate_new_datablock(); + if (ldi->next_datablock == NULL) + return ZIP_INTERNALERROR; + ldi = ldi->next_datablock ; + ll->last_block = ldi; + } + + if (ldi->avail_in_this_block < len) + copy_this = (uInt)ldi->avail_in_this_block; + else + copy_this = (uInt)len; + + to_copy = &(ldi->data[ldi->filled_in_this_block]); + + for (i=0;ifilled_in_this_block += copy_this; + ldi->avail_in_this_block -= copy_this; + from_copy += copy_this ; + len -= copy_this; + } + return ZIP_OK; +} + + + +/****************************************************************************/ + +#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 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); +local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) +{ + unsigned char buf[8]; + int n; + for (n = 0; n < nbByte; n++) + { + buf[n] = (unsigned char)(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,nbByte)!=(uLong)nbByte) + return ZIP_ERRNO; + else + return ZIP_OK; +} + +local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); +local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) +{ + unsigned char* buf=(unsigned char*)dest; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + + if (x != 0) + { /* data overflow - hack for ZIP64 */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } +} + +/****************************************************************************/ + + +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) +{ + uLong year = (uLong)ptm->tm_year; + if (year>=1980) + year-=1980; + else if (year>=80) + year-=80; + return + (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); +} + + +/****************************************************************************/ + +local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); + +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) +{ + unsigned char 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 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +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; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getLong (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; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); + + +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 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* 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; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + 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+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(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 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* 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; + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + 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+i; + break; + } + } + + if (uPosFound!=0) + break; + } + + TRYFREE(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; +} + +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 + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning 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; + } + else if(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; +*/ + + if(hasZIP64Record) + { + ZPOS64_T sizeEndOfCentralDirectory; + 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; + + /* 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_posz_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; + } + } + + byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); + pziinit->add_position_when_writting_offset = byte_before_the_zipfile; + + { + ZPOS64_T size_central_dir_to_read = size_central_dir; + size_t buf_size = SIZEDATA_INDATABLOCK; + void* buf_read = (void*)ALLOC(buf_size); + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + while ((size_central_dir_to_read>0) && (err==ZIP_OK)) + { + ZPOS64_T read_this = SIZEDATA_INDATABLOCK; + if (read_this > size_central_dir_to_read) + read_this = size_central_dir_to_read; + + if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) + err=ZIP_ERRNO; + + if (err==ZIP_OK) + err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); + + size_central_dir_to_read-=read_this; + } + TRYFREE(buf_read); + } + pziinit->begin_pos = byte_before_the_zipfile; + pziinit->number_entry = number_entry_CD; + + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + return err; +} + + +#endif /* !NO_ADDFILEINEXISTINGZIP*/ + + +/************************************************************/ +extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) +{ + zip64_internal ziinit; + zip64_internal* zi; + int err=ZIP_OK; + + ziinit.z_filefunc.zseek32_file = NULL; + ziinit.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); + else + ziinit.z_filefunc = *pzlib_filefunc64_32_def; + + ziinit.filestream = ZOPEN64(ziinit.z_filefunc, + pathname, + (append == APPEND_STATUS_CREATE) ? + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); + + if (ziinit.filestream == NULL) + return NULL; + + if (append == APPEND_STATUS_CREATEAFTER) + ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); + + ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); + ziinit.in_opened_file_inzip = 0; + ziinit.ci.stream_initialised = 0; + ziinit.number_entry = 0; + ziinit.add_position_when_writting_offset = 0; + init_linkedlist(&(ziinit.central_dir)); + + + + 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 (globalcomment) + { + *globalcomment = ziinit.globalcomment; + } +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + + if (err != ZIP_OK) + { +# ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(ziinit.globalcomment); +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + TRYFREE(zi); + return NULL; + } + else + { + *zi = ziinit; + return (zipFile)zi; + } +} + +extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) +{ + if (pzlib_filefunc32_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + +extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) +{ + if (pzlib_filefunc_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; + zlib_filefunc64_32_def_fill.ztell32_file = NULL; + zlib_filefunc64_32_def_fill.zseek32_file = NULL; + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + + + +extern zipFile ZEXPORT zipOpen (const char* pathname, int append) +{ + return zipOpen3((const void*)pathname,append,NULL,NULL); +} + +extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) +{ + return zipOpen3(pathname,append,NULL,NULL); +} + +int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) +{ + /* write the local header */ + int err; + uInt size_filename = (uInt)strlen(filename); + uInt size_extrafield = size_extrafield_local; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); + + 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); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); + } + + return err; +} + +/* + 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. + */ +extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase, int zip64) +{ + zip64_internal* zi; + uInt size_filename; + uInt size_comment; + uInt i; + int err = ZIP_OK; + +# ifdef NOCRYPT + (crcForCrypting); + if (password != NULL) + return ZIP_PARAMERROR; +# endif + + if (file == NULL) + return ZIP_PARAMERROR; + +#ifdef HAVE_BZIP2 + if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) + return ZIP_PARAMERROR; +#else + if ((method!=0) && (method!=Z_DEFLATED)) + return ZIP_PARAMERROR; +#endif + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + if (err != ZIP_OK) + return err; + } + + if (filename==NULL) + filename="-"; + + if (comment==NULL) + size_comment = 0; + else + size_comment = (uInt)strlen(comment); + + size_filename = (uInt)strlen(filename); + + if (zipfi == NULL) + zi->ci.dosDate = 0; + else + { + if (zipfi->dosDate != 0) + zi->ci.dosDate = zipfi->dosDate; + else + zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); + } + + zi->ci.flag = flagBase; + if ((level==8) || (level==9)) + zi->ci.flag |= 2; + if (level==2) + zi->ci.flag |= 4; + if (level==1) + zi->ci.flag |= 6; + if (password != NULL) + zi->ci.flag |= 1; + + zi->ci.crc32 = 0; + zi->ci.method = method; + zi->ci.encrypt = 0; + zi->ci.stream_initialised = 0; + zi->ci.pos_in_buffered_data = 0; + zi->ci.raw = raw; + zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); + + 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 + + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); + + zi->ci.size_centralExtra = size_extrafield_global; + zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); + /* version info */ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); + zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); + zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); + zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); + zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ + zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); + zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); + zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ + + 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); + + if(zi->ci.pos_local_header >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); + + for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = + *(((const char*)extrafield_global)+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ + size_extrafield_global+i) = *(comment+i); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; + + zi->ci.zip64 = zip64; + zi->ci.totalCompressedData = 0; + zi->ci.totalUncompressedData = 0; + zi->ci.pos_zip64extrainfo = 0; + + err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); + +#ifdef HAVE_BZIP2 + zi->ci.bstream.avail_in = (uInt)0; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + zi->ci.bstream.total_in_hi32 = 0; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_out_hi32 = 0; + zi->ci.bstream.total_out_lo32 = 0; +#endif + + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + zi->ci.stream.total_in = 0; + zi->ci.stream.total_out = 0; + zi->ci.stream.data_type = Z_BINARY; + +#ifdef HAVE_BZIP2 + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) +#else + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) +#endif + { + if(zi->ci.method == Z_DEFLATED) + { + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)0; + + if (windowBits>0) + windowBits = -windowBits; + + err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); + + if (err==Z_OK) + zi->ci.stream_initialised = Z_DEFLATED; + } + else if(zi->ci.method == Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + // Init BZip stuff here + zi->ci.bstream.bzalloc = 0; + zi->ci.bstream.bzfree = 0; + zi->ci.bstream.opaque = (voidpf)0; + + err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); + if(err == BZ_OK) + zi->ci.stream_initialised = Z_BZIP2ED; +#endif + } + + } + +# ifndef NOCRYPT + zi->ci.crypt_header_size = 0; + if ((err==Z_OK) && (password != NULL)) + { + unsigned char bufHead[RAND_HEAD_LEN]; + unsigned int sizeHead; + zi->ci.encrypt = 1; + zi->ci.pcrc_32_tab = get_crc_table(); + /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ + + sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); + zi->ci.crypt_header_size = sizeHead; + + if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) + err = ZIP_ERRNO; + } +# endif + + if (err==Z_OK) + zi->in_opened_file_inzip = 1; + return err; +} + +extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, versionMadeBy, flagBase, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +local int zip64FlushWriteBuffer(zip64_internal* zi) +{ + int err=ZIP_OK; + + if (zi->ci.encrypt != 0) + { +#ifndef NOCRYPT + uInt i; + int t; + for (i=0;ici.pos_in_buffered_data;i++) + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); +#endif + } + + if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) + err = ZIP_ERRNO; + + zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED) + { + zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_in_hi32 = 0; + } + else +#endif + { + zi->ci.totalUncompressedData += zi->ci.stream.total_in; + zi->ci.stream.total_in = 0; + } + + + zi->ci.pos_in_buffered_data = 0; + + return err; +} + +extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) +{ + zip64_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + + // DG: cast void pointer to const unsigned char* because crc32() expects that + // and C++ is more strict in these things than plain C + zi->ci.crc32 = crc32(zi->ci.crc32, (const unsigned char *)buf, (uInt)len); + // DG end + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) + { + zi->ci.bstream.next_in = (void*)buf; + zi->ci.bstream.avail_in = len; + err = BZ_RUN_OK; + + while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) + { + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + + + if(err != BZ_RUN_OK) + break; + + if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; +// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; + } + } + + if(err == BZ_RUN_OK) + err = ZIP_OK; + } + else +#endif + { + zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.avail_in = len; + + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + + + if(err != ZIP_OK) + break; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_NO_FLUSH); + if(uTotalOutBefore > zi->ci.stream.total_out) + { + int bBreak = 0; + bBreak++; + } + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; + + for (i = 0; i < copy_this; i++) + *(((char*)zi->ci.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out-= copy_this; + zi->ci.stream.next_in+= copy_this; + zi->ci.stream.next_out+= copy_this; + zi->ci.stream.total_in+= copy_this; + zi->ci.stream.total_out+= copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + }// while(...) + } + + return err; +} + +extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) +{ + return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); +} + +extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) +{ + zip64_internal* zi; + ZPOS64_T compressed_size; + uLong invalidValue = 0xffffffff; + short datasize = 0; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + zi->ci.stream.avail_in = 0; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + while (err==ZIP_OK) + { + uLong uTotalOutBefore; + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + } + else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { +#ifdef HAVE_BZIP2 + err = BZ_FINISH_OK; + while (err==BZ_FINISH_OK) + { + uLong uTotalOutBefore; + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.bstream.total_out_lo32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); + if(err == BZ_STREAM_END) + err = Z_STREAM_END; + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); + } + + if(err == BZ_FINISH_OK) + err = ZIP_OK; +#endif + } + + if (err==Z_STREAM_END) + err=ZIP_OK; /* this is normal */ + + if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) + { + if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) + err = ZIP_ERRNO; + } + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + int tmp_err = deflateEnd(&zi->ci.stream); + if (err == ZIP_OK) + err = tmp_err; + zi->ci.stream_initialised = 0; + } +#ifdef HAVE_BZIP2 + else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); + if (err==ZIP_OK) + err = tmperr; + zi->ci.stream_initialised = 0; + } +#endif + + if (!zi->ci.raw) + { + crc32 = (uLong)zi->ci.crc32; + uncompressed_size = zi->ci.totalUncompressedData; + } + compressed_size = zi->ci.totalCompressedData; + +# ifndef NOCRYPT + compressed_size += zi->ci.crypt_header_size; +# endif + + // update Current Item crc and sizes, + if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) + { + /*version Made by*/ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); + /*version needed*/ + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); + + } + + zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ + + + if(compressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ + + /// 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); + + if(uncompressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ + + // 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; + + if(uncompressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, uncompressed_size, 8); + p += 8; + } + + if(compressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, compressed_size, 8); + p += 8; + } + + if(zi->ci.pos_local_header >= 0xffffffff) + { + zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); + p += 8; + } + + // 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. + + ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ + + if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff ) + { + if(zi->ci.pos_zip64extrainfo > 0) + { + // Update the size in the ZIP64 extended field. + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); + } + else + err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal + } + else + { + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); + } + + if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + } + + zi->number_entry ++; + zi->in_opened_file_inzip = 0; + + return err; +} + +extern int ZEXPORT zipCloseFileInZip (zipFile file) +{ + return zipCloseFileInZipRaw (file,0,0); +} + +int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) +{ + int err = ZIP_OK; + ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); + + /*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; +} + +int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + uLong Zip64DataSize = 44; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); + + 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_writting_offset; + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); + } + return err; +} +int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + /*signature*/ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); + + 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_writting_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_writting_offset),4); + } + + return err; +} + +int Write_GlobalComment(zip64_internal* zi, const char* global_comment) +{ + int err = ZIP_OK; + uInt size_global_comment = 0; + + if(global_comment != NULL) + size_global_comment = (uInt)strlen(global_comment); + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); + + if (err == ZIP_OK && size_global_comment > 0) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) + err = ZIP_ERRNO; + } + return err; +} + +extern int ZEXPORT zipClose (zipFile file, const char* global_comment) +{ + zip64_internal* zi; + int err = 0; + uLong size_centraldir = 0; + ZPOS64_T centraldir_pos_inzip; + ZPOS64_T pos; + + if (file == NULL) + return ZIP_PARAMERROR; + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + } + +#ifndef NO_ADDFILEINEXISTINGZIP + if (global_comment==NULL) + global_comment = zi->globalcomment; +#endif + + centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (err==ZIP_OK) + { + linkedlist_datablock_internal* ldi = zi->central_dir.first_block; + while (ldi!=NULL) + { + if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) + err = ZIP_ERRNO; + } + + size_centraldir += ldi->filled_in_this_block; + ldi = ldi->next_datablock; + } + } + free_linkedlist(&(zi->central_dir)); + + pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) + { + ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); + Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); + } + + if (err==ZIP_OK) + err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + if(err == ZIP_OK) + err = Write_GlobalComment(zi, global_comment); + + if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) + if (err == ZIP_OK) + err = ZIP_ERRNO; + +#ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(zi->globalcomment); +#endif + TRYFREE(zi); + + return err; +} + +extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) +{ + char* p = pData; + int size = 0; + char* pNewHeader; + char* pTmp; + short header; + short dataSize; + + int retVal = ZIP_OK; + + if(pData == NULL || *dataLen < 4) + return ZIP_PARAMERROR; + + pNewHeader = (char*)ALLOC(*dataLen); + pTmp = pNewHeader; + + while(p < (pData + *dataLen)) + { + header = *(short*)p; + dataSize = *(((short*)p)+1); + + 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; + + TRYFREE(pNewHeader); + + return retVal; +} diff --git a/neo/framework/minizip/zip.h b/neo/framework/minizip/zip.h new file mode 100644 index 00000000..477fe89b --- /dev/null +++ b/neo/framework/minizip/zip.h @@ -0,0 +1,362 @@ +/* zip.h -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------- + + Changes + + See header of zip.h + +*/ + +#ifndef _zip12_H +#define _zip12_H + +#ifdef __cplusplus +extern "C" { +#endif + +//#define HAVE_BZIP2 + +#ifndef _ZLIB_H +#include "../../libs/zlib/zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagzipFile__ { int unused; } zipFile__; +typedef zipFile__ *zipFile; +#else +typedef voidp zipFile; +#endif + +#define ZIP_OK (0) +#define ZIP_EOF (0) +#define ZIP_ERRNO (Z_ERRNO) +#define ZIP_PARAMERROR (-102) +#define ZIP_BADZIPFILE (-103) +#define ZIP_INTERNALERROR (-104) + +#ifndef DEF_MEM_LEVEL +# if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +# else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +# endif +#endif +/* default memLevel */ + +/* tm_zip contain date/time info */ +typedef struct tm_zip_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_zip; + +typedef struct +{ + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ +/* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ +} zip_fileinfo; + +typedef const char* zipcharpc; + + +#define APPEND_STATUS_CREATE (0) +#define APPEND_STATUS_CREATEAFTER (1) +#define APPEND_STATUS_ADDINZIP (2) + +extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); +extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); +/* + Create a zipfile. + pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on + an Unix computer "zlib/zlib113.zip". + if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip + will be created at the end of the file. + (useful if the file contain a self extractor code) + if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will + add files in existing zip (be sure you don't add file that doesn't exist) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. +*/ + +/* Note : there is no delete function into a zipfile. + If you want delete file into a zipfile, you must open a zipfile, and create another + Of couse, you can use RAW reading and writing to copy the file you did not want delte +*/ + +extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def)); + +extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc64_def* pzlib_filefunc_def)); + +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level)); + +extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int zip64)); + +/* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + zip64 is set to 1 if a zip64 extended information block should be added to the local file header. + this MUST be '1' if the uncompressed size is >= 0xffffffff. + +*/ + + +extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw)); + + +extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int zip64)); +/* + Same than zipOpenNewFileInZip, except if raw=1, we write raw file + */ + +extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting)); + +extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + int zip64 + )); + +/* + Same than zipOpenNewFileInZip2, except + windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 + password : crypting password (NULL for no crypting) + crcForCrypting : crc of file to compress (needed for crypting) + */ + +extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase + )); + + +extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase, + int zip64 + )); +/* + Same than zipOpenNewFileInZip4, except + versionMadeBy : value for Version made by field + flag : value for flag field (compression level info will be added) + */ + + +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, + const void* buf, + unsigned len)); +/* + Write data in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +/* + Close the current file in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, + uLong uncompressed_size, + uLong crc32)); + +extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, + ZPOS64_T uncompressed_size, + uLong crc32)); + +/* + Close the current file in the zipfile, for file opened with + parameter raw=1 in zipOpenNewFileInZip2 + uncompressed_size and crc32 are value for the uncompressed size +*/ + +extern int ZEXPORT zipClose OF((zipFile file, + const char* global_comment)); +/* + Close the zipfile +*/ + + +extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); +/* + zipRemoveExtraInfoBlock - Added by Mathias Svensson + + Remove extra information block from a extra information data for the local file header or central directory header + + It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. + + 0x0001 is the signature header for the ZIP64 extra information blocks + + usage. + Remove ZIP64 Extra information from a central director extra field data + zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); + + Remove ZIP64 Extra information from a Local File Header extra field data + zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _zip64_H */