Removed global_info structure and added accessors for global comment and number entries.

This commit is contained in:
Nathan Moinvaziri 2017-10-19 09:57:54 -07:00
parent a66cc31fac
commit 6e21e868fa
8 changed files with 157 additions and 133 deletions

View file

@ -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.

View file

@ -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);

View file

@ -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")

View file

@ -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)

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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