mirror of
https://github.com/zlib-ng/minizip-ng
synced 2025-03-28 21:13:18 +00:00
Get rid of shared file moved all the code to mzstrm.
Converted miniunz to use new library changes.
This commit is contained in:
parent
4138ca5144
commit
5ef60a2b39
242
minishared.c
242
minishared.c
@ -1,242 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "zlib.h"
|
||||
#include "mzstrm.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <utime.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include "minishared.h"
|
||||
|
||||
uint32_t get_file_date(const char *path, uint32_t *dos_date)
|
||||
{
|
||||
int ret = 0;
|
||||
#ifdef _WIN32
|
||||
FILETIME ftm_local;
|
||||
HANDLE find = NULL;
|
||||
WIN32_FIND_DATAA ff32;
|
||||
|
||||
find = FindFirstFileA(path, &ff32);
|
||||
if (find != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
FileTimeToLocalFileTime(&(ff32.ftLastWriteTime), &ftm_local);
|
||||
FileTimeToDosDateTime(&ftm_local, ((LPWORD)dos_date) + 1, ((LPWORD)dos_date) + 0);
|
||||
FindClose(find);
|
||||
ret = 1;
|
||||
}
|
||||
#else
|
||||
struct stat s;
|
||||
struct tm *filedate = NULL;
|
||||
time_t tm_t = 0;
|
||||
|
||||
memset(&s, 0, sizeof(s));
|
||||
|
||||
if (strcmp(path, "-") != 0)
|
||||
{
|
||||
size_t len = strlen(path);
|
||||
char *name = (char *)malloc(len + 1);
|
||||
strncpy(name, path, len + 1);
|
||||
name[len] = 0;
|
||||
if (name[len - 1] == '/')
|
||||
name[len - 1] = 0;
|
||||
|
||||
/* Not all systems allow stat'ing a file with / appended */
|
||||
if (stat(name, &s) == 0)
|
||||
{
|
||||
tm_t = s.st_mtime;
|
||||
ret = 1;
|
||||
}
|
||||
free(name);
|
||||
}
|
||||
|
||||
filedate = localtime(&tm_t);
|
||||
*dos_date = tm_to_dosdate(filedate);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
void change_file_date(const char *path, uint32_t dos_date)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE handle = NULL;
|
||||
FILETIME ftm, ftm_local, ftm_create, ftm_access, ftm_modified;
|
||||
|
||||
handle = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
GetFileTime(handle, &ftm_create, &ftm_access, &ftm_modified);
|
||||
DosDateTimeToFileTime((WORD)(dos_date >> 16), (WORD)dos_date, &ftm_local);
|
||||
LocalFileTimeToFileTime(&ftm_local, &ftm);
|
||||
SetFileTime(handle, &ftm, &ftm_access, &ftm);
|
||||
CloseHandle(handle);
|
||||
}
|
||||
#else
|
||||
struct utimbuf ut;
|
||||
ut.actime = ut.modtime = dosdate_to_time_t(dos_date);
|
||||
utime(path, &ut);
|
||||
#endif
|
||||
}
|
||||
|
||||
int invalid_date(const struct tm *ptm)
|
||||
{
|
||||
#define datevalue_in_range(min, max, value) ((min) <= (value) && (value) <= (max))
|
||||
return (!datevalue_in_range(0, 207, ptm->tm_year) ||
|
||||
!datevalue_in_range(0, 11, ptm->tm_mon) ||
|
||||
!datevalue_in_range(1, 31, ptm->tm_mday) ||
|
||||
!datevalue_in_range(0, 23, ptm->tm_hour) ||
|
||||
!datevalue_in_range(0, 59, ptm->tm_min) ||
|
||||
!datevalue_in_range(0, 59, ptm->tm_sec));
|
||||
#undef datevalue_in_range
|
||||
}
|
||||
|
||||
// Conversion without validation
|
||||
void dosdate_to_raw_tm(uint64_t dos_date, struct tm *ptm)
|
||||
{
|
||||
uint64_t date = (uint64_t)(dos_date >> 16);
|
||||
|
||||
ptm->tm_mday = (uint16_t)(date & 0x1f);
|
||||
ptm->tm_mon = (uint16_t)(((date & 0x1E0) / 0x20) - 1);
|
||||
ptm->tm_year = (uint16_t)(((date & 0x0FE00) / 0x0200) + 80);
|
||||
ptm->tm_hour = (uint16_t)((dos_date & 0xF800) / 0x800);
|
||||
ptm->tm_min = (uint16_t)((dos_date & 0x7E0) / 0x20);
|
||||
ptm->tm_sec = (uint16_t)(2 * (dos_date & 0x1f));
|
||||
ptm->tm_isdst = -1;
|
||||
}
|
||||
|
||||
int dosdate_to_tm(uint64_t dos_date, struct tm *ptm)
|
||||
{
|
||||
dosdate_to_raw_tm(dos_date, ptm);
|
||||
|
||||
if (invalid_date(ptm))
|
||||
{
|
||||
// Invalid date stored, so don't return it.
|
||||
memset(ptm, 0, sizeof(struct tm));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
time_t dosdate_to_time_t(uint64_t dos_date)
|
||||
{
|
||||
struct tm ptm;
|
||||
dosdate_to_raw_tm(dos_date, &ptm);
|
||||
return mktime(&ptm);
|
||||
}
|
||||
|
||||
uint32_t tm_to_dosdate(const struct tm *ptm)
|
||||
{
|
||||
struct tm fixed_tm = { 0 };
|
||||
|
||||
/* Years supported:
|
||||
* [00, 79] (assumed to be between 2000 and 2079)
|
||||
* [80, 207] (assumed to be between 1980 and 2107, typical output of old
|
||||
software that does 'year-1900' to get a double digit year)
|
||||
* [1980, 2107] (due to the date format limitations, only years between 1980 and 2107 can be stored.)
|
||||
*/
|
||||
|
||||
memcpy(&fixed_tm, ptm, sizeof(struct tm));
|
||||
if (fixed_tm.tm_year >= 1980) /* range [1980, 2107] */
|
||||
fixed_tm.tm_year -= 1980;
|
||||
else if (fixed_tm.tm_year >= 80) /* range [80, 99] */
|
||||
fixed_tm.tm_year -= 80;
|
||||
else /* range [00, 79] */
|
||||
fixed_tm.tm_year += 20;
|
||||
|
||||
if (invalid_date(ptm))
|
||||
return 0;
|
||||
|
||||
return (uint32_t)(((fixed_tm.tm_mday) + (32 * (fixed_tm.tm_mon + 1)) + (512 * fixed_tm.tm_year)) << 16) |
|
||||
((fixed_tm.tm_sec / 2) + (32 * fixed_tm.tm_min) + (2048 * (uint32_t)fixed_tm.tm_hour));
|
||||
}
|
||||
|
||||
int makedir(const char *newdir)
|
||||
{
|
||||
char *buffer = NULL;
|
||||
char *p = NULL;
|
||||
int len = (int)strlen(newdir);
|
||||
|
||||
if (len <= 0)
|
||||
return 0;
|
||||
|
||||
buffer = (char*)malloc(len + 1);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
printf("Error allocating memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(buffer, newdir);
|
||||
|
||||
if (buffer[len - 1] == '/')
|
||||
buffer[len - 1] = 0;
|
||||
|
||||
if (MKDIR(buffer) == 0)
|
||||
{
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
p = buffer + 1;
|
||||
while (1)
|
||||
{
|
||||
char hold;
|
||||
while (*p && *p != '\\' && *p != '/')
|
||||
p++;
|
||||
hold = *p;
|
||||
*p = 0;
|
||||
|
||||
if ((MKDIR(buffer) == -1) && (errno == ENOENT))
|
||||
{
|
||||
printf("couldn't create directory %s (%d)\n", buffer, errno);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hold == 0)
|
||||
break;
|
||||
|
||||
*p++ = hold;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void display_zpos64(uint64_t n, int size_char)
|
||||
{
|
||||
/* To avoid compatibility problem we do here the conversion */
|
||||
char number[21] = { 0 };
|
||||
int offset = 19;
|
||||
int pos_string = 19;
|
||||
int size_display_string = 19;
|
||||
|
||||
while (1)
|
||||
{
|
||||
number[offset] = (char)((n % 10) + '0');
|
||||
if (number[offset] != '0')
|
||||
pos_string = offset;
|
||||
n /= 10;
|
||||
if (offset == 0)
|
||||
break;
|
||||
offset--;
|
||||
}
|
||||
|
||||
size_display_string -= pos_string;
|
||||
while (size_char-- > size_display_string)
|
||||
printf(" ");
|
||||
printf("%s", &number[pos_string]);
|
||||
}
|
45
minishared.h
45
minishared.h
@ -1,45 +0,0 @@
|
||||
#ifndef _MINISHARED_H
|
||||
#define _MINISHARED_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# define MKDIR(d) _mkdir(d)
|
||||
# define CHDIR(d) _chdir(d)
|
||||
#else
|
||||
# define MKDIR(d) mkdir(d, 0775)
|
||||
# define CHDIR(d) chdir(d)
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/* Get a file's date and time in dos format */
|
||||
uint32_t get_file_date(const char *path, uint32_t *dos_date);
|
||||
|
||||
/* Sets a file's date and time in dos format */
|
||||
void change_file_date(const char *path, uint32_t dos_date);
|
||||
|
||||
/* Convert dos date/time format to struct tm */
|
||||
int dosdate_to_tm(uint64_t dos_date, struct tm *ptm);
|
||||
|
||||
/* Convert dos date/time format to time_t */
|
||||
time_t dosdate_to_time_t(uint64_t dos_date);
|
||||
|
||||
/* Convert struct tm to dos date/time format */
|
||||
uint32_t tm_to_dosdate(const struct tm *ptm);
|
||||
|
||||
/* Create a directory and all subdirectories */
|
||||
int makedir(const char *newdir);
|
||||
|
||||
/* Print a 64-bit number for compatibility */
|
||||
void display_zpos64(uint64_t n, int size_char);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
335
miniunz.c
335
miniunz.c
@ -1,5 +1,5 @@
|
||||
/* miniunz.c
|
||||
Version 1.2.0, September 16th, 2017
|
||||
Version 1.3.0, September 16th, 2017
|
||||
sample part of the MiniZip project
|
||||
|
||||
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||
@ -21,27 +21,16 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <sys/stat.h>
|
||||
# include <unistd.h>
|
||||
# include <utime.h>
|
||||
#endif
|
||||
#include "mzstrm.h"
|
||||
|
||||
#include "unzip.h"
|
||||
|
||||
#include "mz_compat.h"
|
||||
#include "mzstrm.h"
|
||||
|
||||
#include "minishared.h"
|
||||
/***************************************************************************/
|
||||
|
||||
void miniunz_banner()
|
||||
{
|
||||
printf("MiniUnz 1.2.0, demo of zLib + Unz package\n");
|
||||
printf("MiniUnz 1.3.0, demo of zLib + Unz package\n");
|
||||
printf("more info at https://github.com/nmoinvaz/minizip\n\n");
|
||||
}
|
||||
|
||||
@ -57,13 +46,25 @@ void miniunz_help()
|
||||
" -p extract crypted file using password\n\n");
|
||||
}
|
||||
|
||||
int miniunz_list(unzFile uf)
|
||||
/***************************************************************************/
|
||||
|
||||
int miniunz_list(void *handle)
|
||||
{
|
||||
int err = unzGoToFirstFile(uf);
|
||||
if (err != UNZ_OK)
|
||||
mz_unzip_file *file_info = NULL;
|
||||
uint32_t ratio = 0;
|
||||
int16_t level = 0;
|
||||
int16_t err = MZ_OK;
|
||||
struct tm tmu_date = { 0 };
|
||||
const char *string_method = NULL;
|
||||
char crypt = ' ';
|
||||
|
||||
|
||||
err = mz_unzip_goto_first_entry(handle);
|
||||
|
||||
if (err != MZ_OK)
|
||||
{
|
||||
printf("error %d with zipfile in unzGoToFirstFile\n", err);
|
||||
return 1;
|
||||
printf("Error %d with zip file @ mz_unzip_goto_first_entry\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
|
||||
@ -71,130 +72,126 @@ int miniunz_list(unzFile uf)
|
||||
|
||||
do
|
||||
{
|
||||
char filename_inzip[256] = {0};
|
||||
unz_file_info64 file_info = {0};
|
||||
uint32_t ratio = 0;
|
||||
struct tm tmu_date = { 0 };
|
||||
const char *string_method = NULL;
|
||||
char char_crypt = ' ';
|
||||
|
||||
err = unzGetCurrentFileInfo64(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
|
||||
if (err != UNZ_OK)
|
||||
err = mz_unzip_entry_get_info(handle, &file_info);
|
||||
if (err != MZ_OK)
|
||||
{
|
||||
printf("error %d with zipfile in unzGetCurrentFileInfo\n", err);
|
||||
printf("Error %d with zip file @ mz_unzip_entry_get_info\n", err);
|
||||
break;
|
||||
}
|
||||
|
||||
if (file_info.uncompressed_size > 0)
|
||||
ratio = (uint32_t)((file_info.compressed_size * 100) / file_info.uncompressed_size);
|
||||
if (file_info->uncompressed_size > 0)
|
||||
ratio = (uint32_t)((file_info->compressed_size * 100) / file_info->uncompressed_size);
|
||||
|
||||
/* Display a '*' if the file is encrypted */
|
||||
if ((file_info.flag & 1) != 0)
|
||||
char_crypt = '*';
|
||||
// Display a '*' if the file is encrypted
|
||||
if ((file_info->flag & 1) != 0)
|
||||
crypt = '*';
|
||||
|
||||
if (file_info.compression_method == 0)
|
||||
string_method = "Stored";
|
||||
else if (file_info.compression_method == Z_DEFLATED)
|
||||
if (file_info->compression_method == 0)
|
||||
{
|
||||
uint16_t level = (uint16_t)((file_info.flag & 0x6) / 2);
|
||||
string_method = "Stored";
|
||||
}
|
||||
else if (file_info->compression_method == Z_DEFLATED)
|
||||
{
|
||||
level = (int16_t)((file_info->flag & 0x6) / 2);
|
||||
if (level == 0)
|
||||
string_method = "Defl:N";
|
||||
else if (level == 1)
|
||||
string_method = "Defl:X";
|
||||
else if ((level == 2) || (level == 3))
|
||||
string_method = "Defl:F"; /* 2:fast , 3 : extra fast*/
|
||||
string_method = "Defl:F"; // 2:fast , 3 : extra fast
|
||||
else
|
||||
string_method = "Unkn. ";
|
||||
}
|
||||
else if (file_info.compression_method == Z_BZIP2ED)
|
||||
else if (file_info->compression_method == Z_BZIP2ED)
|
||||
{
|
||||
string_method = "BZip2 ";
|
||||
}
|
||||
else
|
||||
{
|
||||
string_method = "Unkn. ";
|
||||
}
|
||||
|
||||
display_zpos64(file_info.uncompressed_size, 7);
|
||||
printf(" %6s%c", string_method, char_crypt);
|
||||
display_zpos64(file_info.compressed_size, 7);
|
||||
mz_dosdate_to_tm(file_info->dos_date, &tmu_date);
|
||||
|
||||
dosdate_to_tm(file_info.dos_date, &tmu_date);
|
||||
printf(" %3u%% %2.2u-%2.2u-%2.2u %2.2u:%2.2u %8.8x %s\n", ratio,
|
||||
printf(" %7llu %6s%c %7llu %3u%% %2.2u-%2.2u-%2.2u %2.2u:%2.2u %8.8x %s\n",
|
||||
file_info->uncompressed_size, string_method, crypt, file_info->compressed_size, ratio,
|
||||
(uint32_t)tmu_date.tm_mon + 1, (uint32_t)tmu_date.tm_mday,
|
||||
(uint32_t)tmu_date.tm_year % 100,
|
||||
(uint32_t)tmu_date.tm_hour, (uint32_t)tmu_date.tm_min,
|
||||
file_info.crc, filename_inzip);
|
||||
file_info->crc, file_info->filename);
|
||||
|
||||
err = unzGoToNextFile(uf);
|
||||
err = mz_unzip_goto_next_entry(handle);
|
||||
}
|
||||
while (err == UNZ_OK);
|
||||
while (err == MZ_OK);
|
||||
|
||||
if (err != UNZ_END_OF_LIST_OF_FILE && err != UNZ_OK)
|
||||
if (err != MZ_END_OF_LIST && err != MZ_OK)
|
||||
{
|
||||
printf("error %d with zipfile in unzGoToNextFile\n", err);
|
||||
printf("Error %d with zip file @ mz_unzip_goto_next_entry\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
int miniunz_extract_currentfile(unzFile uf, int opt_extract_without_path, int *popt_overwrite, const char *password)
|
||||
int miniunz_extract_currentfile(void *handle, uint8_t opt_extract_without_path, uint8_t *opt_overwrite, const char *password)
|
||||
{
|
||||
unz_file_info64 file_info = {0};
|
||||
void* buf = NULL;
|
||||
uint16_t size_buf = 8192;
|
||||
mz_unzip_file *file_info = NULL;
|
||||
uint8_t buf[UINT16_MAX];
|
||||
int32_t read = 0;
|
||||
int err = UNZ_OK;
|
||||
int errclose = UNZ_OK;
|
||||
int skip = 0;
|
||||
char filename_inzip[256] = {0};
|
||||
char *filename_withoutpath = NULL;
|
||||
const char *write_filename = NULL;
|
||||
char *p = NULL;
|
||||
int16_t err = MZ_OK;
|
||||
int16_t err_close = MZ_OK;
|
||||
uint8_t skip = 0;
|
||||
void *stream_entry = NULL;
|
||||
char *match = NULL;
|
||||
char *filename = NULL;
|
||||
char *write_filename = NULL;
|
||||
char directory[512];
|
||||
|
||||
err = unzGetCurrentFileInfo64(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
|
||||
if (err != UNZ_OK)
|
||||
|
||||
err = mz_unzip_entry_get_info(handle, &file_info);
|
||||
|
||||
if (err != MZ_OK)
|
||||
{
|
||||
printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
|
||||
printf("Error %d with zip file @ mz_unzip_entry_get_info\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
p = filename_withoutpath = filename_inzip;
|
||||
while (*p != 0)
|
||||
// Break apart filename and directory from full path
|
||||
strncpy(directory, file_info->filename, sizeof(directory));
|
||||
match = filename = directory;
|
||||
while (*match != 0)
|
||||
{
|
||||
if ((*p == '/') || (*p == '\\'))
|
||||
filename_withoutpath = p+1;
|
||||
p++;
|
||||
if ((*match == '/') || (*match == '\\'))
|
||||
filename = match + 1;
|
||||
match += 1;
|
||||
}
|
||||
if (filename != directory)
|
||||
*match = 0;
|
||||
|
||||
/* If zip entry is a directory then create it on disk */
|
||||
if (*filename_withoutpath == 0)
|
||||
// If zip entry is a directory then create it on disk
|
||||
if (*filename == 0)
|
||||
{
|
||||
if (opt_extract_without_path == 0)
|
||||
{
|
||||
printf("creating directory: %s\n", filename_inzip);
|
||||
MKDIR(filename_inzip);
|
||||
printf("Creating directory: %s\n", file_info->filename);
|
||||
mz_os_make_dir(directory);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
buf = (void*)malloc(size_buf);
|
||||
if (buf == NULL)
|
||||
{
|
||||
printf("Error allocating memory\n");
|
||||
return UNZ_INTERNALERROR;
|
||||
}
|
||||
err = mz_unzip_entry_open(handle, 0, password);
|
||||
|
||||
err = unzOpenCurrentFilePassword(uf, password);
|
||||
if (err != UNZ_OK)
|
||||
printf("error %d with zipfile in unzOpenCurrentFilePassword\n", err);
|
||||
if (err != MZ_OK)
|
||||
printf("Error %d with zip file @ mz_unzip_entry_open\n", err);
|
||||
|
||||
if (opt_extract_without_path)
|
||||
write_filename = filename_withoutpath;
|
||||
write_filename = filename;
|
||||
else
|
||||
write_filename = filename_inzip;
|
||||
write_filename = file_info->filename;
|
||||
|
||||
/* Determine if the file should be overwritten or not and ask the user if needed */
|
||||
if ((err == UNZ_OK) && (*popt_overwrite == 0) && (mz_os_file_exists(write_filename)))
|
||||
// Determine if the file should be overwritten or not and ask the user if needed
|
||||
if ((err == MZ_OK) && (*opt_overwrite == 0) && (mz_os_file_exists(write_filename)))
|
||||
{
|
||||
char rep = 0;
|
||||
do
|
||||
@ -212,41 +209,34 @@ int miniunz_extract_currentfile(unzFile uf, int opt_extract_without_path, int *p
|
||||
if (rep == 'N')
|
||||
skip = 1;
|
||||
if (rep == 'A')
|
||||
*popt_overwrite = 1;
|
||||
*opt_overwrite = 1;
|
||||
}
|
||||
|
||||
voidpf stream_entry = NULL;
|
||||
mz_stream_os_create(&stream_entry);
|
||||
|
||||
/* Create the file on disk so we can unzip to it */
|
||||
if ((skip == 0) && (err == UNZ_OK))
|
||||
// Create the file on disk so we can unzip to it
|
||||
if ((skip == 0) && (err == MZ_OK))
|
||||
{
|
||||
/* Some zips don't contain directory alone before file */
|
||||
// Some zips don't contain directory alone before file
|
||||
if ((mz_stream_os_open(stream_entry, write_filename, MZ_STREAM_MODE_CREATE) != MZ_OK) &&
|
||||
(opt_extract_without_path == 0) &&
|
||||
(filename_withoutpath != (char*)filename_inzip))
|
||||
(opt_extract_without_path == 0) && (filename != file_info->filename))
|
||||
{
|
||||
char c = *(filename_withoutpath-1);
|
||||
*(filename_withoutpath-1) = 0;
|
||||
makedir(write_filename);
|
||||
*(filename_withoutpath-1) = c;
|
||||
|
||||
mz_os_make_dir(directory);
|
||||
mz_stream_os_open(stream_entry, write_filename, MZ_STREAM_MODE_CREATE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read from the zip, unzip to buffer, and write to disk */
|
||||
// Read from the zip, unzip to buffer, and write to disk
|
||||
if (mz_stream_os_is_open(stream_entry) == MZ_OK)
|
||||
{
|
||||
printf(" extracting: %s\n", write_filename);
|
||||
|
||||
printf(" Extracting: %s\n", write_filename);
|
||||
while (1)
|
||||
{
|
||||
read = unzReadCurrentFile(uf, buf, size_buf);
|
||||
read = mz_unzip_entry_read(handle, buf, sizeof(buf));
|
||||
if (read < 0)
|
||||
{
|
||||
err = read;
|
||||
printf("error %d with zipfile in unzReadCurrentFile\n", err);
|
||||
printf("Error %d with zip file @ mz_unzip_entry_read\n", err);
|
||||
break;
|
||||
}
|
||||
if (read == 0)
|
||||
@ -254,87 +244,95 @@ int miniunz_extract_currentfile(unzFile uf, int opt_extract_without_path, int *p
|
||||
|
||||
if (mz_stream_os_write(stream_entry, buf, read) != read)
|
||||
{
|
||||
printf("error %d in writing extracted file\n", err);
|
||||
printf("Error %d in writing extracted file\n", err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mz_stream_os_close(stream_entry);
|
||||
|
||||
/* Set the time of the file that has been unzipped */
|
||||
// Set the time of the file that has been unzipped
|
||||
if (err == 0)
|
||||
change_file_date(write_filename, file_info.dos_date);
|
||||
mz_os_set_file_date(write_filename, file_info->dos_date);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("error opening %s\n", write_filename);
|
||||
printf("Error opening %s\n", write_filename);
|
||||
}
|
||||
|
||||
mz_stream_os_delete(&stream_entry);
|
||||
|
||||
errclose = unzCloseCurrentFile(uf);
|
||||
if (errclose != UNZ_OK)
|
||||
printf("error %d with zipfile in unzCloseCurrentFile\n", errclose);
|
||||
err_close = mz_unzip_entry_close(handle);
|
||||
if (err_close != MZ_OK)
|
||||
printf("Error %d with zip file @ mz_unzip_entry_close\n", err_close);
|
||||
|
||||
free(buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
int miniunz_extract_all(unzFile uf, int opt_extract_without_path, int opt_overwrite, const char *password)
|
||||
int miniunz_extract_all(void *handle, uint8_t opt_extract_without_path, uint8_t opt_overwrite, const char *password)
|
||||
{
|
||||
int err = unzGoToFirstFile(uf);
|
||||
if (err != UNZ_OK)
|
||||
int16_t err = MZ_OK;
|
||||
|
||||
|
||||
err = mz_unzip_goto_first_entry(handle);
|
||||
|
||||
if (err != MZ_OK)
|
||||
{
|
||||
printf("error %d with zipfile in unzGoToFirstFile\n", err);
|
||||
printf("Error %d with zip file @ mz_unzip_goto_first_entry\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
err = miniunz_extract_currentfile(uf, opt_extract_without_path, &opt_overwrite, password);
|
||||
if (err != UNZ_OK)
|
||||
err = miniunz_extract_currentfile(handle, opt_extract_without_path, &opt_overwrite, password);
|
||||
if (err != MZ_OK)
|
||||
break;
|
||||
err = unzGoToNextFile(uf);
|
||||
}
|
||||
while (err == UNZ_OK);
|
||||
|
||||
if (err != UNZ_END_OF_LIST_OF_FILE)
|
||||
err = mz_unzip_goto_next_entry(handle);
|
||||
}
|
||||
while (err == MZ_OK);
|
||||
|
||||
if (err != MZ_END_OF_LIST)
|
||||
{
|
||||
printf("error %d with zipfile in unzGoToNextFile\n", err);
|
||||
printf("Error %d with zip file @ mz_unzip_goto_next_entry\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int miniunz_extract_onefile(unzFile uf, const char *filename, int opt_extract_without_path, int opt_overwrite,
|
||||
const char *password)
|
||||
int miniunz_extract_onefile(void *handle, const char *filename, uint8_t opt_extract_without_path,
|
||||
uint8_t opt_overwrite, const char *password)
|
||||
{
|
||||
if (unzLocateFile(uf, filename, NULL) != UNZ_OK)
|
||||
if (mz_unzip_locate_entry(handle, filename, NULL) != MZ_OK)
|
||||
{
|
||||
printf("file %s not found in the zipfile\n", filename);
|
||||
printf("File %s not found in the zip file\n", filename);
|
||||
return 2;
|
||||
}
|
||||
if (miniunz_extract_currentfile(uf, opt_extract_without_path, &opt_overwrite, password) == UNZ_OK)
|
||||
|
||||
if (miniunz_extract_currentfile(handle, opt_extract_without_path, &opt_overwrite, password) == MZ_OK)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef NOMAIN
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
const char *zipfilename = NULL;
|
||||
const char *filename_to_extract = NULL;
|
||||
void *handle = NULL;
|
||||
void *stream = NULL;
|
||||
int16_t i = 0;
|
||||
uint8_t opt_do_list = 0;
|
||||
uint8_t opt_do_extract = 1;
|
||||
uint8_t opt_do_extract_withoutpath = 0;
|
||||
uint8_t opt_overwrite = 0;
|
||||
uint8_t opt_extractdir = 0;
|
||||
const char *path = NULL;
|
||||
const char *password = NULL;
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
int opt_do_list = 0;
|
||||
int opt_do_extract = 1;
|
||||
int opt_do_extract_withoutpath = 0;
|
||||
int opt_overwrite = 0;
|
||||
int opt_extractdir = 0;
|
||||
const char *dirname = NULL;
|
||||
unzFile uf = NULL;
|
||||
voidpf stream = NULL;
|
||||
const char *directory = NULL;
|
||||
const char *filename_to_extract = NULL;
|
||||
int err = 0;
|
||||
|
||||
|
||||
miniunz_banner();
|
||||
if (argc == 1)
|
||||
@ -343,7 +341,7 @@ int main(int argc, const char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse command line options */
|
||||
// Parse command line options
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if ((*argv[i]) == '-')
|
||||
@ -366,64 +364,61 @@ int main(int argc, const char *argv[])
|
||||
if ((c == 'd') || (c == 'D'))
|
||||
{
|
||||
opt_extractdir = 1;
|
||||
dirname = argv[i+1];
|
||||
directory = argv[i+1];
|
||||
}
|
||||
|
||||
if (((c == 'p') || (c == 'P')) && (i+1 < argc))
|
||||
{
|
||||
password = argv[i+1];
|
||||
i++;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (zipfilename == NULL)
|
||||
zipfilename = argv[i];
|
||||
else if ((filename_to_extract == NULL) && (!opt_extractdir))
|
||||
filename_to_extract = argv[i];
|
||||
}
|
||||
|
||||
if (path == NULL)
|
||||
path = argv[i];
|
||||
else if ((filename_to_extract == NULL) && (!opt_extractdir))
|
||||
filename_to_extract = argv[i];
|
||||
}
|
||||
|
||||
mz_stream_os_create(&stream);
|
||||
|
||||
/* Open zip file */
|
||||
if (zipfilename != NULL)
|
||||
{
|
||||
uf = unzOpen(zipfilename, stream);
|
||||
}
|
||||
// Open zip file
|
||||
if (path != NULL)
|
||||
handle = mz_unzip_open(path, stream);
|
||||
|
||||
if (uf == NULL)
|
||||
if (handle == NULL)
|
||||
{
|
||||
printf("Cannot open %s\n", zipfilename);
|
||||
printf("Cannot open %s\n", path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("%s opened\n", zipfilename);
|
||||
printf("%s opened\n", path);
|
||||
|
||||
/* Process command line options */
|
||||
if (opt_do_list == 1)
|
||||
// Process command line options
|
||||
if (opt_do_list)
|
||||
{
|
||||
ret = miniunz_list(uf);
|
||||
err = miniunz_list(handle);
|
||||
}
|
||||
else if (opt_do_extract == 1)
|
||||
else if (opt_do_extract)
|
||||
{
|
||||
if (opt_extractdir && CHDIR(dirname))
|
||||
if (opt_extractdir && mz_os_change_dir(directory))
|
||||
{
|
||||
printf("Error changing into %s, aborting\n", dirname);
|
||||
printf("Error changing into %s, aborting\n", directory);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (filename_to_extract == NULL)
|
||||
ret = miniunz_extract_all(uf, opt_do_extract_withoutpath, opt_overwrite, password);
|
||||
err = miniunz_extract_all(handle, opt_do_extract_withoutpath, opt_overwrite, password);
|
||||
else
|
||||
ret = miniunz_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
|
||||
err = miniunz_extract_onefile(handle, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
|
||||
}
|
||||
|
||||
unzClose(uf);
|
||||
|
||||
mz_unzip_close(handle);
|
||||
mz_stream_os_delete(&stream);
|
||||
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
16
minizip.c
16
minizip.c
@ -1,5 +1,5 @@
|
||||
/* minizip.c
|
||||
Version 1.2.0, September 16th, 2017
|
||||
Version 1.3.0, September 16th, 2017
|
||||
sample part of the MiniZip project
|
||||
|
||||
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||
@ -39,11 +39,9 @@
|
||||
#include "mzstrm.h"
|
||||
#include "test.h"
|
||||
|
||||
#include "minishared.h"
|
||||
|
||||
void minizip_banner()
|
||||
{
|
||||
printf("MiniZip 1.2.0, demo of zLib + MiniZip64 package\n");
|
||||
printf("MiniZip 1.3.0, demo of zLib + MiniZip64 package\n");
|
||||
printf("more info on MiniZip at https://github.com/nmoinvaz/minizip\n\n");
|
||||
}
|
||||
|
||||
@ -67,8 +65,8 @@ int minizip_addfile(void *zf, const char *path, const char *filenameinzip, int l
|
||||
char buf[UINT16_MAX];
|
||||
|
||||
|
||||
/* Get information about the file on disk so we can store it in zip */
|
||||
get_file_date(path, &zi.dos_date);
|
||||
// Get information about the file on disk so we can store it in zip
|
||||
mz_os_get_file_date(path, &zi.dos_date);
|
||||
|
||||
/* Add to zip file */
|
||||
err = zipOpenNewFileInZip3_64(zf, filenameinzip, &zi,
|
||||
@ -81,7 +79,7 @@ int minizip_addfile(void *zf, const char *path, const char *filenameinzip, int l
|
||||
|
||||
if (err != ZIP_OK)
|
||||
{
|
||||
printf("error in opening %s in zipfile (%d)\n", filenameinzip, err);
|
||||
printf("error in opening %s in zip file (%d)\n", filenameinzip, err);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -109,7 +107,7 @@ int minizip_addfile(void *zf, const char *path, const char *filenameinzip, int l
|
||||
{
|
||||
err = zipWriteInFileInZip(zf, buf, size_read);
|
||||
if (err < 0)
|
||||
printf("error in writing %s in the zipfile (%d)\n", filenameinzip, err);
|
||||
printf("error in writing %s in the zip file (%d)\n", filenameinzip, err);
|
||||
}
|
||||
}
|
||||
while ((err == ZIP_OK) && (size_read > 0));
|
||||
@ -128,7 +126,7 @@ int minizip_addfile(void *zf, const char *path, const char *filenameinzip, int l
|
||||
{
|
||||
err = zipCloseFileInZip(zf);
|
||||
if (err != ZIP_OK)
|
||||
printf("error in closing %s in the zipfile (%d)\n", filenameinzip, err);
|
||||
printf("error in closing %s in the zip file (%d)\n", filenameinzip, err);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -21,7 +21,7 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "zlib.h"
|
||||
#ifdef __GNUC__
|
||||
# define ZIP_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
|
89
mzstrm.c
89
mzstrm.c
@ -17,8 +17,12 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "mzstrm.h"
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_open(void *stream, const char *path, int mode)
|
||||
{
|
||||
mz_stream *strm = (mz_stream *)stream;
|
||||
@ -282,12 +286,16 @@ void mz_stream_delete(void **stream)
|
||||
strm->delete(stream);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
typedef struct mz_stream_passthru_s {
|
||||
mz_stream stream;
|
||||
int64_t total_in;
|
||||
int64_t total_out;
|
||||
} mz_stream_passthru;
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_stream_passthru_open(void *stream, const char *path, int mode)
|
||||
{
|
||||
mz_stream_passthru *passthru = (mz_stream_passthru *)stream;
|
||||
@ -392,6 +400,8 @@ void mz_stream_passthru_delete(void **stream)
|
||||
free(passthru);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_os_file_exists(const char *path)
|
||||
{
|
||||
void *stream = NULL;
|
||||
@ -410,7 +420,7 @@ int32_t mz_os_file_exists(const char *path)
|
||||
return opened;
|
||||
}
|
||||
|
||||
int32_t mz_os_file_is_large(const char *path)
|
||||
int64_t mz_os_file_get_size(const char *path)
|
||||
{
|
||||
void *stream = NULL;
|
||||
int64_t size = 0;
|
||||
@ -426,5 +436,78 @@ int32_t mz_os_file_is_large(const char *path)
|
||||
|
||||
mz_stream_os_delete(&stream);
|
||||
|
||||
return (size >= UINT32_MAX);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int mz_invalid_date(const struct tm *ptm)
|
||||
{
|
||||
#define datevalue_in_range(min, max, value) ((min) <= (value) && (value) <= (max))
|
||||
return (!datevalue_in_range(0, 207, ptm->tm_year) ||
|
||||
!datevalue_in_range(0, 11, ptm->tm_mon) ||
|
||||
!datevalue_in_range(1, 31, ptm->tm_mday) ||
|
||||
!datevalue_in_range(0, 23, ptm->tm_hour) ||
|
||||
!datevalue_in_range(0, 59, ptm->tm_min) ||
|
||||
!datevalue_in_range(0, 59, ptm->tm_sec));
|
||||
#undef datevalue_in_range
|
||||
}
|
||||
|
||||
// Conversion without validation
|
||||
void mz_dosdate_to_raw_tm(uint64_t dos_date, struct tm *ptm)
|
||||
{
|
||||
uint64_t date = (uint64_t)(dos_date >> 16);
|
||||
|
||||
ptm->tm_mday = (uint16_t)(date & 0x1f);
|
||||
ptm->tm_mon = (uint16_t)(((date & 0x1E0) / 0x20) - 1);
|
||||
ptm->tm_year = (uint16_t)(((date & 0x0FE00) / 0x0200) + 80);
|
||||
ptm->tm_hour = (uint16_t)((dos_date & 0xF800) / 0x800);
|
||||
ptm->tm_min = (uint16_t)((dos_date & 0x7E0) / 0x20);
|
||||
ptm->tm_sec = (uint16_t)(2 * (dos_date & 0x1f));
|
||||
ptm->tm_isdst = -1;
|
||||
}
|
||||
|
||||
int32_t mz_dosdate_to_tm(uint64_t dos_date, struct tm *ptm)
|
||||
{
|
||||
mz_dosdate_to_raw_tm(dos_date, ptm);
|
||||
|
||||
if (mz_invalid_date(ptm))
|
||||
{
|
||||
// Invalid date stored, so don't return it.
|
||||
memset(ptm, 0, sizeof(struct tm));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
time_t mz_dosdate_to_time_t(uint64_t dos_date)
|
||||
{
|
||||
struct tm ptm;
|
||||
mz_dosdate_to_raw_tm(dos_date, &ptm);
|
||||
return mktime(&ptm);
|
||||
}
|
||||
|
||||
uint32_t mz_tm_to_dosdate(const struct tm *ptm)
|
||||
{
|
||||
struct tm fixed_tm = { 0 };
|
||||
|
||||
// Years supported:
|
||||
// [00, 79] (assumed to be between 2000 and 2079)
|
||||
// [80, 207] (assumed to be between 1980 and 2107, typical output of old
|
||||
// software that does 'year-1900' to get a double digit year)
|
||||
// [1980, 2107] (due to the date format limitations, only years between 1980 and 2107 can be stored.)
|
||||
|
||||
memcpy(&fixed_tm, ptm, sizeof(struct tm));
|
||||
if (fixed_tm.tm_year >= 1980) // range [1980, 2107]
|
||||
fixed_tm.tm_year -= 1980;
|
||||
else if (fixed_tm.tm_year >= 80) // range [80, 99]
|
||||
fixed_tm.tm_year -= 80;
|
||||
else // range [00, 79]
|
||||
fixed_tm.tm_year += 20;
|
||||
|
||||
if (mz_invalid_date(ptm))
|
||||
return 0;
|
||||
|
||||
return (uint32_t)(((fixed_tm.tm_mday) + (32 * (fixed_tm.tm_mon + 1)) + (512 * fixed_tm.tm_year)) << 16) |
|
||||
((fixed_tm.tm_sec / 2) + (32 * fixed_tm.tm_min) + (2048 * (uint32_t)fixed_tm.tm_hour));
|
||||
}
|
||||
|
21
mzstrm.h
21
mzstrm.h
@ -128,6 +128,10 @@ void mz_stream_passthru_delete(void **stream);
|
||||
#define mz_stream_os_delete mz_stream_posix_delete
|
||||
|
||||
#define mz_os_rand mz_posix_rand
|
||||
#define mz_os_get_file_date mz_posix_get_file_date
|
||||
#define mz_os_set_file_date mz_posix_set_file_date
|
||||
#define mz_os_change_dir mz_posix_change_dir
|
||||
#define mz_os_make_dir mz_posix_make_dir
|
||||
#else
|
||||
#include "mzstrm_win32.h"
|
||||
|
||||
@ -144,10 +148,25 @@ void mz_stream_passthru_delete(void **stream);
|
||||
#define mz_stream_os_delete mz_stream_win32_delete
|
||||
|
||||
#define mz_os_rand mz_win32_rand
|
||||
#define mz_os_get_file_date mz_win32_get_file_date
|
||||
#define mz_os_set_file_date mz_win32_set_file_date
|
||||
#define mz_os_change_dir mz_win32_change_dir
|
||||
#define mz_os_make_dir mz_win32_make_dir
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_os_file_exists(const char *path);
|
||||
int32_t mz_os_file_is_large(const char *path);
|
||||
int64_t mz_os_file_get_size(const char *path);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
int32_t mz_dosdate_to_tm(uint64_t dos_date, struct tm *ptm);
|
||||
// Convert dos date/time format to struct tm
|
||||
time_t mz_dosdate_to_time_t(uint64_t dos_date);
|
||||
// Convert dos date/time format to time_t
|
||||
uint32_t mz_tm_to_dosdate(const struct tm *ptm);
|
||||
// Convert struct tm to dos date/time format
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
@ -63,7 +63,7 @@ int32_t mz_stream_bzip_open(void *stream, const char *path, int mode)
|
||||
else if (mode & MZ_STREAM_MODE_WRITE)
|
||||
{
|
||||
bzip->bzstream.next_out = bzip->buffer;
|
||||
bzip->bzstream.avail_out = UINT16_MAX;
|
||||
bzip->bzstream.avail_out = sizeof(bzip->buffer);
|
||||
|
||||
bzip->error = BZ2_bzCompressInit(&bzip->bzstream, bzip->level, 0, 35);
|
||||
}
|
||||
@ -102,10 +102,10 @@ int32_t mz_stream_bzip_read(void *stream, void *buf, uint32_t size)
|
||||
{
|
||||
if (bzip->bzstream.avail_in == 0)
|
||||
{
|
||||
bytes_to_read = UINT16_MAX;
|
||||
bytes_to_read = sizeof(bzip->buffer);
|
||||
if (bzip->max_total_in > 0)
|
||||
{
|
||||
if ((bzip->max_total_in - bzip->total_in) < UINT16_MAX)
|
||||
if ((bzip->max_total_in - bzip->total_in) < sizeof(bzip->buffer))
|
||||
bytes_to_read = (int32_t)(bzip->max_total_in - bzip->total_in);
|
||||
}
|
||||
|
||||
@ -205,7 +205,7 @@ int32_t mz_stream_bzip_write(void *stream, const void *buf, uint32_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bzip->bzstream.avail_out = UINT32_MAX;
|
||||
bzip->bzstream.avail_out = sizeof(bzip->buffer);
|
||||
bzip->bzstream.next_out = bzip->buffer;
|
||||
|
||||
bzip->buffer_len = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* mzstrm_crypt.c -- Code for traditional PKWARE encryption
|
||||
Version 1.2.0, September 16th, 2017
|
||||
Version 1.3.0, September 16th, 2017
|
||||
|
||||
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* mzstrm_crypt.h -- Code for traditional PKWARE encryption
|
||||
Version 1.2.0, September 16th, 2017
|
||||
Version 1.3.0, September 16th, 2017
|
||||
|
||||
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||
https://github.com/nmoinvaz/minizip
|
||||
|
107
mzstrm_win32.c
107
mzstrm_win32.c
@ -322,3 +322,110 @@ int32_t mz_win32_rand(uint8_t *buf, uint32_t size)
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int16_t mz_win32_get_file_date(const char *path, uint32_t *dos_date)
|
||||
{
|
||||
FILETIME ftm_local;
|
||||
HANDLE handle = NULL;
|
||||
WIN32_FIND_DATAW ff32;
|
||||
wchar_t *path_wide = NULL;
|
||||
uint32_t path_wide_size = 0;
|
||||
int16_t err = MZ_INTERNAL_ERROR;
|
||||
|
||||
path_wide_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
|
||||
path_wide = (wchar_t *)malloc((path_wide_size + 1) * sizeof(wchar_t));
|
||||
memset(path_wide, 0, sizeof(wchar_t) * (path_wide_size + 1));
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wide, path_wide_size);
|
||||
|
||||
handle = FindFirstFileW(path_wide, &ff32);
|
||||
|
||||
free(path_wide);
|
||||
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
FileTimeToLocalFileTime(&(ff32.ftLastWriteTime), &ftm_local);
|
||||
FileTimeToDosDateTime(&ftm_local, ((LPWORD)dos_date) + 1, ((LPWORD)dos_date) + 0);
|
||||
FindClose(handle);
|
||||
err = MZ_OK;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int16_t mz_win32_set_file_date(const char *path, uint32_t dos_date)
|
||||
{
|
||||
HANDLE handle = NULL;
|
||||
FILETIME ftm, ftm_local, ftm_create, ftm_access, ftm_modified;
|
||||
wchar_t *path_wide = NULL;
|
||||
uint32_t path_wide_size = 0;
|
||||
int16_t err = MZ_OK;
|
||||
|
||||
path_wide_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
|
||||
path_wide = (wchar_t *)malloc((path_wide_size + 1) * sizeof(wchar_t));
|
||||
memset(path_wide, 0, sizeof(wchar_t) * (path_wide_size + 1));
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wide, path_wide_size);
|
||||
|
||||
#ifdef IOWIN32_USING_WINRT_API
|
||||
handle = CreateFile2W(path_wide, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
#else
|
||||
handle = CreateFileW(path_wide, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
#endif
|
||||
|
||||
free(path_wide);
|
||||
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
GetFileTime(handle, &ftm_create, &ftm_access, &ftm_modified);
|
||||
DosDateTimeToFileTime((WORD)(dos_date >> 16), (WORD)dos_date, &ftm_local);
|
||||
LocalFileTimeToFileTime(&ftm_local, &ftm);
|
||||
|
||||
if (SetFileTime(handle, &ftm, &ftm_access, &ftm) == 0)
|
||||
err = MZ_INTERNAL_ERROR;
|
||||
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int16_t mz_win32_change_dir(const char *path)
|
||||
{
|
||||
wchar_t *path_wide = NULL;
|
||||
uint32_t path_wide_size = 0;
|
||||
int16_t err = MZ_OK;
|
||||
|
||||
|
||||
path_wide_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
|
||||
path_wide = (wchar_t *)malloc((path_wide_size + 1) * sizeof(wchar_t));
|
||||
memset(path_wide, 0, sizeof(wchar_t) * (path_wide_size + 1));
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wide, path_wide_size);
|
||||
|
||||
if (_wchdir(path_wide) != 0)
|
||||
err = MZ_INTERNAL_ERROR;
|
||||
|
||||
free(path_wide);
|
||||
return err;
|
||||
}
|
||||
|
||||
int16_t mz_win32_make_dir(const char *path)
|
||||
{
|
||||
wchar_t *path_wide = NULL;
|
||||
uint32_t path_wide_size = 0;
|
||||
int16_t err = MZ_OK;
|
||||
|
||||
|
||||
path_wide_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
|
||||
path_wide = (wchar_t *)malloc((path_wide_size + 1) * sizeof(wchar_t));
|
||||
memset(path_wide, 0, sizeof(wchar_t) * (path_wide_size + 1));
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wide, path_wide_size);
|
||||
|
||||
if (_wmkdir(path_wide) != 0)
|
||||
err = MZ_INTERNAL_ERROR;
|
||||
|
||||
free(path_wide);
|
||||
return err;
|
||||
}
|
@ -37,6 +37,10 @@ void* mz_stream_win32_create(void **stream);
|
||||
void mz_stream_win32_delete(void **stream);
|
||||
|
||||
int32_t mz_win32_rand(uint8_t *buf, uint32_t size);
|
||||
int16_t mz_win32_get_file_date(const char *path, uint32_t *dos_date);
|
||||
int16_t mz_win32_set_file_date(const char *path, uint32_t dos_date);
|
||||
int16_t mz_win32_change_dir(const char *path);
|
||||
int16_t mz_win32_make_dir(const char *path);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
@ -120,10 +120,10 @@ int32_t mz_stream_zlib_read(void *stream, void *buf, uint32_t size)
|
||||
{
|
||||
if (zlib->zstream.avail_in == 0)
|
||||
{
|
||||
bytes_to_read = UINT16_MAX;
|
||||
bytes_to_read = sizeof(zlib->buffer);
|
||||
if (zlib->max_total_in > 0)
|
||||
{
|
||||
if ((zlib->max_total_in - zlib->total_in) < UINT16_MAX)
|
||||
if ((zlib->max_total_in - zlib->total_in) < sizeof(zlib->buffer))
|
||||
bytes_to_read = (int32_t)(zlib->max_total_in - zlib->total_in);
|
||||
}
|
||||
|
||||
@ -225,7 +225,7 @@ int32_t mz_stream_zlib_write(void *stream, const void *buf, uint32_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
zlib->zstream.avail_out = UINT32_MAX;
|
||||
zlib->zstream.avail_out = sizeof(zlib->buffer);
|
||||
zlib->zstream.next_out = zlib->buffer;
|
||||
|
||||
zlib->buffer_len = 0;
|
||||
|
16
unzip.c
16
unzip.c
@ -1,4 +1,4 @@
|
||||
/* unzip.c -- IO for uncompress .zip files using zlib
|
||||
/* unzip.c -- Zip manipulation
|
||||
Version 1.2.0, September 16th, 2017
|
||||
part of the MiniZip project
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// Contains internal information about the zipfile
|
||||
// Contains internal information about the zip file
|
||||
typedef struct mz_unzip_s
|
||||
{
|
||||
mz_unzip_global global_info; // public global information
|
||||
@ -71,8 +71,8 @@ typedef struct mz_unzip_s
|
||||
void *crypt_stream; // encryption stream
|
||||
void *file_info_stream; // memory stream for storing file info
|
||||
|
||||
uint64_t byte_before_the_zipfile; // byte before the zipfile, (>0 for sfx)
|
||||
uint64_t num_file; // number of the current file in the zipfile
|
||||
uint64_t byte_before_the_zipfile; // byte before the zip file, (>0 for sfx)
|
||||
uint64_t num_file; // number of the current file in the zip file
|
||||
uint64_t pos_in_central_dir; // pos of the current file in the central dir
|
||||
uint64_t central_pos; // position of the beginning of the central dir
|
||||
uint32_t number_disk; // number of the current disk, used for spanning ZIP
|
||||
@ -80,7 +80,7 @@ typedef struct mz_unzip_s
|
||||
uint64_t offset_central_dir; // offset of start of central directory with
|
||||
// respect to the starting disk number
|
||||
|
||||
uint64_t pos_in_zipfile; // position in byte on the zipfile, for fseek
|
||||
uint64_t pos_in_zipfile; // position in byte on the zip file, for fseek
|
||||
|
||||
uint8_t stream_initialised; // flag set if stream structure is initialised
|
||||
uint64_t stream_available; // number of byte to be decompressed
|
||||
@ -155,7 +155,7 @@ static uint64_t mz_unzip_search_cd(void *stream)
|
||||
return pos_found;
|
||||
}
|
||||
|
||||
// Locate the central directory 64 of a zipfile (at the end, just before the global comment)
|
||||
// Locate the central directory 64 of a zip file (at the end, just before the global comment)
|
||||
static uint64_t mz_unzip_search_zip64_cd(void *stream, const uint64_t endcentraloffset)
|
||||
{
|
||||
uint64_t offset = 0;
|
||||
@ -409,7 +409,7 @@ extern int ZEXPORT mz_unzip_get_global_comment(void *handle, char *comment, uint
|
||||
return MZ_OK;
|
||||
}
|
||||
|
||||
// Get info about the current file in the zipfile
|
||||
// Get info about the current file in the zip file
|
||||
static int mz_unzip_entry_read_header(void *handle)
|
||||
{
|
||||
mz_unzip *unzip = NULL;
|
||||
@ -609,7 +609,7 @@ static int mz_unzip_entry_read_header(void *handle)
|
||||
return err;
|
||||
}
|
||||
|
||||
// Read the local header of the current zipfile. Check the coherency of the local header and info in the
|
||||
// Read the local header of the current zip file. Check the coherency of the local header and info in the
|
||||
// end of central directory about this file store in extrainfo_size the size of extra info in local header
|
||||
// (filename and size of extra field data)
|
||||
static int mz_unzip_entry_check_header(mz_unzip *unzip, uint32_t *extrainfo_size, uint64_t *extrafield_local_offset,
|
||||
|
6
unzip.h
6
unzip.h
@ -1,5 +1,5 @@
|
||||
/* unzip.h -- IO for uncompress .zip files using zlib
|
||||
Version 1.2.0, September 16th, 2017
|
||||
/* unzip.h -- Zip manipulation
|
||||
Version 1.3.0, September 16th, 2017
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||
@ -54,7 +54,7 @@ typedef struct mz_unzip_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 zipfile
|
||||
uint16_t comment_size; // size of the global comment of the zip file
|
||||
} mz_unzip_global;
|
||||
|
||||
// Info about a file in the zip file at the central directory
|
||||
|
@ -143,7 +143,6 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\minishared.c" />
|
||||
<ClCompile Include="..\miniunz.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -151,9 +150,6 @@
|
||||
<Project>{17a4a51f-3e4f-419a-9192-28559785cf66}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\minishared.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -11,16 +11,8 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\minishared.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\miniunz.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\minishared.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -138,12 +138,8 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\minishared.c" />
|
||||
<ClCompile Include="..\minizip.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\minishared.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="libminizip.vcxproj">
|
||||
<Project>{17a4a51f-3e4f-419a-9192-28559785cf66}</Project>
|
||||
|
@ -11,16 +11,8 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\minishared.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\minizip.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\minishared.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
12
zip.c
12
zip.c
@ -1,5 +1,5 @@
|
||||
/* zip.c -- IO on .zip files using zlib
|
||||
Version 1.2.0, September 16th, 2017
|
||||
/* zip.c -- Zip manipulation
|
||||
Version 1.3.0, September 16th, 2017
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2010-2017 Nathan Moinvaziri
|
||||
@ -86,7 +86,7 @@ typedef struct mz_zip_s
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// Locate the central directory of a zipfile (at the end, just before the global comment)
|
||||
// Locate the central directory of a zip file (at the end, just before the global comment)
|
||||
static uint64_t mz_zip_search_cd(void *stream)
|
||||
{
|
||||
uint8_t buf[BUFREADCOMMENT + 4];
|
||||
@ -141,7 +141,7 @@ static uint64_t mz_zip_search_cd(void *stream)
|
||||
return pos_found;
|
||||
}
|
||||
|
||||
// Locate the central directory 64 of a zipfile (at the end, just before the global comment)
|
||||
// Locate the central directory 64 of a zip file (at the end, just before the global comment)
|
||||
static uint64_t mz_zip_search_zip64_cd(void *stream, const uint64_t endcentraloffset)
|
||||
{
|
||||
uint64_t offset = 0;
|
||||
@ -181,7 +181,7 @@ extern void* ZEXPORT mz_zip_open(const char *path, int append, uint64_t disk_siz
|
||||
{
|
||||
mz_zip *zip = NULL;
|
||||
#ifndef NO_ADDFILEINEXISTINGZIP
|
||||
uint64_t byte_before_the_zipfile = 0; // byte before the zipfile, (>0 for sfx)
|
||||
uint64_t byte_before_the_zipfile = 0; // byte before the zip file, (>0 for sfx)
|
||||
uint64_t size_central_dir = 0; // size of the central directory
|
||||
uint64_t offset_central_dir = 0; // offset of start of central directory
|
||||
uint64_t number_entry_CD = 0; // total number of entries in the central dir
|
||||
@ -230,7 +230,7 @@ extern void* ZEXPORT mz_zip_open(const char *path, int append, uint64_t disk_siz
|
||||
mz_stream_mem_open(zip->cd_stream, NULL, MZ_STREAM_MODE_CREATE);
|
||||
|
||||
#ifndef NO_ADDFILEINEXISTINGZIP
|
||||
// Add file in a zipfile
|
||||
// Add file in a zip file
|
||||
if (append == MZ_APPEND_STATUS_ADDINZIP)
|
||||
{
|
||||
// Read and cache central directory records
|
||||
|
16
zip.h
16
zip.h
@ -1,5 +1,5 @@
|
||||
/* zip.h -- IO on .zip files using zlib
|
||||
Version 1.2.0, September 16th, 2017
|
||||
/* zip.h -- Zip manipulation
|
||||
Version 1.3.0, September 16th, 2017
|
||||
part of the MiniZip project
|
||||
|
||||
Copyright (C) 2012-2017 Nathan Moinvaziri
|
||||
@ -90,9 +90,9 @@ typedef struct mz_zip_crypt_s
|
||||
/***************************************************************************/
|
||||
|
||||
extern void* ZEXPORT mz_zip_open(const char *path, int append, uint64_t disk_size, void *stream);
|
||||
// Create a zipfile
|
||||
// Create a zip file
|
||||
//
|
||||
// NOTE: There is no delete function into a zipfile. If you want delete file in 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.
|
||||
|
||||
@ -104,16 +104,16 @@ extern int ZEXPORT mz_zip_entry_open(void *handle, const mz_zip_file *file_info,
|
||||
// Open a file in the ZIP for writing
|
||||
|
||||
extern int ZEXPORT mz_zip_entry_write(void *handle, const void *buf, uint32_t len);
|
||||
// Write data in the zipfile
|
||||
// Write data in the zip file
|
||||
|
||||
extern int ZEXPORT mz_zip_entry_close(void *handle);
|
||||
// Close the current file in the zipfile
|
||||
// Close the current file in the zip file
|
||||
|
||||
extern int ZEXPORT mz_zip_entry_close_raw(void *handle, uint64_t uncompressed_size, uint32_t crc32);
|
||||
// Close the current file in the zipfile where raw is compressed data
|
||||
// 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 zipfile
|
||||
// Close the zip file
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user