mirror of
https://github.com/zlib-ng/minizip-ng
synced 2025-03-28 21:13:18 +00:00
added pkware disk spanning support
This commit is contained in:
parent
35c6102e21
commit
6d35b6b884
67
ChangeLogUnzip
Normal file
67
ChangeLogUnzip
Normal file
@ -0,0 +1,67 @@
|
||||
Change in 1.01e (12 feb 05)
|
||||
- Fix in zipOpen2 for globalcomment (Rolf Kalbermatter)
|
||||
- Fix possible memory leak in unzip.c (Zoran Stevanovic)
|
||||
|
||||
Change in 1.01b (20 may 04)
|
||||
- Integrate patch from Debian package (submited by Mark Brown)
|
||||
- Add tools mztools from Xavier Roche
|
||||
|
||||
Change in 1.01 (8 may 04)
|
||||
- fix buffer overrun risk in unzip.c (Xavier Roche)
|
||||
- fix a minor buffer insecurity in minizip.c (Mike Whittaker)
|
||||
|
||||
Change in 1.00: (10 sept 03)
|
||||
- rename to 1.00
|
||||
- cosmetic code change
|
||||
|
||||
Change in 0.22: (19 May 03)
|
||||
- crypting support (unless you define NOCRYPT)
|
||||
- append file in existing zipfile
|
||||
|
||||
Change in 0.21: (10 Mar 03)
|
||||
- bug fixes
|
||||
|
||||
Change in 0.17: (27 Jan 02)
|
||||
- bug fixes
|
||||
|
||||
Change in 0.16: (19 Jan 02)
|
||||
- Support of ioapi for virtualize zip file access
|
||||
|
||||
Change in 0.15: (19 Mar 98)
|
||||
- fix memory leak in minizip.c
|
||||
|
||||
Change in 0.14: (10 Mar 98)
|
||||
- fix bugs in minizip.c sample for zipping big file
|
||||
- fix problem in month in date handling
|
||||
- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for
|
||||
comment handling
|
||||
|
||||
Change in 0.13: (6 Mar 98)
|
||||
- fix bugs in zip.c
|
||||
- add real minizip sample
|
||||
|
||||
Change in 0.12: (4 Mar 98)
|
||||
- add zip.c and zip.h for creates .zip file
|
||||
- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly)
|
||||
- fix miniunz.c for file without specific record for directory
|
||||
|
||||
Change in 0.11: (3 Mar 98)
|
||||
- fix bug in unzGetCurrentFileInfo for get extra field and comment
|
||||
- enhance miniunz sample, remove the bad unztst.c sample
|
||||
|
||||
Change in 0.10: (2 Mar 98)
|
||||
- fix bug in unzReadCurrentFile
|
||||
- rename unzip* to unz* function and structure
|
||||
- remove Windows-like hungary notation variable name
|
||||
- modify some structure in unzip.h
|
||||
- add somes comment in source
|
||||
- remove unzipGetcCurrentFile function
|
||||
- replace ZUNZEXPORT by ZEXPORT
|
||||
- add unzGetLocalExtrafield for get the local extrafield info
|
||||
- add a new sample, miniunz.c
|
||||
|
||||
Change in 0.4: (25 Feb 98)
|
||||
- suppress the type unzipFileInZip.
|
||||
Only on file in the zipfile can be open at the same time
|
||||
- fix somes typo in code
|
||||
- added tm_unz structure in unzip_file_info (date/time in readable format)
|
606
ioapi.c
606
ioapi.c
@ -1,235 +1,371 @@
|
||||
/* ioapi.h -- IO base function header for compress/uncompress .zip
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
#if (defined(_WIN32))
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "ioapi.h"
|
||||
|
||||
voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
|
||||
{
|
||||
if (pfilefunc->zfile_func64.zopen64_file != NULL)
|
||||
return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
|
||||
else
|
||||
{
|
||||
return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
|
||||
}
|
||||
}
|
||||
|
||||
long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
|
||||
{
|
||||
if (pfilefunc->zfile_func64.zseek64_file != NULL)
|
||||
return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
|
||||
else
|
||||
{
|
||||
uLong offsetTruncated = (uLong)offset;
|
||||
if (offsetTruncated != offset)
|
||||
return -1;
|
||||
else
|
||||
return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
|
||||
}
|
||||
}
|
||||
|
||||
ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
|
||||
{
|
||||
if (pfilefunc->zfile_func64.zseek64_file != NULL)
|
||||
return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
|
||||
else
|
||||
{
|
||||
uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
|
||||
if ((tell_uLong) == ((uLong)-1))
|
||||
return (ZPOS64_T)-1;
|
||||
else
|
||||
return tell_uLong;
|
||||
}
|
||||
}
|
||||
|
||||
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
|
||||
{
|
||||
p_filefunc64_32->zfile_func64.zopen64_file = NULL;
|
||||
p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
|
||||
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
|
||||
p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
|
||||
p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
|
||||
p_filefunc64_32->zfile_func64.ztell64_file = NULL;
|
||||
p_filefunc64_32->zfile_func64.zseek64_file = NULL;
|
||||
p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
|
||||
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
|
||||
p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
|
||||
p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
|
||||
p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
|
||||
static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
|
||||
static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
|
||||
static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
|
||||
static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
|
||||
static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
|
||||
static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
|
||||
|
||||
static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
|
||||
{
|
||||
FILE* file = NULL;
|
||||
const char* mode_fopen = NULL;
|
||||
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
|
||||
mode_fopen = "rb";
|
||||
else
|
||||
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
|
||||
mode_fopen = "r+b";
|
||||
else
|
||||
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
|
||||
mode_fopen = "wb";
|
||||
|
||||
if ((filename!=NULL) && (mode_fopen != NULL))
|
||||
file = fopen(filename, mode_fopen);
|
||||
return file;
|
||||
}
|
||||
|
||||
static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
|
||||
{
|
||||
FILE* file = NULL;
|
||||
const char* mode_fopen = NULL;
|
||||
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
|
||||
mode_fopen = "rb";
|
||||
else
|
||||
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
|
||||
mode_fopen = "r+b";
|
||||
else
|
||||
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
|
||||
mode_fopen = "wb";
|
||||
|
||||
if ((filename!=NULL) && (mode_fopen != NULL))
|
||||
file = fopen64((const char*)filename, mode_fopen);
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
|
||||
{
|
||||
uLong ret;
|
||||
ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
|
||||
{
|
||||
uLong ret;
|
||||
ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
long ret;
|
||||
ret = ftell((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
ZPOS64_T ret;
|
||||
ret = ftello64((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
|
||||
{
|
||||
int fseek_origin=0;
|
||||
long ret;
|
||||
switch (origin)
|
||||
{
|
||||
case ZLIB_FILEFUNC_SEEK_CUR :
|
||||
fseek_origin = SEEK_CUR;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_END :
|
||||
fseek_origin = SEEK_END;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_SET :
|
||||
fseek_origin = SEEK_SET;
|
||||
break;
|
||||
default: return -1;
|
||||
}
|
||||
ret = 0;
|
||||
if (fseek((FILE *)stream, offset, fseek_origin) != 0)
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
|
||||
{
|
||||
int fseek_origin=0;
|
||||
long ret;
|
||||
switch (origin)
|
||||
{
|
||||
case ZLIB_FILEFUNC_SEEK_CUR :
|
||||
fseek_origin = SEEK_CUR;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_END :
|
||||
fseek_origin = SEEK_END;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_SET :
|
||||
fseek_origin = SEEK_SET;
|
||||
break;
|
||||
default: return -1;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
if(fseeko64((FILE *)stream, offset, fseek_origin) != 0)
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
int ret;
|
||||
ret = fclose((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
int ret;
|
||||
ret = ferror((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fill_fopen_filefunc (pzlib_filefunc_def)
|
||||
zlib_filefunc_def* pzlib_filefunc_def;
|
||||
{
|
||||
pzlib_filefunc_def->zopen_file = fopen_file_func;
|
||||
pzlib_filefunc_def->zread_file = fread_file_func;
|
||||
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
|
||||
pzlib_filefunc_def->ztell_file = ftell_file_func;
|
||||
pzlib_filefunc_def->zseek_file = fseek_file_func;
|
||||
pzlib_filefunc_def->zclose_file = fclose_file_func;
|
||||
pzlib_filefunc_def->zerror_file = ferror_file_func;
|
||||
pzlib_filefunc_def->opaque = NULL;
|
||||
}
|
||||
|
||||
void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def)
|
||||
{
|
||||
pzlib_filefunc_def->zopen64_file = fopen64_file_func;
|
||||
pzlib_filefunc_def->zread_file = fread_file_func;
|
||||
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
|
||||
pzlib_filefunc_def->ztell64_file = ftell64_file_func;
|
||||
pzlib_filefunc_def->zseek64_file = fseek64_file_func;
|
||||
pzlib_filefunc_def->zclose_file = fclose_file_func;
|
||||
pzlib_filefunc_def->zerror_file = ferror_file_func;
|
||||
pzlib_filefunc_def->opaque = NULL;
|
||||
}
|
||||
/* ioapi.h -- IO base function header for compress/uncompress .zip
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
#if (defined(_WINDOWS))
|
||||
#include <tchar.h>
|
||||
#define snprintf _snprintf
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
#define fseeko64 fseeko
|
||||
#define fopen64 fopen
|
||||
#define ftello64 ftello
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ioapi.h"
|
||||
|
||||
voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
|
||||
{
|
||||
if (pfilefunc->zfile_func64.zopen64_file != NULL)
|
||||
return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
|
||||
else
|
||||
{
|
||||
return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
|
||||
}
|
||||
}
|
||||
|
||||
voidpf call_zopendisk64 OF((const zlib_filefunc64_32_def* pfilefunc, voidpf filestream, int number_disk, int mode))
|
||||
{
|
||||
if (pfilefunc->zfile_func64.zopendisk64_file != NULL)
|
||||
return (*(pfilefunc->zfile_func64.zopendisk64_file)) (pfilefunc->zfile_func64.opaque,filestream,number_disk,mode);
|
||||
else
|
||||
{
|
||||
return (*(pfilefunc->zopendisk32_file))(pfilefunc->zfile_func64.opaque,filestream,number_disk,mode);
|
||||
}
|
||||
}
|
||||
|
||||
long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
|
||||
{
|
||||
if (pfilefunc->zfile_func64.zseek64_file != NULL)
|
||||
return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
|
||||
else
|
||||
{
|
||||
long offsetTruncated = (long)offset;
|
||||
if (offsetTruncated != offset)
|
||||
return -1;
|
||||
else
|
||||
return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
|
||||
}
|
||||
}
|
||||
|
||||
ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
|
||||
{
|
||||
if (pfilefunc->zfile_func64.zseek64_file != NULL)
|
||||
return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
|
||||
else
|
||||
{
|
||||
uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
|
||||
if ((tell_uLong) == ((uLong)-1))
|
||||
return (ZPOS64_T)-1;
|
||||
else
|
||||
return tell_uLong;
|
||||
}
|
||||
}
|
||||
|
||||
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
|
||||
{
|
||||
p_filefunc64_32->zfile_func64.zopen64_file = NULL;
|
||||
p_filefunc64_32->zfile_func64.zopendisk64_file = NULL;
|
||||
p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
|
||||
p_filefunc64_32->zopendisk32_file = p_filefunc32->zopendisk_file;
|
||||
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
|
||||
p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
|
||||
p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
|
||||
p_filefunc64_32->zfile_func64.ztell64_file = NULL;
|
||||
p_filefunc64_32->zfile_func64.zseek64_file = NULL;
|
||||
p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
|
||||
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
|
||||
p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
|
||||
p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
|
||||
p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
|
||||
}
|
||||
|
||||
static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
|
||||
static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
|
||||
static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
|
||||
static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
|
||||
static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
|
||||
static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
|
||||
static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FILE *file;
|
||||
int filenameLength;
|
||||
void *filename;
|
||||
} FILE_IOPOSIX;
|
||||
|
||||
|
||||
static voidpf file_build_ioposix(FILE *file, const char *filename)
|
||||
{
|
||||
FILE_IOPOSIX *ioposix = NULL;
|
||||
if (file == NULL)
|
||||
return NULL;
|
||||
ioposix = (FILE_IOPOSIX*)malloc(sizeof(FILE_IOPOSIX));
|
||||
ioposix->file = file;
|
||||
ioposix->filenameLength = strlen(filename) + 1;
|
||||
ioposix->filename = (char*)malloc(ioposix->filenameLength * sizeof(char));
|
||||
strncpy(ioposix->filename, filename, ioposix->filenameLength);
|
||||
return (voidpf)ioposix;
|
||||
}
|
||||
|
||||
static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
|
||||
{
|
||||
FILE* file = NULL;
|
||||
const char* mode_fopen = NULL;
|
||||
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
|
||||
mode_fopen = "rb";
|
||||
else
|
||||
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
|
||||
mode_fopen = "r+b";
|
||||
else
|
||||
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
|
||||
mode_fopen = "wb";
|
||||
|
||||
if ((filename!=NULL) && (mode_fopen != NULL))
|
||||
{
|
||||
file = fopen(filename, mode_fopen);
|
||||
return file_build_ioposix(file, filename);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
|
||||
{
|
||||
FILE* file = NULL;
|
||||
const char* mode_fopen = NULL;
|
||||
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
|
||||
mode_fopen = "rb";
|
||||
else
|
||||
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
|
||||
mode_fopen = "r+b";
|
||||
else
|
||||
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
|
||||
mode_fopen = "wb";
|
||||
|
||||
if ((filename!=NULL) && (mode_fopen != NULL))
|
||||
{
|
||||
file = fopen64((const char*)filename, mode_fopen);
|
||||
return file_build_ioposix(file, (const char*)filename);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
static voidpf ZCALLBACK fopendisk64_file_func (voidpf opaque, voidpf stream, int number_disk, int mode)
|
||||
{
|
||||
FILE_IOPOSIX *ioposix = NULL;
|
||||
char *diskFilename = NULL;
|
||||
voidpf ret = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
ioposix = (FILE_IOPOSIX*)stream;
|
||||
diskFilename = (char*)malloc(ioposix->filenameLength * sizeof(char));
|
||||
strncpy(diskFilename, ioposix->filename, ioposix->filenameLength);
|
||||
for (i = ioposix->filenameLength - 1; i >= 0; i -= 1)
|
||||
{
|
||||
if (diskFilename[i] != '.')
|
||||
continue;
|
||||
snprintf(&diskFilename[i], ioposix->filenameLength - i, ".z%02d", number_disk + 1);
|
||||
break;
|
||||
}
|
||||
if (i >= 0)
|
||||
ret = fopen64_file_func(opaque, diskFilename, mode);
|
||||
free(diskFilename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static voidpf ZCALLBACK fopendisk_file_func (voidpf opaque, voidpf stream, int number_disk, int mode)
|
||||
{
|
||||
FILE_IOPOSIX *ioposix = NULL;
|
||||
char *diskFilename = NULL;
|
||||
voidpf ret = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
ioposix = (FILE_IOPOSIX*)stream;
|
||||
diskFilename = (char*)malloc(ioposix->filenameLength * sizeof(char));
|
||||
strncpy(diskFilename, ioposix->filename, ioposix->filenameLength);
|
||||
for (i = ioposix->filenameLength - 1; i >= 0; i -= 1)
|
||||
{
|
||||
if (diskFilename[i] != '.')
|
||||
continue;
|
||||
snprintf(&diskFilename[i], ioposix->filenameLength - i, ".z%02d", number_disk + 1);
|
||||
break;
|
||||
}
|
||||
if (i >= 0)
|
||||
ret = fopen_file_func(opaque, diskFilename, mode);
|
||||
free(diskFilename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
|
||||
{
|
||||
FILE_IOPOSIX *ioposix = NULL;
|
||||
uLong ret;
|
||||
if (stream == NULL)
|
||||
return -1;
|
||||
ioposix = (FILE_IOPOSIX*)stream;
|
||||
ret = (uLong)fread(buf, 1, (size_t)size, ioposix->file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
|
||||
{
|
||||
FILE_IOPOSIX *ioposix = NULL;
|
||||
uLong ret;
|
||||
if (stream == NULL)
|
||||
return -1;
|
||||
ioposix = (FILE_IOPOSIX*)stream;
|
||||
ret = (uLong)fwrite(buf, 1, (size_t)size, ioposix->file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
FILE_IOPOSIX *ioposix = NULL;
|
||||
long ret = -1;
|
||||
if (stream == NULL)
|
||||
return ret;
|
||||
ioposix = (FILE_IOPOSIX*)stream;
|
||||
ret = ftell(ioposix->file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
FILE_IOPOSIX *ioposix = NULL;
|
||||
ZPOS64_T ret = -1;
|
||||
if (stream == NULL)
|
||||
return ret;
|
||||
ioposix = (FILE_IOPOSIX*)stream;
|
||||
ret = ftello64(ioposix->file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
|
||||
{
|
||||
FILE_IOPOSIX *ioposix = NULL;
|
||||
int fseek_origin=0;
|
||||
long ret;
|
||||
|
||||
if (stream == NULL)
|
||||
return -1;
|
||||
ioposix = (FILE_IOPOSIX*)stream;
|
||||
|
||||
switch (origin)
|
||||
{
|
||||
case ZLIB_FILEFUNC_SEEK_CUR :
|
||||
fseek_origin = SEEK_CUR;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_END :
|
||||
fseek_origin = SEEK_END;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_SET :
|
||||
fseek_origin = SEEK_SET;
|
||||
break;
|
||||
default: return -1;
|
||||
}
|
||||
ret = 0;
|
||||
if (fseek(ioposix->file, offset, fseek_origin) != 0)
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
|
||||
{
|
||||
FILE_IOPOSIX *ioposix = NULL;
|
||||
int fseek_origin=0;
|
||||
long ret;
|
||||
|
||||
if (stream == NULL)
|
||||
return -1;
|
||||
ioposix = (FILE_IOPOSIX*)stream;
|
||||
|
||||
switch (origin)
|
||||
{
|
||||
case ZLIB_FILEFUNC_SEEK_CUR :
|
||||
fseek_origin = SEEK_CUR;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_END :
|
||||
fseek_origin = SEEK_END;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_SET :
|
||||
fseek_origin = SEEK_SET;
|
||||
break;
|
||||
default: return -1;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
if(fseeko64(ioposix->file, offset, fseek_origin) != 0)
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
FILE_IOPOSIX *ioposix = NULL;
|
||||
int ret = -1;
|
||||
if (stream == NULL)
|
||||
return ret;
|
||||
ioposix = (FILE_IOPOSIX*)stream;
|
||||
if (ioposix->filename != NULL)
|
||||
free(ioposix->filename);
|
||||
ret = fclose(ioposix->file);
|
||||
free(ioposix);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
FILE_IOPOSIX *ioposix = NULL;
|
||||
int ret = -1;
|
||||
if (stream == NULL)
|
||||
return ret;
|
||||
ioposix = (FILE_IOPOSIX*)stream;
|
||||
ret = ferror(ioposix->file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fill_fopen_filefunc (pzlib_filefunc_def)
|
||||
zlib_filefunc_def* pzlib_filefunc_def;
|
||||
{
|
||||
pzlib_filefunc_def->zopen_file = fopen_file_func;
|
||||
pzlib_filefunc_def->zopendisk_file = fopendisk_file_func;
|
||||
pzlib_filefunc_def->zread_file = fread_file_func;
|
||||
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
|
||||
pzlib_filefunc_def->ztell_file = ftell_file_func;
|
||||
pzlib_filefunc_def->zseek_file = fseek_file_func;
|
||||
pzlib_filefunc_def->zclose_file = fclose_file_func;
|
||||
pzlib_filefunc_def->zerror_file = ferror_file_func;
|
||||
pzlib_filefunc_def->opaque = NULL;
|
||||
}
|
||||
|
||||
void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def)
|
||||
{
|
||||
pzlib_filefunc_def->zopen64_file = fopen64_file_func;
|
||||
pzlib_filefunc_def->zopendisk64_file = fopendisk64_file_func;
|
||||
pzlib_filefunc_def->zread_file = fread_file_func;
|
||||
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
|
||||
pzlib_filefunc_def->ztell64_file = ftell64_file_func;
|
||||
pzlib_filefunc_def->zseek64_file = fseek64_file_func;
|
||||
pzlib_filefunc_def->zclose_file = fclose_file_func;
|
||||
pzlib_filefunc_def->zerror_file = ferror_file_func;
|
||||
pzlib_filefunc_def->opaque = NULL;
|
||||
}
|
||||
|
47
ioapi.h
47
ioapi.h
@ -21,7 +21,7 @@
|
||||
#ifndef _ZLIBIOAPI64_H
|
||||
#define _ZLIBIOAPI64_H
|
||||
|
||||
#if (!defined(_WIN32)) && (!defined(WIN32))
|
||||
#if (!defined(_WINDOWS))
|
||||
|
||||
// Linux needs this to support file operation on files larger then 4+GB
|
||||
// But might need better if/def to select just the platforms that needs them.
|
||||
@ -125,6 +125,7 @@ extern "C" {
|
||||
|
||||
|
||||
typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
|
||||
typedef voidpf (ZCALLBACK *opendisk_file_func) OF((voidpf opaque, voidpf stream, int number_disk, int mode));
|
||||
typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
|
||||
typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
|
||||
typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
|
||||
@ -133,11 +134,11 @@ typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stre
|
||||
typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
|
||||
|
||||
|
||||
/* here is the "old" 32 bits structure structure */
|
||||
typedef struct zlib_filefunc_def_s
|
||||
{
|
||||
open_file_func zopen_file;
|
||||
opendisk_file_func zopendisk_file;
|
||||
read_file_func zread_file;
|
||||
write_file_func zwrite_file;
|
||||
tell_file_func ztell_file;
|
||||
@ -150,48 +151,54 @@ typedef struct zlib_filefunc_def_s
|
||||
typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
|
||||
typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode));
|
||||
typedef voidpf (ZCALLBACK *opendisk64_file_func)OF((voidpf opaque, voidpf stream, int number_disk, int mode));
|
||||
|
||||
typedef struct zlib_filefunc64_def_s
|
||||
{
|
||||
open64_file_func zopen64_file;
|
||||
read_file_func zread_file;
|
||||
write_file_func zwrite_file;
|
||||
tell64_file_func ztell64_file;
|
||||
seek64_file_func zseek64_file;
|
||||
close_file_func zclose_file;
|
||||
testerror_file_func zerror_file;
|
||||
voidpf opaque;
|
||||
open64_file_func zopen64_file;
|
||||
opendisk64_file_func zopendisk64_file;
|
||||
read_file_func zread_file;
|
||||
write_file_func zwrite_file;
|
||||
tell64_file_func ztell64_file;
|
||||
seek64_file_func zseek64_file;
|
||||
close_file_func zclose_file;
|
||||
testerror_file_func zerror_file;
|
||||
voidpf opaque;
|
||||
} zlib_filefunc64_def;
|
||||
|
||||
void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
|
||||
void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
|
||||
void fill_fopendisk64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
|
||||
void fill_fopendisk_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
|
||||
|
||||
/* now internal definition, only for zip.c and unzip.h */
|
||||
typedef struct zlib_filefunc64_32_def_s
|
||||
{
|
||||
zlib_filefunc64_def zfile_func64;
|
||||
open_file_func zopen32_file;
|
||||
opendisk_file_func zopendisk32_file;
|
||||
tell_file_func ztell32_file;
|
||||
seek_file_func zseek32_file;
|
||||
} zlib_filefunc64_32_def;
|
||||
|
||||
|
||||
#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
|
||||
#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
|
||||
//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
|
||||
//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
|
||||
#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
|
||||
#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
|
||||
#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
|
||||
#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
|
||||
//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
|
||||
//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
|
||||
#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
|
||||
#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
|
||||
|
||||
voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
|
||||
voidpf call_zopendisk64 OF((const zlib_filefunc64_32_def* pfilefunc, voidpf filestream, int number_disk, int mode));
|
||||
long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
|
||||
ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
|
||||
|
||||
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
|
||||
|
||||
#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
|
||||
#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
|
||||
#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
|
||||
#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
|
||||
#define ZOPENDISK64(filefunc,filestream,diskn,mode) (call_zopendisk64((&(filefunc)),(filestream),(diskn),(mode)))
|
||||
#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
|
||||
#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
165
ioapi_mem.c
Normal file
165
ioapi_mem.c
Normal file
@ -0,0 +1,165 @@
|
||||
/* ioapi_mem.h -- IO base function header for compress/uncompress .zip
|
||||
files using zlib + zip or unzip API
|
||||
|
||||
This version of ioapi is designed to access memory rather than files.
|
||||
We do use a region of memory to put data in to and take it out of. We do
|
||||
not have auto-extending buffers and do not inform anyone else that the
|
||||
data has been written. It is really intended for accessing a zip archive
|
||||
embedded in an application such that I can write an installer with no
|
||||
external files. Creation of archives has not been attempted, although
|
||||
parts of the framework are present.
|
||||
|
||||
Based on Unzip ioapi.c version 0.22, May 19th, 2003
|
||||
|
||||
Copyright (C) 1998-2003 Gilles Vollant
|
||||
(C) 2003 Justin Fletcher
|
||||
|
||||
This file is under the same license as the Unzip tool it is distributed
|
||||
with.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zlib.h"
|
||||
#include "ioapi.h"
|
||||
|
||||
#include "ioapi_mem.h"
|
||||
|
||||
voidpf ZCALLBACK fopen_mem_func (opaque, filename, mode)
|
||||
voidpf opaque;
|
||||
const char* filename;
|
||||
int mode;
|
||||
{
|
||||
ourmemory_t *mem = (ourmemory_t *)opaque;
|
||||
if (mem==NULL)
|
||||
return NULL; /* Mem structure passed in was null */
|
||||
|
||||
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
|
||||
mem->limit=0; /* When writing we start with 0 bytes written */
|
||||
else
|
||||
mem->limit=mem->size;
|
||||
|
||||
mem->cur_offset = 0;
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
voidpf ZCALLBACK fopendisk_mem_func (opaque, stream, number_disk, mode)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
int number_disk;
|
||||
int mode;
|
||||
{
|
||||
/* Not used */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uLong ZCALLBACK fread_mem_func (opaque, stream, buf, size)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
void* buf;
|
||||
uLong size;
|
||||
{
|
||||
ourmemory_t *mem = (ourmemory_t *)stream;
|
||||
|
||||
if (size > mem->size - mem->cur_offset)
|
||||
size = mem->size - mem->cur_offset;
|
||||
|
||||
memcpy(buf, mem->base + mem->cur_offset, size);
|
||||
mem->cur_offset+=size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
uLong ZCALLBACK fwrite_mem_func (opaque, stream, buf, size)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
const void* buf;
|
||||
uLong size;
|
||||
{
|
||||
ourmemory_t *mem = (ourmemory_t *)stream;
|
||||
|
||||
if (size > mem->size - mem->cur_offset)
|
||||
size = mem->size - mem->cur_offset;
|
||||
|
||||
memcpy(mem->base + mem->cur_offset, buf, size);
|
||||
mem->cur_offset+=size;
|
||||
if (mem->cur_offset > mem->limit)
|
||||
mem->limit = mem->cur_offset;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
long ZCALLBACK ftell_mem_func (opaque, stream)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
{
|
||||
ourmemory_t *mem = (ourmemory_t *)stream;
|
||||
|
||||
return mem->cur_offset;
|
||||
}
|
||||
|
||||
long ZCALLBACK fseek_mem_func (opaque, stream, offset, origin)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
uLong offset;
|
||||
int origin;
|
||||
{
|
||||
ourmemory_t *mem = (ourmemory_t *)stream;
|
||||
uLong new_pos;
|
||||
switch (origin)
|
||||
{
|
||||
case ZLIB_FILEFUNC_SEEK_CUR :
|
||||
new_pos = mem->cur_offset + offset;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_END :
|
||||
new_pos = mem->limit + offset;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_SET :
|
||||
new_pos = offset;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (new_pos > mem->size)
|
||||
return 1; /* Failed to seek that far */
|
||||
|
||||
mem->cur_offset = new_pos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ZCALLBACK fclose_mem_func (opaque, stream)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ZCALLBACK ferror_mem_func (opaque, stream)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
{
|
||||
/* We never return errors */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void fill_memory_filefunc (pzlib_filefunc_def, ourmem)
|
||||
zlib_filefunc_def* pzlib_filefunc_def;
|
||||
ourmemory_t *ourmem;
|
||||
{
|
||||
pzlib_filefunc_def->zopen_file = fopen_mem_func;
|
||||
pzlib_filefunc_def->zopendisk_file = fopendisk_mem_func;
|
||||
pzlib_filefunc_def->zread_file = fread_mem_func;
|
||||
pzlib_filefunc_def->zwrite_file = fwrite_mem_func;
|
||||
pzlib_filefunc_def->ztell_file = ftell_mem_func;
|
||||
pzlib_filefunc_def->zseek_file = fseek_mem_func;
|
||||
pzlib_filefunc_def->zclose_file = fclose_mem_func;
|
||||
pzlib_filefunc_def->zerror_file = ferror_mem_func;
|
||||
pzlib_filefunc_def->opaque = ourmem;
|
||||
}
|
46
ioapi_mem.h
Normal file
46
ioapi_mem.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* ioapi_mem.h -- IO base function header for compress/uncompress .zip
|
||||
files using zlib + zip or unzip API
|
||||
|
||||
This version of ioapi is designed to access memory rather than files.
|
||||
We do use a region of memory to put data in to and take it out of. We do
|
||||
not have auto-extending buffers and do not inform anyone else that the
|
||||
data has been written. It is really intended for accessing a zip archive
|
||||
embedded in an application such that I can write an installer with no
|
||||
external files. Creation of archives has not been attempted, although
|
||||
parts of the framework are present.
|
||||
|
||||
Based on Unzip ioapi.c version 0.22, May 19th, 2003
|
||||
|
||||
Copyright (C) 1998-2003 Gilles Vollant
|
||||
(C) 2003 Justin Fletcher
|
||||
|
||||
This file is under the same license as the Unzip tool it is distributed
|
||||
with.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zlib.h"
|
||||
#include "ioapi.h"
|
||||
|
||||
|
||||
voidpf ZCALLBACK fopen_mem_func OF((voidpf opaque,const char* filename,int mode));
|
||||
voidpf ZCALLBACK fopendisk_mem_func OF((voidpf opaque, voidpf stream, int number_disk, int mode));
|
||||
uLong ZCALLBACK fread_mem_func OF((voidpf opaque,voidpf stream,void* buf,uLong size));
|
||||
uLong ZCALLBACK fwrite_mem_func OF((voidpf opaque,voidpf stream,const void* buf,uLong size));
|
||||
long ZCALLBACK ftell_mem_func OF((voidpf opaque,voidpf stream));
|
||||
long ZCALLBACK fseek_mem_func OF((voidpf opaque,voidpf stream,uLong offset,int origin));
|
||||
int ZCALLBACK fclose_mem_func OF((voidpf opaque,voidpf stream));
|
||||
int ZCALLBACK ferror_mem_func OF((voidpf opaque,voidpf stream));
|
||||
|
||||
typedef struct ourmemory_s {
|
||||
char *base; /* Base of the region of memory we're using */
|
||||
uLong size; /* Size of the region of memory we're using */
|
||||
uLong limit; /* Furthest we've written */
|
||||
uLong cur_offset; /* Current offset in the area */
|
||||
} ourmemory_t;
|
||||
|
||||
void fill_memory_filefunc (zlib_filefunc_def* pzlib_filefunc_def, ourmemory_t *ourmem);
|
196
iowin32.c
196
iowin32.c
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include "zlib.h"
|
||||
#include "ioapi.h"
|
||||
@ -37,6 +38,8 @@ typedef struct
|
||||
{
|
||||
HANDLE hf;
|
||||
int error;
|
||||
void *filename;
|
||||
int filenameLength;
|
||||
} WIN32FILE_IOWIN;
|
||||
|
||||
|
||||
@ -68,21 +71,20 @@ static void win32_translate_open_mode(int mode,
|
||||
|
||||
static voidpf win32_build_iowin(HANDLE hFile)
|
||||
{
|
||||
voidpf ret=NULL;
|
||||
WIN32FILE_IOWIN *iowin = NULL;
|
||||
|
||||
if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
|
||||
{
|
||||
WIN32FILE_IOWIN w32fiow;
|
||||
w32fiow.hf = hFile;
|
||||
w32fiow.error = 0;
|
||||
ret = malloc(sizeof(WIN32FILE_IOWIN));
|
||||
|
||||
if (ret==NULL)
|
||||
iowin = (WIN32FILE_IOWIN *)malloc(sizeof(WIN32FILE_IOWIN));
|
||||
if (iowin==NULL)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
else
|
||||
*((WIN32FILE_IOWIN*)ret) = w32fiow;
|
||||
return NULL;
|
||||
}
|
||||
memset(iowin, 0, sizeof(WIN32FILE_IOWIN));
|
||||
iowin->hf = hFile;
|
||||
}
|
||||
return ret;
|
||||
return (voidpf)iowin;
|
||||
}
|
||||
|
||||
voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int mode)
|
||||
@ -90,13 +92,20 @@ voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int
|
||||
const char* mode_fopen = NULL;
|
||||
DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
|
||||
HANDLE hFile = NULL;
|
||||
WIN32FILE_IOWIN *iowin = NULL;
|
||||
|
||||
win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
|
||||
|
||||
if ((filename!=NULL) && (dwDesiredAccess != 0))
|
||||
hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
|
||||
|
||||
return win32_build_iowin(hFile);
|
||||
iowin = win32_build_iowin(hFile);
|
||||
if (iowin == NULL)
|
||||
return NULL;
|
||||
iowin->filenameLength = _tcslen(filename) + 1;
|
||||
iowin->filename = (void*)malloc(iowin->filenameLength * sizeof(TCHAR));
|
||||
_tcsncpy(iowin->filename, filename, iowin->filenameLength);
|
||||
return iowin;
|
||||
}
|
||||
|
||||
|
||||
@ -105,13 +114,20 @@ voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int
|
||||
const char* mode_fopen = NULL;
|
||||
DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
|
||||
HANDLE hFile = NULL;
|
||||
WIN32FILE_IOWIN *iowin = NULL;
|
||||
|
||||
win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
|
||||
|
||||
if ((filename!=NULL) && (dwDesiredAccess != 0))
|
||||
hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
|
||||
|
||||
return win32_build_iowin(hFile);
|
||||
iowin = win32_build_iowin(hFile);
|
||||
if (iowin == NULL)
|
||||
return NULL;
|
||||
iowin->filenameLength = strlen(filename) + 1;
|
||||
iowin->filename = (void*)malloc(iowin->filenameLength * sizeof(char));
|
||||
strncpy(iowin->filename, filename, iowin->filenameLength);
|
||||
return iowin;
|
||||
}
|
||||
|
||||
|
||||
@ -120,30 +136,146 @@ voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int
|
||||
const char* mode_fopen = NULL;
|
||||
DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
|
||||
HANDLE hFile = NULL;
|
||||
WIN32FILE_IOWIN *iowin = NULL;
|
||||
|
||||
win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
|
||||
|
||||
if ((filename!=NULL) && (dwDesiredAccess != 0))
|
||||
{
|
||||
hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
|
||||
|
||||
return win32_build_iowin(hFile);
|
||||
}
|
||||
iowin = win32_build_iowin(hFile);
|
||||
if (iowin == NULL)
|
||||
return NULL;
|
||||
if (iowin->filename == NULL)
|
||||
{
|
||||
iowin->filenameLength = wcslen(filename) + 1;
|
||||
iowin->filename = (void*)malloc(iowin->filenameLength * sizeof(WCHAR));
|
||||
wcsncpy(iowin->filename, filename, iowin->filenameLength);
|
||||
}
|
||||
return iowin;
|
||||
}
|
||||
|
||||
|
||||
voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mode)
|
||||
{
|
||||
const char* mode_fopen = NULL;
|
||||
DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
|
||||
HANDLE hFile = NULL;
|
||||
WIN32FILE_IOWIN *iowin = NULL;
|
||||
|
||||
win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
|
||||
|
||||
if ((filename!=NULL) && (dwDesiredAccess != 0))
|
||||
hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
|
||||
|
||||
return win32_build_iowin(hFile);
|
||||
iowin = win32_build_iowin(hFile);
|
||||
if (iowin == NULL)
|
||||
return NULL;
|
||||
iowin->filenameLength = _tcslen(filename) + 1;
|
||||
iowin->filename = (void*)malloc(iowin->filenameLength * sizeof(TCHAR));
|
||||
_tcsncpy(iowin->filename, filename, iowin->filenameLength);
|
||||
return iowin;
|
||||
}
|
||||
|
||||
voidpf ZCALLBACK win32_opendisk64_file_func (voidpf opaque, voidpf stream, int number_disk, int mode)
|
||||
{
|
||||
WIN32FILE_IOWIN *iowin = NULL;
|
||||
TCHAR *diskFilename = NULL;
|
||||
voidpf ret = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
iowin = (WIN32FILE_IOWIN*)stream;
|
||||
diskFilename = (TCHAR*)malloc(iowin->filenameLength * sizeof(TCHAR));
|
||||
_tcsncpy(diskFilename, iowin->filename, iowin->filenameLength);
|
||||
for (i = iowin->filenameLength - 1; i >= 0; i -= 1)
|
||||
{
|
||||
if (diskFilename[i] != _T('.'))
|
||||
continue;
|
||||
_sntprintf(&diskFilename[i], iowin->filenameLength - i, _T(".z%02d"), number_disk + 1);
|
||||
break;
|
||||
}
|
||||
if (i >= 0)
|
||||
ret = win32_open64_file_func(opaque, diskFilename, mode);
|
||||
free(diskFilename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
voidpf ZCALLBACK win32_opendisk64_file_funcW (voidpf opaque, voidpf stream, int number_disk, int mode)
|
||||
{
|
||||
WIN32FILE_IOWIN *iowin = NULL;
|
||||
WCHAR *diskFilename = NULL;
|
||||
voidpf ret = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
iowin = (WIN32FILE_IOWIN*)stream;
|
||||
diskFilename = (WCHAR*)malloc((iowin->filenameLength + 10) * sizeof(WCHAR));
|
||||
wcsncpy(diskFilename, iowin->filename, iowin->filenameLength);
|
||||
for (i = iowin->filenameLength - 1; i >= 0; i -= 1)
|
||||
{
|
||||
if (diskFilename[i] != L'.')
|
||||
continue;
|
||||
_snwprintf(&diskFilename[i], (iowin->filenameLength + 10) - i, L".z%02d", number_disk + 1);
|
||||
break;
|
||||
}
|
||||
if (i >= 0)
|
||||
ret = win32_open64_file_funcW(opaque, diskFilename, mode);
|
||||
free(diskFilename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
voidpf ZCALLBACK win32_opendisk64_file_funcA (voidpf opaque, voidpf stream, int number_disk, int mode)
|
||||
{
|
||||
WIN32FILE_IOWIN *iowin = NULL;
|
||||
char *diskFilename = NULL;
|
||||
voidpf ret = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
iowin = (WIN32FILE_IOWIN*)stream;
|
||||
diskFilename = (char*)malloc(iowin->filenameLength * sizeof(char));
|
||||
strncpy(diskFilename, iowin->filename, iowin->filenameLength);
|
||||
for (i = iowin->filenameLength - 1; i >= 0; i -= 1)
|
||||
{
|
||||
if (diskFilename[i] != '.')
|
||||
continue;
|
||||
_snprintf(&diskFilename[i], iowin->filenameLength - i, ".z%02d", number_disk + 1);
|
||||
break;
|
||||
}
|
||||
if (i >= 0)
|
||||
ret = win32_open64_file_funcA(opaque, diskFilename, mode);
|
||||
free(diskFilename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
voidpf ZCALLBACK win32_opendisk_file_func (voidpf opaque, voidpf stream, int number_disk, int mode)
|
||||
{
|
||||
WIN32FILE_IOWIN *iowin = NULL;
|
||||
TCHAR *diskFilename = NULL;
|
||||
voidpf ret = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
iowin = (WIN32FILE_IOWIN*)stream;
|
||||
diskFilename = (TCHAR*)malloc(iowin->filenameLength * sizeof(TCHAR));
|
||||
_tcsncpy(diskFilename, iowin->filename, iowin->filenameLength);
|
||||
for (i = iowin->filenameLength - 1; i >= 0; i -= 1)
|
||||
{
|
||||
if (diskFilename[i] != _T('.'))
|
||||
continue;
|
||||
_sntprintf(&diskFilename[i], iowin->filenameLength - i, _T(".z%02d"), number_disk + 1);
|
||||
break;
|
||||
}
|
||||
if (i >= 0)
|
||||
ret = win32_open_file_func(opaque, diskFilename, mode);
|
||||
free(diskFilename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uLong ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf,uLong size)
|
||||
{
|
||||
@ -312,35 +444,38 @@ long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T off
|
||||
|
||||
int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
WIN32FILE_IOWIN* iowin = NULL;
|
||||
int ret=-1;
|
||||
|
||||
if (stream!=NULL)
|
||||
if (stream==NULL)
|
||||
return ret;
|
||||
iowin = ((WIN32FILE_IOWIN*)stream);
|
||||
if (iowin->filename != NULL)
|
||||
{
|
||||
HANDLE hFile;
|
||||
hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
|
||||
if (hFile != NULL)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
ret=0;
|
||||
}
|
||||
free(stream);
|
||||
free(iowin->filename);
|
||||
}
|
||||
if (iowin->hf != NULL)
|
||||
{
|
||||
CloseHandle(iowin->hf);
|
||||
ret=0;
|
||||
}
|
||||
free(stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ZCALLBACK win32_error_file_func (voidpf opaque,voidpf stream)
|
||||
{
|
||||
int ret=-1;
|
||||
if (stream!=NULL)
|
||||
{
|
||||
ret = ((WIN32FILE_IOWIN*)stream) -> error;
|
||||
}
|
||||
if (stream==NULL)
|
||||
return ret;
|
||||
ret = ((WIN32FILE_IOWIN*)stream) -> error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
|
||||
{
|
||||
pzlib_filefunc_def->zopen_file = win32_open_file_func;
|
||||
pzlib_filefunc_def->zopendisk_file = win32_opendisk_file_func;
|
||||
pzlib_filefunc_def->zread_file = win32_read_file_func;
|
||||
pzlib_filefunc_def->zwrite_file = win32_write_file_func;
|
||||
pzlib_filefunc_def->ztell_file = win32_tell_file_func;
|
||||
@ -353,6 +488,7 @@ void fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
|
||||
void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def)
|
||||
{
|
||||
pzlib_filefunc_def->zopen64_file = win32_open64_file_func;
|
||||
pzlib_filefunc_def->zopendisk64_file = win32_opendisk64_file_func;
|
||||
pzlib_filefunc_def->zread_file = win32_read_file_func;
|
||||
pzlib_filefunc_def->zwrite_file = win32_write_file_func;
|
||||
pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
|
||||
@ -366,6 +502,7 @@ void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def)
|
||||
void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def)
|
||||
{
|
||||
pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA;
|
||||
pzlib_filefunc_def->zopendisk64_file = win32_opendisk64_file_funcA;
|
||||
pzlib_filefunc_def->zread_file = win32_read_file_func;
|
||||
pzlib_filefunc_def->zwrite_file = win32_write_file_func;
|
||||
pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
|
||||
@ -379,6 +516,7 @@ void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def)
|
||||
void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def)
|
||||
{
|
||||
pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW;
|
||||
pzlib_filefunc_def->zopendisk64_file = win32_opendisk64_file_funcW;
|
||||
pzlib_filefunc_def->zread_file = win32_read_file_func;
|
||||
pzlib_filefunc_def->zwrite_file = win32_write_file_func;
|
||||
pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
|
||||
|
65
miniunz.c
65
miniunz.c
@ -296,11 +296,12 @@ int do_list(uf)
|
||||
}
|
||||
|
||||
|
||||
int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
|
||||
int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password,dirname)
|
||||
unzFile uf;
|
||||
const int* popt_extract_without_path;
|
||||
int* popt_overwrite;
|
||||
const char* password;
|
||||
const char* dirname;
|
||||
{
|
||||
char filename_inzip[256];
|
||||
char* filename_withoutpath;
|
||||
@ -346,14 +347,18 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* write_filename;
|
||||
int skip=0;
|
||||
char write_filename[256];
|
||||
int skip=0, i;
|
||||
|
||||
|
||||
strncpy(write_filename,dirname, 256);
|
||||
if (dirname[strlen(dirname) - 1] != '/' && dirname[strlen(dirname) - 1] != '\\')
|
||||
strncat(write_filename, "\\", 256);
|
||||
if ((*popt_extract_without_path)==0)
|
||||
write_filename = filename_inzip;
|
||||
strncat(write_filename, filename_inzip, 256);
|
||||
else
|
||||
write_filename = filename_withoutpath;
|
||||
|
||||
strncat(write_filename, filename_withoutpath, 256);
|
||||
|
||||
err = unzOpenCurrentFilePassword(uf,password);
|
||||
if (err!=UNZ_OK)
|
||||
{
|
||||
@ -398,14 +403,24 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
|
||||
fout=fopen64(write_filename,"wb");
|
||||
|
||||
/* some zipfile don't contain directory alone before file */
|
||||
if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
|
||||
(filename_withoutpath!=(char*)filename_inzip))
|
||||
if ((fout==NULL) && ((*popt_extract_without_path)==0))
|
||||
{
|
||||
char c=*(filename_withoutpath-1);
|
||||
*(filename_withoutpath-1)='\0';
|
||||
makedir(write_filename);
|
||||
*(filename_withoutpath-1)=c;
|
||||
fout=fopen64(write_filename,"wb");
|
||||
char write_path[256];
|
||||
strncpy(write_path, write_filename, 256);
|
||||
for (i = strlen(write_path) - 1; i >= 0; i -= 1)
|
||||
{
|
||||
if (write_path[i] == '/' || write_path[i] == '\\')
|
||||
{
|
||||
write_path[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((*write_path) != '\0')
|
||||
{
|
||||
printf("creating directory: %s\n",write_path);
|
||||
makedir(write_path);
|
||||
fout=fopen64(write_filename,"wb");
|
||||
}
|
||||
}
|
||||
|
||||
if (fout==NULL)
|
||||
@ -460,11 +475,12 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
|
||||
}
|
||||
|
||||
|
||||
int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
|
||||
int do_extract(uf,opt_extract_without_path,opt_overwrite,password,dirname)
|
||||
unzFile uf;
|
||||
int opt_extract_without_path;
|
||||
int opt_overwrite;
|
||||
const char* password;
|
||||
const char *dirname;
|
||||
{
|
||||
uLong i;
|
||||
unz_global_info64 gi;
|
||||
@ -479,7 +495,7 @@ int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
|
||||
{
|
||||
if (do_extract_currentfile(uf,&opt_extract_without_path,
|
||||
&opt_overwrite,
|
||||
password) != UNZ_OK)
|
||||
password,dirname) != UNZ_OK)
|
||||
break;
|
||||
|
||||
if ((i+1)<gi.number_entry)
|
||||
@ -496,12 +512,13 @@ int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
|
||||
int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password,dirname)
|
||||
unzFile uf;
|
||||
const char* filename;
|
||||
int opt_extract_without_path;
|
||||
int opt_overwrite;
|
||||
const char* password;
|
||||
const char *dirname;
|
||||
{
|
||||
int err = UNZ_OK;
|
||||
if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
|
||||
@ -512,7 +529,7 @@ int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,passwo
|
||||
|
||||
if (do_extract_currentfile(uf,&opt_extract_without_path,
|
||||
&opt_overwrite,
|
||||
password) == UNZ_OK)
|
||||
password,dirname) == UNZ_OK)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
@ -626,20 +643,10 @@ int main(argc,argv)
|
||||
ret_value = do_list(uf);
|
||||
else if (opt_do_extract==1)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (opt_extractdir && _chdir(dirname))
|
||||
#else
|
||||
if (opt_extractdir && chdir(dirname))
|
||||
#endif
|
||||
{
|
||||
printf("Error changing into %s, aborting\n", dirname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (filename_to_extract == NULL)
|
||||
ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password);
|
||||
ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password, dirname);
|
||||
else
|
||||
ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
|
||||
ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password, dirname);
|
||||
}
|
||||
|
||||
unzClose(uf);
|
||||
|
18
minizip.c
18
minizip.c
@ -158,12 +158,13 @@ void do_banner()
|
||||
|
||||
void do_help()
|
||||
{
|
||||
printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
|
||||
printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-d bytes] [-j] file.zip [files_to_add]\n\n" \
|
||||
" -o Overwrite existing file.zip\n" \
|
||||
" -a Append to existing file.zip\n" \
|
||||
" -0 Store only\n" \
|
||||
" -1 Compress faster\n" \
|
||||
" -9 Compress better\n\n" \
|
||||
" -9 Compress better\n" \
|
||||
" -d Disk size\n" \
|
||||
" -j exclude path. store only the file name.\n\n");
|
||||
}
|
||||
|
||||
@ -219,12 +220,12 @@ int isLargeFile(const char* filename)
|
||||
|
||||
pos = ftello64(pFile);
|
||||
|
||||
printf("File : %s is %lld bytes\n", filename, pos);
|
||||
printf("File : %s is %lld bytes\n", filename, pos);
|
||||
|
||||
if(pos >= 0xffffffff)
|
||||
largeFile = 1;
|
||||
|
||||
fclose(pFile);
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
return largeFile;
|
||||
@ -243,6 +244,7 @@ int main(argc,argv)
|
||||
int zipok;
|
||||
int err=0;
|
||||
int size_buf=0;
|
||||
uLong disk_size = 0;
|
||||
void* buf=NULL;
|
||||
const char* password=NULL;
|
||||
|
||||
@ -272,7 +274,11 @@ int main(argc,argv)
|
||||
opt_compress_level = c-'0';
|
||||
if ((c=='j') || (c=='J'))
|
||||
opt_exclude_path = 1;
|
||||
|
||||
if ((c=='d') && (i+1<argc))
|
||||
{
|
||||
disk_size = atoi(argv[i+1]);
|
||||
i++;
|
||||
}
|
||||
if (((c=='p') || (c=='P')) && (i+1<argc))
|
||||
{
|
||||
password=argv[i+1];
|
||||
@ -360,7 +366,7 @@ int main(argc,argv)
|
||||
# ifdef USEWIN32IOAPI
|
||||
zlib_filefunc64_def ffunc;
|
||||
fill_win32_filefunc64A(&ffunc);
|
||||
zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
|
||||
zf = zipOpen3_64(filename_try,(opt_overwrite==2) ? 2 : 0,disk_size,NULL,&ffunc);
|
||||
# else
|
||||
zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0);
|
||||
# endif
|
||||
|
344
unzip.c
344
unzip.c
@ -32,32 +32,33 @@
|
||||
whole source package can be freely distributed, including from the USA.
|
||||
(Prior to January 2000, re-export from the US was a violation of US law.)
|
||||
|
||||
This encryption code is a direct transcription of the algorithm from
|
||||
This encryption code is a direct transcription of the algorithm from
|
||||
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
|
||||
file (appnote.txt) is distributed with the PKZIP program (even in the
|
||||
version without encryption capabilities).
|
||||
|
||||
------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------
|
||||
|
||||
Changes in unzip.c
|
||||
Changes in unzip.c
|
||||
|
||||
2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
|
||||
2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
|
||||
2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
|
||||
2007-2008 - Even Rouault - Remove old C style function prototypes
|
||||
2007-2008 - Even Rouault - Add unzip support for ZIP64
|
||||
|
||||
Copyright (C) 2007-2008 Even Rouault
|
||||
Copyright (C) 2007-2008 Even Rouault
|
||||
|
||||
|
||||
Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
|
||||
Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
|
||||
Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
|
||||
should only read the compressed/uncompressed size from the Zip64 format if
|
||||
the size from normal header was 0xFFFFFFFF
|
||||
Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
|
||||
Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
|
||||
Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
|
||||
Patch created by Daniel Borca
|
||||
|
||||
Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
|
||||
Aug-2010 - Nathan Moinvaziri - Added PKZIP spanning support
|
||||
|
||||
Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
|
||||
|
||||
@ -68,9 +69,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef NOUNCRYPT
|
||||
/*#ifndef NOUNCRYPT
|
||||
#define NOUNCRYPT
|
||||
#endif
|
||||
#endif*/
|
||||
|
||||
#include "zlib.h"
|
||||
#include "unzip.h"
|
||||
@ -85,7 +86,9 @@
|
||||
#else
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#ifndef local
|
||||
# define local static
|
||||
@ -101,7 +104,7 @@
|
||||
|
||||
|
||||
#ifndef UNZ_BUFSIZE
|
||||
#define UNZ_BUFSIZE (16384)
|
||||
#define UNZ_BUFSIZE (64 * 1024)
|
||||
#endif
|
||||
|
||||
#ifndef UNZ_MAXFILENAMEINZIP
|
||||
@ -126,6 +129,7 @@ const char unz_copyright[] =
|
||||
typedef struct unz_file_info64_internal_s
|
||||
{
|
||||
ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
|
||||
ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
|
||||
} unz_file_info64_internal;
|
||||
|
||||
|
||||
@ -166,14 +170,16 @@ typedef struct
|
||||
{
|
||||
zlib_filefunc64_32_def z_filefunc;
|
||||
int is64bitOpenFunction;
|
||||
voidpf filestream; /* io structore of the zipfile */
|
||||
unz_global_info64 gi; /* public global information */
|
||||
voidpf filestream; /* io structure of the current zipfile */
|
||||
voidpf filestream_with_CD; /* io structure of the disk with the central directory */
|
||||
unz_global_info64 gi; /* public global information */
|
||||
ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
|
||||
ZPOS64_T num_file; /* number of the current file in the zipfile*/
|
||||
ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
|
||||
ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
|
||||
ZPOS64_T central_pos; /* position of the beginning of the central dir*/
|
||||
|
||||
uLong number_disk; /* number of the current disk, used for
|
||||
spanning ZIP*/
|
||||
ZPOS64_T size_central_dir; /* size of the central directory */
|
||||
ZPOS64_T offset_central_dir; /* offset of start of central directory with
|
||||
respect to the starting disk number */
|
||||
@ -484,7 +490,7 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
|
||||
ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
|
||||
ZPOS64_T uPosFound=0;
|
||||
uLong uL;
|
||||
ZPOS64_T relativeOffset;
|
||||
ZPOS64_T relativeOffset;
|
||||
|
||||
if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
|
||||
return 0;
|
||||
@ -588,14 +594,8 @@ local unzFile unzOpenInternal (const void *path,
|
||||
unz64_s us;
|
||||
unz64_s *s;
|
||||
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_CD; /* total number of entries in
|
||||
the central dir
|
||||
uLong uL;
|
||||
ZPOS64_T number_entry_CD; /* total number of entries in the central dir
|
||||
(same than number_entry on nospan) */
|
||||
|
||||
int err=UNZ_OK;
|
||||
@ -603,6 +603,8 @@ local unzFile unzOpenInternal (const void *path,
|
||||
if (unz_copyright[0]!=' ')
|
||||
return NULL;
|
||||
|
||||
us.filestream = NULL;
|
||||
us.filestream_with_CD = NULL;
|
||||
us.z_filefunc.zseek32_file = NULL;
|
||||
us.z_filefunc.ztell32_file = NULL;
|
||||
if (pzlib_filefunc64_32_def==NULL)
|
||||
@ -611,16 +613,14 @@ local unzFile unzOpenInternal (const void *path,
|
||||
us.z_filefunc = *pzlib_filefunc64_32_def;
|
||||
us.is64bitOpenFunction = is64bitOpenFunction;
|
||||
|
||||
|
||||
|
||||
us.filestream = ZOPEN64(us.z_filefunc,
|
||||
path,
|
||||
ZLIB_FILEFUNC_MODE_READ |
|
||||
ZLIB_FILEFUNC_MODE_EXISTING);
|
||||
if (us.filestream==NULL)
|
||||
us.filestream = ZOPEN64(us.z_filefunc, path, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING);
|
||||
|
||||
if (us.filestream == NULL)
|
||||
return NULL;
|
||||
|
||||
us.filestream_with_CD = us.filestream;
|
||||
central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
|
||||
|
||||
if (central_pos)
|
||||
{
|
||||
uLong uS;
|
||||
@ -628,9 +628,8 @@ local unzFile unzOpenInternal (const void *path,
|
||||
|
||||
us.isZip64 = 1;
|
||||
|
||||
if (ZSEEK64(us.z_filefunc, us.filestream,
|
||||
central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
err=UNZ_ERRNO;
|
||||
if (ZSEEK64(us.z_filefunc, us.filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
/* the signature, already checked */
|
||||
if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
|
||||
@ -649,11 +648,11 @@ local unzFile unzOpenInternal (const void *path,
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
/* number of this disk */
|
||||
if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
|
||||
if (unz64local_getLong(&us.z_filefunc, us.filestream,&us.number_disk)!=UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
/* number of the disk with the start of the central directory */
|
||||
if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
|
||||
if (unz64local_getLong(&us.z_filefunc, us.filestream,&us.gi.number_disk_with_CD)!=UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
/* total number of entries in the central directory on this disk */
|
||||
@ -664,9 +663,7 @@ local unzFile unzOpenInternal (const void *path,
|
||||
if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if ((number_entry_CD!=us.gi.number_entry) ||
|
||||
(number_disk_with_CD!=0) ||
|
||||
(number_disk!=0))
|
||||
if (number_entry_CD!=us.gi.number_entry)
|
||||
err=UNZ_BADZIPFILE;
|
||||
|
||||
/* size of the central directory */
|
||||
@ -683,13 +680,13 @@ local unzFile unzOpenInternal (const void *path,
|
||||
else
|
||||
{
|
||||
central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
|
||||
|
||||
if (central_pos==0)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
us.isZip64 = 0;
|
||||
|
||||
if (ZSEEK64(us.z_filefunc, us.filestream,
|
||||
central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
if (ZSEEK64(us.z_filefunc, us.filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
/* the signature, already checked */
|
||||
@ -697,11 +694,11 @@ local unzFile unzOpenInternal (const void *path,
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
/* number of this disk */
|
||||
if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
|
||||
if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.number_disk)!=UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
/* number of the disk with the start of the central directory */
|
||||
if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
|
||||
if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.number_disk_with_CD)!=UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
/* total number of entries in the central dir on this disk */
|
||||
@ -714,9 +711,7 @@ local unzFile unzOpenInternal (const void *path,
|
||||
err=UNZ_ERRNO;
|
||||
number_entry_CD = uL;
|
||||
|
||||
if ((number_entry_CD!=us.gi.number_entry) ||
|
||||
(number_disk_with_CD!=0) ||
|
||||
(number_disk!=0))
|
||||
if (number_entry_CD!=us.gi.number_entry)
|
||||
err=UNZ_BADZIPFILE;
|
||||
|
||||
/* size of the central directory */
|
||||
@ -751,7 +746,6 @@ local unzFile unzOpenInternal (const void *path,
|
||||
us.pfile_in_zip_read = NULL;
|
||||
us.encrypted = 0;
|
||||
|
||||
|
||||
s=(unz64_s*)ALLOC(sizeof(unz64_s));
|
||||
if( s != NULL)
|
||||
{
|
||||
@ -815,7 +809,14 @@ extern int ZEXPORT unzClose (unzFile file)
|
||||
if (s->pfile_in_zip_read!=NULL)
|
||||
unzCloseCurrentFile(file);
|
||||
|
||||
ZCLOSE64(s->z_filefunc, s->filestream);
|
||||
if ((s->filestream != NULL) && (s->filestream != s->filestream_with_CD))
|
||||
ZCLOSE64(s->z_filefunc, s->filestream);
|
||||
if (s->filestream_with_CD != NULL)
|
||||
ZCLOSE64(s->z_filefunc, s->filestream_with_CD);
|
||||
|
||||
s->filestream = NULL;
|
||||
s->filestream_with_CD = NULL;
|
||||
|
||||
TRYFREE(s);
|
||||
return UNZ_OK;
|
||||
}
|
||||
@ -844,6 +845,7 @@ extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info
|
||||
/* to do : check if number_entry is not truncated */
|
||||
pglobal_info32->number_entry = (uLong)s->gi.number_entry;
|
||||
pglobal_info32->size_comment = s->gi.size_comment;
|
||||
pglobal_info32->number_disk_with_CD = s->gi.number_disk_with_CD;
|
||||
return UNZ_OK;
|
||||
}
|
||||
/*
|
||||
@ -893,75 +895,76 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
||||
int err=UNZ_OK;
|
||||
uLong uMagic;
|
||||
long lSeek=0;
|
||||
uLong consumedExtraSize = 0;
|
||||
uLong uL;
|
||||
|
||||
if (file==NULL)
|
||||
return UNZ_PARAMERROR;
|
||||
s=(unz64_s*)file;
|
||||
if (ZSEEK64(s->z_filefunc, s->filestream,
|
||||
s->pos_in_central_dir+s->byte_before_the_zipfile,
|
||||
ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, s->pos_in_central_dir+s->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
/* we check the magic */
|
||||
if (err==UNZ_OK)
|
||||
{
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD,&uMagic) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
else if (uMagic!=0x02014b50)
|
||||
err=UNZ_BADZIPFILE;
|
||||
}
|
||||
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD,&file_info.version) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD,&file_info.version_needed) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD,&file_info.flag) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD,&file_info.compression_method) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD,&file_info.dosDate) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
|
||||
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD,&file_info.crc) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD,&uL) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
file_info.compressed_size = uL;
|
||||
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD,&uL) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
file_info.uncompressed_size = uL;
|
||||
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD,&file_info.size_filename) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD,&file_info.size_file_extra) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD,&file_info.size_file_comment) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD,&file_info.disk_num_start) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD,&file_info.internal_fa) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD,&file_info.external_fa) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
// relative offset of local header
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD,&uL) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
file_info.size_file_extra_internal = 0;
|
||||
file_info.disk_offset = uL;
|
||||
file_info_internal.offset_curfile = uL;
|
||||
|
||||
lSeek+=file_info.size_filename;
|
||||
@ -977,7 +980,7 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
||||
uSizeRead = fileNameBufferSize;
|
||||
|
||||
if ((file_info.size_filename>0) && (fileNameBufferSize>0))
|
||||
if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
|
||||
if (ZREAD64(s->z_filefunc, s->filestream_with_CD,szFileName,uSizeRead)!=uSizeRead)
|
||||
err=UNZ_ERRNO;
|
||||
lSeek -= uSizeRead;
|
||||
}
|
||||
@ -993,14 +996,14 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
||||
|
||||
if (lSeek!=0)
|
||||
{
|
||||
if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
|
||||
if (ZSEEK64(s->z_filefunc, s->filestream_with_CD,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
|
||||
lSeek=0;
|
||||
else
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
|
||||
if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
|
||||
if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
|
||||
if (ZREAD64(s->z_filefunc, s->filestream_with_CD,extraField,(uLong)uSizeRead)!=uSizeRead)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
lSeek += file_info.size_file_extra - (uLong)uSizeRead;
|
||||
@ -1011,14 +1014,14 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
||||
|
||||
if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
|
||||
{
|
||||
uLong acc = 0;
|
||||
uLong acc = 0;
|
||||
|
||||
// since lSeek now points to after the extra field we need to move back
|
||||
lSeek -= file_info.size_file_extra;
|
||||
|
||||
if (lSeek!=0)
|
||||
{
|
||||
if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
|
||||
if (ZSEEK64(s->z_filefunc, s->filestream_with_CD,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
|
||||
lSeek=0;
|
||||
else
|
||||
err=UNZ_ERRNO;
|
||||
@ -1027,49 +1030,50 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
||||
while(acc < file_info.size_file_extra)
|
||||
{
|
||||
uLong headerId;
|
||||
uLong dataSize;
|
||||
uLong dataSize;
|
||||
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD,&headerId) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
|
||||
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD,&dataSize) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
/* ZIP64 extra fields */
|
||||
if (headerId == 0x0001)
|
||||
{
|
||||
uLong uL;
|
||||
/* Subtract size of ZIP64 field, since ZIP64 is handled internally */
|
||||
file_info.size_file_extra_internal += 20;
|
||||
|
||||
if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)
|
||||
{
|
||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
if(file_info.uncompressed_size == 0xffffffff)
|
||||
{
|
||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream_with_CD,&file_info.uncompressed_size) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
|
||||
if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)
|
||||
{
|
||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
if(file_info.compressed_size == 0xffffffff)
|
||||
{
|
||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream_with_CD,&file_info.compressed_size) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
|
||||
if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)
|
||||
{
|
||||
/* Relative Header offset */
|
||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
|
||||
if(file_info.disk_num_start == (unsigned long)-1)
|
||||
{
|
||||
/* Disk Start Number */
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
if(file_info_internal.offset_curfile == 0xffffffff)
|
||||
{
|
||||
/* Relative Header offset */
|
||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream_with_CD,&file_info_internal.offset_curfile) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
file_info.disk_offset = file_info_internal.offset_curfile;
|
||||
}
|
||||
|
||||
if(file_info.disk_num_start == 0xffffffff)
|
||||
{
|
||||
/* Disk Start Number */
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD,&file_info.disk_num_start) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
|
||||
if (ZSEEK64(s->z_filefunc, s->filestream_with_CD,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
|
||||
@ -1077,6 +1081,11 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
||||
}
|
||||
}
|
||||
|
||||
if (file_info.disk_num_start == s->gi.number_disk_with_CD)
|
||||
file_info_internal.byte_before_the_zipfile = s->byte_before_the_zipfile;
|
||||
else
|
||||
file_info_internal.byte_before_the_zipfile = 0;
|
||||
|
||||
if ((err==UNZ_OK) && (szComment!=NULL))
|
||||
{
|
||||
uLong uSizeRead ;
|
||||
@ -1090,14 +1099,14 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
||||
|
||||
if (lSeek!=0)
|
||||
{
|
||||
if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
|
||||
if (ZSEEK64(s->z_filefunc, s->filestream_with_CD,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
|
||||
lSeek=0;
|
||||
else
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
|
||||
if ((file_info.size_file_comment>0) && (commentBufferSize>0))
|
||||
if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
|
||||
if (ZREAD64(s->z_filefunc, s->filestream_with_CD,szComment,uSizeRead)!=uSizeRead)
|
||||
err=UNZ_ERRNO;
|
||||
lSeek+=file_info.size_file_comment - uSizeRead;
|
||||
}
|
||||
@ -1155,7 +1164,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
|
||||
pfile_info->crc = file_info64.crc;
|
||||
|
||||
pfile_info->size_filename = file_info64.size_filename;
|
||||
pfile_info->size_file_extra = file_info64.size_file_extra;
|
||||
pfile_info->size_file_extra = file_info64.size_file_extra - file_info64.size_file_extra_internal;
|
||||
pfile_info->size_file_comment = file_info64.size_file_comment;
|
||||
|
||||
pfile_info->disk_num_start = file_info64.disk_num_start;
|
||||
@ -1164,7 +1173,6 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
|
||||
|
||||
pfile_info->tmu_date = file_info64.tmu_date,
|
||||
|
||||
|
||||
pfile_info->compressed_size = (uLong)file_info64.compressed_size;
|
||||
pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
|
||||
|
||||
@ -1370,6 +1378,54 @@ extern int ZEXPORT unzGoToFilePos(
|
||||
return unzGoToFilePos64(file,&file_pos64);
|
||||
}
|
||||
|
||||
local int unzGoToNextDisk(unzFile file)
|
||||
{
|
||||
unz64_s* s;
|
||||
file_in_zip64_read_info_s* pfile_in_zip_read_info;
|
||||
int err = UNZ_OK;
|
||||
int number_disk_next;
|
||||
|
||||
|
||||
s=(unz64_s*)file;
|
||||
pfile_in_zip_read_info=s->pfile_in_zip_read;
|
||||
number_disk_next = s->number_disk;
|
||||
|
||||
if ((pfile_in_zip_read_info != NULL) && (pfile_in_zip_read_info->rest_read_uncompressed > 0))
|
||||
{
|
||||
/* We are currently reading a file and we need the next sequential disk */
|
||||
number_disk_next += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Goto the disk for the current file */
|
||||
number_disk_next = s->cur_file_info.disk_num_start;
|
||||
}
|
||||
|
||||
if (number_disk_next != s->number_disk)
|
||||
{
|
||||
/* Switch disks */
|
||||
if ((s->filestream != NULL) && (s->filestream != s->filestream_with_CD))
|
||||
ZCLOSE64(s->z_filefunc, s->filestream);
|
||||
|
||||
if (number_disk_next == s->gi.number_disk_with_CD)
|
||||
{
|
||||
s->filestream = s->filestream_with_CD;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->filestream = ZOPENDISK64(s->z_filefunc, s->filestream_with_CD, number_disk_next,
|
||||
ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING);
|
||||
}
|
||||
|
||||
if (s->filestream == NULL)
|
||||
return UNZ_ERRNO;
|
||||
|
||||
s->number_disk = number_disk_next;
|
||||
}
|
||||
|
||||
return UNZ_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
// Unzip Helper Functions - should be here?
|
||||
///////////////////////////////////////////
|
||||
@ -1395,10 +1451,13 @@ local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVa
|
||||
*poffset_local_extrafield = 0;
|
||||
*psize_local_extrafield = 0;
|
||||
|
||||
if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
|
||||
s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
return UNZ_ERRNO;
|
||||
err = unzGoToNextDisk((unzFile)s);
|
||||
if (err != UNZ_OK)
|
||||
return err;
|
||||
|
||||
if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
|
||||
s->cur_file_info_internal.byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
return UNZ_ERRNO;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
{
|
||||
@ -1543,8 +1602,10 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
|
||||
pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
|
||||
pfile_in_zip_read_info->filestream=s->filestream;
|
||||
pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
|
||||
pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
|
||||
|
||||
if (s->filestream == s->filestream_with_CD)
|
||||
pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
|
||||
else
|
||||
pfile_in_zip_read_info->byte_before_the_zipfile=0;
|
||||
pfile_in_zip_read_info->stream.total_out = 0;
|
||||
|
||||
if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
|
||||
@ -1610,7 +1671,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
|
||||
pfile_in_zip_read_info->stream.avail_in = (uInt)0;
|
||||
|
||||
s->pfile_in_zip_read = pfile_in_zip_read_info;
|
||||
s->encrypted = 0;
|
||||
s->encrypted = 0;
|
||||
|
||||
# ifndef NOUNCRYPT
|
||||
if (password != NULL)
|
||||
@ -1723,42 +1784,60 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
|
||||
(pfile_in_zip_read_info->rest_read_compressed>0))
|
||||
{
|
||||
uInt uReadThis = UNZ_BUFSIZE;
|
||||
uInt uBytesRead = 0;
|
||||
uInt uTotalBytesRead = 0;
|
||||
|
||||
if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
|
||||
uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
|
||||
if (uReadThis == 0)
|
||||
return UNZ_EOF;
|
||||
if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
|
||||
pfile_in_zip_read_info->filestream,
|
||||
pfile_in_zip_read_info->pos_in_zipfile +
|
||||
pfile_in_zip_read_info->byte_before_the_zipfile,
|
||||
ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
return UNZ_ERRNO;
|
||||
if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
|
||||
pfile_in_zip_read_info->filestream,
|
||||
pfile_in_zip_read_info->read_buffer,
|
||||
uReadThis)!=uReadThis)
|
||||
return UNZ_ERRNO;
|
||||
|
||||
while (uTotalBytesRead != uReadThis)
|
||||
{
|
||||
if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
|
||||
pfile_in_zip_read_info->filestream,
|
||||
pfile_in_zip_read_info->pos_in_zipfile +
|
||||
pfile_in_zip_read_info->byte_before_the_zipfile,
|
||||
ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
return UNZ_ERRNO;
|
||||
|
||||
uBytesRead = ZREAD64(pfile_in_zip_read_info->z_filefunc,
|
||||
pfile_in_zip_read_info->filestream,
|
||||
pfile_in_zip_read_info->read_buffer + uTotalBytesRead,
|
||||
uReadThis - uTotalBytesRead);
|
||||
|
||||
uTotalBytesRead += uBytesRead;
|
||||
pfile_in_zip_read_info->pos_in_zipfile += uBytesRead;
|
||||
|
||||
if (uBytesRead == 0)
|
||||
{
|
||||
if (ZERROR64(pfile_in_zip_read_info->z_filefunc,pfile_in_zip_read_info->filestream))
|
||||
return UNZ_ERRNO;
|
||||
|
||||
err = unzGoToNextDisk(file);
|
||||
|
||||
if (err != UNZ_OK)
|
||||
return err;
|
||||
|
||||
pfile_in_zip_read_info->pos_in_zipfile = 0;
|
||||
pfile_in_zip_read_info->filestream = s->filestream;
|
||||
}
|
||||
}
|
||||
|
||||
# ifndef NOUNCRYPT
|
||||
if(s->encrypted)
|
||||
{
|
||||
uInt i;
|
||||
for(i=0;i<uReadThis;i++)
|
||||
for(i=0;i<uTotalBytesRead;i++)
|
||||
pfile_in_zip_read_info->read_buffer[i] =
|
||||
zdecode(s->keys,s->pcrc_32_tab,
|
||||
pfile_in_zip_read_info->read_buffer[i]);
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
|
||||
|
||||
pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
|
||||
|
||||
pfile_in_zip_read_info->stream.next_in =
|
||||
(Bytef*)pfile_in_zip_read_info->read_buffer;
|
||||
pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
|
||||
pfile_in_zip_read_info->rest_read_compressed -= uTotalBytesRead;
|
||||
pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->read_buffer;
|
||||
pfile_in_zip_read_info->stream.avail_in = (uInt)uTotalBytesRead;
|
||||
}
|
||||
|
||||
if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
|
||||
@ -2052,6 +2131,7 @@ extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uS
|
||||
{
|
||||
unz64_s* s;
|
||||
uLong uReadThis ;
|
||||
|
||||
if (file==NULL)
|
||||
return (int)UNZ_PARAMERROR;
|
||||
s=(unz64_s*)file;
|
||||
@ -2060,13 +2140,13 @@ extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uS
|
||||
if (uReadThis>s->gi.size_comment)
|
||||
uReadThis = s->gi.size_comment;
|
||||
|
||||
if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
if (ZSEEK64(s->z_filefunc,s->filestream_with_CD,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
return UNZ_ERRNO;
|
||||
|
||||
if (uReadThis>0)
|
||||
{
|
||||
*szComment='\0';
|
||||
if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
|
||||
if (ZREAD64(s->z_filefunc,s->filestream_with_CD,szComment,uReadThis)!=uReadThis)
|
||||
return UNZ_ERRNO;
|
||||
}
|
||||
|
||||
|
12
unzip.h
12
unzip.h
@ -95,8 +95,10 @@ typedef struct tm_unz_s
|
||||
These data comes from the end of central dir */
|
||||
typedef struct unz_global_info64_s
|
||||
{
|
||||
ZPOS64_T number_entry; /* total number of entries in
|
||||
ZPOS64_T number_entry; /* total number of entries in
|
||||
the central dir on this disk */
|
||||
uLong number_disk_with_CD; /* number the the disk with central dir, used
|
||||
for spanning ZIP*/
|
||||
uLong size_comment; /* size of the global comment of the zipfile */
|
||||
} unz_global_info64;
|
||||
|
||||
@ -104,6 +106,8 @@ typedef struct unz_global_info_s
|
||||
{
|
||||
uLong number_entry; /* total number of entries in
|
||||
the central dir on this disk */
|
||||
uLong number_disk_with_CD; /* number the the disk with central dir, used
|
||||
for spanning ZIP*/
|
||||
uLong size_comment; /* size of the global comment of the zipfile */
|
||||
} unz_global_info;
|
||||
|
||||
@ -127,6 +131,8 @@ typedef struct unz_file_info64_s
|
||||
uLong external_fa; /* external file attributes 4 bytes */
|
||||
|
||||
tm_unz tmu_date;
|
||||
ZPOS64_T disk_offset;
|
||||
uLong size_file_extra_internal;
|
||||
} unz_file_info64;
|
||||
|
||||
typedef struct unz_file_info_s
|
||||
@ -146,8 +152,9 @@ typedef struct unz_file_info_s
|
||||
uLong disk_num_start; /* disk number start 2 bytes */
|
||||
uLong internal_fa; /* internal file attributes 2 bytes */
|
||||
uLong external_fa; /* external file attributes 4 bytes */
|
||||
|
||||
|
||||
tm_unz tmu_date;
|
||||
uLong disk_offset;
|
||||
} unz_file_info;
|
||||
|
||||
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
|
||||
@ -251,7 +258,6 @@ extern int ZEXPORT unzLocateFile OF((unzFile file,
|
||||
UNZ_END_OF_LIST_OF_FILE if the file is not found
|
||||
*/
|
||||
|
||||
|
||||
/* ****************************************** */
|
||||
/* Ryan supplied functions */
|
||||
/* unz_file_info contain information about a file in the zipfile */
|
||||
|
354
zip.c
354
zip.c
@ -18,7 +18,7 @@
|
||||
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
|
||||
|
||||
Aug-2010 - Nathan Moinvaziri - Added PKZIP spanning support
|
||||
*/
|
||||
|
||||
|
||||
@ -39,7 +39,9 @@
|
||||
#else
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#ifndef local
|
||||
# define local static
|
||||
@ -51,7 +53,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef Z_BUFSIZE
|
||||
#define Z_BUFSIZE (64*1024) //(16384)
|
||||
#define Z_BUFSIZE (64 * 1024)
|
||||
#endif
|
||||
|
||||
#ifndef Z_MAXFILENAMEINZIP
|
||||
@ -100,6 +102,7 @@ const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http
|
||||
|
||||
#define SIZEDATA_INDATABLOCK (4096-(4*4))
|
||||
|
||||
#define DISKHEADERMAGIC (0x08074b50)
|
||||
#define LOCALHEADERMAGIC (0x04034b50)
|
||||
#define CENTRALHEADERMAGIC (0x02014b50)
|
||||
#define ENDHEADERMAGIC (0x06054b50)
|
||||
@ -152,6 +155,7 @@ typedef struct
|
||||
uLong crc32;
|
||||
int encrypt;
|
||||
int zip64; /* Add ZIP64 extened information in the extra field */
|
||||
uLong number_disk; /* number of current disk used for spanning ZIP */
|
||||
ZPOS64_T pos_zip64extrainfo;
|
||||
ZPOS64_T totalCompressedData;
|
||||
ZPOS64_T totalUncompressedData;
|
||||
@ -165,15 +169,21 @@ typedef struct
|
||||
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 */
|
||||
voidpf filestream; /* io structure of the zipfile */
|
||||
voidpf filestream_with_CD; /* io structure of the zipfile with the central dir */
|
||||
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.*/
|
||||
int append; /* append mode */
|
||||
curfile64_info ci; /* info on the file currently writing */
|
||||
|
||||
ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
|
||||
ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
|
||||
ZPOS64_T add_position_when_writting_offset;
|
||||
ZPOS64_T number_entry;
|
||||
|
||||
ZPOS64_T disk_size; /* size of each disk */
|
||||
uLong number_disk; /* number of the current disk, used for
|
||||
spanning ZIP */
|
||||
uLong number_disk_with_CD; /* number the the disk with central dir, used
|
||||
for spanning ZIP */
|
||||
#ifndef NO_ADDFILEINEXISTINGZIP
|
||||
char *globalcomment;
|
||||
#endif
|
||||
@ -471,6 +481,101 @@ local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def
|
||||
#ifndef BUFREADCOMMENT
|
||||
#define BUFREADCOMMENT (0x400)
|
||||
#endif
|
||||
|
||||
local int zipGetDiskSizeAvailable(zipFile file, ZPOS64_T *size_available)
|
||||
{
|
||||
zip64_internal* zi;
|
||||
ZPOS64_T current_disk_size;
|
||||
|
||||
|
||||
zi=(zip64_internal*)file;
|
||||
ZSEEK64(zi->z_filefunc, zi->filestream,0,ZLIB_FILEFUNC_SEEK_END);
|
||||
current_disk_size = ZTELL64(zi->z_filefunc, zi->filestream);
|
||||
*size_available = zi->disk_size - current_disk_size;
|
||||
return ZIP_OK;
|
||||
}
|
||||
|
||||
local int zipGoToSpecificDisk(zipFile file, int number_disk, int openExisting)
|
||||
{
|
||||
zip64_internal* zi;
|
||||
int err = ZIP_OK;
|
||||
|
||||
|
||||
zi=(zip64_internal*)file;
|
||||
if (zi->disk_size == 0)
|
||||
return err;
|
||||
|
||||
if ((zi->filestream != NULL) && (zi->filestream != zi->filestream_with_CD))
|
||||
ZCLOSE64(zi->z_filefunc, zi->filestream);
|
||||
|
||||
zi->filestream = ZOPENDISK64(zi->z_filefunc, zi->filestream_with_CD, number_disk, (openExisting == 1) ?
|
||||
(ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING) :
|
||||
(ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE));
|
||||
|
||||
if (zi->filestream == NULL)
|
||||
err = ZIP_ERRNO;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
local int zipGoToFirstDisk(zipFile file)
|
||||
{
|
||||
zip64_internal* zi;
|
||||
int number_disk_next;
|
||||
int err = ZIP_OK;
|
||||
|
||||
|
||||
zi=(zip64_internal*)file;
|
||||
|
||||
if (zi->disk_size == 0)
|
||||
return err;
|
||||
number_disk_next = 0;
|
||||
if (zi->number_disk_with_CD > 0)
|
||||
number_disk_next = zi->number_disk_with_CD - 1;
|
||||
err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP));
|
||||
if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP))
|
||||
err = zipGoToSpecificDisk(file, number_disk_next, 0);
|
||||
if (err == ZIP_OK)
|
||||
zi->number_disk = number_disk_next;
|
||||
ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END);
|
||||
return err;
|
||||
}
|
||||
|
||||
local int zipGoToNextDisk(zipFile file)
|
||||
{
|
||||
zip64_internal* zi;
|
||||
ZPOS64_T size_available_in_disk;
|
||||
int err = ZIP_OK;
|
||||
int number_disk_next;
|
||||
|
||||
|
||||
zi=(zip64_internal*)file;
|
||||
|
||||
if (zi->disk_size == 0)
|
||||
return err;
|
||||
|
||||
number_disk_next = zi->number_disk + 1;
|
||||
|
||||
do
|
||||
{
|
||||
err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP));
|
||||
if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP))
|
||||
err = zipGoToSpecificDisk(file, number_disk_next, 0);
|
||||
if (err != ZIP_OK)
|
||||
break;
|
||||
err = zipGetDiskSizeAvailable(file, &size_available_in_disk);
|
||||
if (err != ZIP_OK)
|
||||
break;
|
||||
zi->number_disk = number_disk_next;
|
||||
zi->number_disk_with_CD = zi->number_disk + 1;
|
||||
|
||||
number_disk_next += 1;
|
||||
}
|
||||
while (size_available_in_disk <= 0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
Locate the Central directory of a zipfile (at the end, just before
|
||||
the global comment)
|
||||
@ -646,11 +751,6 @@ int LoadCentralDirectoryRecord(zip64_internal* pziinit)
|
||||
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
|
||||
@ -700,11 +800,11 @@ int LoadCentralDirectoryRecord(zip64_internal* pziinit)
|
||||
err=ZIP_ERRNO;
|
||||
|
||||
/* number of this disk */
|
||||
if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
|
||||
if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&pziinit->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)
|
||||
if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&pziinit->number_disk_with_CD)!=ZIP_OK)
|
||||
err=ZIP_ERRNO;
|
||||
|
||||
/* total number of entries in the central directory on this disk */
|
||||
@ -715,7 +815,7 @@ int LoadCentralDirectoryRecord(zip64_internal* pziinit)
|
||||
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))
|
||||
if (number_entry_CD!=number_entry)
|
||||
err=ZIP_BADZIPFILE;
|
||||
|
||||
/* size of the central directory */
|
||||
@ -742,11 +842,11 @@ int LoadCentralDirectoryRecord(zip64_internal* pziinit)
|
||||
err=ZIP_ERRNO;
|
||||
|
||||
/* number of this disk */
|
||||
if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
|
||||
if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&pziinit->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)
|
||||
if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&pziinit->number_disk_with_CD)!=ZIP_OK)
|
||||
err=ZIP_ERRNO;
|
||||
|
||||
/* total number of entries in the central dir on this disk */
|
||||
@ -763,7 +863,7 @@ int LoadCentralDirectoryRecord(zip64_internal* pziinit)
|
||||
else
|
||||
number_entry_CD = uL;
|
||||
|
||||
if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
|
||||
if (number_entry_CD!=number_entry)
|
||||
err=ZIP_BADZIPFILE;
|
||||
|
||||
/* size of the central directory */
|
||||
@ -846,7 +946,7 @@ int LoadCentralDirectoryRecord(zip64_internal* pziinit)
|
||||
|
||||
|
||||
/************************************************************/
|
||||
extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
|
||||
extern zipFile ZEXPORT zipOpen4 (const void *pathname, int append, ZPOS64_T disk_size, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
|
||||
{
|
||||
zip64_internal ziinit;
|
||||
zip64_internal* zi;
|
||||
@ -858,7 +958,7 @@ extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* gl
|
||||
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) ?
|
||||
@ -867,10 +967,21 @@ extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* gl
|
||||
|
||||
if (ziinit.filestream == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
if (append == APPEND_STATUS_CREATEAFTER)
|
||||
ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
|
||||
{
|
||||
/* Don't support spanning ZIP with APPEND_STATUS_CREATEAFTER */
|
||||
if (disk_size > 0)
|
||||
return NULL;
|
||||
|
||||
ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
|
||||
}
|
||||
|
||||
ziinit.filestream_with_CD = ziinit.filestream;
|
||||
ziinit.append = append;
|
||||
ziinit.number_disk = 0;
|
||||
ziinit.number_disk_with_CD = 0;
|
||||
ziinit.disk_size = disk_size;
|
||||
ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
|
||||
ziinit.in_opened_file_inzip = 0;
|
||||
ziinit.ci.stream_initialised = 0;
|
||||
@ -878,8 +989,6 @@ extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* gl
|
||||
ziinit.add_position_when_writting_offset = 0;
|
||||
init_linkedlist(&(ziinit.central_dir));
|
||||
|
||||
|
||||
|
||||
zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
|
||||
if (zi==NULL)
|
||||
{
|
||||
@ -913,6 +1022,7 @@ extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* gl
|
||||
else
|
||||
{
|
||||
*zi = ziinit;
|
||||
zipGoToFirstDisk((zipFile)zi);
|
||||
return (zipFile)zi;
|
||||
}
|
||||
}
|
||||
@ -923,10 +1033,10 @@ extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* gl
|
||||
{
|
||||
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);
|
||||
return zipOpen4(pathname, append, 0, globalcomment, &zlib_filefunc64_32_def_fill);
|
||||
}
|
||||
else
|
||||
return zipOpen3(pathname, append, globalcomment, NULL);
|
||||
return zipOpen4(pathname, append, 0, globalcomment, NULL);
|
||||
}
|
||||
|
||||
extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
|
||||
@ -937,22 +1047,47 @@ extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc*
|
||||
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);
|
||||
return zipOpen4(pathname, append, 0, globalcomment, &zlib_filefunc64_32_def_fill);
|
||||
}
|
||||
else
|
||||
return zipOpen3(pathname, append, globalcomment, NULL);
|
||||
return zipOpen4(pathname, append, 0, globalcomment, NULL);
|
||||
}
|
||||
|
||||
extern zipFile ZEXPORT zipOpen3 (const char *pathname, int append, ZPOS64_T disk_size, 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 zipOpen4(pathname, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill);
|
||||
}
|
||||
else
|
||||
return zipOpen4(pathname, append, disk_size, globalcomment, NULL);
|
||||
}
|
||||
|
||||
extern zipFile ZEXPORT zipOpen3_64 (const void *pathname, int append, ZPOS64_T disk_size, 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 zipOpen4(pathname, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill);
|
||||
}
|
||||
else
|
||||
return zipOpen4(pathname, append, disk_size, globalcomment, NULL);
|
||||
}
|
||||
|
||||
|
||||
extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
|
||||
{
|
||||
return zipOpen3((const void*)pathname,append,NULL,NULL);
|
||||
return zipOpen3((const void*)pathname,append,0,NULL,NULL);
|
||||
}
|
||||
|
||||
extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
|
||||
{
|
||||
return zipOpen3(pathname,append,NULL,NULL);
|
||||
return zipOpen3(pathname,append,0,NULL,NULL);
|
||||
}
|
||||
|
||||
int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
|
||||
@ -961,6 +1096,19 @@ int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_ex
|
||||
int err;
|
||||
uInt size_filename = (uInt)strlen(filename);
|
||||
uInt size_extrafield = size_extrafield_local;
|
||||
ZPOS64_T size_available;
|
||||
ZPOS64_T size_needed;
|
||||
|
||||
if (zi->disk_size > 0)
|
||||
{
|
||||
/* Make sure enough space available on current disk for local header */
|
||||
zipGetDiskSizeAvailable((zipFile)zi, &size_available);
|
||||
size_needed = 30 + size_filename + size_extrafield_local;
|
||||
if (zi->ci.zip64)
|
||||
size_needed += 20;
|
||||
if (size_available < size_needed)
|
||||
zipGoToNextDisk((zipFile)zi);
|
||||
}
|
||||
|
||||
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
|
||||
|
||||
@ -1022,7 +1170,7 @@ int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_ex
|
||||
err = ZIP_ERRNO;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((err==ZIP_OK) && (zi->ci.zip64))
|
||||
{
|
||||
// write the Zip64 extended info
|
||||
@ -1127,13 +1275,17 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
|
||||
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);
|
||||
|
||||
if ((zi->disk_size > 0) && (zi->number_disk == 0) && (zi->number_entry == 0))
|
||||
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)DISKHEADERMAGIC, 4);
|
||||
|
||||
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.number_disk = zi->number_disk;
|
||||
zi->ci.size_centralExtra = size_extrafield_global;
|
||||
zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
|
||||
/* version info */
|
||||
@ -1148,7 +1300,7 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
|
||||
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*/
|
||||
zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)zi->ci.number_disk,2); /*disk nm start*/
|
||||
|
||||
if (zipfi==NULL)
|
||||
zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
|
||||
@ -1182,7 +1334,7 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
|
||||
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
|
||||
@ -1238,7 +1390,7 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
|
||||
|
||||
}
|
||||
|
||||
# ifndef NOCRYPT
|
||||
#ifndef NOCRYPT
|
||||
zi->ci.crypt_header_size = 0;
|
||||
if ((err==Z_OK) && (password != NULL))
|
||||
{
|
||||
@ -1252,9 +1404,9 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
|
||||
zi->ci.crypt_header_size = sizeHead;
|
||||
|
||||
if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
|
||||
err = ZIP_ERRNO;
|
||||
err = ZIP_ERRNO;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (err==Z_OK)
|
||||
zi->in_opened_file_inzip = 1;
|
||||
@ -1362,6 +1514,11 @@ extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, cons
|
||||
local int zip64FlushWriteBuffer(zip64_internal* zi)
|
||||
{
|
||||
int err=ZIP_OK;
|
||||
uInt uBytesWritten = 0;
|
||||
uInt uTotalBytesWritten = 0;
|
||||
uInt uBytesToWrite = 0;
|
||||
uInt uMaxBytesToWrite = 0;
|
||||
ZPOS64_T size_available;
|
||||
|
||||
if (zi->ci.encrypt != 0)
|
||||
{
|
||||
@ -1373,9 +1530,43 @@ local int zip64FlushWriteBuffer(zip64_internal* zi)
|
||||
#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;
|
||||
uBytesToWrite = zi->ci.pos_in_buffered_data;
|
||||
|
||||
do
|
||||
{
|
||||
uMaxBytesToWrite = uBytesToWrite;
|
||||
|
||||
if (zi->disk_size > 0)
|
||||
{
|
||||
err = zipGetDiskSizeAvailable((zipFile)zi, &size_available);
|
||||
|
||||
if (err != ZIP_OK)
|
||||
return err;
|
||||
|
||||
if (size_available == 0)
|
||||
{
|
||||
err = zipGoToNextDisk((zipFile)zi);
|
||||
if (err != ZIP_OK)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (size_available < (ZPOS64_T)uMaxBytesToWrite)
|
||||
uMaxBytesToWrite = (uInt)size_available;
|
||||
}
|
||||
|
||||
uBytesWritten = ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data + uTotalBytesWritten,uMaxBytesToWrite);
|
||||
|
||||
if (ZERROR64(zi->z_filefunc,zi->filestream))
|
||||
{
|
||||
err = ZIP_ERRNO;
|
||||
break;
|
||||
}
|
||||
|
||||
uTotalBytesWritten += uBytesWritten;
|
||||
uBytesToWrite -= uBytesWritten;
|
||||
}
|
||||
while (uBytesToWrite > 0);
|
||||
|
||||
zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
|
||||
|
||||
#ifdef HAVE_BZIP2
|
||||
@ -1392,7 +1583,6 @@ local int zip64FlushWriteBuffer(zip64_internal* zi)
|
||||
zi->ci.stream.total_in = 0;
|
||||
}
|
||||
|
||||
|
||||
zi->ci.pos_in_buffered_data = 0;
|
||||
|
||||
return err;
|
||||
@ -1527,22 +1717,22 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s
|
||||
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) ;
|
||||
}
|
||||
}
|
||||
{
|
||||
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
|
||||
@ -1574,10 +1764,10 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s
|
||||
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))
|
||||
{
|
||||
@ -1703,6 +1893,10 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s
|
||||
// Update the LocalFileHeader with the new values.
|
||||
|
||||
ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
|
||||
uLong cur_number_disk = zi->number_disk;
|
||||
|
||||
|
||||
zipGoToSpecificDisk(file, zi->ci.number_disk, 1);
|
||||
|
||||
if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
err = ZIP_ERRNO;
|
||||
@ -1710,7 +1904,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s
|
||||
if (err==ZIP_OK)
|
||||
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
|
||||
|
||||
if(uncompressed_size >= 0xffffffff)
|
||||
if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff)
|
||||
{
|
||||
if(zi->ci.pos_zip64extrainfo > 0)
|
||||
{
|
||||
@ -1724,6 +1918,8 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s
|
||||
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
|
||||
{
|
||||
@ -1734,6 +1930,8 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s
|
||||
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
|
||||
}
|
||||
|
||||
zipGoToSpecificDisk(file, cur_number_disk, 1);
|
||||
|
||||
if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
err = ZIP_ERRNO;
|
||||
}
|
||||
@ -1758,15 +1956,15 @@ int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eo
|
||||
|
||||
/*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);
|
||||
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_disk_with_CD,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*/
|
||||
/*total 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)1,4);
|
||||
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_disk_with_CD+1,4);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -1789,10 +1987,10 @@ int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centra
|
||||
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);
|
||||
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_disk_with_CD,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);
|
||||
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_disk_with_CD,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);
|
||||
@ -1818,10 +2016,10 @@ int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir,
|
||||
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);
|
||||
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_disk_with_CD,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);
|
||||
err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_disk_with_CD,2);
|
||||
|
||||
if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
|
||||
{
|
||||
@ -1848,11 +2046,9 @@ int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir,
|
||||
{
|
||||
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);
|
||||
err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
|
||||
}
|
||||
|
||||
return err;
|
||||
@ -1898,6 +2094,16 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
|
||||
if (global_comment==NULL)
|
||||
global_comment = zi->globalcomment;
|
||||
#endif
|
||||
|
||||
if (zi->filestream != zi->filestream_with_CD)
|
||||
{
|
||||
if (ZCLOSE64(zi->z_filefunc, zi->filestream) != 0)
|
||||
if (err == ZIP_OK)
|
||||
err = ZIP_ERRNO;
|
||||
if (zi->disk_size > 0)
|
||||
zi->number_disk_with_CD = zi->number_disk + 1;
|
||||
zi->filestream = zi->filestream_with_CD;
|
||||
}
|
||||
|
||||
centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
|
||||
|
||||
@ -1919,7 +2125,7 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
|
||||
free_linkedlist(&(zi->central_dir));
|
||||
|
||||
pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
|
||||
if(pos >= 0xffffffff)
|
||||
if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
|
||||
{
|
||||
ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
|
||||
Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
|
||||
@ -1932,7 +2138,7 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
|
||||
|
||||
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;
|
||||
|
12
zip.h
12
zip.h
@ -144,6 +144,18 @@ extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
|
||||
zipcharpc* globalcomment,
|
||||
zlib_filefunc64_def* pzlib_filefunc_def));
|
||||
|
||||
extern zipFile ZEXPORT zipOpen3 OF((const char *pathname,
|
||||
int append,
|
||||
ZPOS64_T disk_size,
|
||||
zipcharpc* globalcomment,
|
||||
zlib_filefunc_def* pzlib_filefunc_def));
|
||||
|
||||
extern zipFile ZEXPORT zipOpen3_64 OF((const void *pathname,
|
||||
int append,
|
||||
ZPOS64_T disk_size,
|
||||
zipcharpc* globalcomment,
|
||||
zlib_filefunc64_def* pzlib_filefunc_def));
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
|
||||
const char* filename,
|
||||
const zip_fileinfo* zipfi,
|
||||
|
Loading…
x
Reference in New Issue
Block a user