mirror of
https://github.com/zlib-ng/minizip-ng
synced 2026-08-25 14:26:08 -04:00
Removed global_info structure and added accessors for global comment and number entries.
This commit is contained in:
parent
a66cc31fac
commit
6e21e868fa
8 changed files with 157 additions and 133 deletions
|
|
@ -20,7 +20,7 @@ cmake --build .
|
|||
|
||||
| File(s) | Description | Required |
|
||||
|:- |:-|:-:|
|
||||
| minizip.c | Sample application | No |
|
||||
| minizip.c | Sample application | No |
|
||||
| mz_compat.\* | Minizip 1.0 compatibility layer | No |
|
||||
| mz.h | Error codes and flags | Yes |
|
||||
| mz_os\* | OS specific helper functions | Encryption |
|
||||
|
|
@ -141,10 +141,6 @@ When unzipping it will automatically determine when in needs to cross disk bound
|
|||
When zipping with a password it will always use AES 256-bit encryption.
|
||||
When unzipping it will use AES decryption only if necessary.
|
||||
|
||||
#### Central Directory Encryption
|
||||
|
||||
This library does not support central directory or local file header encryption since it is not supported outside of PKZIP. For a more secure method it is best to just encrypt the zip post-process.
|
||||
|
||||
#### Disabling All Encryption
|
||||
|
||||
To disable encryption use the following cmake commands:
|
||||
|
|
@ -160,4 +156,5 @@ cmake . -DUSE_CRYPT=OFF
|
|||
|
||||
## Limitations
|
||||
|
||||
Archives are required to have a central directory with correct header values for unzipping.
|
||||
+ Archives are required to have a central directory with correct header values for unzipping.
|
||||
+ Central directory encryption is not supported due to licensing restrictions mentioned by PKWARE in their zip appnote.
|
||||
|
|
|
|||
|
|
@ -113,12 +113,13 @@ int32_t minizip_add_file(void *handle, const char *path, const char *password, m
|
|||
// Get information about the file on disk so we can store it in zip
|
||||
printf("Adding: %s\n", filenameinzip);
|
||||
|
||||
file_info.aes_version = options->aes;
|
||||
file_info.compression_method = options->compress_method;
|
||||
file_info.filename = filenameinzip;
|
||||
|
||||
if (mz_file_get_size(path) >= UINT32_MAX)
|
||||
file_info.zip_64 = 1;
|
||||
if (options->aes)
|
||||
file_info.aes_version = MZ_AES_VERSION;
|
||||
|
||||
mz_os_get_file_date(path, &file_info.dos_date);
|
||||
|
||||
|
|
@ -708,7 +709,7 @@ int main(int argc, char *argv[])
|
|||
for (i = path_arg + 1; (i < argc) && (err == MZ_OK); i += 1)
|
||||
err = minizip_add(handle, argv[i], password, &options, 1);
|
||||
|
||||
err_close = mz_zip_close(handle, NULL, MZ_VERSION_MADEBY);
|
||||
err_close = mz_zip_close(handle, MZ_VERSION_MADEBY);
|
||||
if (err_close != MZ_OK)
|
||||
{
|
||||
printf("Error in closing %s (%d)\n", path, err_close);
|
||||
|
|
|
|||
7
src/mz.h
7
src/mz.h
|
|
@ -39,6 +39,7 @@ extern "C" {
|
|||
#define MZ_COMPRESS_METHOD_DEFLATE (8)
|
||||
#define MZ_COMPRESS_METHOD_BZIP2 (12)
|
||||
#define MZ_COMPRESS_METHOD_LZMA (14)
|
||||
#define MZ_COMPRESS_METHOD_AES (99)
|
||||
|
||||
// MZ_COMPRESS_OPTIONS
|
||||
#define MZ_COMPRESS_LEVEL_DEFAULT (-1)
|
||||
|
|
@ -56,6 +57,12 @@ extern "C" {
|
|||
MZ_ZIP_FLAG_DEFLATE_MAX)
|
||||
#define MZ_ZIP_FLAG_DATA_DESCRIPTOR (1 << 3)
|
||||
|
||||
// MZ_AES
|
||||
#define MZ_AES_VERSION (1)
|
||||
#define MZ_AES_ENCRYPTION_MODE_128 (0x01)
|
||||
#define MZ_AES_ENCRYPTION_MODE_192 (0x02)
|
||||
#define MZ_AES_ENCRYPTION_MODE_256 (0x03)
|
||||
|
||||
// MZ_VERSION
|
||||
#define MZ_VERSION ("2.0.1")
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@ extern zipFile ZEXPORT zipOpen2_64(const void *path, int append, const char **gl
|
|||
zlib_filefunc64_def *pzlib_filefunc_def)
|
||||
{
|
||||
mz_compat *compat = NULL;
|
||||
mz_zip_global *global_info = NULL;
|
||||
int32_t mode = MZ_STREAM_MODE_READWRITE;
|
||||
int32_t open_existing = 0;
|
||||
int16_t err = MZ_OK;
|
||||
|
|
@ -89,10 +88,7 @@ extern zipFile ZEXPORT zipOpen2_64(const void *path, int append, const char **gl
|
|||
}
|
||||
|
||||
if (globalcomment != NULL)
|
||||
{
|
||||
mz_zip_get_global_info(handle, &global_info);
|
||||
*globalcomment = global_info->comment;
|
||||
}
|
||||
mz_zip_get_comment(handle, globalcomment);
|
||||
|
||||
compat = (mz_compat *)malloc(sizeof(mz_compat));
|
||||
compat->handle = handle;
|
||||
|
|
@ -131,7 +127,7 @@ extern int ZEXPORT zipOpenNewFileInZip5(zipFile file, const char *filename, cons
|
|||
file_info.flag = flag_base;
|
||||
file_info.zip_64 = zip64;
|
||||
#ifdef HAVE_AES
|
||||
file_info.aes_version = 1;
|
||||
file_info.aes_version = MZ_AES_VERSION;
|
||||
#endif
|
||||
|
||||
return mz_zip_entry_write_open(compat->handle, &file_info, level, password);
|
||||
|
|
@ -225,7 +221,10 @@ extern int ZEXPORT zipClose2_64(zipFile file, const char *global_comment, uint16
|
|||
if (compat == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
err = mz_zip_close(compat->handle, global_comment, version_madeby);
|
||||
if (global_comment != NULL)
|
||||
mz_zip_set_comment(compat->handle, global_comment);
|
||||
|
||||
err = mz_zip_close(compat->handle, version_madeby);
|
||||
|
||||
if (compat->stream != NULL)
|
||||
mz_stream_delete(&compat->stream);
|
||||
|
|
@ -293,7 +292,7 @@ extern int ZEXPORT unzClose(unzFile file)
|
|||
if (compat == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
err = mz_zip_close(compat->handle, NULL, 0);
|
||||
err = mz_zip_close(compat->handle, 0);
|
||||
|
||||
if (compat->stream != NULL)
|
||||
mz_stream_delete(&compat->stream);
|
||||
|
|
@ -325,32 +324,29 @@ extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info3
|
|||
extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64 *pglobal_info)
|
||||
{
|
||||
mz_compat *compat = (mz_compat *)file;
|
||||
mz_zip_global *global_info = NULL;
|
||||
const char *comment_ptr = NULL;
|
||||
int16_t err = MZ_OK;
|
||||
|
||||
if (compat == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
err = mz_zip_get_global_info(compat->handle, &global_info);
|
||||
err = mz_zip_get_comment(compat->handle, &comment_ptr);
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
pglobal_info->size_comment = global_info->comment_size;
|
||||
pglobal_info->number_entry = global_info->number_entry;
|
||||
pglobal_info->number_disk_with_CD = global_info->number_disk_with_cd;
|
||||
}
|
||||
pglobal_info->size_comment = (uint16_t)strlen(comment_ptr);
|
||||
mz_zip_get_number_entry(compat->handle, &pglobal_info->number_entry);
|
||||
return err;
|
||||
}
|
||||
|
||||
extern int ZEXPORT unzGetGlobalComment(unzFile file, char *comment, uint16_t comment_size)
|
||||
{
|
||||
mz_compat *compat = (mz_compat *)file;
|
||||
mz_zip_global *global_info = NULL;
|
||||
const char *comment_ptr = NULL;
|
||||
int16_t err = MZ_OK;
|
||||
|
||||
if (comment == NULL || comment_size == 0)
|
||||
return MZ_PARAM_ERROR;
|
||||
err = mz_zip_get_global_info(compat->handle, &global_info);
|
||||
err = mz_zip_get_comment(compat->handle, &comment_ptr);
|
||||
if (err == MZ_OK)
|
||||
strncpy(comment, global_info->comment, comment_size);
|
||||
strncpy(comment, comment_ptr, comment_size);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -537,6 +533,7 @@ extern int ZEXPORT unzLocateFile(unzFile file, const char *filename, unzFileName
|
|||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def)
|
||||
{
|
||||
if (pzlib_filefunc_def != NULL)
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ void *mz_stream_aes_create(void **stream)
|
|||
{
|
||||
memset(aes, 0, sizeof(mz_stream_aes));
|
||||
aes->stream.vtbl = &mz_stream_aes_vtbl;
|
||||
aes->encryption_mode = MZ_AES_ENCRYPTIONMODE;
|
||||
aes->encryption_mode = MZ_AES_ENCRYPTION_MODE_256;
|
||||
}
|
||||
if (stream != NULL)
|
||||
*stream = aes;
|
||||
|
|
@ -269,4 +269,9 @@ void mz_stream_aes_delete(void **stream)
|
|||
if (aes != NULL)
|
||||
free(aes);
|
||||
*stream = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void *mz_stream_aes_get_interface(void)
|
||||
{
|
||||
return (void *)&mz_stream_aes_vtbl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,12 +20,6 @@ extern "C" {
|
|||
|
||||
/***************************************************************************/
|
||||
|
||||
#define MZ_AES_METHOD (99)
|
||||
#define MZ_AES_VERSION (0x0001)
|
||||
#define MZ_AES_ENCRYPTIONMODE (0x03)
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_aes_open(void *stream, const char *filename, int32_t mode);
|
||||
int32_t mz_stream_aes_is_open(void *stream);
|
||||
int32_t mz_stream_aes_read(void *stream, void *buf, int32_t size);
|
||||
|
|
|
|||
154
src/mz_zip.c
154
src/mz_zip.c
|
|
@ -55,11 +55,13 @@
|
|||
#define MZ_ZIP_SIZE_CD_LOCATOR64 (0x14)
|
||||
#define MZ_ZIP_SIZE_LOCALHEADER (0x1e)
|
||||
|
||||
#define MZ_ZIP_EXTENSION_ZIP64 (0x0001)
|
||||
#define MZ_ZIP_EXTENSION_AES (0x9901)
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_zip_s
|
||||
{
|
||||
mz_zip_global global_info;
|
||||
mz_zip_file file_info;
|
||||
mz_zip_file local_file_info;
|
||||
|
||||
|
|
@ -83,6 +85,11 @@ typedef struct mz_zip_s
|
|||
uint16_t entry_opened; // 1 if a file in the zip is currently writ.
|
||||
uint64_t entry_read;
|
||||
|
||||
int64_t number_entry;
|
||||
uint32_t number_disk_with_cd;
|
||||
|
||||
char *comment;
|
||||
|
||||
#ifdef HAVE_AES
|
||||
uint16_t aes_version;
|
||||
uint8_t aes_encryption_mode;
|
||||
|
|
@ -202,6 +209,7 @@ static int mz_zip_read_cd(void *handle)
|
|||
uint16_t value16 = 0;
|
||||
uint32_t value32 = 0;
|
||||
uint64_t value64 = 0;
|
||||
uint16_t comment_size = 0;
|
||||
int16_t err = MZ_OK;
|
||||
|
||||
|
||||
|
|
@ -223,16 +231,16 @@ static int mz_zip_read_cd(void *handle)
|
|||
// Number of the disk with the start of the central directory
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_read_uint16(zip->stream, &value16);
|
||||
zip->global_info.number_disk_with_cd = value16;
|
||||
zip->number_disk_with_cd = value16;
|
||||
// Total number of entries in the central dir on this disk
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_read_uint16(zip->stream, &value16);
|
||||
zip->global_info.number_entry = value16;
|
||||
zip->number_entry = value16;
|
||||
// Total number of entries in the central dir
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_read_uint16(zip->stream, &value16);
|
||||
number_entry_cd = value16;
|
||||
if (number_entry_cd != zip->global_info.number_entry)
|
||||
if (number_entry_cd != zip->number_entry)
|
||||
err = MZ_FORMAT_ERROR;
|
||||
// Size of the central directory
|
||||
if (err == MZ_OK)
|
||||
|
|
@ -245,7 +253,7 @@ static int mz_zip_read_cd(void *handle)
|
|||
zip->cd_offset = value32;
|
||||
// Zip file global comment length
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_read_uint16(zip->stream, &zip->global_info.comment_size);
|
||||
err = mz_stream_read_uint16(zip->stream, &comment_size);
|
||||
|
||||
if ((err == MZ_OK) && ((number_entry_cd == UINT16_MAX) || (zip->cd_offset == UINT32_MAX)))
|
||||
{
|
||||
|
|
@ -272,7 +280,7 @@ static int mz_zip_read_cd(void *handle)
|
|||
err = mz_stream_read_uint32(zip->stream, &value32);
|
||||
// Number of the disk with the start of the central directory
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_read_uint32(zip->stream, &zip->global_info.number_disk_with_cd);
|
||||
err = mz_stream_read_uint32(zip->stream, &zip->number_disk_with_cd);
|
||||
// Total number of entries in the central directory on this disk
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_read_uint64(zip->stream, &number_entry);
|
||||
|
|
@ -280,7 +288,7 @@ static int mz_zip_read_cd(void *handle)
|
|||
if (err == MZ_OK)
|
||||
err = mz_stream_read_uint64(zip->stream, &number_entry_cd64);
|
||||
if (number_entry == UINT32_MAX)
|
||||
zip->global_info.number_entry = number_entry_cd64;
|
||||
zip->number_entry = number_entry_cd64;
|
||||
// Size of the central directory
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_read_uint64(zip->stream, &zip->cd_size);
|
||||
|
|
@ -288,8 +296,8 @@ static int mz_zip_read_cd(void *handle)
|
|||
if (err == MZ_OK)
|
||||
err = mz_stream_read_uint64(zip->stream, &zip->cd_offset);
|
||||
}
|
||||
else if ((zip->global_info.number_entry == UINT16_MAX) || (number_entry_cd != zip->global_info.number_entry) ||
|
||||
(zip->cd_size == UINT16_MAX) || (zip->cd_offset == UINT32_MAX))
|
||||
else if ((zip->number_entry == UINT16_MAX) || (number_entry_cd != zip->number_entry) ||
|
||||
(zip->cd_size == UINT16_MAX) || (zip->cd_offset == UINT32_MAX))
|
||||
{
|
||||
err = MZ_FORMAT_ERROR;
|
||||
}
|
||||
|
|
@ -302,16 +310,14 @@ static int mz_zip_read_cd(void *handle)
|
|||
err = MZ_FORMAT_ERROR;
|
||||
}
|
||||
|
||||
if ((err == MZ_OK) && (zip->global_info.comment_size > 0))
|
||||
if ((err == MZ_OK) && (comment_size > 0))
|
||||
{
|
||||
zip->global_info.comment = (char *)malloc(zip->global_info.comment_size + 1);
|
||||
if (zip->global_info.comment)
|
||||
zip->comment = (char *)malloc(comment_size + 1);
|
||||
if (zip->comment)
|
||||
{
|
||||
if (mz_stream_read(zip->stream, zip->global_info.comment,
|
||||
zip->global_info.comment_size) != zip->global_info.comment_size)
|
||||
if (mz_stream_read(zip->stream, zip->comment, comment_size) != comment_size)
|
||||
err = MZ_STREAM_ERROR;
|
||||
|
||||
zip->global_info.comment[zip->global_info.comment_size] = 0;
|
||||
zip->comment[comment_size] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -324,7 +330,7 @@ static int mz_zip_read_cd(void *handle)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int mz_zip_write_cd(void *handle, const char *global_comment, uint16_t version_madeby)
|
||||
static int mz_zip_write_cd(void *handle, uint16_t version_madeby)
|
||||
{
|
||||
mz_zip *zip = NULL;
|
||||
uint16_t comment_size = 0;
|
||||
|
|
@ -339,14 +345,11 @@ static int mz_zip_write_cd(void *handle, const char *global_comment, uint16_t ve
|
|||
zip = (mz_zip *)handle;
|
||||
if (zip == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (global_comment == NULL)
|
||||
global_comment = zip->global_info.comment;
|
||||
|
||||
if (mz_stream_get_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_NUMBER, &disk_number) == MZ_OK)
|
||||
zip->global_info.number_disk_with_cd = (uint32_t)disk_number;
|
||||
zip->number_disk_with_cd = (uint32_t)disk_number;
|
||||
if (mz_stream_get_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_SIZE, &disk_size) == MZ_OK && disk_size > 0)
|
||||
zip->global_info.number_disk_with_cd += 1;
|
||||
zip->number_disk_with_cd += 1;
|
||||
mz_stream_set_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_NUMBER, -1);
|
||||
|
||||
zip->cd_pos = mz_stream_tell(zip->stream);
|
||||
|
|
@ -360,7 +363,7 @@ static int mz_zip_write_cd(void *handle, const char *global_comment, uint16_t ve
|
|||
mz_stream_delete(&zip->cd_stream);
|
||||
|
||||
// Write the ZIP64 central directory header
|
||||
if (pos >= UINT32_MAX || zip->global_info.number_entry > UINT32_MAX)
|
||||
if (pos >= UINT32_MAX || zip->number_entry > UINT32_MAX)
|
||||
{
|
||||
zip64_eocd_pos_inzip = mz_stream_tell(zip->stream);
|
||||
|
||||
|
|
@ -377,16 +380,16 @@ static int mz_zip_write_cd(void *handle, const char *global_comment, uint16_t ve
|
|||
err = mz_stream_write_uint16(zip->stream, (uint16_t)45);
|
||||
// Number of this disk
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_write_uint32(zip->stream, zip->global_info.number_disk_with_cd);
|
||||
err = mz_stream_write_uint32(zip->stream, zip->number_disk_with_cd);
|
||||
// Number of the disk with the start of the central directory
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_write_uint32(zip->stream, zip->global_info.number_disk_with_cd);
|
||||
err = mz_stream_write_uint32(zip->stream, zip->number_disk_with_cd);
|
||||
// Total number of entries in the central dir on this disk
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_write_uint64(zip->stream, zip->global_info.number_entry);
|
||||
err = mz_stream_write_uint64(zip->stream, zip->number_entry);
|
||||
// Total number of entries in the central dir
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_write_uint64(zip->stream, zip->global_info.number_entry);
|
||||
err = mz_stream_write_uint64(zip->stream, zip->number_entry);
|
||||
// Size of the central directory
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_write_uint64(zip->stream, (uint64_t)zip->cd_size);
|
||||
|
|
@ -400,7 +403,7 @@ static int mz_zip_write_cd(void *handle, const char *global_comment, uint16_t ve
|
|||
err = mz_stream_write_uint32(zip->stream, MZ_ZIP_MAGIC_ENDLOCHEADER64);
|
||||
// Number of the disk with the start of the central directory
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_write_uint32(zip->stream, zip->global_info.number_disk_with_cd);
|
||||
err = mz_stream_write_uint32(zip->stream, zip->number_disk_with_cd);
|
||||
// Relative offset to the end of zip64 central directory
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
|
|
@ -409,7 +412,7 @@ static int mz_zip_write_cd(void *handle, const char *global_comment, uint16_t ve
|
|||
}
|
||||
// Number of the disk with the start of the central directory
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_write_uint32(zip->stream, zip->global_info.number_disk_with_cd);
|
||||
err = mz_stream_write_uint32(zip->stream, zip->number_disk_with_cd);
|
||||
}
|
||||
|
||||
// Write the central directory header
|
||||
|
|
@ -419,25 +422,25 @@ static int mz_zip_write_cd(void *handle, const char *global_comment, uint16_t ve
|
|||
err = mz_stream_write_uint32(zip->stream, MZ_ZIP_MAGIC_ENDHEADER);
|
||||
// Number of this disk
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_write_uint16(zip->stream, (uint16_t)zip->global_info.number_disk_with_cd);
|
||||
err = mz_stream_write_uint16(zip->stream, (uint16_t)zip->number_disk_with_cd);
|
||||
// Number of the disk with the start of the central directory
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_write_uint16(zip->stream, (uint16_t)zip->global_info.number_disk_with_cd);
|
||||
err = mz_stream_write_uint16(zip->stream, (uint16_t)zip->number_disk_with_cd);
|
||||
// Total number of entries in the central dir on this disk
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
if (zip->global_info.number_entry >= UINT16_MAX)
|
||||
if (zip->number_entry >= UINT16_MAX)
|
||||
err = mz_stream_write_uint16(zip->stream, UINT16_MAX);
|
||||
else
|
||||
err = mz_stream_write_uint16(zip->stream, (uint16_t)zip->global_info.number_entry);
|
||||
err = mz_stream_write_uint16(zip->stream, (uint16_t)zip->number_entry);
|
||||
}
|
||||
// Total number of entries in the central dir
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
if (zip->global_info.number_entry >= UINT16_MAX)
|
||||
if (zip->number_entry >= UINT16_MAX)
|
||||
err = mz_stream_write_uint16(zip->stream, UINT16_MAX);
|
||||
else
|
||||
err = mz_stream_write_uint16(zip->stream, (uint16_t)zip->global_info.number_entry);
|
||||
err = mz_stream_write_uint16(zip->stream, (uint16_t)zip->number_entry);
|
||||
}
|
||||
// Size of the central directory
|
||||
if (err == MZ_OK)
|
||||
|
|
@ -453,13 +456,13 @@ static int mz_zip_write_cd(void *handle, const char *global_comment, uint16_t ve
|
|||
}
|
||||
|
||||
// Write global comment
|
||||
if (global_comment != NULL)
|
||||
comment_size = (uint16_t)strlen(global_comment);
|
||||
if (zip->comment != NULL)
|
||||
comment_size = (uint16_t)strlen(zip->comment);
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_write_uint16(zip->stream, comment_size);
|
||||
if (err == MZ_OK)
|
||||
{
|
||||
if (mz_stream_write(zip->stream, global_comment, comment_size) != comment_size)
|
||||
if (mz_stream_write(zip->stream, zip->comment, comment_size) != comment_size)
|
||||
err = MZ_STREAM_ERROR;
|
||||
}
|
||||
return err;
|
||||
|
|
@ -520,8 +523,8 @@ extern void* ZEXPORT mz_zip_open(void *stream, int32_t mode)
|
|||
mz_stream_close(zip->cd_stream);
|
||||
mz_stream_delete(&zip->cd_stream);
|
||||
|
||||
if (zip->global_info.comment)
|
||||
free(zip->global_info.comment);
|
||||
if (zip->comment)
|
||||
free(zip->comment);
|
||||
|
||||
free(zip);
|
||||
return NULL;
|
||||
|
|
@ -530,10 +533,10 @@ extern void* ZEXPORT mz_zip_open(void *stream, int32_t mode)
|
|||
return zip;
|
||||
}
|
||||
|
||||
extern int ZEXPORT mz_zip_close(void *handle, const char *global_comment, uint16_t version_madeby)
|
||||
extern int ZEXPORT mz_zip_close(void *handle, uint32_t flags)
|
||||
{
|
||||
mz_zip *zip = NULL;
|
||||
|
||||
int16_t version_madeby = 0;
|
||||
int16_t err = MZ_OK;
|
||||
|
||||
if (handle == NULL)
|
||||
|
|
@ -548,26 +551,46 @@ extern int ZEXPORT mz_zip_close(void *handle, const char *global_comment, uint16
|
|||
}
|
||||
|
||||
if (zip->open_mode & MZ_STREAM_MODE_WRITE)
|
||||
err = mz_zip_write_cd(handle, global_comment, version_madeby);
|
||||
{
|
||||
version_madeby = (flags & 0xffff);
|
||||
err = mz_zip_write_cd(handle, version_madeby);
|
||||
}
|
||||
|
||||
mz_stream_mem_close(zip->file_info_stream);
|
||||
mz_stream_mem_delete(&zip->file_info_stream);
|
||||
|
||||
if (zip->global_info.comment)
|
||||
free(zip->global_info.comment);
|
||||
if (zip->comment)
|
||||
free(zip->comment);
|
||||
|
||||
free(zip);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
extern int ZEXPORT mz_zip_get_global_info(void *handle, mz_zip_global **global_info)
|
||||
extern int ZEXPORT mz_zip_get_comment(void *handle, const char **comment)
|
||||
{
|
||||
mz_zip *zip = NULL;
|
||||
if (handle == NULL || global_info == NULL)
|
||||
if (handle == NULL || comment == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
zip = (mz_zip *)handle;
|
||||
*global_info = &zip->global_info;
|
||||
if (zip->comment == NULL)
|
||||
return MZ_EXIST_ERROR;
|
||||
*comment = zip->comment;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
extern int ZEXPORT mz_zip_set_comment(void *handle, const char *comment)
|
||||
{
|
||||
mz_zip *zip = NULL;
|
||||
uint16_t comment_size = 0;
|
||||
if (handle == NULL || comment == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
zip = (mz_zip *)handle;
|
||||
if (zip->comment != NULL)
|
||||
free(zip->comment);
|
||||
comment_size = (uint16_t)(strlen(comment) + 1);
|
||||
zip->comment = (char *)malloc(comment_size);
|
||||
strncpy(zip->comment, comment, comment_size);
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
|
|
@ -700,7 +723,7 @@ static int mz_zip_entry_read_header(void *stream, uint8_t local, mz_zip_file *fi
|
|||
err = mz_stream_read_uint16(file_info_stream, &extra_data_size);
|
||||
|
||||
// ZIP64 extra field
|
||||
if (extra_header_id == 0x0001)
|
||||
if (extra_header_id == MZ_ZIP_EXTENSION_ZIP64)
|
||||
{
|
||||
if ((err == MZ_OK) && (file_info->uncompressed_size == UINT32_MAX))
|
||||
err = mz_stream_read_uint64(file_info_stream, &file_info->uncompressed_size);
|
||||
|
|
@ -714,7 +737,7 @@ static int mz_zip_entry_read_header(void *stream, uint8_t local, mz_zip_file *fi
|
|||
}
|
||||
#ifdef HAVE_AES
|
||||
// AES extra field
|
||||
else if (extra_header_id == 0x9901)
|
||||
else if (extra_header_id == MZ_ZIP_EXTENSION_AES)
|
||||
{
|
||||
uint8_t value8 = 0;
|
||||
// Verify version info
|
||||
|
|
@ -810,8 +833,8 @@ static int mz_zip_entry_write_header(void *stream, uint8_t local, mz_zip_file *f
|
|||
if (err == MZ_OK)
|
||||
{
|
||||
#ifdef HAVE_AES
|
||||
if (file_info->aes_version > 0)
|
||||
err = mz_stream_write_uint16(stream, MZ_AES_METHOD);
|
||||
if (file_info->aes_version)
|
||||
err = mz_stream_write_uint16(stream, MZ_COMPRESS_METHOD_AES);
|
||||
else
|
||||
#endif
|
||||
err = mz_stream_write_uint16(stream, file_info->compression_method);
|
||||
|
|
@ -876,7 +899,7 @@ static int mz_zip_entry_write_header(void *stream, uint8_t local, mz_zip_file *f
|
|||
// Add ZIP64 extra info header to central directory
|
||||
if ((err == MZ_OK) && (file_info->zip_64))
|
||||
{
|
||||
err = mz_stream_write_uint16(stream, 0x0001);
|
||||
err = mz_stream_write_uint16(stream, MZ_ZIP_EXTENSION_ZIP64);
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_write_uint16(stream, extrafield_zip64_size);
|
||||
if ((err == MZ_OK) && (file_info->uncompressed_size >= UINT32_MAX))
|
||||
|
|
@ -891,7 +914,7 @@ static int mz_zip_entry_write_header(void *stream, uint8_t local, mz_zip_file *f
|
|||
// Write AES extra info header to central directory
|
||||
if ((err == MZ_OK) && (file_info->flag & MZ_ZIP_FLAG_ENCRYPTED) && (file_info->aes_version))
|
||||
{
|
||||
err = mz_stream_write_uint16(stream, 0x9901);
|
||||
err = mz_stream_write_uint16(stream, MZ_ZIP_EXTENSION_AES);
|
||||
if (err == MZ_OK)
|
||||
err = mz_stream_write_uint16(stream, 7);
|
||||
if (err == MZ_OK)
|
||||
|
|
@ -1072,7 +1095,7 @@ extern int ZEXPORT mz_zip_entry_read_open(void *handle, int raw, const char *pas
|
|||
if ((zip->file_info.flag & MZ_ZIP_FLAG_ENCRYPTED) && (password == NULL))
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
if (zip->file_info.disk_num_start == zip->global_info.number_disk_with_cd)
|
||||
if (zip->file_info.disk_num_start == zip->number_disk_with_cd)
|
||||
mz_stream_set_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_NUMBER, -1);
|
||||
else
|
||||
mz_stream_set_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_NUMBER, zip->file_info.disk_num_start);
|
||||
|
|
@ -1138,13 +1161,6 @@ extern int ZEXPORT mz_zip_entry_write_open(void *handle, const mz_zip_file *file
|
|||
zip->file_info.crc = 0;
|
||||
zip->file_info.compressed_size = 0;
|
||||
zip->file_info.uncompressed_size = 0;
|
||||
#ifdef HAVE_AES
|
||||
if (file_info->aes_version)
|
||||
{
|
||||
zip->file_info.aes_version = MZ_AES_VERSION;
|
||||
zip->file_info.aes_encryption_mode = MZ_AES_ENCRYPTIONMODE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (err == MZ_OK)
|
||||
err = mz_zip_entry_write_header(zip->stream, 1, &zip->file_info);
|
||||
|
|
@ -1275,7 +1291,7 @@ extern int ZEXPORT mz_zip_entry_close_raw(void *handle, uint64_t uncompressed_si
|
|||
if (err == MZ_OK)
|
||||
err = mz_zip_entry_write_header(zip->cd_stream, 0, &zip->file_info);
|
||||
|
||||
zip->global_info.number_entry += 1;
|
||||
zip->number_entry += 1;
|
||||
}
|
||||
|
||||
zip->entry_opened = 0;
|
||||
|
|
@ -1337,6 +1353,18 @@ static int mz_zip_goto_next_entry_int(void *handle)
|
|||
return err;
|
||||
}
|
||||
|
||||
extern int ZEXPORT mz_zip_get_number_entry(void *handle, int64_t *number_entry)
|
||||
{
|
||||
mz_zip *zip = NULL;
|
||||
|
||||
if (handle == NULL || number_entry == NULL)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
zip = (mz_zip *)handle;
|
||||
*number_entry = zip->number_entry;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
extern int ZEXPORT mz_zip_goto_first_entry(void *handle)
|
||||
{
|
||||
mz_zip *zip = NULL;
|
||||
|
|
|
|||
67
src/mz_zip.h
67
src/mz_zip.h
|
|
@ -29,14 +29,6 @@ extern "C" {
|
|||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_zip_global_s
|
||||
{
|
||||
uint64_t number_entry; // total number of entries in the central dir on this disk
|
||||
uint32_t number_disk_with_cd; // number the the disk with central dir, used for spanning ZIP
|
||||
uint16_t comment_size; // size of the global comment of the zip file
|
||||
uint8_t *comment;
|
||||
} mz_zip_global;
|
||||
|
||||
typedef struct mz_zip_file_s
|
||||
{
|
||||
uint16_t version_madeby; // version made by 2 bytes
|
||||
|
|
@ -64,8 +56,8 @@ typedef struct mz_zip_file_s
|
|||
uint8_t zip_64; // zip 64 extensions if 1
|
||||
|
||||
#ifdef HAVE_AES
|
||||
uint16_t aes_version;
|
||||
uint8_t aes_encryption_mode;
|
||||
uint16_t aes_version; // winzip aes extension if not 0
|
||||
uint8_t aes_encryption_mode; // winzip aes encryption mode
|
||||
#endif
|
||||
} mz_zip_file;
|
||||
|
||||
|
|
@ -74,25 +66,31 @@ typedef struct mz_zip_file_s
|
|||
extern void* ZEXPORT mz_zip_open(void *stream, int32_t mode);
|
||||
// Create a zip file
|
||||
//
|
||||
// NOTE: There is no delete function into a zip file. If you want delete file in a zip file,
|
||||
// you must open a zip file, and create another. You can use RAW reading and writing to copy
|
||||
// the file you did not want delete.
|
||||
// NOTE: There is no delete function into a zip file. If you want delete file in a
|
||||
// zip file, you must open a zip file, and create another. You can use RAW reading
|
||||
// and writing to copy the file you did not want delete.
|
||||
|
||||
extern int ZEXPORT mz_zip_get_global_info(void *handle, mz_zip_global **global_info);
|
||||
// Gets the global zip file info
|
||||
extern int ZEXPORT mz_zip_close(void *handle, uint32_t flags);
|
||||
// Close the zip file
|
||||
|
||||
extern int ZEXPORT mz_zip_get_comment(void *handle, const char **comment);
|
||||
// Gets a pointer to the global comment
|
||||
|
||||
extern int ZEXPORT mz_zip_set_comment(void *handle, const char *comment);
|
||||
// Sets the global comment used for writing zip file
|
||||
|
||||
extern int ZEXPORT mz_zip_entry_write_open(void *handle, const mz_zip_file *file_info,
|
||||
int16_t compress_level, const char *password);
|
||||
// Open a file in the zip for writing
|
||||
// Open for writing the current file in the zip file
|
||||
|
||||
extern int ZEXPORT mz_zip_entry_write(void *handle, const void *buf, uint32_t len);
|
||||
// Write data in the zip file
|
||||
// Write bytes from the current file in the zip file
|
||||
|
||||
extern int ZEXPORT mz_zip_entry_read_open(void *handle, int raw, const char *password);
|
||||
// Open for reading data the current file in the zip file
|
||||
// Open for reading the current file in the zip file
|
||||
|
||||
extern int ZEXPORT mz_zip_entry_read(void *handle, void *buf, uint32_t len);
|
||||
// Read bytes from the current file
|
||||
// Read bytes from the current file in the zip file
|
||||
|
||||
extern int ZEXPORT mz_zip_entry_close(void *handle);
|
||||
// Close the current file in the zip file
|
||||
|
|
@ -100,33 +98,20 @@ extern int ZEXPORT mz_zip_entry_close(void *handle);
|
|||
extern int ZEXPORT mz_zip_entry_get_info(void *handle, mz_zip_file **file_info);
|
||||
// Get info about the current file
|
||||
//
|
||||
// NOTE: The file info is only valid while the current entry is open
|
||||
// NOTE: The file info is only valid while the current entry is open.
|
||||
|
||||
extern int ZEXPORT mz_zip_entry_get_local_info(void *handle, mz_zip_file **local_file_info);
|
||||
// Get local info about the current file
|
||||
//
|
||||
// NOTE: The local file info is only valid while the current entry is being read
|
||||
// NOTE: The local file info is only valid while the current entry is being read.
|
||||
|
||||
extern int ZEXPORT mz_zip_entry_close_raw(void *handle, uint64_t uncompressed_size, uint32_t crc32);
|
||||
// Close the current file in the zip file where raw is compressed data
|
||||
|
||||
extern int ZEXPORT mz_zip_close(void *handle, const char *global_comment, uint16_t version_madeby);
|
||||
// Close the zip file
|
||||
//
|
||||
// NOTE: global_comment and version_madeby are only used when the zip file is open for writing
|
||||
|
||||
/***************************************************************************/
|
||||
// Navigate the directory of the zip file
|
||||
|
||||
typedef int(*mz_filename_compare_cb)(void *handle, const char *filename1, const char *filename2);
|
||||
|
||||
extern int ZEXPORT mz_zip_locate_entry(void *file, const char *filename, mz_filename_compare_cb filename_compare_cb);
|
||||
// Locate the file with the specified name in the zip file
|
||||
//
|
||||
// if filename_compare_cb == NULL, it uses strcmp
|
||||
//
|
||||
// return MZ_OK if the file is found (it becomes the current file)
|
||||
// return MZ_END_OF_LIST if the file is not found
|
||||
extern int ZEXPORT mz_zip_get_number_entry(void *handle, int64_t *number_entry);
|
||||
// Get the total number of entries
|
||||
|
||||
extern int ZEXPORT mz_zip_goto_first_entry(void *handle);
|
||||
// Go to the first entry in the zip file
|
||||
|
|
@ -134,6 +119,16 @@ extern int ZEXPORT mz_zip_goto_first_entry(void *handle);
|
|||
extern int ZEXPORT mz_zip_goto_next_entry(void *handle);
|
||||
// Go to the next entry in the zip file or MZ_END_OF_LIST if reaching the end
|
||||
|
||||
typedef int (*mz_filename_compare_cb)(void *handle, const char *filename1, const char *filename2);
|
||||
|
||||
extern int ZEXPORT mz_zip_locate_entry(void *handle, const char *filename, mz_filename_compare_cb filename_compare_cb);
|
||||
// Locate the file with the specified name in the zip file
|
||||
//
|
||||
// NOTE: if filename_compare_cb == NULL, it uses strcmp
|
||||
//
|
||||
// return MZ_OK if the file is found (it becomes the current file)
|
||||
// return MZ_END_OF_LIST if the file is not found
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue