Externals: Convert minizip-ng To Submodule
Due to an oversight in our CMakeLists, pkg-config would attempt to find *minizip* 3.0.0 (which doesn't exist) instead of *minizip-ng* 3.0.0, or at least it was on my Manjaro Linux machine. This has been fixed. The new submodule is using minizip-ng 3.0.4, the same version that was being used before.
This commit is contained in:
parent
6bee21e272
commit
0acdd404e3
|
@ -78,3 +78,6 @@
|
||||||
[submodule "Externals/tinygltf/tinygltf"]
|
[submodule "Externals/tinygltf/tinygltf"]
|
||||||
path = Externals/tinygltf/tinygltf
|
path = Externals/tinygltf/tinygltf
|
||||||
url = https://github.com/syoyo/tinygltf.git
|
url = https://github.com/syoyo/tinygltf.git
|
||||||
|
[submodule "Externals/minizip-ng/minizip-ng"]
|
||||||
|
path = Externals/minizip-ng/minizip-ng
|
||||||
|
url = https://github.com/zlib-ng/minizip-ng
|
||||||
|
|
|
@ -674,7 +674,8 @@ dolphin_find_optional_system_library_pkgconfig(ZSTD libzstd>=1.4.0 zstd::zstd Ex
|
||||||
|
|
||||||
dolphin_find_optional_system_library_pkgconfig(ZLIB zlib-ng ZLIB::ZLIB Externals/zlib-ng)
|
dolphin_find_optional_system_library_pkgconfig(ZLIB zlib-ng ZLIB::ZLIB Externals/zlib-ng)
|
||||||
|
|
||||||
dolphin_find_optional_system_library_pkgconfig(MINIZIP minizip>=3.0.0 minizip::minizip Externals/minizip)
|
# TODO: Some distributions might call this package "minizip" without the "-ng" suffix.
|
||||||
|
dolphin_find_optional_system_library_pkgconfig(MINIZIP minizip-ng>=3.0.0 minizip::minizip Externals/minizip-ng)
|
||||||
|
|
||||||
dolphin_find_optional_system_library(LZO Externals/LZO)
|
dolphin_find_optional_system_library(LZO Externals/LZO)
|
||||||
|
|
||||||
|
|
|
@ -1,48 +1,46 @@
|
||||||
project(minizip C)
|
project(minizip C)
|
||||||
|
|
||||||
add_library(minizip STATIC
|
add_library(minizip STATIC
|
||||||
mz.h
|
minizip-ng/mz.h
|
||||||
mz_compat.c
|
minizip-ng/mz_compat.c
|
||||||
mz_compat.h
|
minizip-ng/mz_compat.h
|
||||||
mz_crypt.c
|
minizip-ng/mz_crypt.c
|
||||||
mz_crypt.h
|
minizip-ng/mz_crypt.h
|
||||||
mz_os.c
|
minizip-ng/mz_os.c
|
||||||
mz_os.h
|
minizip-ng/mz_os.h
|
||||||
mz_strm.c
|
minizip-ng/mz_strm.c
|
||||||
mz_strm.h
|
minizip-ng/mz_strm.h
|
||||||
mz_strm_buf.c
|
minizip-ng/mz_strm_buf.c
|
||||||
mz_strm_buf.h
|
minizip-ng/mz_strm_buf.h
|
||||||
mz_strm_mem.c
|
minizip-ng/mz_strm_mem.c
|
||||||
mz_strm_mem.h
|
minizip-ng/mz_strm_mem.h
|
||||||
mz_strm_os.h
|
minizip-ng/mz_strm_os.h
|
||||||
mz_strm_split.c
|
minizip-ng/mz_strm_split.c
|
||||||
mz_strm_split.h
|
minizip-ng/mz_strm_split.h
|
||||||
mz_strm_zlib.c
|
minizip-ng/mz_strm_zlib.c
|
||||||
mz_strm_zlib.h
|
minizip-ng/mz_strm_zlib.h
|
||||||
mz_zip.c
|
minizip-ng/mz_zip.c
|
||||||
mz_zip.h
|
minizip-ng/mz_zip.h
|
||||||
mz_zip_rw.c
|
minizip-ng/mz_zip_rw.c
|
||||||
mz_zip_rw.h
|
minizip-ng/mz_zip_rw.h
|
||||||
unzip.h
|
|
||||||
zip.h
|
|
||||||
)
|
)
|
||||||
dolphin_disable_warnings(minizip)
|
dolphin_disable_warnings(minizip)
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
target_sources(minizip PRIVATE
|
target_sources(minizip PRIVATE
|
||||||
mz_os_posix.c
|
minizip-ng/mz_os_posix.c
|
||||||
mz_strm_os_posix.c
|
minizip-ng/mz_strm_os_posix.c
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
target_sources(minizip PRIVATE
|
target_sources(minizip PRIVATE
|
||||||
mz_os_win32.c
|
minizip-ng/mz_os_win32.c
|
||||||
mz_strm_os_win32.c
|
minizip-ng/mz_strm_os_win32.c
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(minizip PUBLIC .)
|
target_include_directories(minizip PUBLIC minizip-ng)
|
||||||
|
|
||||||
target_compile_definitions(minizip PRIVATE HAVE_ZLIB ZLIB_COMPAT MZ_ZIP_NO_CRYPTO MZ_ZIP_NO_ENCRYPTION)
|
target_compile_definitions(minizip PRIVATE HAVE_ZLIB ZLIB_COMPAT MZ_ZIP_NO_CRYPTO MZ_ZIP_NO_ENCRYPTION)
|
||||||
if (UNIX)
|
if (UNIX)
|
|
@ -2,11 +2,11 @@
|
||||||
<Project>
|
<Project>
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>$(ExternalsDir)minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(ExternalsDir)minizip-ng\minizip-ng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="$(ExternalsDir)minizip\minizip.vcxproj">
|
<ProjectReference Include="$(ExternalsDir)minizip-ng\minizip-ng.vcxproj">
|
||||||
<Project>{23114507-079a-4418-9707-cfa81a03ca99}</Project>
|
<Project>{23114507-079a-4418-9707-cfa81a03ca99}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 3eed562ef0ea3516db30d1c8ecb0e1b486d8cb70
|
|
@ -21,41 +21,32 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Text Include="CMakeLists.txt" />
|
<ClCompile Include="minizip-ng\mz_compat.c" />
|
||||||
|
<ClCompile Include="minizip-ng\mz_crypt.c" />
|
||||||
|
<ClCompile Include="minizip-ng\mz_os.c" />
|
||||||
|
<ClCompile Include="minizip-ng\mz_os_win32.c" />
|
||||||
|
<ClCompile Include="minizip-ng\mz_strm.c" />
|
||||||
|
<ClCompile Include="minizip-ng\mz_strm_buf.c" />
|
||||||
|
<ClCompile Include="minizip-ng\mz_strm_mem.c" />
|
||||||
|
<ClCompile Include="minizip-ng\mz_strm_os_win32.c" />
|
||||||
|
<ClCompile Include="minizip-ng\mz_strm_split.c" />
|
||||||
|
<ClCompile Include="minizip-ng\mz_strm_zlib.c" />
|
||||||
|
<ClCompile Include="minizip-ng\mz_zip.c" />
|
||||||
|
<ClCompile Include="minizip-ng\mz_zip_rw.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="mz_compat.c" />
|
<ClInclude Include="minizip-ng\mz.h" />
|
||||||
<ClCompile Include="mz_crypt.c" />
|
<ClInclude Include="minizip-ng\mz_compat.h" />
|
||||||
<ClCompile Include="mz_os.c" />
|
<ClInclude Include="minizip-ng\mz_crypt.h" />
|
||||||
<ClCompile Include="mz_os_win32.c" />
|
<ClInclude Include="minizip-ng\mz_os.h" />
|
||||||
<ClCompile Include="mz_strm.c" />
|
<ClInclude Include="minizip-ng\mz_strm.h" />
|
||||||
<ClCompile Include="mz_strm_buf.c" />
|
<ClInclude Include="minizip-ng\mz_strm_buf.h" />
|
||||||
<ClCompile Include="mz_strm_mem.c" />
|
<ClInclude Include="minizip-ng\mz_strm_mem.h" />
|
||||||
<ClCompile Include="mz_strm_os_win32.c" />
|
<ClInclude Include="minizip-ng\mz_strm_os.h" />
|
||||||
<ClCompile Include="mz_strm_split.c" />
|
<ClInclude Include="minizip-ng\mz_strm_split.h" />
|
||||||
<ClCompile Include="mz_strm_zlib.c" />
|
<ClInclude Include="minizip-ng\mz_strm_zlib.h" />
|
||||||
<ClCompile Include="mz_zip.c" />
|
<ClInclude Include="minizip-ng\mz_zip.h" />
|
||||||
<ClCompile Include="mz_zip_rw.c" />
|
<ClInclude Include="minizip-ng\mz_zip_rw.h" />
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="mz.h" />
|
|
||||||
<ClInclude Include="mz_compat.h" />
|
|
||||||
<ClInclude Include="mz_crypt.h" />
|
|
||||||
<ClInclude Include="mz_os.h" />
|
|
||||||
<ClInclude Include="mz_strm.h" />
|
|
||||||
<ClInclude Include="mz_strm_buf.h" />
|
|
||||||
<ClInclude Include="mz_strm_mem.h" />
|
|
||||||
<ClInclude Include="mz_strm_os.h" />
|
|
||||||
<ClInclude Include="mz_strm_split.h" />
|
|
||||||
<ClInclude Include="mz_strm_zlib.h" />
|
|
||||||
<ClInclude Include="mz_zip.h" />
|
|
||||||
<ClInclude Include="mz_zip_rw.h" />
|
|
||||||
<ClInclude Include="unzip.h" />
|
|
||||||
<ClInclude Include="zip.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="LICENSE" />
|
|
||||||
<None Include="README" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(ExternalsDir)zlib-ng\exports.props" />
|
<Import Project="$(ExternalsDir)zlib-ng\exports.props" />
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +0,0 @@
|
||||||
Condition of use and distribution are the same as zlib:
|
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any damages
|
|
||||||
arising from the use of this software.
|
|
||||||
|
|
||||||
Permission is granted to anyone to use this software for any purpose,
|
|
||||||
including commercial applications, and to alter it and redistribute it
|
|
||||||
freely, subject to the following restrictions:
|
|
||||||
|
|
||||||
1. The origin of this software must not be misrepresented; you must not
|
|
||||||
claim that you wrote the original software. If you use this software
|
|
||||||
in a product, an acknowledgement in the product documentation would be
|
|
||||||
appreciated but is not required.
|
|
||||||
2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
misrepresented as being the original software.
|
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
|
|
@ -1,3 +0,0 @@
|
||||||
minizip-ng, Version 3.0.4 (2021-11-29)
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
Revision: 95987e98b4862c055b8cf91d6e7ce5f9153ddc24
|
|
|
@ -1,182 +0,0 @@
|
||||||
/* minigzip.c
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_os.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_os.h"
|
|
||||||
#include "mz_strm_zlib.h"
|
|
||||||
|
|
||||||
#include <stdio.h> /* printf */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#define MZ_GZIP_COMPRESS (1)
|
|
||||||
#define MZ_GZIP_DECOMPRESS (2)
|
|
||||||
|
|
||||||
int32_t minigzip_banner(void);
|
|
||||||
int32_t minigzip_help(void);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t minigzip_banner(void) {
|
|
||||||
printf("Minigzip %s - https://github.com/zlib-ng/minizip-ng\n", MZ_VERSION);
|
|
||||||
printf("---------------------------------------------------\n");
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t minigzip_help(void) {
|
|
||||||
printf("Usage: minigzip [-x] [-d] [-0 to -9] [files]\n\n" \
|
|
||||||
" -x Extract file\n" \
|
|
||||||
" -d Destination directory\n" \
|
|
||||||
" -0 Store only\n" \
|
|
||||||
" -1 Compress faster\n" \
|
|
||||||
" -9 Compress better\n\n");
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t minigzip_copy(const char *path, const char *destination, int16_t operation, int16_t level) {
|
|
||||||
void *target_stream = NULL;
|
|
||||||
void *source_stream = NULL;
|
|
||||||
void *zlib_stream = NULL;
|
|
||||||
const char *filename = NULL;
|
|
||||||
char target_path[1024];
|
|
||||||
int32_t err = 0;
|
|
||||||
|
|
||||||
|
|
||||||
memset(target_path, 0, sizeof(target_path));
|
|
||||||
|
|
||||||
if (destination != NULL) {
|
|
||||||
if (mz_os_file_exists(destination) != MZ_OK)
|
|
||||||
mz_dir_make(destination);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (operation == MZ_GZIP_COMPRESS) {
|
|
||||||
mz_path_combine(target_path, path, sizeof(target_path));
|
|
||||||
strncat(target_path, ".gz", sizeof(target_path) - strlen(target_path) - 1);
|
|
||||||
printf("Compressing to %s\n", target_path);
|
|
||||||
} else if (operation == MZ_GZIP_DECOMPRESS) {
|
|
||||||
if (destination != NULL)
|
|
||||||
mz_path_combine(target_path, destination, sizeof(target_path));
|
|
||||||
|
|
||||||
if (mz_path_get_filename(path, &filename) != MZ_OK)
|
|
||||||
filename = path;
|
|
||||||
|
|
||||||
mz_path_combine(target_path, filename, sizeof(target_path));
|
|
||||||
mz_path_remove_extension(target_path);
|
|
||||||
printf("Decompressing to %s\n", target_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_stream_zlib_create(&zlib_stream);
|
|
||||||
mz_stream_zlib_set_prop_int64(zlib_stream, MZ_STREAM_PROP_COMPRESS_WINDOW, 15 + 16);
|
|
||||||
|
|
||||||
mz_stream_os_create(&source_stream);
|
|
||||||
err = mz_stream_os_open(source_stream, path, MZ_OPEN_MODE_READ);
|
|
||||||
|
|
||||||
if (err == MZ_OK) {
|
|
||||||
mz_stream_os_create(&target_stream);
|
|
||||||
err = mz_stream_os_open(target_stream, target_path, MZ_OPEN_MODE_CREATE | MZ_OPEN_MODE_WRITE);
|
|
||||||
|
|
||||||
if (err == MZ_OK) {
|
|
||||||
if (operation == MZ_GZIP_COMPRESS) {
|
|
||||||
mz_stream_zlib_set_prop_int64(zlib_stream, MZ_STREAM_PROP_COMPRESS_LEVEL, level);
|
|
||||||
mz_stream_zlib_open(zlib_stream, target_path, MZ_OPEN_MODE_WRITE);
|
|
||||||
mz_stream_set_base(zlib_stream, target_stream);
|
|
||||||
err = mz_stream_copy_to_end(zlib_stream, source_stream);
|
|
||||||
} else if (operation == MZ_GZIP_DECOMPRESS) {
|
|
||||||
mz_stream_zlib_open(zlib_stream, path, MZ_OPEN_MODE_READ);
|
|
||||||
mz_stream_set_base(zlib_stream, source_stream);
|
|
||||||
err = mz_stream_copy_to_end(target_stream, zlib_stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err != MZ_OK)
|
|
||||||
printf("Error %d in zlib stream (%d)\n", err, mz_stream_zlib_error(zlib_stream));
|
|
||||||
else
|
|
||||||
printf("Operation completed successfully\n");
|
|
||||||
|
|
||||||
mz_stream_zlib_close(zlib_stream);
|
|
||||||
} else {
|
|
||||||
printf("Error %d opening target path %s\n", err, target_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_stream_os_close(target_stream);
|
|
||||||
mz_stream_os_delete(&target_stream);
|
|
||||||
} else {
|
|
||||||
printf("Error %d opening source path %s\n", err, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_stream_os_close(source_stream);
|
|
||||||
mz_stream_os_delete(&source_stream);
|
|
||||||
|
|
||||||
mz_stream_zlib_delete(&zlib_stream);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if !defined(MZ_ZIP_NO_MAIN)
|
|
||||||
int main(int argc, const char *argv[]) {
|
|
||||||
int16_t operation_level = MZ_COMPRESS_LEVEL_DEFAULT;
|
|
||||||
int32_t path_arg = 0;
|
|
||||||
int32_t err = 0;
|
|
||||||
int32_t i = 0;
|
|
||||||
uint8_t operation = MZ_GZIP_COMPRESS;
|
|
||||||
const char *path = NULL;
|
|
||||||
const char *destination = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
minigzip_banner();
|
|
||||||
if (argc == 1) {
|
|
||||||
minigzip_help();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse command line options */
|
|
||||||
for (i = 1; i < argc; i += 1) {
|
|
||||||
printf("%s ", argv[i]);
|
|
||||||
if (argv[i][0] == '-') {
|
|
||||||
char c = argv[i][1];
|
|
||||||
if ((c == 'x') || (c == 'X'))
|
|
||||||
operation = MZ_GZIP_DECOMPRESS;
|
|
||||||
else if ((c >= '0') && (c <= '9'))
|
|
||||||
operation_level = (c - '0');
|
|
||||||
else if (((c == 'd') || (c == 'D')) && (i + 1 < argc)) {
|
|
||||||
destination = argv[i + 1];
|
|
||||||
printf("%s ", argv[i + 1]);
|
|
||||||
i += 1;
|
|
||||||
} else {
|
|
||||||
err = MZ_SUPPORT_ERROR;
|
|
||||||
}
|
|
||||||
} else if (path_arg == 0) {
|
|
||||||
path_arg = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if (err == MZ_SUPPORT_ERROR) {
|
|
||||||
printf("Feature not supported\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path_arg == 0) {
|
|
||||||
minigzip_help();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = argv[path_arg];
|
|
||||||
err = minigzip_copy(path, destination, operation, operation_level);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,671 +0,0 @@
|
||||||
/* minizip.c
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
Copyright (C) 1998-2010 Gilles Vollant
|
|
||||||
https://www.winimage.com/zLibDll/minizip.html
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_os.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_buf.h"
|
|
||||||
#include "mz_strm_split.h"
|
|
||||||
#include "mz_zip.h"
|
|
||||||
#include "mz_zip_rw.h"
|
|
||||||
|
|
||||||
#include <stdio.h> /* printf */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct minizip_opt_s {
|
|
||||||
uint8_t include_path;
|
|
||||||
int16_t compress_level;
|
|
||||||
uint8_t compress_method;
|
|
||||||
uint8_t overwrite;
|
|
||||||
uint8_t append;
|
|
||||||
int64_t disk_size;
|
|
||||||
uint8_t follow_links;
|
|
||||||
uint8_t store_links;
|
|
||||||
uint8_t zip_cd;
|
|
||||||
int32_t encoding;
|
|
||||||
uint8_t verbose;
|
|
||||||
uint8_t aes;
|
|
||||||
const char *cert_path;
|
|
||||||
const char *cert_pwd;
|
|
||||||
} minizip_opt;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t minizip_banner(void);
|
|
||||||
int32_t minizip_help(void);
|
|
||||||
|
|
||||||
int32_t minizip_list(const char *path);
|
|
||||||
|
|
||||||
int32_t minizip_add_entry_cb(void *handle, void *userdata, mz_zip_file *file_info);
|
|
||||||
int32_t minizip_add_progress_cb(void *handle, void *userdata, mz_zip_file *file_info, int64_t position);
|
|
||||||
int32_t minizip_add_overwrite_cb(void *handle, void *userdata, const char *path);
|
|
||||||
int32_t minizip_add(const char *path, const char *password, minizip_opt *options, int32_t arg_count, const char **args);
|
|
||||||
|
|
||||||
int32_t minizip_extract_entry_cb(void *handle, void *userdata, mz_zip_file *file_info, const char *path);
|
|
||||||
int32_t minizip_extract_progress_cb(void *handle, void *userdata, mz_zip_file *file_info, int64_t position);
|
|
||||||
int32_t minizip_extract_overwrite_cb(void *handle, void *userdata, mz_zip_file *file_info, const char *path);
|
|
||||||
int32_t minizip_extract(const char *path, const char *pattern, const char *destination, const char *password, minizip_opt *options);
|
|
||||||
|
|
||||||
int32_t minizip_erase(const char *src_path, const char *target_path, int32_t arg_count, const char **args);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t minizip_banner(void) {
|
|
||||||
printf("minizip-ng %s - https://github.com/zlib-ng/minizip-ng\n", MZ_VERSION);
|
|
||||||
printf("---------------------------------------------------\n");
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t minizip_help(void) {
|
|
||||||
printf("Usage: minizip [-x][-d dir|-l|-e][-o][-f][-y][-c cp][-a][-0 to -9][-b|-m|-t][-k 512][-p pwd][-s] file.zip [files]\n\n" \
|
|
||||||
" -x Extract files\n" \
|
|
||||||
" -l List files\n" \
|
|
||||||
" -d Destination directory\n" \
|
|
||||||
" -e Erase files\n" \
|
|
||||||
" -o Overwrite existing files\n" \
|
|
||||||
" -c File names use cp437 encoding (or specified codepage)\n" \
|
|
||||||
" -a Append to existing zip file\n" \
|
|
||||||
" -i Include full path of files\n" \
|
|
||||||
" -f Follow symbolic links\n" \
|
|
||||||
" -y Store symbolic links\n" \
|
|
||||||
" -v Verbose info\n" \
|
|
||||||
" -0 Store only\n" \
|
|
||||||
" -1 Compress faster\n" \
|
|
||||||
" -9 Compress better\n" \
|
|
||||||
" -k Disk size in KB\n" \
|
|
||||||
" -z Zip central directory\n" \
|
|
||||||
" -p Encryption password\n" \
|
|
||||||
" -s AES encryption\n" \
|
|
||||||
" -h PKCS12 certificate path\n" \
|
|
||||||
" -w PKCS12 certificate password\n" \
|
|
||||||
" -b BZIP2 compression\n" \
|
|
||||||
" -m LZMA compression\n" \
|
|
||||||
" -n XZ compression\n" \
|
|
||||||
" -t ZSTD compression\n\n");
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t minizip_list(const char *path) {
|
|
||||||
mz_zip_file *file_info = NULL;
|
|
||||||
uint32_t ratio = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
struct tm tmu_date;
|
|
||||||
const char *method = NULL;
|
|
||||||
char crypt = ' ';
|
|
||||||
void *reader = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
mz_zip_reader_create(&reader);
|
|
||||||
err = mz_zip_reader_open_file(reader, path);
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
printf("Error %" PRId32 " opening archive %s\n", err, path);
|
|
||||||
mz_zip_reader_delete(&reader);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mz_zip_reader_goto_first_entry(reader);
|
|
||||||
|
|
||||||
if (err != MZ_OK && err != MZ_END_OF_LIST) {
|
|
||||||
printf("Error %" PRId32 " going to first entry in archive\n", err);
|
|
||||||
mz_zip_reader_delete(&reader);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(" Packed Unpacked Ratio Method Attribs Date Time CRC-32 Name\n");
|
|
||||||
printf(" ------ -------- ----- ------ ------- ---- ---- ------ ----\n");
|
|
||||||
|
|
||||||
/* Enumerate all entries in the archive */
|
|
||||||
do {
|
|
||||||
err = mz_zip_reader_entry_get_info(reader, &file_info);
|
|
||||||
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
printf("Error %" PRId32 " getting entry info in archive\n", err);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ratio = 0;
|
|
||||||
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 & MZ_ZIP_FLAG_ENCRYPTED)
|
|
||||||
crypt = '*';
|
|
||||||
else
|
|
||||||
crypt = ' ';
|
|
||||||
|
|
||||||
method = mz_zip_get_compression_method_string(file_info->compression_method);
|
|
||||||
mz_zip_time_t_to_tm(file_info->modified_date, &tmu_date);
|
|
||||||
|
|
||||||
/* Print entry information */
|
|
||||||
printf("%12" PRId64 " %12" PRId64 " %3" PRIu32 "%% %6s%c %8" PRIx32 " %2.2" PRIu32 \
|
|
||||||
"-%2.2" PRIu32 "-%2.2" PRIu32 " %2.2" PRIu32 ":%2.2" PRIu32 " %8.8" PRIx32 " %s\n",
|
|
||||||
file_info->compressed_size, file_info->uncompressed_size, ratio,
|
|
||||||
method, crypt, file_info->external_fa,
|
|
||||||
(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, file_info->filename);
|
|
||||||
|
|
||||||
err = mz_zip_reader_goto_next_entry(reader);
|
|
||||||
|
|
||||||
if (err != MZ_OK && err != MZ_END_OF_LIST) {
|
|
||||||
printf("Error %" PRId32 " going to next entry in archive\n", err);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (err == MZ_OK);
|
|
||||||
|
|
||||||
mz_zip_reader_delete(&reader);
|
|
||||||
|
|
||||||
if (err == MZ_END_OF_LIST)
|
|
||||||
return MZ_OK;
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t minizip_add_entry_cb(void *handle, void *userdata, mz_zip_file *file_info) {
|
|
||||||
MZ_UNUSED(handle);
|
|
||||||
MZ_UNUSED(userdata);
|
|
||||||
|
|
||||||
/* Print the current file we are trying to compress */
|
|
||||||
printf("Adding %s\n", file_info->filename);
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t minizip_add_progress_cb(void *handle, void *userdata, mz_zip_file *file_info, int64_t position) {
|
|
||||||
minizip_opt *options = (minizip_opt *)userdata;
|
|
||||||
double progress = 0;
|
|
||||||
uint8_t raw = 0;
|
|
||||||
|
|
||||||
MZ_UNUSED(userdata);
|
|
||||||
|
|
||||||
mz_zip_writer_get_raw(handle, &raw);
|
|
||||||
|
|
||||||
if (raw && file_info->compressed_size > 0)
|
|
||||||
progress = ((double)position / file_info->compressed_size) * 100;
|
|
||||||
else if (!raw && file_info->uncompressed_size > 0)
|
|
||||||
progress = ((double)position / file_info->uncompressed_size) * 100;
|
|
||||||
|
|
||||||
/* Print the progress of the current compress operation */
|
|
||||||
if (options->verbose)
|
|
||||||
printf("%s - %" PRId64 " / %" PRId64 " (%.02f%%)\n", file_info->filename, position,
|
|
||||||
file_info->uncompressed_size, progress);
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t minizip_add_overwrite_cb(void *handle, void *userdata, const char *path) {
|
|
||||||
minizip_opt *options = (minizip_opt *)userdata;
|
|
||||||
|
|
||||||
MZ_UNUSED(handle);
|
|
||||||
|
|
||||||
if (options->overwrite == 0) {
|
|
||||||
/* If ask the user what to do because append and overwrite args not set */
|
|
||||||
char rep = 0;
|
|
||||||
do {
|
|
||||||
char answer[128];
|
|
||||||
printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ", path);
|
|
||||||
if (scanf("%1s", answer) != 1)
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
rep = answer[0];
|
|
||||||
|
|
||||||
if ((rep >= 'a') && (rep <= 'z'))
|
|
||||||
rep -= 0x20;
|
|
||||||
} while ((rep != 'Y') && (rep != 'N') && (rep != 'A'));
|
|
||||||
|
|
||||||
if (rep == 'A') {
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
} else if (rep == 'N') {
|
|
||||||
return MZ_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t minizip_add(const char *path, const char *password, minizip_opt *options, int32_t arg_count, const char **args) {
|
|
||||||
void *writer = NULL;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
int32_t err_close = MZ_OK;
|
|
||||||
int32_t i = 0;
|
|
||||||
const char *filename_in_zip = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
printf("Archive %s\n", path);
|
|
||||||
|
|
||||||
/* Create zip writer */
|
|
||||||
mz_zip_writer_create(&writer);
|
|
||||||
mz_zip_writer_set_password(writer, password);
|
|
||||||
mz_zip_writer_set_aes(writer, options->aes);
|
|
||||||
mz_zip_writer_set_compress_method(writer, options->compress_method);
|
|
||||||
mz_zip_writer_set_compress_level(writer, options->compress_level);
|
|
||||||
mz_zip_writer_set_follow_links(writer, options->follow_links);
|
|
||||||
mz_zip_writer_set_store_links(writer, options->store_links);
|
|
||||||
mz_zip_writer_set_overwrite_cb(writer, options, minizip_add_overwrite_cb);
|
|
||||||
mz_zip_writer_set_progress_cb(writer, options, minizip_add_progress_cb);
|
|
||||||
mz_zip_writer_set_entry_cb(writer, options, minizip_add_entry_cb);
|
|
||||||
mz_zip_writer_set_zip_cd(writer, options->zip_cd);
|
|
||||||
if (options->cert_path != NULL)
|
|
||||||
mz_zip_writer_set_certificate(writer, options->cert_path, options->cert_pwd);
|
|
||||||
|
|
||||||
err = mz_zip_writer_open_file(writer, path, options->disk_size, options->append);
|
|
||||||
|
|
||||||
if (err == MZ_OK) {
|
|
||||||
for (i = 0; i < arg_count; i += 1) {
|
|
||||||
filename_in_zip = args[i];
|
|
||||||
|
|
||||||
/* Add file system path to archive */
|
|
||||||
err = mz_zip_writer_add_path(writer, filename_in_zip, NULL, options->include_path, 1);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
printf("Error %" PRId32 " adding path to archive %s\n", err, filename_in_zip);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("Error %" PRId32 " opening archive for writing\n", err);
|
|
||||||
}
|
|
||||||
|
|
||||||
err_close = mz_zip_writer_close(writer);
|
|
||||||
if (err_close != MZ_OK) {
|
|
||||||
printf("Error %" PRId32 " closing archive for writing %s\n", err_close, path);
|
|
||||||
err = err_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_zip_writer_delete(&writer);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t minizip_extract_entry_cb(void *handle, void *userdata, mz_zip_file *file_info, const char *path) {
|
|
||||||
MZ_UNUSED(handle);
|
|
||||||
MZ_UNUSED(userdata);
|
|
||||||
MZ_UNUSED(path);
|
|
||||||
|
|
||||||
/* Print the current entry extracting */
|
|
||||||
printf("Extracting %s\n", file_info->filename);
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t minizip_extract_progress_cb(void *handle, void *userdata, mz_zip_file *file_info, int64_t position) {
|
|
||||||
minizip_opt *options = (minizip_opt *)userdata;
|
|
||||||
double progress = 0;
|
|
||||||
uint8_t raw = 0;
|
|
||||||
|
|
||||||
MZ_UNUSED(userdata);
|
|
||||||
|
|
||||||
mz_zip_reader_get_raw(handle, &raw);
|
|
||||||
|
|
||||||
if (raw && file_info->compressed_size > 0)
|
|
||||||
progress = ((double)position / file_info->compressed_size) * 100;
|
|
||||||
else if (!raw && file_info->uncompressed_size > 0)
|
|
||||||
progress = ((double)position / file_info->uncompressed_size) * 100;
|
|
||||||
|
|
||||||
/* Print the progress of the current extraction */
|
|
||||||
if (options->verbose)
|
|
||||||
printf("%s - %" PRId64 " / %" PRId64 " (%.02f%%)\n", file_info->filename, position,
|
|
||||||
file_info->uncompressed_size, progress);
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t minizip_extract_overwrite_cb(void *handle, void *userdata, mz_zip_file *file_info, const char *path) {
|
|
||||||
minizip_opt *options = (minizip_opt *)userdata;
|
|
||||||
|
|
||||||
MZ_UNUSED(handle);
|
|
||||||
MZ_UNUSED(file_info);
|
|
||||||
|
|
||||||
/* Verify if we want to overwrite current entry on disk */
|
|
||||||
if (options->overwrite == 0) {
|
|
||||||
char rep = 0;
|
|
||||||
do {
|
|
||||||
char answer[128];
|
|
||||||
printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ", path);
|
|
||||||
if (scanf("%1s", answer) != 1)
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
rep = answer[0];
|
|
||||||
if ((rep >= 'a') && (rep <= 'z'))
|
|
||||||
rep -= 0x20;
|
|
||||||
} while ((rep != 'Y') && (rep != 'N') && (rep != 'A'));
|
|
||||||
|
|
||||||
if (rep == 'N')
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
if (rep == 'A')
|
|
||||||
options->overwrite = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t minizip_extract(const char *path, const char *pattern, const char *destination, const char *password, minizip_opt *options) {
|
|
||||||
void *reader = NULL;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
int32_t err_close = MZ_OK;
|
|
||||||
|
|
||||||
|
|
||||||
printf("Archive %s\n", path);
|
|
||||||
|
|
||||||
/* Create zip reader */
|
|
||||||
mz_zip_reader_create(&reader);
|
|
||||||
mz_zip_reader_set_pattern(reader, pattern, 1);
|
|
||||||
mz_zip_reader_set_password(reader, password);
|
|
||||||
mz_zip_reader_set_encoding(reader, options->encoding);
|
|
||||||
mz_zip_reader_set_entry_cb(reader, options, minizip_extract_entry_cb);
|
|
||||||
mz_zip_reader_set_progress_cb(reader, options, minizip_extract_progress_cb);
|
|
||||||
mz_zip_reader_set_overwrite_cb(reader, options, minizip_extract_overwrite_cb);
|
|
||||||
|
|
||||||
err = mz_zip_reader_open_file(reader, path);
|
|
||||||
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
printf("Error %" PRId32 " opening archive %s\n", err, path);
|
|
||||||
} else {
|
|
||||||
/* Save all entries in archive to destination directory */
|
|
||||||
err = mz_zip_reader_save_all(reader, destination);
|
|
||||||
|
|
||||||
if (err == MZ_END_OF_LIST) {
|
|
||||||
if (pattern != NULL) {
|
|
||||||
printf("Files matching %s not found in archive\n", pattern);
|
|
||||||
} else {
|
|
||||||
printf("No files in archive\n");
|
|
||||||
err = MZ_OK;
|
|
||||||
}
|
|
||||||
} else if (err != MZ_OK) {
|
|
||||||
printf("Error %" PRId32 " saving entries to disk %s\n", err, path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err_close = mz_zip_reader_close(reader);
|
|
||||||
if (err_close != MZ_OK) {
|
|
||||||
printf("Error %" PRId32 " closing archive for reading\n", err_close);
|
|
||||||
err = err_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_zip_reader_delete(&reader);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t minizip_erase(const char *src_path, const char *target_path, int32_t arg_count, const char **args) {
|
|
||||||
mz_zip_file *file_info = NULL;
|
|
||||||
const char *filename_in_zip = NULL;
|
|
||||||
const char *target_path_ptr = target_path;
|
|
||||||
void *reader = NULL;
|
|
||||||
void *writer = NULL;
|
|
||||||
int32_t skip = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
int32_t i = 0;
|
|
||||||
uint8_t zip_cd = 0;
|
|
||||||
char bak_path[256];
|
|
||||||
char tmp_path[256];
|
|
||||||
|
|
||||||
if (target_path == NULL) {
|
|
||||||
/* Construct temporary zip name */
|
|
||||||
strncpy(tmp_path, src_path, sizeof(tmp_path) - 1);
|
|
||||||
tmp_path[sizeof(tmp_path) - 1] = 0;
|
|
||||||
strncat(tmp_path, ".tmp.zip", sizeof(tmp_path) - strlen(tmp_path) - 1);
|
|
||||||
target_path_ptr = tmp_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_zip_reader_create(&reader);
|
|
||||||
mz_zip_writer_create(&writer);
|
|
||||||
|
|
||||||
/* Open original archive we want to erase an entry in */
|
|
||||||
err = mz_zip_reader_open_file(reader, src_path);
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
printf("Error %" PRId32 " opening archive for reading %s\n", err, src_path);
|
|
||||||
mz_zip_reader_delete(&reader);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open temporary archive */
|
|
||||||
err = mz_zip_writer_open_file(writer, target_path_ptr, 0, 0);
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
printf("Error %" PRId32 " opening archive for writing %s\n", err, target_path_ptr);
|
|
||||||
mz_zip_reader_delete(&reader);
|
|
||||||
mz_zip_writer_delete(&writer);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mz_zip_reader_goto_first_entry(reader);
|
|
||||||
|
|
||||||
if (err != MZ_OK && err != MZ_END_OF_LIST)
|
|
||||||
printf("Error %" PRId32 " going to first entry in archive\n", err);
|
|
||||||
|
|
||||||
while (err == MZ_OK) {
|
|
||||||
err = mz_zip_reader_entry_get_info(reader, &file_info);
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
printf("Error %" PRId32 " getting info from archive\n", err);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy all entries from original archive to temporary archive
|
|
||||||
except the ones we don't want */
|
|
||||||
for (i = 0, skip = 0; i < arg_count; i += 1) {
|
|
||||||
filename_in_zip = args[i];
|
|
||||||
|
|
||||||
if (mz_path_compare_wc(file_info->filename, filename_in_zip, 1) == MZ_OK)
|
|
||||||
skip = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skip) {
|
|
||||||
printf("Skipping %s\n", file_info->filename);
|
|
||||||
} else {
|
|
||||||
printf("Copying %s\n", file_info->filename);
|
|
||||||
err = mz_zip_writer_copy_from_reader(writer, reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
printf("Error %" PRId32 " copying entry into new zip\n", err);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mz_zip_reader_goto_next_entry(reader);
|
|
||||||
|
|
||||||
if (err != MZ_OK && err != MZ_END_OF_LIST)
|
|
||||||
printf("Error %" PRId32 " going to next entry in archive\n", err);
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_zip_reader_get_zip_cd(reader, &zip_cd);
|
|
||||||
mz_zip_writer_set_zip_cd(writer, zip_cd);
|
|
||||||
|
|
||||||
mz_zip_reader_close(reader);
|
|
||||||
mz_zip_reader_delete(&reader);
|
|
||||||
|
|
||||||
mz_zip_writer_close(writer);
|
|
||||||
mz_zip_writer_delete(&writer);
|
|
||||||
|
|
||||||
if (err == MZ_END_OF_LIST) {
|
|
||||||
if (target_path == NULL) {
|
|
||||||
/* Swap original archive with temporary archive, backup old archive if possible */
|
|
||||||
strncpy(bak_path, src_path, sizeof(bak_path) - 1);
|
|
||||||
bak_path[sizeof(bak_path) - 1] = 0;
|
|
||||||
strncat(bak_path, ".bak", sizeof(bak_path) - strlen(bak_path) - 1);
|
|
||||||
|
|
||||||
if (mz_os_file_exists(bak_path) == MZ_OK)
|
|
||||||
mz_os_unlink(bak_path);
|
|
||||||
|
|
||||||
if (mz_os_rename(src_path, bak_path) != MZ_OK)
|
|
||||||
printf("Error backing up archive before replacing %s\n", bak_path);
|
|
||||||
|
|
||||||
if (mz_os_rename(tmp_path, src_path) != MZ_OK)
|
|
||||||
printf("Error replacing archive with temp %s\n", tmp_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if !defined(MZ_ZIP_NO_MAIN)
|
|
||||||
int main(int argc, const char *argv[]) {
|
|
||||||
minizip_opt options;
|
|
||||||
int32_t path_arg = 0;
|
|
||||||
int32_t err = 0;
|
|
||||||
int32_t i = 0;
|
|
||||||
uint8_t do_list = 0;
|
|
||||||
uint8_t do_extract = 0;
|
|
||||||
uint8_t do_erase = 0;
|
|
||||||
const char *path = NULL;
|
|
||||||
const char *password = NULL;
|
|
||||||
const char *destination = NULL;
|
|
||||||
const char *filename_to_extract = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
minizip_banner();
|
|
||||||
if (argc == 1) {
|
|
||||||
minizip_help();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&options, 0, sizeof(options));
|
|
||||||
|
|
||||||
options.compress_method = MZ_COMPRESS_METHOD_DEFLATE;
|
|
||||||
options.compress_level = MZ_COMPRESS_LEVEL_DEFAULT;
|
|
||||||
|
|
||||||
/* Parse command line options */
|
|
||||||
for (i = 1; i < argc; i += 1) {
|
|
||||||
printf("%s ", argv[i]);
|
|
||||||
if (argv[i][0] == '-') {
|
|
||||||
char c = argv[i][1];
|
|
||||||
if ((c == 'l') || (c == 'L'))
|
|
||||||
do_list = 1;
|
|
||||||
else if ((c == 'x') || (c == 'X'))
|
|
||||||
do_extract = 1;
|
|
||||||
else if ((c == 'e') || (c == 'E'))
|
|
||||||
do_erase = 1;
|
|
||||||
else if ((c == 'a') || (c == 'A'))
|
|
||||||
options.append = 1;
|
|
||||||
else if ((c == 'o') || (c == 'O'))
|
|
||||||
options.overwrite = 1;
|
|
||||||
else if ((c == 'f') || (c == 'F'))
|
|
||||||
options.follow_links = 1;
|
|
||||||
else if ((c == 'y') || (c == 'Y'))
|
|
||||||
options.store_links = 1;
|
|
||||||
else if ((c == 'i') || (c == 'I'))
|
|
||||||
options.include_path = 1;
|
|
||||||
else if ((c == 'z') || (c == 'Z'))
|
|
||||||
options.zip_cd = 1;
|
|
||||||
else if ((c == 'v') || (c == 'V'))
|
|
||||||
options.verbose = 1;
|
|
||||||
else if ((c >= '0') && (c <= '9')) {
|
|
||||||
options.compress_level = (c - '0');
|
|
||||||
if (options.compress_level == 0)
|
|
||||||
options.compress_method = MZ_COMPRESS_METHOD_STORE;
|
|
||||||
} else if ((c == 'b') || (c == 'B'))
|
|
||||||
#ifdef HAVE_BZIP2
|
|
||||||
options.compress_method = MZ_COMPRESS_METHOD_BZIP2;
|
|
||||||
#else
|
|
||||||
err = MZ_SUPPORT_ERROR;
|
|
||||||
#endif
|
|
||||||
else if ((c == 'm') || (c == 'M'))
|
|
||||||
#ifdef HAVE_LZMA
|
|
||||||
options.compress_method = MZ_COMPRESS_METHOD_LZMA;
|
|
||||||
#else
|
|
||||||
err = MZ_SUPPORT_ERROR;
|
|
||||||
#endif
|
|
||||||
else if ((c == 'n') || (c == 'N'))
|
|
||||||
#if defined(HAVE_LZMA) || defined(HAVE_LIBCOMP)
|
|
||||||
options.compress_method = MZ_COMPRESS_METHOD_XZ;
|
|
||||||
#else
|
|
||||||
err = MZ_SUPPORT_ERROR;
|
|
||||||
#endif
|
|
||||||
else if ((c == 't') || (c == 'T'))
|
|
||||||
#ifdef HAVE_ZSTD
|
|
||||||
options.compress_method = MZ_COMPRESS_METHOD_ZSTD;
|
|
||||||
#else
|
|
||||||
err = MZ_SUPPORT_ERROR;
|
|
||||||
#endif
|
|
||||||
else if ((c == 's') || (c == 'S'))
|
|
||||||
#ifdef HAVE_WZAES
|
|
||||||
options.aes = 1;
|
|
||||||
#else
|
|
||||||
err = MZ_SUPPORT_ERROR;
|
|
||||||
#endif
|
|
||||||
else if (((c == 'h') || (c == 'H')) && (i + 1 < argc)) {
|
|
||||||
#ifdef MZ_ZIP_SIGNING
|
|
||||||
options.cert_path = argv[i + 1];
|
|
||||||
printf("%s ", argv[i + 1]);
|
|
||||||
#else
|
|
||||||
err = MZ_SUPPORT_ERROR;
|
|
||||||
#endif
|
|
||||||
i += 1;
|
|
||||||
} else if (((c == 'w') || (c == 'W')) && (i + 1 < argc)) {
|
|
||||||
#ifdef MZ_ZIP_SIGNING
|
|
||||||
options.cert_pwd = argv[i + 1];
|
|
||||||
printf("%s ", argv[i + 1]);
|
|
||||||
#else
|
|
||||||
err = MZ_SUPPORT_ERROR;
|
|
||||||
#endif
|
|
||||||
i += 1;
|
|
||||||
} else if (((c == 'c') || (c == 'C')) && (i + 1 < argc)) {
|
|
||||||
options.encoding = (int32_t)atoi(argv[i + 1]);
|
|
||||||
i += 1;
|
|
||||||
} else if (((c == 'k') || (c == 'K')) && (i + 1 < argc)) {
|
|
||||||
options.disk_size = (int64_t)atoi(argv[i + 1]) * 1024;
|
|
||||||
printf("%s ", argv[i + 1]);
|
|
||||||
i += 1;
|
|
||||||
} else if (((c == 'd') || (c == 'D')) && (i + 1 < argc)) {
|
|
||||||
destination = argv[i + 1];
|
|
||||||
printf("%s ", argv[i + 1]);
|
|
||||||
i += 1;
|
|
||||||
} else if (((c == 'p') || (c == 'P')) && (i + 1 < argc)) {
|
|
||||||
#ifndef MZ_ZIP_NO_ENCRYPTION
|
|
||||||
password = argv[i + 1];
|
|
||||||
printf("*** ");
|
|
||||||
#else
|
|
||||||
err = MZ_SUPPORT_ERROR;
|
|
||||||
#endif
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
} else if (path_arg == 0)
|
|
||||||
path_arg = i;
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if (err == MZ_SUPPORT_ERROR) {
|
|
||||||
printf("Feature not supported\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path_arg == 0) {
|
|
||||||
minizip_help();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = argv[path_arg];
|
|
||||||
|
|
||||||
if (do_list) {
|
|
||||||
/* List archive contents */
|
|
||||||
err = minizip_list(path);
|
|
||||||
} else if (do_extract) {
|
|
||||||
if (argc > path_arg + 1)
|
|
||||||
filename_to_extract = argv[path_arg + 1];
|
|
||||||
|
|
||||||
/* Extract archive */
|
|
||||||
err = minizip_extract(path, filename_to_extract, destination, password, &options);
|
|
||||||
} else if (do_erase) {
|
|
||||||
/* Erase file in archive */
|
|
||||||
err = minizip_erase(path, NULL, argc - (path_arg + 1), &argv[path_arg + 1]);
|
|
||||||
} else {
|
|
||||||
/* Add files to archive */
|
|
||||||
err = minizip_add(path, password, &options, argc - (path_arg + 1), &argv[path_arg + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,14 +0,0 @@
|
||||||
prefix=@CMAKE_INSTALL_PREFIX@
|
|
||||||
exec_prefix=@CMAKE_INSTALL_PREFIX@
|
|
||||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
|
||||||
sharedlibdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
|
||||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
|
||||||
|
|
||||||
Name: @PROJECT_NAME@
|
|
||||||
Description: Minizip zip file manipulation library
|
|
||||||
Version: @VERSION@
|
|
||||||
|
|
||||||
Requires: zlib
|
|
||||||
Libs: -L${libdir} -L${sharedlibdir} -l@PROJECT_NAME@
|
|
||||||
Libs.private:@PC_PRIVATE_LIBS@
|
|
||||||
Cflags: -I${includedir}
|
|
|
@ -1,274 +0,0 @@
|
||||||
/* mz.h -- Errors codes, zip flags and magic
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_H
|
|
||||||
#define MZ_H
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
/* MZ_VERSION */
|
|
||||||
#define MZ_VERSION ("3.0.4")
|
|
||||||
#define MZ_VERSION_BUILD (030004)
|
|
||||||
|
|
||||||
/* MZ_ERROR */
|
|
||||||
#define MZ_OK (0) /* zlib */
|
|
||||||
#define MZ_STREAM_ERROR (-1) /* zlib */
|
|
||||||
#define MZ_DATA_ERROR (-3) /* zlib */
|
|
||||||
#define MZ_MEM_ERROR (-4) /* zlib */
|
|
||||||
#define MZ_BUF_ERROR (-5) /* zlib */
|
|
||||||
#define MZ_VERSION_ERROR (-6) /* zlib */
|
|
||||||
|
|
||||||
#define MZ_END_OF_LIST (-100)
|
|
||||||
#define MZ_END_OF_STREAM (-101)
|
|
||||||
|
|
||||||
#define MZ_PARAM_ERROR (-102)
|
|
||||||
#define MZ_FORMAT_ERROR (-103)
|
|
||||||
#define MZ_INTERNAL_ERROR (-104)
|
|
||||||
#define MZ_CRC_ERROR (-105)
|
|
||||||
#define MZ_CRYPT_ERROR (-106)
|
|
||||||
#define MZ_EXIST_ERROR (-107)
|
|
||||||
#define MZ_PASSWORD_ERROR (-108)
|
|
||||||
#define MZ_SUPPORT_ERROR (-109)
|
|
||||||
#define MZ_HASH_ERROR (-110)
|
|
||||||
#define MZ_OPEN_ERROR (-111)
|
|
||||||
#define MZ_CLOSE_ERROR (-112)
|
|
||||||
#define MZ_SEEK_ERROR (-113)
|
|
||||||
#define MZ_TELL_ERROR (-114)
|
|
||||||
#define MZ_READ_ERROR (-115)
|
|
||||||
#define MZ_WRITE_ERROR (-116)
|
|
||||||
#define MZ_SIGN_ERROR (-117)
|
|
||||||
#define MZ_SYMLINK_ERROR (-118)
|
|
||||||
|
|
||||||
/* MZ_OPEN */
|
|
||||||
#define MZ_OPEN_MODE_READ (0x01)
|
|
||||||
#define MZ_OPEN_MODE_WRITE (0x02)
|
|
||||||
#define MZ_OPEN_MODE_READWRITE (MZ_OPEN_MODE_READ | MZ_OPEN_MODE_WRITE)
|
|
||||||
#define MZ_OPEN_MODE_APPEND (0x04)
|
|
||||||
#define MZ_OPEN_MODE_CREATE (0x08)
|
|
||||||
#define MZ_OPEN_MODE_EXISTING (0x10)
|
|
||||||
|
|
||||||
/* MZ_SEEK */
|
|
||||||
#define MZ_SEEK_SET (0)
|
|
||||||
#define MZ_SEEK_CUR (1)
|
|
||||||
#define MZ_SEEK_END (2)
|
|
||||||
|
|
||||||
/* MZ_COMPRESS */
|
|
||||||
#define MZ_COMPRESS_METHOD_STORE (0)
|
|
||||||
#define MZ_COMPRESS_METHOD_DEFLATE (8)
|
|
||||||
#define MZ_COMPRESS_METHOD_BZIP2 (12)
|
|
||||||
#define MZ_COMPRESS_METHOD_LZMA (14)
|
|
||||||
#define MZ_COMPRESS_METHOD_ZSTD (93)
|
|
||||||
#define MZ_COMPRESS_METHOD_XZ (95)
|
|
||||||
#define MZ_COMPRESS_METHOD_AES (99)
|
|
||||||
|
|
||||||
#define MZ_COMPRESS_LEVEL_DEFAULT (-1)
|
|
||||||
#define MZ_COMPRESS_LEVEL_FAST (2)
|
|
||||||
#define MZ_COMPRESS_LEVEL_NORMAL (6)
|
|
||||||
#define MZ_COMPRESS_LEVEL_BEST (9)
|
|
||||||
|
|
||||||
/* MZ_ZIP_FLAG */
|
|
||||||
#define MZ_ZIP_FLAG_ENCRYPTED (1 << 0)
|
|
||||||
#define MZ_ZIP_FLAG_LZMA_EOS_MARKER (1 << 1)
|
|
||||||
#define MZ_ZIP_FLAG_DEFLATE_MAX (1 << 1)
|
|
||||||
#define MZ_ZIP_FLAG_DEFLATE_NORMAL (0)
|
|
||||||
#define MZ_ZIP_FLAG_DEFLATE_FAST (1 << 2)
|
|
||||||
#define MZ_ZIP_FLAG_DEFLATE_SUPER_FAST (MZ_ZIP_FLAG_DEFLATE_FAST | \
|
|
||||||
MZ_ZIP_FLAG_DEFLATE_MAX)
|
|
||||||
#define MZ_ZIP_FLAG_DATA_DESCRIPTOR (1 << 3)
|
|
||||||
#define MZ_ZIP_FLAG_UTF8 (1 << 11)
|
|
||||||
#define MZ_ZIP_FLAG_MASK_LOCAL_INFO (1 << 13)
|
|
||||||
|
|
||||||
/* MZ_ZIP_EXTENSION */
|
|
||||||
#define MZ_ZIP_EXTENSION_ZIP64 (0x0001)
|
|
||||||
#define MZ_ZIP_EXTENSION_NTFS (0x000a)
|
|
||||||
#define MZ_ZIP_EXTENSION_AES (0x9901)
|
|
||||||
#define MZ_ZIP_EXTENSION_UNIX1 (0x000d)
|
|
||||||
#define MZ_ZIP_EXTENSION_SIGN (0x10c5)
|
|
||||||
#define MZ_ZIP_EXTENSION_HASH (0x1a51)
|
|
||||||
#define MZ_ZIP_EXTENSION_CDCD (0xcdcd)
|
|
||||||
|
|
||||||
/* MZ_ZIP64 */
|
|
||||||
#define MZ_ZIP64_AUTO (0)
|
|
||||||
#define MZ_ZIP64_FORCE (1)
|
|
||||||
#define MZ_ZIP64_DISABLE (2)
|
|
||||||
|
|
||||||
/* MZ_HOST_SYSTEM */
|
|
||||||
#define MZ_HOST_SYSTEM(VERSION_MADEBY) ((uint8_t)(VERSION_MADEBY >> 8))
|
|
||||||
#define MZ_HOST_SYSTEM_MSDOS (0)
|
|
||||||
#define MZ_HOST_SYSTEM_UNIX (3)
|
|
||||||
#define MZ_HOST_SYSTEM_WINDOWS_NTFS (10)
|
|
||||||
#define MZ_HOST_SYSTEM_RISCOS (13)
|
|
||||||
#define MZ_HOST_SYSTEM_OSX_DARWIN (19)
|
|
||||||
|
|
||||||
/* MZ_PKCRYPT */
|
|
||||||
#define MZ_PKCRYPT_HEADER_SIZE (12)
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
#define MZ_AES_KEY_LENGTH(MODE) (8 * (MODE & 3) + 8)
|
|
||||||
#define MZ_AES_KEY_LENGTH_MAX (32)
|
|
||||||
#define MZ_AES_BLOCK_SIZE (16)
|
|
||||||
#define MZ_AES_HEADER_SIZE(MODE) ((4 * (MODE & 3) + 4) + 2)
|
|
||||||
#define MZ_AES_FOOTER_SIZE (10)
|
|
||||||
|
|
||||||
/* MZ_HASH */
|
|
||||||
#define MZ_HASH_MD5 (10)
|
|
||||||
#define MZ_HASH_MD5_SIZE (16)
|
|
||||||
#define MZ_HASH_SHA1 (20)
|
|
||||||
#define MZ_HASH_SHA1_SIZE (20)
|
|
||||||
#define MZ_HASH_SHA256 (23)
|
|
||||||
#define MZ_HASH_SHA256_SIZE (32)
|
|
||||||
#define MZ_HASH_MAX_SIZE (256)
|
|
||||||
|
|
||||||
/* MZ_ENCODING */
|
|
||||||
#define MZ_ENCODING_CODEPAGE_437 (437)
|
|
||||||
#define MZ_ENCODING_CODEPAGE_932 (932)
|
|
||||||
#define MZ_ENCODING_CODEPAGE_936 (936)
|
|
||||||
#define MZ_ENCODING_CODEPAGE_950 (950)
|
|
||||||
#define MZ_ENCODING_UTF8 (65001)
|
|
||||||
|
|
||||||
/* MZ_UTILITY */
|
|
||||||
#define MZ_UNUSED(SYMBOL) ((void)SYMBOL)
|
|
||||||
|
|
||||||
#ifndef MZ_CUSTOM_ALLOC
|
|
||||||
#define MZ_ALLOC(SIZE) (malloc((SIZE)))
|
|
||||||
#endif
|
|
||||||
#ifndef MZ_CUSTOM_FREE
|
|
||||||
#define MZ_FREE(PTR) (free(PTR))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(MZ_EXPORTS)
|
|
||||||
#define MZ_EXPORT __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define MZ_EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#include <stdlib.h> /* size_t, NULL, malloc */
|
|
||||||
#include <time.h> /* time_t, time() */
|
|
||||||
#include <string.h> /* memset, strncpy, strlen */
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#if defined(HAVE_STDINT_H)
|
|
||||||
# include <stdint.h>
|
|
||||||
#elif defined(__has_include)
|
|
||||||
# if __has_include(<stdint.h>)
|
|
||||||
# include <stdint.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef INT8_MAX
|
|
||||||
typedef signed char int8_t;
|
|
||||||
#endif
|
|
||||||
#ifndef INT16_MAX
|
|
||||||
typedef short int16_t;
|
|
||||||
#endif
|
|
||||||
#ifndef INT32_MAX
|
|
||||||
typedef int int32_t;
|
|
||||||
#endif
|
|
||||||
#ifndef INT64_MAX
|
|
||||||
typedef long long int64_t;
|
|
||||||
#endif
|
|
||||||
#ifndef UINT8_MAX
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
#endif
|
|
||||||
#ifndef UINT16_MAX
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
#endif
|
|
||||||
#ifndef UINT32_MAX
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
#endif
|
|
||||||
#ifndef UINT64_MAX
|
|
||||||
typedef unsigned long long uint64_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_INTTYPES_H)
|
|
||||||
# include <inttypes.h>
|
|
||||||
#elif defined(__has_include)
|
|
||||||
# if __has_include(<inttypes.h>)
|
|
||||||
# include <inttypes.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PRId8
|
|
||||||
# define PRId8 "hhd"
|
|
||||||
#endif
|
|
||||||
#ifndef PRIu8
|
|
||||||
# define PRIu8 "hhu"
|
|
||||||
#endif
|
|
||||||
#ifndef PRIx8
|
|
||||||
# define PRIx8 "hhx"
|
|
||||||
#endif
|
|
||||||
#ifndef PRId16
|
|
||||||
# define PRId16 "hd"
|
|
||||||
#endif
|
|
||||||
#ifndef PRIu16
|
|
||||||
# define PRIu16 "hu"
|
|
||||||
#endif
|
|
||||||
#ifndef PRIx16
|
|
||||||
# define PRIx16 "hx"
|
|
||||||
#endif
|
|
||||||
#ifndef PRId32
|
|
||||||
# define PRId32 "d"
|
|
||||||
#endif
|
|
||||||
#ifndef PRIu32
|
|
||||||
# define PRIu32 "u"
|
|
||||||
#endif
|
|
||||||
#ifndef PRIx32
|
|
||||||
# define PRIx32 "x"
|
|
||||||
#endif
|
|
||||||
#if ULONG_MAX == 0xfffffffful
|
|
||||||
# ifndef PRId64
|
|
||||||
# define PRId64 "ld"
|
|
||||||
# endif
|
|
||||||
# ifndef PRIu64
|
|
||||||
# define PRIu64 "lu"
|
|
||||||
# endif
|
|
||||||
# ifndef PRIx64
|
|
||||||
# define PRIx64 "lx"
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# ifndef PRId64
|
|
||||||
# define PRId64 "lld"
|
|
||||||
# endif
|
|
||||||
# ifndef PRIu64
|
|
||||||
# define PRIu64 "llu"
|
|
||||||
# endif
|
|
||||||
# ifndef PRIx64
|
|
||||||
# define PRIx64 "llx"
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef INT16_MAX
|
|
||||||
# define INT16_MAX 32767
|
|
||||||
#endif
|
|
||||||
#ifndef INT32_MAX
|
|
||||||
# define INT32_MAX 2147483647L
|
|
||||||
#endif
|
|
||||||
#ifndef INT64_MAX
|
|
||||||
# define INT64_MAX 9223372036854775807LL
|
|
||||||
#endif
|
|
||||||
#ifndef UINT16_MAX
|
|
||||||
# define UINT16_MAX 65535U
|
|
||||||
#endif
|
|
||||||
#ifndef UINT32_MAX
|
|
||||||
# define UINT32_MAX 4294967295UL
|
|
||||||
#endif
|
|
||||||
#ifndef UINT64_MAX
|
|
||||||
# define UINT64_MAX 18446744073709551615ULL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,396 +0,0 @@
|
||||||
/* mz_compat.h -- Backwards compatible interface for older versions
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
Copyright (C) 1998-2010 Gilles Vollant
|
|
||||||
https://www.winimage.com/zLibDll/minizip.html
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_COMPAT_H
|
|
||||||
#define MZ_COMPAT_H
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(HAVE_ZLIB) && defined(MAX_MEM_LEVEL)
|
|
||||||
#ifndef DEF_MEM_LEVEL
|
|
||||||
# if MAX_MEM_LEVEL >= 8
|
|
||||||
# define DEF_MEM_LEVEL 8
|
|
||||||
# else
|
|
||||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifndef MAX_WBITS
|
|
||||||
#define MAX_WBITS (15)
|
|
||||||
#endif
|
|
||||||
#ifndef DEF_MEM_LEVEL
|
|
||||||
#define DEF_MEM_LEVEL (8)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ZEXPORT
|
|
||||||
# define ZEXPORT MZ_EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
|
|
||||||
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
|
||||||
from (void*) without cast */
|
|
||||||
typedef struct TagzipFile__ { int unused; } zip_file__;
|
|
||||||
typedef zip_file__ *zipFile;
|
|
||||||
#else
|
|
||||||
typedef void *zipFile;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef uint64_t ZPOS64_T;
|
|
||||||
|
|
||||||
#ifndef ZCALLBACK
|
|
||||||
#define ZCALLBACK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef void* (ZCALLBACK *open_file_func) (void *opaque, const char *filename, int mode);
|
|
||||||
typedef void* (ZCALLBACK *open64_file_func) (void *opaque, const void *filename, int mode);
|
|
||||||
typedef unsigned long (ZCALLBACK *read_file_func) (void *opaque, void *stream, void* buf, unsigned long size);
|
|
||||||
typedef unsigned long (ZCALLBACK *write_file_func) (void *opaque, void *stream, const void* buf,
|
|
||||||
unsigned long size);
|
|
||||||
typedef int (ZCALLBACK *close_file_func) (void *opaque, void *stream);
|
|
||||||
typedef int (ZCALLBACK *testerror_file_func)(void *opaque, void *stream);
|
|
||||||
typedef long (ZCALLBACK *tell_file_func) (void *opaque, void *stream);
|
|
||||||
typedef ZPOS64_T (ZCALLBACK *tell64_file_func) (void *opaque, void *stream);
|
|
||||||
typedef long (ZCALLBACK *seek_file_func) (void *opaque, void *stream, unsigned long offset, int origin);
|
|
||||||
typedef long (ZCALLBACK *seek64_file_func) (void *opaque, void *stream, ZPOS64_T offset, int origin);
|
|
||||||
|
|
||||||
typedef struct zlib_filefunc_def_s
|
|
||||||
{
|
|
||||||
open_file_func zopen_file;
|
|
||||||
read_file_func zread_file;
|
|
||||||
write_file_func zwrite_file;
|
|
||||||
tell_file_func ztell_file;
|
|
||||||
seek_file_func zseek_file;
|
|
||||||
close_file_func zclose_file;
|
|
||||||
testerror_file_func zerror_file;
|
|
||||||
void* opaque;
|
|
||||||
} zlib_filefunc_def;
|
|
||||||
|
|
||||||
typedef struct zlib_filefunc64_def_s
|
|
||||||
{
|
|
||||||
open64_file_func zopen64_file;
|
|
||||||
read_file_func zread_file;
|
|
||||||
write_file_func zwrite_file;
|
|
||||||
tell64_file_func ztell64_file;
|
|
||||||
seek64_file_func zseek64_file;
|
|
||||||
close_file_func zclose_file;
|
|
||||||
testerror_file_func zerror_file;
|
|
||||||
void* opaque;
|
|
||||||
} zlib_filefunc64_def;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#define ZLIB_FILEFUNC_SEEK_SET (0)
|
|
||||||
#define ZLIB_FILEFUNC_SEEK_CUR (1)
|
|
||||||
#define ZLIB_FILEFUNC_SEEK_END (2)
|
|
||||||
|
|
||||||
#define ZLIB_FILEFUNC_MODE_READ (1)
|
|
||||||
#define ZLIB_FILEFUNC_MODE_WRITE (2)
|
|
||||||
#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
|
|
||||||
|
|
||||||
#define ZLIB_FILEFUNC_MODE_EXISTING (4)
|
|
||||||
#define ZLIB_FILEFUNC_MODE_CREATE (8)
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
ZEXPORT void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def);
|
|
||||||
ZEXPORT void fill_fopen64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def);
|
|
||||||
ZEXPORT void fill_win32_filefunc(zlib_filefunc_def *pzlib_filefunc_def);
|
|
||||||
ZEXPORT void fill_win32_filefunc64(zlib_filefunc64_def *pzlib_filefunc_def);
|
|
||||||
ZEXPORT void fill_win32_filefunc64A(zlib_filefunc64_def *pzlib_filefunc_def);
|
|
||||||
ZEXPORT void fill_memory_filefunc(zlib_filefunc_def *pzlib_filefunc_def);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if MZ_COMPAT_VERSION <= 110
|
|
||||||
#define mz_dos_date dosDate
|
|
||||||
#else
|
|
||||||
#define mz_dos_date dos_date
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct tm tm_unz;
|
|
||||||
typedef struct tm tm_zip;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t mz_dos_date;
|
|
||||||
struct tm tmz_date;
|
|
||||||
uint16_t internal_fa; /* internal file attributes 2 bytes */
|
|
||||||
uint32_t external_fa; /* external file attributes 4 bytes */
|
|
||||||
} zip_fileinfo;
|
|
||||||
|
|
||||||
typedef const char *zipcharpc;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#define ZIP_OK (0)
|
|
||||||
#define ZIP_EOF (0)
|
|
||||||
#define ZIP_ERRNO (-1)
|
|
||||||
#define ZIP_PARAMERROR (-102)
|
|
||||||
#define ZIP_BADZIPFILE (-103)
|
|
||||||
#define ZIP_INTERNALERROR (-104)
|
|
||||||
|
|
||||||
#ifndef Z_DEFLATED
|
|
||||||
#define Z_DEFLATED (8)
|
|
||||||
#endif
|
|
||||||
#define Z_BZIP2ED (12)
|
|
||||||
|
|
||||||
#define APPEND_STATUS_CREATE (0)
|
|
||||||
#define APPEND_STATUS_CREATEAFTER (1)
|
|
||||||
#define APPEND_STATUS_ADDINZIP (2)
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/* Writing a zip file */
|
|
||||||
|
|
||||||
ZEXPORT zipFile zipOpen(const char *path, int append);
|
|
||||||
ZEXPORT zipFile zipOpen64(const void *path, int append);
|
|
||||||
ZEXPORT zipFile zipOpen2(const char *path, int append, const char **globalcomment,
|
|
||||||
zlib_filefunc_def *pzlib_filefunc_def);
|
|
||||||
|
|
||||||
ZEXPORT zipFile zipOpen2_64(const void *path, int append, const char **globalcomment,
|
|
||||||
zlib_filefunc64_def *pzlib_filefunc_def);
|
|
||||||
ZEXPORT zipFile zipOpen_MZ(void *stream, int append, const char **globalcomment);
|
|
||||||
|
|
||||||
ZEXPORT void* zipGetHandle_MZ(zipFile);
|
|
||||||
ZEXPORT void* zipGetStream_MZ(zipFile file);
|
|
||||||
|
|
||||||
ZEXPORT int zipOpenNewFileInZip(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
||||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
||||||
uint16_t size_extrafield_global, const char *comment, int compression_method, int level);
|
|
||||||
ZEXPORT int zipOpenNewFileInZip_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
||||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
||||||
uint16_t size_extrafield_global, const char *comment, int compression_method, int level,
|
|
||||||
int zip64);
|
|
||||||
ZEXPORT int zipOpenNewFileInZip2(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
||||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
||||||
uint16_t size_extrafield_global, const char *comment, int compression_method, int level,
|
|
||||||
int raw);
|
|
||||||
ZEXPORT int zipOpenNewFileInZip2_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
||||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
||||||
uint16_t size_extrafield_global, const char *comment, int compression_method, int level,
|
|
||||||
int raw, int zip64);
|
|
||||||
ZEXPORT int zipOpenNewFileInZip3(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
||||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
||||||
uint16_t size_extrafield_global, const char *comment, int compression_method, int level,
|
|
||||||
int raw, int windowBits, int memLevel, int strategy, const char *password,
|
|
||||||
unsigned long crc_for_crypting);
|
|
||||||
ZEXPORT int zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
||||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
||||||
uint16_t size_extrafield_global, const char *comment, int compression_method, int level,
|
|
||||||
int raw, int windowBits, int memLevel, int strategy, const char *password,
|
|
||||||
uint32_t crc_for_crypting, int zip64);
|
|
||||||
ZEXPORT int zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
||||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
||||||
uint16_t size_extrafield_global, const char *comment, int compression_method, int level,
|
|
||||||
int raw, int windowBits, int memLevel, int strategy, const char *password,
|
|
||||||
unsigned long crc_for_crypting, unsigned long version_madeby, unsigned long flag_base);
|
|
||||||
ZEXPORT int zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
||||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
||||||
uint16_t size_extrafield_global, const char *comment, int compression_method, int level,
|
|
||||||
int raw, int windowBits, int memLevel, int strategy, const char *password,
|
|
||||||
unsigned long crc_for_crypting, unsigned long version_madeby, unsigned long flag_base, int zip64);
|
|
||||||
ZEXPORT int zipOpenNewFileInZip5(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
|
||||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
|
||||||
uint16_t size_extrafield_global, const char *comment, int compression_method, int level,
|
|
||||||
int raw, int windowBits, int memLevel, int strategy, const char *password,
|
|
||||||
unsigned long crc_for_crypting, unsigned long version_madeby, unsigned long flag_base, int zip64);
|
|
||||||
|
|
||||||
ZEXPORT int zipWriteInFileInZip(zipFile file, const void *buf, uint32_t len);
|
|
||||||
|
|
||||||
ZEXPORT int zipCloseFileInZipRaw(zipFile file, unsigned long uncompressed_size, unsigned long crc32);
|
|
||||||
ZEXPORT int zipCloseFileInZipRaw64(zipFile file, uint64_t uncompressed_size, unsigned long crc32);
|
|
||||||
ZEXPORT int zipCloseFileInZip(zipFile file);
|
|
||||||
ZEXPORT int zipCloseFileInZip64(zipFile file);
|
|
||||||
|
|
||||||
ZEXPORT int zipClose(zipFile file, const char *global_comment);
|
|
||||||
ZEXPORT int zipClose_64(zipFile file, const char *global_comment);
|
|
||||||
ZEXPORT int zipClose2_64(zipFile file, const char *global_comment, uint16_t version_madeby);
|
|
||||||
int zipClose_MZ(zipFile file, const char *global_comment);
|
|
||||||
int zipClose2_MZ(zipFile file, const char *global_comment, uint16_t version_madeby);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
|
|
||||||
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
|
||||||
from (void*) without cast */
|
|
||||||
typedef struct TagunzFile__ { int unused; } unz_file__;
|
|
||||||
typedef unz_file__ *unzFile;
|
|
||||||
#else
|
|
||||||
typedef void *unzFile;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#define UNZ_OK (0)
|
|
||||||
#define UNZ_END_OF_LIST_OF_FILE (-100)
|
|
||||||
#define UNZ_ERRNO (-1)
|
|
||||||
#define UNZ_EOF (0)
|
|
||||||
#define UNZ_PARAMERROR (-102)
|
|
||||||
#define UNZ_BADZIPFILE (-103)
|
|
||||||
#define UNZ_INTERNALERROR (-104)
|
|
||||||
#define UNZ_CRCERROR (-105)
|
|
||||||
#define UNZ_BADPASSWORD (-106)
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct unz_global_info64_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 size_comment; /* size of the global comment of the zipfile */
|
|
||||||
} unz_global_info64;
|
|
||||||
|
|
||||||
typedef struct unz_global_info_s {
|
|
||||||
uint32_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 size_comment; /* size of the global comment of the zipfile */
|
|
||||||
} unz_global_info;
|
|
||||||
|
|
||||||
typedef struct unz_file_info64_s {
|
|
||||||
uint16_t version; /* version made by 2 bytes */
|
|
||||||
uint16_t version_needed; /* version needed to extract 2 bytes */
|
|
||||||
uint16_t flag; /* general purpose bit flag 2 bytes */
|
|
||||||
uint16_t compression_method; /* compression method 2 bytes */
|
|
||||||
uint32_t mz_dos_date; /* last mod file date in Dos fmt 4 bytes */
|
|
||||||
struct tm tmu_date;
|
|
||||||
uint32_t crc; /* crc-32 4 bytes */
|
|
||||||
uint64_t compressed_size; /* compressed size 8 bytes */
|
|
||||||
uint64_t uncompressed_size; /* uncompressed size 8 bytes */
|
|
||||||
uint16_t size_filename; /* filename length 2 bytes */
|
|
||||||
uint16_t size_file_extra; /* extra field length 2 bytes */
|
|
||||||
uint16_t size_file_comment; /* file comment length 2 bytes */
|
|
||||||
|
|
||||||
uint32_t disk_num_start; /* disk number start 4 bytes */
|
|
||||||
uint16_t internal_fa; /* internal file attributes 2 bytes */
|
|
||||||
uint32_t external_fa; /* external file attributes 4 bytes */
|
|
||||||
|
|
||||||
uint64_t disk_offset;
|
|
||||||
|
|
||||||
uint16_t size_file_extra_internal;
|
|
||||||
} unz_file_info64;
|
|
||||||
|
|
||||||
typedef struct unz_file_info_s {
|
|
||||||
uint16_t version; /* version made by 2 bytes */
|
|
||||||
uint16_t version_needed; /* version needed to extract 2 bytes */
|
|
||||||
uint16_t flag; /* general purpose bit flag 2 bytes */
|
|
||||||
uint16_t compression_method; /* compression method 2 bytes */
|
|
||||||
uint32_t mz_dos_date; /* last mod file date in Dos fmt 4 bytes */
|
|
||||||
struct tm tmu_date;
|
|
||||||
uint32_t crc; /* crc-32 4 bytes */
|
|
||||||
uint32_t compressed_size; /* compressed size 4 bytes */
|
|
||||||
uint32_t uncompressed_size; /* uncompressed size 4 bytes */
|
|
||||||
uint16_t size_filename; /* filename length 2 bytes */
|
|
||||||
uint16_t size_file_extra; /* extra field length 2 bytes */
|
|
||||||
uint16_t size_file_comment; /* file comment length 2 bytes */
|
|
||||||
|
|
||||||
uint16_t disk_num_start; /* disk number start 2 bytes */
|
|
||||||
uint16_t internal_fa; /* internal file attributes 2 bytes */
|
|
||||||
uint32_t external_fa; /* external file attributes 4 bytes */
|
|
||||||
|
|
||||||
uint64_t disk_offset;
|
|
||||||
} unz_file_info;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef int (*unzFileNameComparer)(unzFile file, const char *filename1, const char *filename2);
|
|
||||||
typedef int (*unzIteratorFunction)(unzFile file);
|
|
||||||
typedef int (*unzIteratorFunction2)(unzFile file, unz_file_info64 *pfile_info, char *filename,
|
|
||||||
uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment,
|
|
||||||
uint16_t comment_size);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/* Reading a zip file */
|
|
||||||
|
|
||||||
ZEXPORT unzFile unzOpen(const char *path);
|
|
||||||
ZEXPORT unzFile unzOpen64(const void *path);
|
|
||||||
ZEXPORT unzFile unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def);
|
|
||||||
ZEXPORT unzFile unzOpen2_64(const void *path, zlib_filefunc64_def *pzlib_filefunc_def);
|
|
||||||
unzFile unzOpen_MZ(void *stream);
|
|
||||||
|
|
||||||
ZEXPORT int unzClose(unzFile file);
|
|
||||||
ZEXPORT int unzClose_MZ(unzFile file);
|
|
||||||
|
|
||||||
ZEXPORT void* unzGetHandle_MZ(unzFile file);
|
|
||||||
ZEXPORT void* unzGetStream_MZ(zipFile file);
|
|
||||||
|
|
||||||
ZEXPORT int unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32);
|
|
||||||
ZEXPORT int unzGetGlobalInfo64(unzFile file, unz_global_info64 *pglobal_info);
|
|
||||||
ZEXPORT int unzGetGlobalComment(unzFile file, char *comment, unsigned long comment_size);
|
|
||||||
|
|
||||||
ZEXPORT int unzOpenCurrentFile(unzFile file);
|
|
||||||
ZEXPORT int unzOpenCurrentFilePassword(unzFile file, const char *password);
|
|
||||||
ZEXPORT int unzOpenCurrentFile2(unzFile file, int *method, int *level, int raw);
|
|
||||||
ZEXPORT int unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password);
|
|
||||||
ZEXPORT int unzReadCurrentFile(unzFile file, void *buf, uint32_t len);
|
|
||||||
ZEXPORT int unzCloseCurrentFile(unzFile file);
|
|
||||||
|
|
||||||
ZEXPORT int unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *filename,
|
|
||||||
unsigned long filename_size, void *extrafield, unsigned long extrafield_size, char *comment,
|
|
||||||
unsigned long comment_size);
|
|
||||||
ZEXPORT int unzGetCurrentFileInfo64(unzFile file, unz_file_info64 * pfile_info, char *filename,
|
|
||||||
unsigned long filename_size, void *extrafield, unsigned long extrafield_size, char *comment,
|
|
||||||
unsigned long comment_size);
|
|
||||||
|
|
||||||
ZEXPORT int unzGoToFirstFile(unzFile file);
|
|
||||||
ZEXPORT int unzGoToNextFile(unzFile file);
|
|
||||||
ZEXPORT int unzLocateFile(unzFile file, const char *filename, unzFileNameComparer filename_compare_func);
|
|
||||||
|
|
||||||
ZEXPORT int unzGetLocalExtrafield(unzFile file, void *buf, unsigned int len);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/* Raw access to zip file */
|
|
||||||
|
|
||||||
typedef struct unz_file_pos_s {
|
|
||||||
uint32_t pos_in_zip_directory; /* offset in zip file directory */
|
|
||||||
uint32_t num_of_file; /* # of file */
|
|
||||||
} unz_file_pos;
|
|
||||||
|
|
||||||
ZEXPORT int unzGetFilePos(unzFile file, unz_file_pos *file_pos);
|
|
||||||
ZEXPORT int unzGoToFilePos(unzFile file, unz_file_pos *file_pos);
|
|
||||||
|
|
||||||
typedef struct unz64_file_pos_s {
|
|
||||||
int64_t pos_in_zip_directory; /* offset in zip file directory */
|
|
||||||
uint64_t num_of_file; /* # of file */
|
|
||||||
} unz64_file_pos;
|
|
||||||
|
|
||||||
ZEXPORT int unzGetFilePos64(unzFile file, unz64_file_pos *file_pos);
|
|
||||||
ZEXPORT int unzGoToFilePos64(unzFile file, const unz64_file_pos *file_pos);
|
|
||||||
|
|
||||||
ZEXPORT int64_t unzGetOffset64(unzFile file);
|
|
||||||
ZEXPORT unsigned long
|
|
||||||
unzGetOffset(unzFile file);
|
|
||||||
ZEXPORT int unzSetOffset64(unzFile file, int64_t pos);
|
|
||||||
ZEXPORT int unzSetOffset(unzFile file, unsigned long pos);
|
|
||||||
ZEXPORT int32_t unztell(unzFile file);
|
|
||||||
ZEXPORT int32_t unzTell(unzFile file);
|
|
||||||
ZEXPORT uint64_t unztell64(unzFile file);
|
|
||||||
ZEXPORT uint64_t unzTell64(unzFile file);
|
|
||||||
ZEXPORT int unzSeek(unzFile file, int32_t offset, int origin);
|
|
||||||
ZEXPORT int unzSeek64(unzFile file, int64_t offset, int origin);
|
|
||||||
ZEXPORT int unzEndOfFile(unzFile file);
|
|
||||||
ZEXPORT int unzeof(unzFile file);
|
|
||||||
ZEXPORT void* unzGetStream(unzFile file);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,196 +0,0 @@
|
||||||
/* mz_crypt.c -- Crypto/hash functions
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_os.h"
|
|
||||||
#include "mz_crypt.h"
|
|
||||||
|
|
||||||
#if defined(HAVE_ZLIB)
|
|
||||||
# include "zlib.h"
|
|
||||||
# if defined(ZLIBNG_VERNUM) && !defined(ZLIB_COMPAT)
|
|
||||||
# include "zlib-ng.h"
|
|
||||||
# endif
|
|
||||||
#elif defined(HAVE_LZMA)
|
|
||||||
# include "lzma.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/* Define z_crc_t in zlib 1.2.5 and less or if using zlib-ng */
|
|
||||||
|
|
||||||
#if defined(HAVE_ZLIB) && defined(ZLIBNG_VERNUM)
|
|
||||||
# if defined(ZLIB_COMPAT)
|
|
||||||
# define ZLIB_PREFIX(x) x
|
|
||||||
# else
|
|
||||||
# define ZLIB_PREFIX(x) zng_ ## x
|
|
||||||
# endif
|
|
||||||
typedef uint32_t z_crc_t;
|
|
||||||
#elif defined(HAVE_ZLIB)
|
|
||||||
# define ZLIB_PREFIX(x) x
|
|
||||||
# if (ZLIB_VERNUM < 0x1270)
|
|
||||||
typedef unsigned long z_crc_t;
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(MZ_ZIP_NO_CRYPTO)
|
|
||||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size) {
|
|
||||||
return mz_os_rand(buf, size);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t mz_crypt_crc32_update(uint32_t value, const uint8_t *buf, int32_t size) {
|
|
||||||
#if defined(HAVE_ZLIB)
|
|
||||||
return (uint32_t)ZLIB_PREFIX(crc32)((z_crc_t)value, buf, (uInt)size);
|
|
||||||
#elif defined(HAVE_LZMA)
|
|
||||||
return (uint32_t)lzma_crc32(buf, (size_t)size, (uint32_t)value);
|
|
||||||
#else
|
|
||||||
static uint32_t crc32_table[256] = {
|
|
||||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
|
||||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
|
||||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
|
||||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
|
||||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
|
||||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
|
||||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
|
||||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
|
||||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
|
||||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
|
||||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
|
||||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
|
||||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
|
||||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
|
||||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
|
||||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
|
||||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
|
||||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
|
||||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
|
||||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
|
||||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
|
||||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
|
||||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
|
||||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
|
||||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
|
||||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
|
||||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
|
||||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
|
||||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
|
||||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
|
||||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
|
||||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
|
||||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
|
||||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
|
||||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
|
||||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
|
||||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
|
||||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
|
||||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
|
||||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
|
||||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
|
||||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
|
||||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
|
||||||
};
|
|
||||||
value = ~value;
|
|
||||||
|
|
||||||
while (size > 0) {
|
|
||||||
value = (value >> 8) ^ crc32_table[(value ^ *buf) & 0xFF];
|
|
||||||
|
|
||||||
buf += 1;
|
|
||||||
size -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ~value;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(HAVE_WZAES)
|
|
||||||
int32_t mz_crypt_pbkdf2(uint8_t *password, int32_t password_length, uint8_t *salt,
|
|
||||||
int32_t salt_length, int32_t iteration_count, uint8_t *key, int32_t key_length) {
|
|
||||||
void *hmac1 = NULL;
|
|
||||||
void *hmac2 = NULL;
|
|
||||||
void *hmac3 = NULL;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
uint16_t i = 0;
|
|
||||||
uint16_t j = 0;
|
|
||||||
uint16_t k = 0;
|
|
||||||
uint16_t block_count = 0;
|
|
||||||
uint8_t uu[MZ_HASH_SHA1_SIZE];
|
|
||||||
uint8_t ux[MZ_HASH_SHA1_SIZE];
|
|
||||||
|
|
||||||
if (password == NULL || salt == NULL || key == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
memset(key, 0, key_length);
|
|
||||||
|
|
||||||
mz_crypt_hmac_create(&hmac1);
|
|
||||||
mz_crypt_hmac_create(&hmac2);
|
|
||||||
mz_crypt_hmac_create(&hmac3);
|
|
||||||
|
|
||||||
mz_crypt_hmac_set_algorithm(hmac1, MZ_HASH_SHA1);
|
|
||||||
mz_crypt_hmac_set_algorithm(hmac2, MZ_HASH_SHA1);
|
|
||||||
mz_crypt_hmac_set_algorithm(hmac3, MZ_HASH_SHA1);
|
|
||||||
|
|
||||||
err = mz_crypt_hmac_init(hmac1, password, password_length);
|
|
||||||
if (err == MZ_OK)
|
|
||||||
err = mz_crypt_hmac_init(hmac2, password, password_length);
|
|
||||||
if (err == MZ_OK)
|
|
||||||
err = mz_crypt_hmac_update(hmac2, salt, salt_length);
|
|
||||||
|
|
||||||
block_count = 1 + ((uint16_t)key_length - 1) / MZ_HASH_SHA1_SIZE;
|
|
||||||
|
|
||||||
for (i = 0; (err == MZ_OK) && (i < block_count); i += 1) {
|
|
||||||
memset(ux, 0, sizeof(ux));
|
|
||||||
|
|
||||||
err = mz_crypt_hmac_copy(hmac2, hmac3);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
break;
|
|
||||||
|
|
||||||
uu[0] = (uint8_t)((i + 1) >> 24);
|
|
||||||
uu[1] = (uint8_t)((i + 1) >> 16);
|
|
||||||
uu[2] = (uint8_t)((i + 1) >> 8);
|
|
||||||
uu[3] = (uint8_t)(i + 1);
|
|
||||||
|
|
||||||
for (j = 0, k = 4; j < iteration_count; j += 1) {
|
|
||||||
err = mz_crypt_hmac_update(hmac3, uu, k);
|
|
||||||
if (err == MZ_OK)
|
|
||||||
err = mz_crypt_hmac_end(hmac3, uu, sizeof(uu));
|
|
||||||
if (err != MZ_OK)
|
|
||||||
break;
|
|
||||||
|
|
||||||
for(k = 0; k < MZ_HASH_SHA1_SIZE; k += 1)
|
|
||||||
ux[k] ^= uu[k];
|
|
||||||
|
|
||||||
err = mz_crypt_hmac_copy(hmac1, hmac3);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err != MZ_OK)
|
|
||||||
break;
|
|
||||||
|
|
||||||
j = 0;
|
|
||||||
k = i * MZ_HASH_SHA1_SIZE;
|
|
||||||
|
|
||||||
while (j < MZ_HASH_SHA1_SIZE && k < key_length)
|
|
||||||
key[k++] = ux[j++];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* hmac3 uses the same provider as hmac2, so it must be deleted
|
|
||||||
before the context is destroyed. */
|
|
||||||
mz_crypt_hmac_delete(&hmac3);
|
|
||||||
mz_crypt_hmac_delete(&hmac1);
|
|
||||||
mz_crypt_hmac_delete(&hmac2);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
|
@ -1,65 +0,0 @@
|
||||||
/* mz_crypt.h -- Crypto/hash functions
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_CRYPT_H
|
|
||||||
#define MZ_CRYPT_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
uint32_t mz_crypt_crc32_update(uint32_t value, const uint8_t *buf, int32_t size);
|
|
||||||
|
|
||||||
int32_t mz_crypt_pbkdf2(uint8_t *password, int32_t password_length, uint8_t *salt,
|
|
||||||
int32_t salt_length, int32_t iteration_count, uint8_t *key, int32_t key_length);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size);
|
|
||||||
|
|
||||||
void mz_crypt_sha_reset(void *handle);
|
|
||||||
int32_t mz_crypt_sha_begin(void *handle);
|
|
||||||
int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size);
|
|
||||||
int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size);
|
|
||||||
void mz_crypt_sha_set_algorithm(void *handle, uint16_t algorithm);
|
|
||||||
void* mz_crypt_sha_create(void **handle);
|
|
||||||
void mz_crypt_sha_delete(void **handle);
|
|
||||||
|
|
||||||
void mz_crypt_aes_reset(void *handle);
|
|
||||||
int32_t mz_crypt_aes_encrypt(void *handle, uint8_t *buf, int32_t size);
|
|
||||||
int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size);
|
|
||||||
int32_t mz_crypt_aes_set_encrypt_key(void *handle, const void *key, int32_t key_length);
|
|
||||||
int32_t mz_crypt_aes_set_decrypt_key(void *handle, const void *key, int32_t key_length);
|
|
||||||
void mz_crypt_aes_set_mode(void *handle, int32_t mode);
|
|
||||||
void* mz_crypt_aes_create(void **handle);
|
|
||||||
void mz_crypt_aes_delete(void **handle);
|
|
||||||
|
|
||||||
void mz_crypt_hmac_reset(void *handle);
|
|
||||||
int32_t mz_crypt_hmac_init(void *handle, const void *key, int32_t key_length);
|
|
||||||
int32_t mz_crypt_hmac_update(void *handle, const void *buf, int32_t size);
|
|
||||||
int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size);
|
|
||||||
int32_t mz_crypt_hmac_copy(void *src_handle, void *target_handle);
|
|
||||||
void mz_crypt_hmac_set_algorithm(void *handle, uint16_t algorithm);
|
|
||||||
void* mz_crypt_hmac_create(void **handle);
|
|
||||||
void mz_crypt_hmac_delete(void **handle);
|
|
||||||
|
|
||||||
int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size,
|
|
||||||
const char *cert_pwd, uint8_t **signature, int32_t *signature_size);
|
|
||||||
int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,487 +0,0 @@
|
||||||
/* mz_crypt_apple.c -- Crypto/hash functions for Apple
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
|
||||||
#include <CommonCrypto/CommonCryptor.h>
|
|
||||||
#include <CommonCrypto/CommonDigest.h>
|
|
||||||
#include <CommonCrypto/CommonHMAC.h>
|
|
||||||
#include <Security/Security.h>
|
|
||||||
#include <Security/SecPolicy.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size) {
|
|
||||||
if (SecRandomCopyBytes(kSecRandomDefault, size, buf) != errSecSuccess)
|
|
||||||
return 0;
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_crypt_sha_s {
|
|
||||||
CC_SHA1_CTX ctx1;
|
|
||||||
CC_SHA256_CTX ctx256;
|
|
||||||
int32_t error;
|
|
||||||
int32_t initialized;
|
|
||||||
uint16_t algorithm;
|
|
||||||
} mz_crypt_sha;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void mz_crypt_sha_reset(void *handle) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
|
|
||||||
sha->error = 0;
|
|
||||||
sha->initialized = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_sha_begin(void *handle) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
|
|
||||||
if (sha == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_sha_reset(handle);
|
|
||||||
|
|
||||||
if (sha->algorithm == MZ_HASH_SHA1)
|
|
||||||
sha->error = CC_SHA1_Init(&sha->ctx1);
|
|
||||||
else if (sha->algorithm == MZ_HASH_SHA256)
|
|
||||||
sha->error = CC_SHA256_Init(&sha->ctx256);
|
|
||||||
else
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (!sha->error)
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
|
|
||||||
sha->initialized = 1;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
|
|
||||||
if (sha == NULL || buf == NULL || !sha->initialized)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (sha->algorithm == MZ_HASH_SHA1)
|
|
||||||
sha->error = CC_SHA1_Update(&sha->ctx1, buf, size);
|
|
||||||
else
|
|
||||||
sha->error = CC_SHA256_Update(&sha->ctx256, buf, size);
|
|
||||||
|
|
||||||
if (!sha->error)
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
|
|
||||||
if (sha == NULL || digest == NULL || !sha->initialized)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (sha->algorithm == MZ_HASH_SHA1) {
|
|
||||||
if (digest_size < MZ_HASH_SHA1_SIZE)
|
|
||||||
return MZ_BUF_ERROR;
|
|
||||||
sha->error = CC_SHA1_Final(digest, &sha->ctx1);
|
|
||||||
} else {
|
|
||||||
if (digest_size < MZ_HASH_SHA256_SIZE)
|
|
||||||
return MZ_BUF_ERROR;
|
|
||||||
sha->error = CC_SHA256_Final(digest, &sha->ctx256);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sha->error)
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_sha_set_algorithm(void *handle, uint16_t algorithm) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
sha->algorithm = algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_crypt_sha_create(void **handle) {
|
|
||||||
mz_crypt_sha *sha = NULL;
|
|
||||||
|
|
||||||
sha = (mz_crypt_sha *)MZ_ALLOC(sizeof(mz_crypt_sha));
|
|
||||||
if (sha != NULL) {
|
|
||||||
memset(sha, 0, sizeof(mz_crypt_sha));
|
|
||||||
sha->algorithm = MZ_HASH_SHA256;
|
|
||||||
}
|
|
||||||
if (handle != NULL)
|
|
||||||
*handle = sha;
|
|
||||||
|
|
||||||
return sha;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_sha_delete(void **handle) {
|
|
||||||
mz_crypt_sha *sha = NULL;
|
|
||||||
if (handle == NULL)
|
|
||||||
return;
|
|
||||||
sha = (mz_crypt_sha *)*handle;
|
|
||||||
if (sha != NULL) {
|
|
||||||
mz_crypt_sha_reset(*handle);
|
|
||||||
MZ_FREE(sha);
|
|
||||||
}
|
|
||||||
*handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_crypt_aes_s {
|
|
||||||
CCCryptorRef crypt;
|
|
||||||
int32_t mode;
|
|
||||||
int32_t error;
|
|
||||||
} mz_crypt_aes;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void mz_crypt_aes_reset(void *handle) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
|
|
||||||
if (aes->crypt != NULL)
|
|
||||||
CCCryptorRelease(aes->crypt);
|
|
||||||
aes->crypt = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_aes_encrypt(void *handle, uint8_t *buf, int32_t size) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
size_t data_moved = 0;
|
|
||||||
|
|
||||||
if (aes == NULL || buf == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (size != MZ_AES_BLOCK_SIZE)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
aes->error = CCCryptorUpdate(aes->crypt, buf, size, buf, size, &data_moved);
|
|
||||||
|
|
||||||
if (aes->error != kCCSuccess)
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
size_t data_moved = 0;
|
|
||||||
|
|
||||||
if (aes == NULL || buf == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (size != MZ_AES_BLOCK_SIZE)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
aes->error = CCCryptorUpdate(aes->crypt, buf, size, buf, size, &data_moved);
|
|
||||||
|
|
||||||
if (aes->error != kCCSuccess)
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_aes_set_encrypt_key(void *handle, const void *key, int32_t key_length) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
|
|
||||||
|
|
||||||
if (aes == NULL || key == NULL || key_length == 0)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_aes_reset(handle);
|
|
||||||
|
|
||||||
aes->error = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES, kCCOptionECBMode,
|
|
||||||
key, key_length, NULL, &aes->crypt);
|
|
||||||
|
|
||||||
if (aes->error != kCCSuccess)
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_aes_set_decrypt_key(void *handle, const void *key, int32_t key_length) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
|
|
||||||
|
|
||||||
if (aes == NULL || key == NULL || key_length == 0)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_aes_reset(handle);
|
|
||||||
|
|
||||||
aes->error = CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES, kCCOptionECBMode,
|
|
||||||
key, key_length, NULL, &aes->crypt);
|
|
||||||
|
|
||||||
if (aes->error != kCCSuccess)
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_aes_set_mode(void *handle, int32_t mode) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
aes->mode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_crypt_aes_create(void **handle) {
|
|
||||||
mz_crypt_aes *aes = NULL;
|
|
||||||
|
|
||||||
aes = (mz_crypt_aes *)MZ_ALLOC(sizeof(mz_crypt_aes));
|
|
||||||
if (aes != NULL)
|
|
||||||
memset(aes, 0, sizeof(mz_crypt_aes));
|
|
||||||
if (handle != NULL)
|
|
||||||
*handle = aes;
|
|
||||||
|
|
||||||
return aes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_aes_delete(void **handle) {
|
|
||||||
mz_crypt_aes *aes = NULL;
|
|
||||||
if (handle == NULL)
|
|
||||||
return;
|
|
||||||
aes = (mz_crypt_aes *)*handle;
|
|
||||||
if (aes != NULL) {
|
|
||||||
mz_crypt_aes_reset(*handle);
|
|
||||||
MZ_FREE(aes);
|
|
||||||
}
|
|
||||||
*handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_crypt_hmac_s {
|
|
||||||
CCHmacContext ctx;
|
|
||||||
int32_t initialized;
|
|
||||||
int32_t error;
|
|
||||||
uint16_t algorithm;
|
|
||||||
} mz_crypt_hmac;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void mz_crypt_hmac_free(void *handle) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
memset(&hmac->ctx, 0, sizeof(hmac->ctx));
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_hmac_reset(void *handle) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
mz_crypt_hmac_free(handle);
|
|
||||||
hmac->error = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_hmac_init(void *handle, const void *key, int32_t key_length) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
CCHmacAlgorithm algorithm = 0;
|
|
||||||
|
|
||||||
if (hmac == NULL || key == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_hmac_reset(handle);
|
|
||||||
|
|
||||||
if (hmac->algorithm == MZ_HASH_SHA1)
|
|
||||||
algorithm = kCCHmacAlgSHA1;
|
|
||||||
else if (hmac->algorithm == MZ_HASH_SHA256)
|
|
||||||
algorithm = kCCHmacAlgSHA256;
|
|
||||||
else
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
CCHmacInit(&hmac->ctx, algorithm, key, key_length);
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_hmac_update(void *handle, const void *buf, int32_t size) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
|
|
||||||
if (hmac == NULL || buf == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
CCHmacUpdate(&hmac->ctx, buf, size);
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
|
|
||||||
if (hmac == NULL || digest == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (hmac->algorithm == MZ_HASH_SHA1) {
|
|
||||||
if (digest_size < MZ_HASH_SHA1_SIZE)
|
|
||||||
return MZ_BUF_ERROR;
|
|
||||||
CCHmacFinal(&hmac->ctx, digest);
|
|
||||||
} else {
|
|
||||||
if (digest_size < MZ_HASH_SHA256_SIZE)
|
|
||||||
return MZ_BUF_ERROR;
|
|
||||||
CCHmacFinal(&hmac->ctx, digest);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_hmac_set_algorithm(void *handle, uint16_t algorithm) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
hmac->algorithm = algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_hmac_copy(void *src_handle, void *target_handle) {
|
|
||||||
mz_crypt_hmac *source = (mz_crypt_hmac *)src_handle;
|
|
||||||
mz_crypt_hmac *target = (mz_crypt_hmac *)target_handle;
|
|
||||||
|
|
||||||
if (source == NULL || target == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
memcpy(&target->ctx, &source->ctx, sizeof(CCHmacContext));
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_crypt_hmac_create(void **handle) {
|
|
||||||
mz_crypt_hmac *hmac = NULL;
|
|
||||||
|
|
||||||
hmac = (mz_crypt_hmac *)MZ_ALLOC(sizeof(mz_crypt_hmac));
|
|
||||||
if (hmac != NULL) {
|
|
||||||
memset(hmac, 0, sizeof(mz_crypt_hmac));
|
|
||||||
hmac->algorithm = MZ_HASH_SHA256;
|
|
||||||
}
|
|
||||||
if (handle != NULL)
|
|
||||||
*handle = hmac;
|
|
||||||
|
|
||||||
return hmac;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_hmac_delete(void **handle) {
|
|
||||||
mz_crypt_hmac *hmac = NULL;
|
|
||||||
if (handle == NULL)
|
|
||||||
return;
|
|
||||||
hmac = (mz_crypt_hmac *)*handle;
|
|
||||||
if (hmac != NULL) {
|
|
||||||
mz_crypt_hmac_free(*handle);
|
|
||||||
MZ_FREE(hmac);
|
|
||||||
}
|
|
||||||
*handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(MZ_ZIP_SIGNING)
|
|
||||||
int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size,
|
|
||||||
const char *cert_pwd, uint8_t **signature, int32_t *signature_size) {
|
|
||||||
CFStringRef password_ref = NULL;
|
|
||||||
CFDictionaryRef options_dict = NULL;
|
|
||||||
CFDictionaryRef identity_trust = NULL;
|
|
||||||
CFDataRef signature_out = NULL;
|
|
||||||
CFDataRef pkcs12_data = NULL;
|
|
||||||
CFArrayRef items = 0;
|
|
||||||
SecIdentityRef identity = NULL;
|
|
||||||
SecTrustRef trust = NULL;
|
|
||||||
OSStatus status = noErr;
|
|
||||||
const void *options_key[2] = { kSecImportExportPassphrase, kSecReturnRef };
|
|
||||||
const void *options_values[2] = { 0, kCFBooleanTrue };
|
|
||||||
int32_t err = MZ_SIGN_ERROR;
|
|
||||||
|
|
||||||
|
|
||||||
if (message == NULL || cert_data == NULL || signature == NULL || signature_size == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
*signature = NULL;
|
|
||||||
*signature_size = 0;
|
|
||||||
|
|
||||||
password_ref = CFStringCreateWithCString(0, cert_pwd, kCFStringEncodingUTF8);
|
|
||||||
options_values[0] = password_ref;
|
|
||||||
|
|
||||||
options_dict = CFDictionaryCreate(0, options_key, options_values, 2, 0, 0);
|
|
||||||
if (options_dict)
|
|
||||||
pkcs12_data = CFDataCreate(0, cert_data, cert_data_size);
|
|
||||||
if (pkcs12_data)
|
|
||||||
status = SecPKCS12Import(pkcs12_data, options_dict, &items);
|
|
||||||
if (status == noErr)
|
|
||||||
identity_trust = CFArrayGetValueAtIndex(items, 0);
|
|
||||||
if (identity_trust)
|
|
||||||
identity = (SecIdentityRef)CFDictionaryGetValue(identity_trust, kSecImportItemIdentity);
|
|
||||||
if (identity)
|
|
||||||
trust = (SecTrustRef)CFDictionaryGetValue(identity_trust, kSecImportItemTrust);
|
|
||||||
if (trust) {
|
|
||||||
status = CMSEncodeContent(identity, NULL, NULL, FALSE, 0, message, message_size, &signature_out);
|
|
||||||
|
|
||||||
if (status == errSecSuccess) {
|
|
||||||
*signature_size = CFDataGetLength(signature_out);
|
|
||||||
*signature = (uint8_t *)MZ_ALLOC(*signature_size);
|
|
||||||
|
|
||||||
memcpy(*signature, CFDataGetBytePtr(signature_out), *signature_size);
|
|
||||||
|
|
||||||
err = MZ_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (signature_out)
|
|
||||||
CFRelease(signature_out);
|
|
||||||
if (items)
|
|
||||||
CFRelease(items);
|
|
||||||
if (pkcs12_data)
|
|
||||||
CFRelease(pkcs12_data);
|
|
||||||
if (options_dict)
|
|
||||||
CFRelease(options_dict);
|
|
||||||
if (password_ref)
|
|
||||||
CFRelease(password_ref);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size) {
|
|
||||||
CMSDecoderRef decoder = NULL;
|
|
||||||
CMSSignerStatus signer_status = 0;
|
|
||||||
CFDataRef message_out = NULL;
|
|
||||||
SecPolicyRef trust_policy = NULL;
|
|
||||||
OSStatus status = noErr;
|
|
||||||
OSStatus verify_status = noErr;
|
|
||||||
size_t signer_count = 0;
|
|
||||||
size_t i = 0;
|
|
||||||
int32_t err = MZ_SIGN_ERROR;
|
|
||||||
|
|
||||||
if (message == NULL || signature == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
status = CMSDecoderCreate(&decoder);
|
|
||||||
if (status == errSecSuccess)
|
|
||||||
status = CMSDecoderUpdateMessage(decoder, signature, signature_size);
|
|
||||||
if (status == errSecSuccess)
|
|
||||||
status = CMSDecoderFinalizeMessage(decoder);
|
|
||||||
if (status == errSecSuccess)
|
|
||||||
trust_policy = SecPolicyCreateBasicX509();
|
|
||||||
|
|
||||||
if (status == errSecSuccess && trust_policy) {
|
|
||||||
CMSDecoderGetNumSigners(decoder, &signer_count);
|
|
||||||
if (signer_count > 0)
|
|
||||||
err = MZ_OK;
|
|
||||||
for (i = 0; i < signer_count; i += 1) {
|
|
||||||
status = CMSDecoderCopySignerStatus(decoder, i, trust_policy, TRUE, &signer_status, NULL, &verify_status);
|
|
||||||
if (status != errSecSuccess || verify_status != 0 || signer_status != kCMSSignerValid) {
|
|
||||||
err = MZ_SIGN_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err == MZ_OK) {
|
|
||||||
status = CMSDecoderCopyContent(decoder, &message_out);
|
|
||||||
if ((status != errSecSuccess) ||
|
|
||||||
(CFDataGetLength(message_out) != message_size) ||
|
|
||||||
(memcmp(message, CFDataGetBytePtr(message_out), message_size) != 0))
|
|
||||||
err = MZ_SIGN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trust_policy)
|
|
||||||
CFRelease(trust_policy);
|
|
||||||
if (decoder)
|
|
||||||
CFRelease(decoder);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,638 +0,0 @@
|
||||||
/* mz_crypt_openssl.c -- Crypto/hash functions for OpenSSL
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
|
|
||||||
#include <openssl/err.h>
|
|
||||||
#include <openssl/engine.h>
|
|
||||||
#include <openssl/rand.h>
|
|
||||||
#include <openssl/sha.h>
|
|
||||||
#include <openssl/aes.h>
|
|
||||||
#include <openssl/crypto.h>
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#include <openssl/hmac.h>
|
|
||||||
|
|
||||||
#if defined(MZ_ZIP_SIGNING)
|
|
||||||
/* Note: https://www.imperialviolet.org/2015/10/17/boringssl.html says that
|
|
||||||
BoringSSL does not support CMS. "#include <etc/cms.h>" will fail. See
|
|
||||||
https://bugs.chromium.org/p/boringssl/issues/detail?id=421
|
|
||||||
*/
|
|
||||||
#include <openssl/cms.h>
|
|
||||||
#include <openssl/pkcs12.h>
|
|
||||||
#include <openssl/x509.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void mz_crypt_init(void) {
|
|
||||||
static int32_t openssl_initialized = 0;
|
|
||||||
if (openssl_initialized == 0) {
|
|
||||||
OpenSSL_add_all_algorithms();
|
|
||||||
|
|
||||||
ERR_load_BIO_strings();
|
|
||||||
ERR_load_crypto_strings();
|
|
||||||
|
|
||||||
ENGINE_load_builtin_engines();
|
|
||||||
ENGINE_register_all_complete();
|
|
||||||
|
|
||||||
openssl_initialized = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size) {
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
result = RAND_bytes(buf, size);
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
return MZ_CRYPT_ERROR;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_crypt_sha_s {
|
|
||||||
SHA256_CTX ctx256;
|
|
||||||
SHA_CTX ctx1;
|
|
||||||
int32_t initialized;
|
|
||||||
int32_t error;
|
|
||||||
uint16_t algorithm;
|
|
||||||
} mz_crypt_sha;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void mz_crypt_sha_reset(void *handle) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
|
|
||||||
sha->error = 0;
|
|
||||||
sha->initialized = 0;
|
|
||||||
|
|
||||||
mz_crypt_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_sha_begin(void *handle) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
|
|
||||||
if (sha == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_sha_reset(handle);
|
|
||||||
|
|
||||||
if (sha->algorithm == MZ_HASH_SHA1)
|
|
||||||
result = SHA1_Init(&sha->ctx1);
|
|
||||||
else
|
|
||||||
result = SHA256_Init(&sha->ctx256);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
sha->error = ERR_get_error();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
sha->initialized = 1;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
if (sha == NULL || buf == NULL || !sha->initialized)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (sha->algorithm == MZ_HASH_SHA1)
|
|
||||||
result = SHA1_Update(&sha->ctx1, buf, size);
|
|
||||||
else
|
|
||||||
result = SHA256_Update(&sha->ctx256, buf, size);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
sha->error = ERR_get_error();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
if (sha == NULL || digest == NULL || !sha->initialized)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (sha->algorithm == MZ_HASH_SHA1) {
|
|
||||||
if (digest_size < MZ_HASH_SHA1_SIZE)
|
|
||||||
return MZ_BUF_ERROR;
|
|
||||||
result = SHA1_Final(digest, &sha->ctx1);
|
|
||||||
} else {
|
|
||||||
if (digest_size < MZ_HASH_SHA256_SIZE)
|
|
||||||
return MZ_BUF_ERROR;
|
|
||||||
result = SHA256_Final(digest, &sha->ctx256);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
sha->error = ERR_get_error();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_sha_set_algorithm(void *handle, uint16_t algorithm) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
sha->algorithm = algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_crypt_sha_create(void **handle) {
|
|
||||||
mz_crypt_sha *sha = NULL;
|
|
||||||
|
|
||||||
sha = (mz_crypt_sha *)MZ_ALLOC(sizeof(mz_crypt_sha));
|
|
||||||
if (sha != NULL) {
|
|
||||||
memset(sha, 0, sizeof(mz_crypt_sha));
|
|
||||||
sha->algorithm = MZ_HASH_SHA256;
|
|
||||||
}
|
|
||||||
if (handle != NULL)
|
|
||||||
*handle = sha;
|
|
||||||
|
|
||||||
return sha;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_sha_delete(void **handle) {
|
|
||||||
mz_crypt_sha *sha = NULL;
|
|
||||||
if (handle == NULL)
|
|
||||||
return;
|
|
||||||
sha = (mz_crypt_sha *)*handle;
|
|
||||||
if (sha != NULL) {
|
|
||||||
mz_crypt_sha_reset(*handle);
|
|
||||||
MZ_FREE(sha);
|
|
||||||
}
|
|
||||||
*handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_crypt_aes_s {
|
|
||||||
AES_KEY key;
|
|
||||||
int32_t mode;
|
|
||||||
int32_t error;
|
|
||||||
uint8_t *key_copy;
|
|
||||||
int32_t key_length;
|
|
||||||
} mz_crypt_aes;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void mz_crypt_aes_reset(void *handle) {
|
|
||||||
MZ_UNUSED(handle);
|
|
||||||
|
|
||||||
mz_crypt_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_aes_encrypt(void *handle, uint8_t *buf, int32_t size) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
|
|
||||||
if (aes == NULL || buf == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (size != MZ_AES_BLOCK_SIZE)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
AES_encrypt(buf, buf, &aes->key);
|
|
||||||
/* Equivalent to AES_ecb_encrypt with AES_ENCRYPT */
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
if (aes == NULL || buf == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (size != MZ_AES_BLOCK_SIZE)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
AES_decrypt(buf, buf, &aes->key);
|
|
||||||
/* Equivalent to AES_ecb_encrypt with AES_DECRYPT */
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_aes_set_encrypt_key(void *handle, const void *key, int32_t key_length) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t key_bits = 0;
|
|
||||||
|
|
||||||
|
|
||||||
if (aes == NULL || key == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_aes_reset(handle);
|
|
||||||
|
|
||||||
key_bits = key_length * 8;
|
|
||||||
result = AES_set_encrypt_key(key, key_bits, &aes->key);
|
|
||||||
if (result) {
|
|
||||||
aes->error = ERR_get_error();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_aes_set_decrypt_key(void *handle, const void *key, int32_t key_length) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t key_bits = 0;
|
|
||||||
|
|
||||||
|
|
||||||
if (aes == NULL || key == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_aes_reset(handle);
|
|
||||||
|
|
||||||
key_bits = key_length * 8;
|
|
||||||
result = AES_set_decrypt_key(key, key_bits, &aes->key);
|
|
||||||
if (result) {
|
|
||||||
aes->error = ERR_get_error();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_aes_set_mode(void *handle, int32_t mode) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
aes->mode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_crypt_aes_create(void **handle) {
|
|
||||||
mz_crypt_aes *aes = NULL;
|
|
||||||
|
|
||||||
aes = (mz_crypt_aes *)MZ_ALLOC(sizeof(mz_crypt_aes));
|
|
||||||
if (aes != NULL)
|
|
||||||
memset(aes, 0, sizeof(mz_crypt_aes));
|
|
||||||
if (handle != NULL)
|
|
||||||
*handle = aes;
|
|
||||||
|
|
||||||
return aes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_aes_delete(void **handle) {
|
|
||||||
mz_crypt_aes *aes = NULL;
|
|
||||||
if (handle == NULL)
|
|
||||||
return;
|
|
||||||
aes = (mz_crypt_aes *)*handle;
|
|
||||||
if (aes != NULL)
|
|
||||||
MZ_FREE(aes);
|
|
||||||
*handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_crypt_hmac_s {
|
|
||||||
HMAC_CTX *ctx;
|
|
||||||
int32_t initialized;
|
|
||||||
int32_t error;
|
|
||||||
uint16_t algorithm;
|
|
||||||
} mz_crypt_hmac;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x2070000fL))
|
|
||||||
static HMAC_CTX *HMAC_CTX_new(void) {
|
|
||||||
HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX));
|
|
||||||
if (ctx != NULL)
|
|
||||||
HMAC_CTX_init(ctx);
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void HMAC_CTX_free(HMAC_CTX *ctx) {
|
|
||||||
if (ctx != NULL) {
|
|
||||||
HMAC_CTX_cleanup(ctx);
|
|
||||||
OPENSSL_free(ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void mz_crypt_hmac_reset(void *handle) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
|
|
||||||
HMAC_CTX_free(hmac->ctx);
|
|
||||||
|
|
||||||
hmac->ctx = NULL;
|
|
||||||
hmac->error = 0;
|
|
||||||
|
|
||||||
mz_crypt_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_hmac_init(void *handle, const void *key, int32_t key_length) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
const EVP_MD *evp_md = NULL;
|
|
||||||
|
|
||||||
if (hmac == NULL || key == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_hmac_reset(handle);
|
|
||||||
|
|
||||||
hmac->ctx = HMAC_CTX_new();
|
|
||||||
|
|
||||||
if (hmac->algorithm == MZ_HASH_SHA1)
|
|
||||||
evp_md = EVP_sha1();
|
|
||||||
else
|
|
||||||
evp_md = EVP_sha256();
|
|
||||||
|
|
||||||
result = HMAC_Init_ex(hmac->ctx, key, key_length, evp_md, NULL);
|
|
||||||
if (!result) {
|
|
||||||
hmac->error = ERR_get_error();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_hmac_update(void *handle, const void *buf, int32_t size) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
if (hmac == NULL || buf == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
result = HMAC_Update(hmac->ctx, buf, size);
|
|
||||||
if (!result) {
|
|
||||||
hmac->error = ERR_get_error();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
if (hmac == NULL || digest == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (hmac->algorithm == MZ_HASH_SHA1) {
|
|
||||||
if (digest_size < MZ_HASH_SHA1_SIZE)
|
|
||||||
return MZ_BUF_ERROR;
|
|
||||||
|
|
||||||
result = HMAC_Final(hmac->ctx, digest, (uint32_t *)&digest_size);
|
|
||||||
} else {
|
|
||||||
if (digest_size < MZ_HASH_SHA256_SIZE)
|
|
||||||
return MZ_BUF_ERROR;
|
|
||||||
result = HMAC_Final(hmac->ctx, digest, (uint32_t *)&digest_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
hmac->error = ERR_get_error();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_hmac_set_algorithm(void *handle, uint16_t algorithm) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
hmac->algorithm = algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_hmac_copy(void *src_handle, void *target_handle) {
|
|
||||||
mz_crypt_hmac *source = (mz_crypt_hmac *)src_handle;
|
|
||||||
mz_crypt_hmac *target = (mz_crypt_hmac *)target_handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
if (source == NULL || target == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_hmac_reset(target_handle);
|
|
||||||
|
|
||||||
if (target->ctx == NULL)
|
|
||||||
target->ctx = HMAC_CTX_new();
|
|
||||||
|
|
||||||
result = HMAC_CTX_copy(target->ctx, source->ctx);
|
|
||||||
if (!result) {
|
|
||||||
target->error = ERR_get_error();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_crypt_hmac_create(void **handle) {
|
|
||||||
mz_crypt_hmac *hmac = NULL;
|
|
||||||
|
|
||||||
hmac = (mz_crypt_hmac *)MZ_ALLOC(sizeof(mz_crypt_hmac));
|
|
||||||
if (hmac != NULL) {
|
|
||||||
memset(hmac, 0, sizeof(mz_crypt_hmac));
|
|
||||||
hmac->algorithm = MZ_HASH_SHA256;
|
|
||||||
}
|
|
||||||
if (handle != NULL)
|
|
||||||
*handle = hmac;
|
|
||||||
|
|
||||||
return hmac;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_hmac_delete(void **handle) {
|
|
||||||
mz_crypt_hmac *hmac = NULL;
|
|
||||||
if (handle == NULL)
|
|
||||||
return;
|
|
||||||
hmac = (mz_crypt_hmac *)*handle;
|
|
||||||
if (hmac != NULL) {
|
|
||||||
mz_crypt_hmac_reset(*handle);
|
|
||||||
MZ_FREE(hmac);
|
|
||||||
}
|
|
||||||
*handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(MZ_ZIP_SIGNING)
|
|
||||||
int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size,
|
|
||||||
const char *cert_pwd, uint8_t **signature, int32_t *signature_size) {
|
|
||||||
PKCS12 *p12 = NULL;
|
|
||||||
EVP_PKEY *evp_pkey = NULL;
|
|
||||||
BUF_MEM *buf_mem = NULL;
|
|
||||||
BIO *cert_bio = NULL;
|
|
||||||
BIO *message_bio = NULL;
|
|
||||||
BIO *signature_bio = NULL;
|
|
||||||
CMS_ContentInfo *cms = NULL;
|
|
||||||
CMS_SignerInfo *signer_info = NULL;
|
|
||||||
STACK_OF(X509) *ca_stack = NULL;
|
|
||||||
X509 *cert = NULL;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
|
|
||||||
if (message == NULL || cert_data == NULL || signature == NULL || signature_size == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_init();
|
|
||||||
|
|
||||||
*signature = NULL;
|
|
||||||
*signature_size = 0;
|
|
||||||
|
|
||||||
cert_bio = BIO_new_mem_buf(cert_data, cert_data_size);
|
|
||||||
|
|
||||||
if (d2i_PKCS12_bio(cert_bio, &p12) == NULL)
|
|
||||||
err = MZ_SIGN_ERROR;
|
|
||||||
if (err == MZ_OK)
|
|
||||||
result = PKCS12_parse(p12, cert_pwd, &evp_pkey, &cert, &ca_stack);
|
|
||||||
if (result) {
|
|
||||||
cms = CMS_sign(NULL, NULL, ca_stack, NULL, CMS_BINARY | CMS_PARTIAL);
|
|
||||||
if (cms)
|
|
||||||
signer_info = CMS_add1_signer(cms, cert, evp_pkey, EVP_sha256(), 0);
|
|
||||||
if (signer_info == NULL) {
|
|
||||||
err = MZ_SIGN_ERROR;
|
|
||||||
} else {
|
|
||||||
message_bio = BIO_new_mem_buf(message, message_size);
|
|
||||||
signature_bio = BIO_new(BIO_s_mem());
|
|
||||||
|
|
||||||
result = CMS_final(cms, message_bio, NULL, CMS_BINARY);
|
|
||||||
if (result)
|
|
||||||
result = i2d_CMS_bio(signature_bio, cms);
|
|
||||||
if (result) {
|
|
||||||
BIO_flush(signature_bio);
|
|
||||||
BIO_get_mem_ptr(signature_bio, &buf_mem);
|
|
||||||
|
|
||||||
*signature_size = buf_mem->length;
|
|
||||||
*signature = MZ_ALLOC(buf_mem->length);
|
|
||||||
|
|
||||||
memcpy(*signature, buf_mem->data, buf_mem->length);
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
BIO *yy = BIO_new_file("xyz", "wb");
|
|
||||||
BIO_write(yy, *signature, *signature_size);
|
|
||||||
BIO_flush(yy);
|
|
||||||
BIO_free(yy);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
err = MZ_SIGN_ERROR;
|
|
||||||
|
|
||||||
if (cms)
|
|
||||||
CMS_ContentInfo_free(cms);
|
|
||||||
if (signature_bio)
|
|
||||||
BIO_free(signature_bio);
|
|
||||||
if (cert_bio)
|
|
||||||
BIO_free(cert_bio);
|
|
||||||
if (message_bio)
|
|
||||||
BIO_free(message_bio);
|
|
||||||
if (p12)
|
|
||||||
PKCS12_free(p12);
|
|
||||||
|
|
||||||
if (err != MZ_OK && *signature != NULL) {
|
|
||||||
MZ_FREE(*signature);
|
|
||||||
*signature = NULL;
|
|
||||||
*signature_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size) {
|
|
||||||
CMS_ContentInfo *cms = NULL;
|
|
||||||
STACK_OF(X509) *signers = NULL;
|
|
||||||
STACK_OF(X509) *intercerts = NULL;
|
|
||||||
X509_STORE *cert_store = NULL;
|
|
||||||
X509_LOOKUP *lookup = NULL;
|
|
||||||
X509_STORE_CTX *store_ctx = NULL;
|
|
||||||
BIO *message_bio = NULL;
|
|
||||||
BIO *signature_bio = NULL;
|
|
||||||
BUF_MEM *buf_mem = NULL;
|
|
||||||
int32_t signer_count = 0;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t i = 0;
|
|
||||||
int32_t err = MZ_SIGN_ERROR;
|
|
||||||
|
|
||||||
|
|
||||||
if (message == NULL || message_size == 0 || signature == NULL || signature_size == 0)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_init();
|
|
||||||
|
|
||||||
cert_store = X509_STORE_new();
|
|
||||||
|
|
||||||
X509_STORE_load_locations(cert_store, "cacert.pem", NULL);
|
|
||||||
X509_STORE_set_default_paths(cert_store);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
BIO *yy = BIO_new_file("xyz", "wb");
|
|
||||||
BIO_write(yy, signature, signature_size);
|
|
||||||
BIO_flush(yy);
|
|
||||||
BIO_free(yy);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lookup = X509_STORE_add_lookup(cert_store, X509_LOOKUP_file());
|
|
||||||
if (lookup != NULL)
|
|
||||||
X509_LOOKUP_load_file(lookup, "cacert.pem", X509_FILETYPE_PEM);
|
|
||||||
lookup = X509_STORE_add_lookup(cert_store, X509_LOOKUP_hash_dir());
|
|
||||||
if (lookup != NULL)
|
|
||||||
X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
|
|
||||||
|
|
||||||
signature_bio = BIO_new_mem_buf(signature, signature_size);
|
|
||||||
message_bio = BIO_new(BIO_s_mem());
|
|
||||||
|
|
||||||
cms = d2i_CMS_bio(signature_bio, NULL);
|
|
||||||
if (cms) {
|
|
||||||
result = CMS_verify(cms, NULL, cert_store, NULL, message_bio, CMS_NO_SIGNER_CERT_VERIFY | CMS_BINARY);
|
|
||||||
if (result)
|
|
||||||
signers = CMS_get0_signers(cms);
|
|
||||||
if (signers)
|
|
||||||
intercerts = CMS_get1_certs(cms);
|
|
||||||
if (intercerts) {
|
|
||||||
/* Verify signer certificates */
|
|
||||||
signer_count = sk_X509_num(signers);
|
|
||||||
if (signer_count > 0)
|
|
||||||
err = MZ_OK;
|
|
||||||
|
|
||||||
for (i = 0; i < signer_count; i++) {
|
|
||||||
store_ctx = X509_STORE_CTX_new();
|
|
||||||
X509_STORE_CTX_init(store_ctx, cert_store, sk_X509_value(signers, i), intercerts);
|
|
||||||
result = X509_verify_cert(store_ctx);
|
|
||||||
if (store_ctx)
|
|
||||||
X509_STORE_CTX_free(store_ctx);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
err = MZ_SIGN_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BIO_get_mem_ptr(message_bio, &buf_mem);
|
|
||||||
|
|
||||||
if (err == MZ_OK) {
|
|
||||||
/* Verify the message */
|
|
||||||
if (((int32_t)buf_mem->length != message_size) ||
|
|
||||||
(memcmp(buf_mem->data, message, message_size) != 0))
|
|
||||||
err = MZ_SIGN_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (!result)
|
|
||||||
printf(ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (cms)
|
|
||||||
CMS_ContentInfo_free(cms);
|
|
||||||
if (message_bio)
|
|
||||||
BIO_free(message_bio);
|
|
||||||
if (signature_bio)
|
|
||||||
BIO_free(signature_bio);
|
|
||||||
if (cert_store)
|
|
||||||
X509_STORE_free(cert_store);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,739 +0,0 @@
|
||||||
/* mz_crypt_win32.c -- Crypto/hash functions for Windows
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_os.h"
|
|
||||||
#include "mz_crypt.h"
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <wincrypt.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_crypt_rand(uint8_t *buf, int32_t size) {
|
|
||||||
HCRYPTPROV provider;
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
|
|
||||||
result = CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
|
|
||||||
if (result) {
|
|
||||||
result = CryptGenRandom(provider, size, buf);
|
|
||||||
CryptReleaseContext(provider, 0);
|
|
||||||
if (result)
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mz_os_rand(buf, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_crypt_sha_s {
|
|
||||||
HCRYPTPROV provider;
|
|
||||||
HCRYPTHASH hash;
|
|
||||||
int32_t error;
|
|
||||||
uint16_t algorithm;
|
|
||||||
} mz_crypt_sha;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void mz_crypt_sha_reset(void *handle) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
if (sha->hash)
|
|
||||||
CryptDestroyHash(sha->hash);
|
|
||||||
sha->hash = 0;
|
|
||||||
if (sha->provider)
|
|
||||||
CryptReleaseContext(sha->provider, 0);
|
|
||||||
sha->provider = 0;
|
|
||||||
sha->error = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_sha_begin(void *handle) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
ALG_ID alg_id = 0;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
|
|
||||||
if (sha == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (sha->algorithm == MZ_HASH_SHA1)
|
|
||||||
alg_id = CALG_SHA1;
|
|
||||||
else
|
|
||||||
alg_id = CALG_SHA_256;
|
|
||||||
|
|
||||||
result = CryptAcquireContext(&sha->provider, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
|
|
||||||
if (!result) {
|
|
||||||
sha->error = GetLastError();
|
|
||||||
err = MZ_CRYPT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
result = CryptCreateHash(sha->provider, alg_id, 0, 0, &sha->hash);
|
|
||||||
if (!result) {
|
|
||||||
sha->error = GetLastError();
|
|
||||||
err = MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
if (sha == NULL || buf == NULL || sha->hash == 0)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
result = CryptHashData(sha->hash, buf, size, 0);
|
|
||||||
if (!result) {
|
|
||||||
sha->error = GetLastError();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t expected_size = 0;
|
|
||||||
|
|
||||||
if (sha == NULL || digest == NULL || sha->hash == 0)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
result = CryptGetHashParam(sha->hash, HP_HASHVAL, NULL, (DWORD *)&expected_size, 0);
|
|
||||||
if (expected_size > digest_size)
|
|
||||||
return MZ_BUF_ERROR;
|
|
||||||
if (!result)
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
result = CryptGetHashParam(sha->hash, HP_HASHVAL, digest, (DWORD *)&digest_size, 0);
|
|
||||||
if (!result) {
|
|
||||||
sha->error = GetLastError();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_sha_set_algorithm(void *handle, uint16_t algorithm) {
|
|
||||||
mz_crypt_sha *sha = (mz_crypt_sha *)handle;
|
|
||||||
sha->algorithm = algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_crypt_sha_create(void **handle) {
|
|
||||||
mz_crypt_sha *sha = NULL;
|
|
||||||
|
|
||||||
sha = (mz_crypt_sha *)MZ_ALLOC(sizeof(mz_crypt_sha));
|
|
||||||
if (sha != NULL) {
|
|
||||||
memset(sha, 0, sizeof(mz_crypt_sha));
|
|
||||||
sha->algorithm = MZ_HASH_SHA256;
|
|
||||||
}
|
|
||||||
if (handle != NULL)
|
|
||||||
*handle = sha;
|
|
||||||
|
|
||||||
return sha;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_sha_delete(void **handle) {
|
|
||||||
mz_crypt_sha *sha = NULL;
|
|
||||||
if (handle == NULL)
|
|
||||||
return;
|
|
||||||
sha = (mz_crypt_sha *)*handle;
|
|
||||||
if (sha != NULL) {
|
|
||||||
mz_crypt_sha_reset(*handle);
|
|
||||||
MZ_FREE(sha);
|
|
||||||
}
|
|
||||||
*handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_crypt_aes_s {
|
|
||||||
HCRYPTPROV provider;
|
|
||||||
HCRYPTKEY key;
|
|
||||||
int32_t mode;
|
|
||||||
int32_t error;
|
|
||||||
} mz_crypt_aes;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void mz_crypt_aes_free(void *handle) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
if (aes->key)
|
|
||||||
CryptDestroyKey(aes->key);
|
|
||||||
aes->key = 0;
|
|
||||||
if (aes->provider)
|
|
||||||
CryptReleaseContext(aes->provider, 0);
|
|
||||||
aes->provider = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_aes_reset(void *handle) {
|
|
||||||
mz_crypt_aes_free(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_aes_encrypt(void *handle, uint8_t *buf, int32_t size) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
if (aes == NULL || buf == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (size != MZ_AES_BLOCK_SIZE)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
result = CryptEncrypt(aes->key, 0, 0, 0, buf, (DWORD *)&size, size);
|
|
||||||
if (!result) {
|
|
||||||
aes->error = GetLastError();
|
|
||||||
return MZ_CRYPT_ERROR;
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
if (aes == NULL || buf == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (size != MZ_AES_BLOCK_SIZE)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
result = CryptDecrypt(aes->key, 0, 0, 0, buf, (DWORD *)&size);
|
|
||||||
if (!result) {
|
|
||||||
aes->error = GetLastError();
|
|
||||||
return MZ_CRYPT_ERROR;
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_crypt_aes_set_key(void *handle, const void *key, int32_t key_length) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
HCRYPTHASH hash = 0;
|
|
||||||
ALG_ID alg_id = 0;
|
|
||||||
typedef struct key_blob_header_s {
|
|
||||||
BLOBHEADER hdr;
|
|
||||||
uint32_t key_length;
|
|
||||||
} key_blob_header_s;
|
|
||||||
key_blob_header_s *key_blob_s = NULL;
|
|
||||||
uint32_t mode = CRYPT_MODE_ECB;
|
|
||||||
uint8_t *key_blob = NULL;
|
|
||||||
int32_t key_blob_size = 0;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
|
|
||||||
if (aes == NULL || key == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_aes_reset(handle);
|
|
||||||
|
|
||||||
if (key_length == MZ_AES_KEY_LENGTH(MZ_AES_ENCRYPTION_MODE_128))
|
|
||||||
alg_id = CALG_AES_128;
|
|
||||||
else if (key_length == MZ_AES_KEY_LENGTH(MZ_AES_ENCRYPTION_MODE_192))
|
|
||||||
alg_id = CALG_AES_192;
|
|
||||||
else if (key_length == MZ_AES_KEY_LENGTH(MZ_AES_ENCRYPTION_MODE_256))
|
|
||||||
alg_id = CALG_AES_256;
|
|
||||||
else
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
result = CryptAcquireContext(&aes->provider, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
|
|
||||||
if (result) {
|
|
||||||
key_blob_size = sizeof(key_blob_header_s) + key_length;
|
|
||||||
key_blob = (uint8_t *)MZ_ALLOC(key_blob_size);
|
|
||||||
if (key_blob) {
|
|
||||||
key_blob_s = (key_blob_header_s *)key_blob;
|
|
||||||
key_blob_s->hdr.bType = PLAINTEXTKEYBLOB;
|
|
||||||
key_blob_s->hdr.bVersion = CUR_BLOB_VERSION;
|
|
||||||
key_blob_s->hdr.aiKeyAlg = alg_id;
|
|
||||||
key_blob_s->hdr.reserved = 0;
|
|
||||||
key_blob_s->key_length = key_length;
|
|
||||||
|
|
||||||
memcpy(key_blob + sizeof(key_blob_header_s), key, key_length);
|
|
||||||
|
|
||||||
result = CryptImportKey(aes->provider, key_blob, key_blob_size, 0, 0, &aes->key);
|
|
||||||
|
|
||||||
SecureZeroMemory(key_blob, key_blob_size);
|
|
||||||
MZ_FREE(key_blob);
|
|
||||||
} else {
|
|
||||||
err = MZ_MEM_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result && err == MZ_OK)
|
|
||||||
result = CryptSetKeyParam(aes->key, KP_MODE, (const uint8_t *)&mode, 0);
|
|
||||||
|
|
||||||
if (!result && err == MZ_OK) {
|
|
||||||
aes->error = GetLastError();
|
|
||||||
err = MZ_CRYPT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hash)
|
|
||||||
CryptDestroyHash(hash);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_aes_set_encrypt_key(void *handle, const void *key, int32_t key_length) {
|
|
||||||
return mz_crypt_aes_set_key(handle, key, key_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_aes_set_decrypt_key(void *handle, const void *key, int32_t key_length) {
|
|
||||||
return mz_crypt_aes_set_key(handle, key, key_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_aes_set_mode(void *handle, int32_t mode) {
|
|
||||||
mz_crypt_aes *aes = (mz_crypt_aes *)handle;
|
|
||||||
aes->mode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_crypt_aes_create(void **handle) {
|
|
||||||
mz_crypt_aes *aes = NULL;
|
|
||||||
|
|
||||||
aes = (mz_crypt_aes *)MZ_ALLOC(sizeof(mz_crypt_aes));
|
|
||||||
if (aes != NULL)
|
|
||||||
memset(aes, 0, sizeof(mz_crypt_aes));
|
|
||||||
if (handle != NULL)
|
|
||||||
*handle = aes;
|
|
||||||
|
|
||||||
return aes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_aes_delete(void **handle) {
|
|
||||||
mz_crypt_aes *aes = NULL;
|
|
||||||
if (handle == NULL)
|
|
||||||
return;
|
|
||||||
aes = (mz_crypt_aes *)*handle;
|
|
||||||
if (aes != NULL) {
|
|
||||||
mz_crypt_aes_free(*handle);
|
|
||||||
MZ_FREE(aes);
|
|
||||||
}
|
|
||||||
*handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_crypt_hmac_s {
|
|
||||||
HCRYPTPROV provider;
|
|
||||||
HCRYPTHASH hash;
|
|
||||||
HCRYPTKEY key;
|
|
||||||
HMAC_INFO info;
|
|
||||||
int32_t mode;
|
|
||||||
int32_t error;
|
|
||||||
uint16_t algorithm;
|
|
||||||
} mz_crypt_hmac;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static void mz_crypt_hmac_free(void *handle) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
if (hmac->key)
|
|
||||||
CryptDestroyKey(hmac->key);
|
|
||||||
hmac->key = 0;
|
|
||||||
if (hmac->hash)
|
|
||||||
CryptDestroyHash(hmac->hash);
|
|
||||||
hmac->hash = 0;
|
|
||||||
if (hmac->provider)
|
|
||||||
CryptReleaseContext(hmac->provider, 0);
|
|
||||||
hmac->provider = 0;
|
|
||||||
memset(&hmac->info, 0, sizeof(hmac->info));
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_hmac_reset(void *handle) {
|
|
||||||
mz_crypt_hmac_free(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_hmac_init(void *handle, const void *key, int32_t key_length) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
ALG_ID alg_id = 0;
|
|
||||||
typedef struct key_blob_header_s {
|
|
||||||
BLOBHEADER hdr;
|
|
||||||
uint32_t key_length;
|
|
||||||
} key_blob_header_s;
|
|
||||||
key_blob_header_s *key_blob_s = NULL;
|
|
||||||
uint8_t *key_blob = NULL;
|
|
||||||
int32_t key_blob_size = 0;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
|
|
||||||
if (hmac == NULL || key == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_crypt_hmac_reset(handle);
|
|
||||||
|
|
||||||
if (hmac->algorithm == MZ_HASH_SHA1)
|
|
||||||
alg_id = CALG_SHA1;
|
|
||||||
else
|
|
||||||
alg_id = CALG_SHA_256;
|
|
||||||
|
|
||||||
hmac->info.HashAlgid = alg_id;
|
|
||||||
|
|
||||||
result = CryptAcquireContext(&hmac->provider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,
|
|
||||||
CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
hmac->error = GetLastError();
|
|
||||||
err = MZ_CRYPT_ERROR;
|
|
||||||
} else {
|
|
||||||
/* Zero-pad odd key lengths */
|
|
||||||
if (key_length % 2 == 1)
|
|
||||||
key_length += 1;
|
|
||||||
key_blob_size = sizeof(key_blob_header_s) + key_length;
|
|
||||||
key_blob = (uint8_t *)MZ_ALLOC(key_blob_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key_blob) {
|
|
||||||
memset(key_blob, 0, key_blob_size);
|
|
||||||
key_blob_s = (key_blob_header_s *)key_blob;
|
|
||||||
key_blob_s->hdr.bType = PLAINTEXTKEYBLOB;
|
|
||||||
key_blob_s->hdr.bVersion = CUR_BLOB_VERSION;
|
|
||||||
key_blob_s->hdr.aiKeyAlg = CALG_RC2;
|
|
||||||
key_blob_s->hdr.reserved = 0;
|
|
||||||
key_blob_s->key_length = key_length;
|
|
||||||
|
|
||||||
memcpy(key_blob + sizeof(key_blob_header_s), key, key_length);
|
|
||||||
|
|
||||||
result = CryptImportKey(hmac->provider, key_blob, key_blob_size, 0, CRYPT_IPSEC_HMAC_KEY, &hmac->key);
|
|
||||||
if (result)
|
|
||||||
result = CryptCreateHash(hmac->provider, CALG_HMAC, hmac->key, 0, &hmac->hash);
|
|
||||||
if (result)
|
|
||||||
result = CryptSetHashParam(hmac->hash, HP_HMAC_INFO, (uint8_t *)&hmac->info, 0);
|
|
||||||
|
|
||||||
SecureZeroMemory(key_blob, key_blob_size);
|
|
||||||
MZ_FREE(key_blob);
|
|
||||||
} else if (err == MZ_OK) {
|
|
||||||
err = MZ_MEM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
hmac->error = GetLastError();
|
|
||||||
err = MZ_CRYPT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err != MZ_OK)
|
|
||||||
mz_crypt_hmac_free(handle);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_hmac_update(void *handle, const void *buf, int32_t size) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
if (hmac == NULL || buf == NULL || hmac->hash == 0)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
result = CryptHashData(hmac->hash, buf, size, 0);
|
|
||||||
if (!result) {
|
|
||||||
hmac->error = GetLastError();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t expected_size = 0;
|
|
||||||
|
|
||||||
if (hmac == NULL || digest == NULL || hmac->hash == 0)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
result = CryptGetHashParam(hmac->hash, HP_HASHVAL, NULL, (DWORD *)&expected_size, 0);
|
|
||||||
if (expected_size > digest_size)
|
|
||||||
return MZ_BUF_ERROR;
|
|
||||||
if (!result)
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
result = CryptGetHashParam(hmac->hash, HP_HASHVAL, digest, (DWORD *)&digest_size, 0);
|
|
||||||
if (!result) {
|
|
||||||
hmac->error = GetLastError();
|
|
||||||
return MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_hmac_set_algorithm(void *handle, uint16_t algorithm) {
|
|
||||||
mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
|
|
||||||
hmac->algorithm = algorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_hmac_copy(void *src_handle, void *target_handle) {
|
|
||||||
mz_crypt_hmac *source = (mz_crypt_hmac *)src_handle;
|
|
||||||
mz_crypt_hmac *target = (mz_crypt_hmac *)target_handle;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
if (target->hash) {
|
|
||||||
CryptDestroyHash(target->hash);
|
|
||||||
target->hash = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = CryptDuplicateHash(source->hash, NULL, 0, &target->hash);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
target->error = GetLastError();
|
|
||||||
err = MZ_HASH_ERROR;
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_crypt_hmac_create(void **handle) {
|
|
||||||
mz_crypt_hmac *hmac = NULL;
|
|
||||||
|
|
||||||
hmac = (mz_crypt_hmac *)MZ_ALLOC(sizeof(mz_crypt_hmac));
|
|
||||||
if (hmac != NULL) {
|
|
||||||
memset(hmac, 0, sizeof(mz_crypt_hmac));
|
|
||||||
hmac->algorithm = MZ_HASH_SHA256;
|
|
||||||
}
|
|
||||||
if (handle != NULL)
|
|
||||||
*handle = hmac;
|
|
||||||
|
|
||||||
return hmac;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_crypt_hmac_delete(void **handle) {
|
|
||||||
mz_crypt_hmac *hmac = NULL;
|
|
||||||
if (handle == NULL)
|
|
||||||
return;
|
|
||||||
hmac = (mz_crypt_hmac *)*handle;
|
|
||||||
if (hmac != NULL) {
|
|
||||||
mz_crypt_hmac_free(*handle);
|
|
||||||
MZ_FREE(hmac);
|
|
||||||
}
|
|
||||||
*handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(MZ_ZIP_SIGNING)
|
|
||||||
int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size,
|
|
||||||
const char *cert_pwd, uint8_t **signature, int32_t *signature_size) {
|
|
||||||
CRYPT_SIGN_MESSAGE_PARA sign_params;
|
|
||||||
CRYPT_DATA_BLOB cert_data_blob;
|
|
||||||
PCCERT_CONTEXT cert_context = NULL;
|
|
||||||
HCERTSTORE cert_store = 0;
|
|
||||||
wchar_t *password_wide = NULL;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
uint32_t messages_sizes[1];
|
|
||||||
uint8_t *messages[1];
|
|
||||||
|
|
||||||
|
|
||||||
if (message == NULL || cert_data == NULL || signature == NULL || signature_size == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
*signature = NULL;
|
|
||||||
*signature_size = 0;
|
|
||||||
|
|
||||||
cert_data_blob.pbData = cert_data;
|
|
||||||
cert_data_blob.cbData = cert_data_size;
|
|
||||||
|
|
||||||
password_wide = mz_os_unicode_string_create(cert_pwd, MZ_ENCODING_UTF8);
|
|
||||||
if (password_wide) {
|
|
||||||
cert_store = PFXImportCertStore(&cert_data_blob, password_wide, 0);
|
|
||||||
mz_os_unicode_string_delete(&password_wide);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cert_store == NULL)
|
|
||||||
cert_store = PFXImportCertStore(&cert_data_blob, L"", 0);
|
|
||||||
if (cert_store == NULL)
|
|
||||||
cert_store = PFXImportCertStore(&cert_data_blob, NULL, 0);
|
|
||||||
if (cert_store == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (err == MZ_OK) {
|
|
||||||
cert_context = CertFindCertificateInStore(cert_store,
|
|
||||||
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_HAS_PRIVATE_KEY, NULL, NULL);
|
|
||||||
if (cert_context == NULL)
|
|
||||||
err = MZ_PARAM_ERROR;
|
|
||||||
}
|
|
||||||
if (err == MZ_OK) {
|
|
||||||
memset(&sign_params, 0, sizeof(sign_params));
|
|
||||||
|
|
||||||
sign_params.cbSize = sizeof(sign_params);
|
|
||||||
sign_params.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
|
|
||||||
sign_params.pSigningCert = cert_context;
|
|
||||||
sign_params.HashAlgorithm.pszObjId = szOID_NIST_sha256;
|
|
||||||
sign_params.cMsgCert = 1;
|
|
||||||
sign_params.rgpMsgCert = &cert_context;
|
|
||||||
|
|
||||||
messages[0] = message;
|
|
||||||
messages_sizes[0] = message_size;
|
|
||||||
|
|
||||||
#if 0 /* Timestamp support */
|
|
||||||
CRYPT_ATTR_BLOB crypt_blob;
|
|
||||||
CRYPT_TIMESTAMP_CONTEXT *ts_context = NULL;
|
|
||||||
CRYPT_ATTRIBUTE unauth_attribs[1];
|
|
||||||
wchar_t *timestamp_url_wide = NULL;
|
|
||||||
const char *timestamp_url = NULL;
|
|
||||||
|
|
||||||
if (timestamp_url != NULL)
|
|
||||||
timestamp_url_wide = mz_os_unicode_string_create(timestamp_url);
|
|
||||||
if (timestamp_url_wide != NULL) {
|
|
||||||
result = CryptRetrieveTimeStamp(timestamp_url_wide,
|
|
||||||
TIMESTAMP_NO_AUTH_RETRIEVAL | TIMESTAMP_VERIFY_CONTEXT_SIGNATURE, 0, szOID_NIST_sha256,
|
|
||||||
NULL, message, message_size, &ts_context, NULL, NULL);
|
|
||||||
|
|
||||||
mz_os_unicode_string_delete(×tamp_url_wide);
|
|
||||||
|
|
||||||
if ((result) && (ts_context != NULL)) {
|
|
||||||
crypt_blob.cbData = ts_context->cbEncoded;
|
|
||||||
crypt_blob.pbData = ts_context->pbEncoded;
|
|
||||||
|
|
||||||
unauth_attribs[0].pszObjId = "1.2.840.113549.1.9.16.2.14"; //id-smime-aa-timeStampToken
|
|
||||||
unauth_attribs[0].cValue = 1;
|
|
||||||
unauth_attribs[0].rgValue = &crypt_blob;
|
|
||||||
|
|
||||||
sign_params.rgUnauthAttr = &unauth_attribs[0];
|
|
||||||
sign_params.cUnauthAttr = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ts_context != NULL)
|
|
||||||
CryptMemFree(ts_context);
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result = CryptSignMessage(&sign_params, FALSE, 1, (const BYTE **)messages, (DWORD *)messages_sizes,
|
|
||||||
NULL, (DWORD *)signature_size);
|
|
||||||
|
|
||||||
if (result && *signature_size > 0)
|
|
||||||
*signature = (uint8_t *)MZ_ALLOC(*signature_size);
|
|
||||||
|
|
||||||
if (result && *signature != NULL)
|
|
||||||
result = CryptSignMessage(&sign_params, FALSE, 1, (const BYTE **)messages, (DWORD *)messages_sizes,
|
|
||||||
*signature, (DWORD *)signature_size);
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
err = MZ_SIGN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cert_context != NULL)
|
|
||||||
CertFreeCertificateContext(cert_context);
|
|
||||||
if (cert_store != NULL)
|
|
||||||
CertCloseStore(cert_store, 0);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size) {
|
|
||||||
CRYPT_VERIFY_MESSAGE_PARA verify_params;
|
|
||||||
CERT_CONTEXT *signer_cert = NULL;
|
|
||||||
CERT_CHAIN_PARA chain_para;
|
|
||||||
CERT_CHAIN_CONTEXT *chain_context = NULL;
|
|
||||||
CERT_CHAIN_POLICY_PARA chain_policy;
|
|
||||||
CERT_CHAIN_POLICY_STATUS chain_policy_status;
|
|
||||||
HCRYPTMSG crypt_msg = 0;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t err = MZ_SIGN_ERROR;
|
|
||||||
uint8_t *decoded = NULL;
|
|
||||||
int32_t decoded_size = 0;
|
|
||||||
|
|
||||||
|
|
||||||
memset(&verify_params, 0, sizeof(verify_params));
|
|
||||||
|
|
||||||
verify_params.cbSize = sizeof(verify_params);
|
|
||||||
verify_params.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
|
|
||||||
|
|
||||||
result = CryptVerifyMessageSignature(&verify_params, 0, signature, signature_size,
|
|
||||||
NULL, (DWORD *)&decoded_size, NULL);
|
|
||||||
|
|
||||||
if (result && decoded_size > 0)
|
|
||||||
decoded = (uint8_t *)MZ_ALLOC(decoded_size);
|
|
||||||
|
|
||||||
if (result && decoded != NULL)
|
|
||||||
result = CryptVerifyMessageSignature(&verify_params, 0, signature, signature_size,
|
|
||||||
decoded, (DWORD *)&decoded_size, (const CERT_CONTEXT **)&signer_cert);
|
|
||||||
|
|
||||||
/* Get and validate certificate chain */
|
|
||||||
memset(&chain_para, 0, sizeof(chain_para));
|
|
||||||
|
|
||||||
if (result && signer_cert != NULL)
|
|
||||||
result = CertGetCertificateChain(NULL, signer_cert, NULL, NULL, &chain_para,
|
|
||||||
CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, NULL, (const CERT_CHAIN_CONTEXT **)&chain_context);
|
|
||||||
|
|
||||||
memset(&chain_policy, 0, sizeof(chain_policy));
|
|
||||||
chain_policy.cbSize = sizeof(CERT_CHAIN_POLICY_PARA);
|
|
||||||
|
|
||||||
memset(&chain_policy_status, 0, sizeof(chain_policy_status));
|
|
||||||
chain_policy_status.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS);
|
|
||||||
|
|
||||||
if (result && chain_context != NULL)
|
|
||||||
result = CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_BASE, chain_context,
|
|
||||||
&chain_policy, &chain_policy_status);
|
|
||||||
|
|
||||||
if (chain_policy_status.dwError != S_OK)
|
|
||||||
result = 0;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
crypt_msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
|
|
||||||
if (crypt_msg != NULL) {
|
|
||||||
/* Timestamp support */
|
|
||||||
PCRYPT_ATTRIBUTES unauth_attribs = NULL;
|
|
||||||
HCRYPTMSG ts_msg = 0;
|
|
||||||
uint8_t *ts_content = NULL;
|
|
||||||
int32_t ts_content_size = 0;
|
|
||||||
uint8_t *ts_signature = NULL;
|
|
||||||
int32_t ts_signature_size = 0;
|
|
||||||
|
|
||||||
result = CryptMsgUpdate(crypt_msg, signature, signature_size, 1);
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
CryptMsgGetParam(crypt_msg, CMSG_SIGNER_UNAUTH_ATTR_PARAM, 0, NULL, &ts_signature_size);
|
|
||||||
|
|
||||||
if ((result) && (ts_signature_size > 0))
|
|
||||||
ts_signature = (uint8_t *)MZ_ALLOC(ts_signature_size);
|
|
||||||
|
|
||||||
if ((result) && (ts_signature != NULL)) {
|
|
||||||
result = CryptMsgGetParam(crypt_msg, CMSG_SIGNER_UNAUTH_ATTR_PARAM, 0, ts_signature,
|
|
||||||
&ts_signature_size);
|
|
||||||
if (result)
|
|
||||||
{
|
|
||||||
unauth_attribs = (PCRYPT_ATTRIBUTES)ts_signature;
|
|
||||||
|
|
||||||
if ((unauth_attribs->cAttr > 0) && (unauth_attribs->rgAttr[0].cValue > 0))
|
|
||||||
{
|
|
||||||
ts_content = unauth_attribs->rgAttr[0].rgValue->pbData;
|
|
||||||
ts_content_size = unauth_attribs->rgAttr[0].rgValue->cbData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((result) && (ts_content != NULL))
|
|
||||||
result = CryptVerifyTimeStampSignature(ts_content, ts_content_size, decoded,
|
|
||||||
decoded_size, 0, &crypt_context, NULL, NULL);
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
err = MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ts_signature != NULL)
|
|
||||||
MZ_FREE(ts_signature);
|
|
||||||
|
|
||||||
if (crypt_context != NULL)
|
|
||||||
CryptMemFree(crypt_context);
|
|
||||||
} else {
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((result) && (decoded != NULL) && (decoded_size == message_size)) {
|
|
||||||
/* Verify cms message with our stored message */
|
|
||||||
if (memcmp(decoded, message, message_size) == 0)
|
|
||||||
err = MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chain_context != NULL)
|
|
||||||
CertFreeCertificateChain(chain_context);
|
|
||||||
if (signer_cert != NULL)
|
|
||||||
CertFreeCertificateContext(signer_cert);
|
|
||||||
if (crypt_msg != NULL)
|
|
||||||
CryptMsgClose(crypt_msg);
|
|
||||||
|
|
||||||
if (decoded != NULL)
|
|
||||||
MZ_FREE(decoded);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,354 +0,0 @@
|
||||||
/* mz_os.c -- System functions
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
Copyright (C) 1998-2010 Gilles Vollant
|
|
||||||
https://www.winimage.com/zLibDll/minizip.html
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_crypt.h"
|
|
||||||
#include "mz_os.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_os.h"
|
|
||||||
|
|
||||||
#include <ctype.h> /* tolower */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_path_combine(char *path, const char *join, int32_t max_path) {
|
|
||||||
int32_t path_len = 0;
|
|
||||||
|
|
||||||
if (path == NULL || join == NULL || max_path == 0)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
path_len = (int32_t)strlen(path);
|
|
||||||
|
|
||||||
if (path_len == 0) {
|
|
||||||
strncpy(path, join, max_path - 1);
|
|
||||||
path[max_path - 1] = 0;
|
|
||||||
} else {
|
|
||||||
mz_path_append_slash(path, max_path, MZ_PATH_SLASH_PLATFORM);
|
|
||||||
strncat(path, join, max_path - path_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_path_append_slash(char *path, int32_t max_path, char slash) {
|
|
||||||
int32_t path_len = (int32_t)strlen(path);
|
|
||||||
if ((path_len + 2) >= max_path)
|
|
||||||
return MZ_BUF_ERROR;
|
|
||||||
if (path[path_len - 1] != '\\' && path[path_len - 1] != '/') {
|
|
||||||
path[path_len] = slash;
|
|
||||||
path[path_len + 1] = 0;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_path_remove_slash(char *path) {
|
|
||||||
int32_t path_len = (int32_t)strlen(path);
|
|
||||||
while (path_len > 0) {
|
|
||||||
if (path[path_len - 1] == '\\' || path[path_len - 1] == '/')
|
|
||||||
path[path_len - 1] = 0;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
path_len -= 1;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_path_has_slash(const char *path) {
|
|
||||||
int32_t path_len = (int32_t)strlen(path);
|
|
||||||
if (path[path_len - 1] != '\\' && path[path_len - 1] != '/')
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_path_convert_slashes(char *path, char slash) {
|
|
||||||
int32_t i = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < (int32_t)strlen(path); i += 1) {
|
|
||||||
if (path[i] == '\\' || path[i] == '/')
|
|
||||||
path[i] = slash;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_path_compare_wc(const char *path, const char *wildcard, uint8_t ignore_case) {
|
|
||||||
while (*path != 0) {
|
|
||||||
switch (*wildcard) {
|
|
||||||
case '*':
|
|
||||||
|
|
||||||
if (*(wildcard + 1) == 0)
|
|
||||||
return MZ_OK;
|
|
||||||
|
|
||||||
while (*path != 0) {
|
|
||||||
if (mz_path_compare_wc(path, (wildcard + 1), ignore_case) == MZ_OK)
|
|
||||||
return MZ_OK;
|
|
||||||
|
|
||||||
path += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* Ignore differences in path slashes on platforms */
|
|
||||||
if ((*path == '\\' && *wildcard == '/') || (*path == '/' && *wildcard == '\\'))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (ignore_case) {
|
|
||||||
if (tolower(*path) != tolower(*wildcard))
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
} else {
|
|
||||||
if (*path != *wildcard)
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
path += 1;
|
|
||||||
wildcard += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*wildcard != 0) && (*wildcard != '*'))
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_path_resolve(const char *path, char *output, int32_t max_output) {
|
|
||||||
const char *source = path;
|
|
||||||
const char *check = output;
|
|
||||||
char *target = output;
|
|
||||||
|
|
||||||
|
|
||||||
if (max_output <= 0)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
while (*source != 0 && max_output > 1) {
|
|
||||||
check = source;
|
|
||||||
if ((*check == '\\') || (*check == '/'))
|
|
||||||
check += 1;
|
|
||||||
|
|
||||||
if ((source == path) || (target == output) || (check != source)) {
|
|
||||||
/* Skip double paths */
|
|
||||||
if ((*check == '\\') || (*check == '/')) {
|
|
||||||
source += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (*check == '.') {
|
|
||||||
check += 1;
|
|
||||||
|
|
||||||
/* Remove . if at end of string and not at the beginning */
|
|
||||||
if ((*check == 0) && (source != path && target != output)) {
|
|
||||||
/* Copy last slash */
|
|
||||||
*target = *source;
|
|
||||||
target += 1;
|
|
||||||
max_output -= 1;
|
|
||||||
source += (check - source);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Remove . if not at end of string */
|
|
||||||
else if ((*check == '\\') || (*check == '/')) {
|
|
||||||
source += (check - source);
|
|
||||||
/* Skip slash if at beginning of string */
|
|
||||||
if (target == output && *source != 0)
|
|
||||||
source += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Go to parent directory .. */
|
|
||||||
else if (*check == '.') {
|
|
||||||
check += 1;
|
|
||||||
if ((*check == 0) || (*check == '\\' || *check == '/')) {
|
|
||||||
source += (check - source);
|
|
||||||
|
|
||||||
/* Search backwards for previous slash */
|
|
||||||
if (target != output) {
|
|
||||||
target -= 1;
|
|
||||||
do {
|
|
||||||
if ((*target == '\\') || (*target == '/'))
|
|
||||||
break;
|
|
||||||
|
|
||||||
target -= 1;
|
|
||||||
max_output += 1;
|
|
||||||
} while (target > output);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((target == output) && (*source != 0))
|
|
||||||
source += 1;
|
|
||||||
if ((*target == '\\' || *target == '/') && (*source == 0))
|
|
||||||
target += 1;
|
|
||||||
|
|
||||||
*target = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*target = *source;
|
|
||||||
|
|
||||||
source += 1;
|
|
||||||
target += 1;
|
|
||||||
max_output -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*target = 0;
|
|
||||||
|
|
||||||
if (*path == 0)
|
|
||||||
return MZ_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_path_remove_filename(char *path) {
|
|
||||||
char *path_ptr = NULL;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
path_ptr = path + strlen(path) - 1;
|
|
||||||
|
|
||||||
while (path_ptr > path) {
|
|
||||||
if ((*path_ptr == '/') || (*path_ptr == '\\')) {
|
|
||||||
*path_ptr = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
path_ptr -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path_ptr == path)
|
|
||||||
*path_ptr = 0;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_path_remove_extension(char *path) {
|
|
||||||
char *path_ptr = NULL;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
path_ptr = path + strlen(path) - 1;
|
|
||||||
|
|
||||||
while (path_ptr > path) {
|
|
||||||
if ((*path_ptr == '/') || (*path_ptr == '\\'))
|
|
||||||
break;
|
|
||||||
if (*path_ptr == '.') {
|
|
||||||
*path_ptr = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
path_ptr -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path_ptr == path)
|
|
||||||
*path_ptr = 0;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_path_get_filename(const char *path, const char **filename) {
|
|
||||||
const char *match = NULL;
|
|
||||||
|
|
||||||
if (path == NULL || filename == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
*filename = NULL;
|
|
||||||
|
|
||||||
for (match = path; *match != 0; match += 1) {
|
|
||||||
if ((*match == '\\') || (*match == '/'))
|
|
||||||
*filename = match + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*filename == NULL)
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_dir_make(const char *path) {
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
int16_t len = 0;
|
|
||||||
char *current_dir = NULL;
|
|
||||||
char *match = NULL;
|
|
||||||
char hold = 0;
|
|
||||||
|
|
||||||
|
|
||||||
len = (int16_t)strlen(path);
|
|
||||||
if (len <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
current_dir = (char *)MZ_ALLOC((uint16_t)len + 1);
|
|
||||||
if (current_dir == NULL)
|
|
||||||
return MZ_MEM_ERROR;
|
|
||||||
|
|
||||||
strcpy(current_dir, path);
|
|
||||||
mz_path_remove_slash(current_dir);
|
|
||||||
|
|
||||||
err = mz_os_make_dir(current_dir);
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
match = current_dir + 1;
|
|
||||||
while (1) {
|
|
||||||
while (*match != 0 && *match != '\\' && *match != '/')
|
|
||||||
match += 1;
|
|
||||||
hold = *match;
|
|
||||||
*match = 0;
|
|
||||||
|
|
||||||
err = mz_os_make_dir(current_dir);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
break;
|
|
||||||
if (hold == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
*match = hold;
|
|
||||||
match += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MZ_FREE(current_dir);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_file_get_crc(const char *path, uint32_t *result_crc) {
|
|
||||||
void *stream = NULL;
|
|
||||||
uint32_t crc32 = 0;
|
|
||||||
int32_t read = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
uint8_t buf[16384];
|
|
||||||
|
|
||||||
mz_stream_os_create(&stream);
|
|
||||||
|
|
||||||
err = mz_stream_os_open(stream, path, MZ_OPEN_MODE_READ);
|
|
||||||
|
|
||||||
if (err == MZ_OK) {
|
|
||||||
do {
|
|
||||||
read = mz_stream_os_read(stream, buf, sizeof(buf));
|
|
||||||
|
|
||||||
if (read < 0) {
|
|
||||||
err = read;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
crc32 = mz_crypt_crc32_update(crc32, buf, read);
|
|
||||||
} while ((err == MZ_OK) && (read > 0));
|
|
||||||
|
|
||||||
mz_stream_os_close(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
*result_crc = crc32;
|
|
||||||
|
|
||||||
mz_stream_os_delete(&stream);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
|
@ -1,175 +0,0 @@
|
||||||
/* mz_os.h -- System functions
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_OS_H
|
|
||||||
#define MZ_OS_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
# define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_OSX_DARWIN)
|
|
||||||
#elif defined(__riscos__)
|
|
||||||
# define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_RISCOS)
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
# define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_WINDOWS_NTFS)
|
|
||||||
#else
|
|
||||||
# define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_UNIX)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_LZMA) || defined(HAVE_LIBCOMP)
|
|
||||||
# define MZ_VERSION_MADEBY_ZIP_VERSION (63)
|
|
||||||
#elif defined(HAVE_WZAES)
|
|
||||||
# define MZ_VERSION_MADEBY_ZIP_VERSION (51)
|
|
||||||
#elif defined(HAVE_BZIP2)
|
|
||||||
# define MZ_VERSION_MADEBY_ZIP_VERSION (46)
|
|
||||||
#else
|
|
||||||
# define MZ_VERSION_MADEBY_ZIP_VERSION (45)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MZ_VERSION_MADEBY ((MZ_VERSION_MADEBY_HOST_SYSTEM << 8) | \
|
|
||||||
(MZ_VERSION_MADEBY_ZIP_VERSION))
|
|
||||||
|
|
||||||
#define MZ_PATH_SLASH_UNIX ('/')
|
|
||||||
#if defined(_WIN32)
|
|
||||||
# define MZ_PATH_SLASH_PLATFORM ('\\')
|
|
||||||
#else
|
|
||||||
# define MZ_PATH_SLASH_PLATFORM (MZ_PATH_SLASH_UNIX)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
struct dirent {
|
|
||||||
char d_name[256];
|
|
||||||
};
|
|
||||||
typedef void* DIR;
|
|
||||||
#else
|
|
||||||
#include <dirent.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/* Shared functions */
|
|
||||||
|
|
||||||
int32_t mz_path_combine(char *path, const char *join, int32_t max_path);
|
|
||||||
/* Combines two paths */
|
|
||||||
|
|
||||||
int32_t mz_path_append_slash(char *path, int32_t max_path, char slash);
|
|
||||||
/* Appends a path slash on to the end of the path */
|
|
||||||
|
|
||||||
int32_t mz_path_remove_slash(char *path);
|
|
||||||
/* Removes a path slash from the end of the path */
|
|
||||||
|
|
||||||
int32_t mz_path_has_slash(const char *path);
|
|
||||||
/* Returns whether or not the path ends with slash */
|
|
||||||
|
|
||||||
int32_t mz_path_convert_slashes(char *path, char slash);
|
|
||||||
/* Converts the slashes in a path */
|
|
||||||
|
|
||||||
int32_t mz_path_compare_wc(const char *path, const char *wildcard, uint8_t ignore_case);
|
|
||||||
/* Compare two paths with wildcard */
|
|
||||||
|
|
||||||
int32_t mz_path_resolve(const char *path, char *target, int32_t max_target);
|
|
||||||
/* Resolves path */
|
|
||||||
|
|
||||||
int32_t mz_path_remove_filename(char *path);
|
|
||||||
/* Remove the filename from a path */
|
|
||||||
|
|
||||||
int32_t mz_path_remove_extension(char *path);
|
|
||||||
/* Remove the extension from a path */
|
|
||||||
|
|
||||||
int32_t mz_path_get_filename(const char *path, const char **filename);
|
|
||||||
/* Get the filename from a path */
|
|
||||||
|
|
||||||
int32_t mz_dir_make(const char *path);
|
|
||||||
/* Creates a directory recursively */
|
|
||||||
|
|
||||||
int32_t mz_file_get_crc(const char *path, uint32_t *result_crc);
|
|
||||||
/* Gets the crc32 hash of a file */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/* Platform specific functions */
|
|
||||||
|
|
||||||
wchar_t *mz_os_unicode_string_create(const char *string, int32_t encoding);
|
|
||||||
/* Create unicode string from a utf8 string */
|
|
||||||
|
|
||||||
void mz_os_unicode_string_delete(wchar_t **string);
|
|
||||||
/* Delete a unicode string that was created */
|
|
||||||
|
|
||||||
uint8_t *mz_os_utf8_string_create(const char *string, int32_t encoding);
|
|
||||||
/* Create a utf8 string from a string with another encoding */
|
|
||||||
|
|
||||||
void mz_os_utf8_string_delete(uint8_t **string);
|
|
||||||
/* Delete a utf8 string that was created */
|
|
||||||
|
|
||||||
int32_t mz_os_rand(uint8_t *buf, int32_t size);
|
|
||||||
/* Random number generator (not cryptographically secure) */
|
|
||||||
|
|
||||||
int32_t mz_os_rename(const char *source_path, const char *target_path);
|
|
||||||
/* Rename a file */
|
|
||||||
|
|
||||||
int32_t mz_os_unlink(const char *path);
|
|
||||||
/* Delete an existing file */
|
|
||||||
|
|
||||||
int32_t mz_os_file_exists(const char *path);
|
|
||||||
/* Check to see if a file exists */
|
|
||||||
|
|
||||||
int64_t mz_os_get_file_size(const char *path);
|
|
||||||
/* Gets the length of a file */
|
|
||||||
|
|
||||||
int32_t mz_os_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date);
|
|
||||||
/* Gets a file's modified, access, and creation dates if supported */
|
|
||||||
|
|
||||||
int32_t mz_os_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date);
|
|
||||||
/* Sets a file's modified, access, and creation dates if supported */
|
|
||||||
|
|
||||||
int32_t mz_os_get_file_attribs(const char *path, uint32_t *attributes);
|
|
||||||
/* Gets a file's attributes */
|
|
||||||
|
|
||||||
int32_t mz_os_set_file_attribs(const char *path, uint32_t attributes);
|
|
||||||
/* Sets a file's attributes */
|
|
||||||
|
|
||||||
int32_t mz_os_make_dir(const char *path);
|
|
||||||
/* Recursively creates a directory */
|
|
||||||
|
|
||||||
DIR* mz_os_open_dir(const char *path);
|
|
||||||
/* Opens a directory for listing */
|
|
||||||
struct
|
|
||||||
dirent* mz_os_read_dir(DIR *dir);
|
|
||||||
/* Reads a directory listing entry */
|
|
||||||
|
|
||||||
int32_t mz_os_close_dir(DIR *dir);
|
|
||||||
/* Closes a directory that has been opened for listing */
|
|
||||||
|
|
||||||
int32_t mz_os_is_dir(const char *path);
|
|
||||||
/* Checks to see if path is a directory */
|
|
||||||
|
|
||||||
int32_t mz_os_is_symlink(const char *path);
|
|
||||||
/* Checks to see if path is a symbolic link */
|
|
||||||
|
|
||||||
int32_t mz_os_make_symlink(const char *path, const char *target_path);
|
|
||||||
/* Creates a symbolic link pointing to a target */
|
|
||||||
|
|
||||||
int32_t mz_os_read_symlink(const char *path, char *target_path, int32_t max_target_path);
|
|
||||||
/* Gets the target path for a symbolic link */
|
|
||||||
|
|
||||||
uint64_t mz_os_ms_time(void);
|
|
||||||
/* Gets the time in milliseconds */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,367 +0,0 @@
|
||||||
/* mz_os_posix.c -- System functions for posix
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_os.h"
|
|
||||||
|
|
||||||
#include <stdio.h> /* rename */
|
|
||||||
#include <errno.h>
|
|
||||||
#if defined(HAVE_ICONV)
|
|
||||||
#include <iconv.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
# include <utime.h>
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
# include <mach/clock.h>
|
|
||||||
# include <mach/mach.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_GETRANDOM)
|
|
||||||
# include <sys/random.h>
|
|
||||||
#endif
|
|
||||||
#if defined(HAVE_LIBBSD)
|
|
||||||
# include <sys/types.h>
|
|
||||||
# ifndef __u_char_defined
|
|
||||||
typedef unsigned char u_char;
|
|
||||||
# endif
|
|
||||||
# include <bsd/stdlib.h> /* arc4random_buf */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(HAVE_ICONV)
|
|
||||||
uint8_t *mz_os_utf8_string_create(const char *string, int32_t encoding) {
|
|
||||||
iconv_t cd;
|
|
||||||
const char *from_encoding = NULL;
|
|
||||||
size_t result = 0;
|
|
||||||
size_t string_length = 0;
|
|
||||||
size_t string_utf8_size = 0;
|
|
||||||
uint8_t *string_utf8 = NULL;
|
|
||||||
uint8_t *string_utf8_ptr = NULL;
|
|
||||||
|
|
||||||
if (string == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (encoding == MZ_ENCODING_CODEPAGE_437)
|
|
||||||
from_encoding = "CP437";
|
|
||||||
else if (encoding == MZ_ENCODING_CODEPAGE_932)
|
|
||||||
from_encoding = "CP932";
|
|
||||||
else if (encoding == MZ_ENCODING_CODEPAGE_936)
|
|
||||||
from_encoding = "CP936";
|
|
||||||
else if (encoding == MZ_ENCODING_CODEPAGE_950)
|
|
||||||
from_encoding = "CP950";
|
|
||||||
else if (encoding == MZ_ENCODING_UTF8)
|
|
||||||
from_encoding = "UTF-8";
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
cd = iconv_open("UTF-8", from_encoding);
|
|
||||||
if (cd == (iconv_t)-1)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
string_length = strlen(string);
|
|
||||||
string_utf8_size = string_length * 2;
|
|
||||||
string_utf8 = (uint8_t *)MZ_ALLOC((int32_t)(string_utf8_size + 1));
|
|
||||||
string_utf8_ptr = string_utf8;
|
|
||||||
|
|
||||||
if (string_utf8) {
|
|
||||||
memset(string_utf8, 0, string_utf8_size + 1);
|
|
||||||
|
|
||||||
result = iconv(cd, (char **)&string, &string_length,
|
|
||||||
(char **)&string_utf8_ptr, &string_utf8_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
iconv_close(cd);
|
|
||||||
|
|
||||||
if (result == (size_t)-1) {
|
|
||||||
MZ_FREE(string_utf8);
|
|
||||||
string_utf8 = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return string_utf8;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
uint8_t *mz_os_utf8_string_create(const char *string, int32_t encoding) {
|
|
||||||
size_t string_length = 0;
|
|
||||||
uint8_t *string_copy = NULL;
|
|
||||||
|
|
||||||
string_length = strlen(string);
|
|
||||||
string_copy = (uint8_t *)MZ_ALLOC((int32_t)(string_length + 1));
|
|
||||||
strncpy((char *)string_copy, string, string_length);
|
|
||||||
string_copy[string_length] = 0;
|
|
||||||
|
|
||||||
return string_copy;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void mz_os_utf8_string_delete(uint8_t **string) {
|
|
||||||
if (string != NULL) {
|
|
||||||
MZ_FREE(*string);
|
|
||||||
*string = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(HAVE_ARC4RANDOM_BUF)
|
|
||||||
int32_t mz_os_rand(uint8_t *buf, int32_t size) {
|
|
||||||
if (size < 0)
|
|
||||||
return 0;
|
|
||||||
arc4random_buf(buf, (uint32_t)size);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
#elif defined(HAVE_ARC4RANDOM)
|
|
||||||
int32_t mz_os_rand(uint8_t *buf, int32_t size) {
|
|
||||||
int32_t left = size;
|
|
||||||
for (; left > 2; left -= 3, buf += 3) {
|
|
||||||
uint32_t val = arc4random();
|
|
||||||
|
|
||||||
buf[0] = (val) & 0xFF;
|
|
||||||
buf[1] = (val >> 8) & 0xFF;
|
|
||||||
buf[2] = (val >> 16) & 0xFF;
|
|
||||||
}
|
|
||||||
for (; left > 0; left--, buf++) {
|
|
||||||
*buf = arc4random() & 0xFF;
|
|
||||||
}
|
|
||||||
return size - left;
|
|
||||||
}
|
|
||||||
#elif defined(HAVE_GETRANDOM)
|
|
||||||
int32_t mz_os_rand(uint8_t *buf, int32_t size) {
|
|
||||||
int32_t left = size;
|
|
||||||
int32_t written = 0;
|
|
||||||
|
|
||||||
while (left > 0) {
|
|
||||||
written = getrandom(buf, left, 0);
|
|
||||||
if (written < 0)
|
|
||||||
return MZ_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
buf += written;
|
|
||||||
left -= written;
|
|
||||||
}
|
|
||||||
return size - left;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int32_t mz_os_rand(uint8_t *buf, int32_t size) {
|
|
||||||
static unsigned calls = 0;
|
|
||||||
int32_t i = 0;
|
|
||||||
|
|
||||||
/* Ensure different random header each time */
|
|
||||||
if (++calls == 1) {
|
|
||||||
#define PI_SEED 3141592654UL
|
|
||||||
srand((unsigned)(time(NULL) ^ PI_SEED));
|
|
||||||
}
|
|
||||||
|
|
||||||
while (i < size)
|
|
||||||
buf[i++] = (rand() >> 7) & 0xff;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int32_t mz_os_rename(const char *source_path, const char *target_path) {
|
|
||||||
if (rename(source_path, target_path) == -1)
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_unlink(const char *path) {
|
|
||||||
if (unlink(path) == -1)
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_file_exists(const char *path) {
|
|
||||||
struct stat path_stat;
|
|
||||||
|
|
||||||
memset(&path_stat, 0, sizeof(path_stat));
|
|
||||||
if (stat(path, &path_stat) == 0)
|
|
||||||
return MZ_OK;
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_os_get_file_size(const char *path) {
|
|
||||||
struct stat path_stat;
|
|
||||||
|
|
||||||
memset(&path_stat, 0, sizeof(path_stat));
|
|
||||||
if (stat(path, &path_stat) == 0) {
|
|
||||||
/* Stat returns size taken up by directory entry, so return 0 */
|
|
||||||
if (S_ISDIR(path_stat.st_mode))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return path_stat.st_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date) {
|
|
||||||
struct stat path_stat;
|
|
||||||
char *name = NULL;
|
|
||||||
size_t len = 0;
|
|
||||||
int32_t err = MZ_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
memset(&path_stat, 0, sizeof(path_stat));
|
|
||||||
|
|
||||||
if (strcmp(path, "-") != 0) {
|
|
||||||
/* Not all systems allow stat'ing a file with / appended */
|
|
||||||
len = strlen(path);
|
|
||||||
name = (char *)malloc(len + 1);
|
|
||||||
strncpy(name, path, len + 1);
|
|
||||||
mz_path_remove_slash(name);
|
|
||||||
|
|
||||||
if (stat(name, &path_stat) == 0) {
|
|
||||||
if (modified_date != NULL)
|
|
||||||
*modified_date = path_stat.st_mtime;
|
|
||||||
if (accessed_date != NULL)
|
|
||||||
*accessed_date = path_stat.st_atime;
|
|
||||||
/* Creation date not supported */
|
|
||||||
if (creation_date != NULL)
|
|
||||||
*creation_date = 0;
|
|
||||||
|
|
||||||
err = MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date) {
|
|
||||||
struct utimbuf ut;
|
|
||||||
|
|
||||||
ut.actime = accessed_date;
|
|
||||||
ut.modtime = modified_date;
|
|
||||||
|
|
||||||
/* Creation date not supported */
|
|
||||||
MZ_UNUSED(creation_date);
|
|
||||||
|
|
||||||
if (utime(path, &ut) != 0)
|
|
||||||
return MZ_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_get_file_attribs(const char *path, uint32_t *attributes) {
|
|
||||||
struct stat path_stat;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
memset(&path_stat, 0, sizeof(path_stat));
|
|
||||||
if (lstat(path, &path_stat) == -1)
|
|
||||||
err = MZ_INTERNAL_ERROR;
|
|
||||||
*attributes = path_stat.st_mode;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_set_file_attribs(const char *path, uint32_t attributes) {
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
if (chmod(path, (mode_t)attributes) == -1)
|
|
||||||
err = MZ_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_make_dir(const char *path) {
|
|
||||||
int32_t err = 0;
|
|
||||||
|
|
||||||
err = mkdir(path, 0755);
|
|
||||||
|
|
||||||
if (err != 0 && errno != EEXIST)
|
|
||||||
return MZ_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIR* mz_os_open_dir(const char *path) {
|
|
||||||
return opendir(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dirent* mz_os_read_dir(DIR *dir) {
|
|
||||||
if (dir == NULL)
|
|
||||||
return NULL;
|
|
||||||
return readdir(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_close_dir(DIR *dir) {
|
|
||||||
if (dir == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (closedir(dir) == -1)
|
|
||||||
return MZ_INTERNAL_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_is_dir(const char *path) {
|
|
||||||
struct stat path_stat;
|
|
||||||
|
|
||||||
memset(&path_stat, 0, sizeof(path_stat));
|
|
||||||
stat(path, &path_stat);
|
|
||||||
if (S_ISDIR(path_stat.st_mode))
|
|
||||||
return MZ_OK;
|
|
||||||
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_is_symlink(const char *path) {
|
|
||||||
struct stat path_stat;
|
|
||||||
|
|
||||||
memset(&path_stat, 0, sizeof(path_stat));
|
|
||||||
lstat(path, &path_stat);
|
|
||||||
if (S_ISLNK(path_stat.st_mode))
|
|
||||||
return MZ_OK;
|
|
||||||
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_make_symlink(const char *path, const char *target_path) {
|
|
||||||
if (symlink(target_path, path) != 0)
|
|
||||||
return MZ_INTERNAL_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_read_symlink(const char *path, char *target_path, int32_t max_target_path) {
|
|
||||||
size_t length = 0;
|
|
||||||
|
|
||||||
length = (size_t)readlink(path, target_path, max_target_path - 1);
|
|
||||||
if (length == (size_t)-1)
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
|
|
||||||
target_path[length] = 0;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t mz_os_ms_time(void) {
|
|
||||||
struct timespec ts;
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
clock_serv_t cclock;
|
|
||||||
mach_timespec_t mts;
|
|
||||||
|
|
||||||
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
|
|
||||||
clock_get_time(cclock, &mts);
|
|
||||||
mach_port_deallocate(mach_task_self(), cclock);
|
|
||||||
|
|
||||||
ts.tv_sec = mts.tv_sec;
|
|
||||||
ts.tv_nsec = mts.tv_nsec;
|
|
||||||
#else
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ((uint64_t)ts.tv_sec * 1000) + ((uint64_t)ts.tv_nsec / 1000000);
|
|
||||||
}
|
|
|
@ -1,659 +0,0 @@
|
||||||
/* mz_os_win32.c -- System functions for Windows
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_os.h"
|
|
||||||
#include "mz_strm_os.h"
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <winioctl.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(MZ_WINRT_API)))
|
|
||||||
# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
|
||||||
# define MZ_WINRT_API 1
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY
|
|
||||||
# define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct DIR_int_s {
|
|
||||||
void *find_handle;
|
|
||||||
WIN32_FIND_DATAW find_data;
|
|
||||||
struct dirent entry;
|
|
||||||
uint8_t end;
|
|
||||||
} DIR_int;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
wchar_t *mz_os_unicode_string_create(const char *string, int32_t encoding) {
|
|
||||||
wchar_t *string_wide = NULL;
|
|
||||||
uint32_t string_wide_size = 0;
|
|
||||||
|
|
||||||
string_wide_size = MultiByteToWideChar(encoding, 0, string, -1, NULL, 0);
|
|
||||||
if (string_wide_size == 0)
|
|
||||||
return NULL;
|
|
||||||
string_wide = (wchar_t *)MZ_ALLOC((string_wide_size + 1) * sizeof(wchar_t));
|
|
||||||
if (string_wide == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
memset(string_wide, 0, sizeof(wchar_t) * (string_wide_size + 1));
|
|
||||||
MultiByteToWideChar(encoding, 0, string, -1, string_wide, string_wide_size);
|
|
||||||
|
|
||||||
return string_wide;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_os_unicode_string_delete(wchar_t **string) {
|
|
||||||
if (string != NULL) {
|
|
||||||
MZ_FREE(*string);
|
|
||||||
*string = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *mz_os_utf8_string_create(const char *string, int32_t encoding) {
|
|
||||||
wchar_t *string_wide = NULL;
|
|
||||||
uint8_t *string_utf8 = NULL;
|
|
||||||
uint32_t string_utf8_size = 0;
|
|
||||||
|
|
||||||
string_wide = mz_os_unicode_string_create(string, encoding);
|
|
||||||
if (string_wide) {
|
|
||||||
string_utf8_size = WideCharToMultiByte(CP_UTF8, 0, string_wide, -1, NULL, 0, NULL, NULL);
|
|
||||||
string_utf8 = (uint8_t *)MZ_ALLOC((string_utf8_size + 1) * sizeof(wchar_t));
|
|
||||||
|
|
||||||
if (string_utf8) {
|
|
||||||
memset(string_utf8, 0, string_utf8_size + 1);
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, string_wide, -1, (char *)string_utf8, string_utf8_size, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_os_unicode_string_delete(&string_wide);
|
|
||||||
}
|
|
||||||
|
|
||||||
return string_utf8;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *mz_os_utf8_string_create_from_unicode(const wchar_t *string, int32_t encoding) {
|
|
||||||
uint8_t *string_utf8 = NULL;
|
|
||||||
uint32_t string_utf8_size = 0;
|
|
||||||
|
|
||||||
MZ_UNUSED(encoding);
|
|
||||||
|
|
||||||
string_utf8_size = WideCharToMultiByte(CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
|
|
||||||
string_utf8 = (uint8_t *)MZ_ALLOC((string_utf8_size + 1) * sizeof(wchar_t));
|
|
||||||
|
|
||||||
if (string_utf8) {
|
|
||||||
memset(string_utf8, 0, string_utf8_size + 1);
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, string, -1, (char *)string_utf8, string_utf8_size, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return string_utf8;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_os_utf8_string_delete(uint8_t **string) {
|
|
||||||
if (string != NULL) {
|
|
||||||
MZ_FREE(*string);
|
|
||||||
*string = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_os_rand(uint8_t *buf, int32_t size) {
|
|
||||||
unsigned __int64 pentium_tsc[1];
|
|
||||||
int32_t len = 0;
|
|
||||||
|
|
||||||
for (len = 0; len < (int)size; len += 1) {
|
|
||||||
if (len % 8 == 0)
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER *)pentium_tsc);
|
|
||||||
buf[len] = ((unsigned char*)pentium_tsc)[len % 8];
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_rename(const char *source_path, const char *target_path) {
|
|
||||||
wchar_t *source_path_wide = NULL;
|
|
||||||
wchar_t *target_path_wide = NULL;
|
|
||||||
int32_t result = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
if (source_path == NULL || target_path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
source_path_wide = mz_os_unicode_string_create(source_path, MZ_ENCODING_UTF8);
|
|
||||||
if (source_path_wide == NULL) {
|
|
||||||
err = MZ_PARAM_ERROR;
|
|
||||||
} else {
|
|
||||||
target_path_wide = mz_os_unicode_string_create(target_path, MZ_ENCODING_UTF8);
|
|
||||||
if (target_path_wide == NULL)
|
|
||||||
err = MZ_PARAM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err == MZ_OK) {
|
|
||||||
#ifdef MZ_WINRT_API
|
|
||||||
result = MoveFileExW(source_path_wide, target_path_wide, MOVEFILE_WRITE_THROUGH);
|
|
||||||
#else
|
|
||||||
result = MoveFileW(source_path_wide, target_path_wide);
|
|
||||||
#endif
|
|
||||||
if (result == 0)
|
|
||||||
err = MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target_path_wide)
|
|
||||||
mz_os_unicode_string_delete(&target_path_wide);
|
|
||||||
if (source_path_wide)
|
|
||||||
mz_os_unicode_string_delete(&source_path_wide);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_unlink(const char *path) {
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (mz_os_is_dir(path) == MZ_OK)
|
|
||||||
result = RemoveDirectoryW(path_wide);
|
|
||||||
else
|
|
||||||
result = DeleteFileW(path_wide);
|
|
||||||
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
|
|
||||||
if (result == 0)
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_file_exists(const char *path) {
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
DWORD attribs = 0;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
attribs = GetFileAttributesW(path_wide);
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
|
|
||||||
if (attribs == 0xFFFFFFFF)
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_os_get_file_size(const char *path) {
|
|
||||||
HANDLE handle = NULL;
|
|
||||||
LARGE_INTEGER large_size;
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
#ifdef MZ_WINRT_API
|
|
||||||
handle = CreateFile2(path_wide, GENERIC_READ, 0, OPEN_EXISTING, NULL);
|
|
||||||
#else
|
|
||||||
handle = CreateFileW(path_wide, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
#endif
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
|
|
||||||
large_size.QuadPart = 0;
|
|
||||||
|
|
||||||
if (handle != INVALID_HANDLE_VALUE) {
|
|
||||||
GetFileSizeEx(handle, &large_size);
|
|
||||||
CloseHandle(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
return large_size.QuadPart;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mz_os_file_to_unix_time(FILETIME file_time, time_t *unix_time) {
|
|
||||||
uint64_t quad_file_time = 0;
|
|
||||||
quad_file_time = file_time.dwLowDateTime;
|
|
||||||
quad_file_time |= ((uint64_t)file_time.dwHighDateTime << 32);
|
|
||||||
*unix_time = (time_t)((quad_file_time - 116444736000000000LL) / 10000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mz_os_unix_to_file_time(time_t unix_time, FILETIME *file_time) {
|
|
||||||
uint64_t quad_file_time = 0;
|
|
||||||
quad_file_time = ((uint64_t)unix_time * 10000000) + 116444736000000000LL;
|
|
||||||
file_time->dwHighDateTime = (quad_file_time >> 32);
|
|
||||||
file_time->dwLowDateTime = (uint32_t)(quad_file_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date) {
|
|
||||||
WIN32_FIND_DATAW ff32;
|
|
||||||
HANDLE handle = NULL;
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
int32_t err = MZ_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
handle = FindFirstFileW(path_wide, &ff32);
|
|
||||||
MZ_FREE(path_wide);
|
|
||||||
|
|
||||||
if (handle != INVALID_HANDLE_VALUE) {
|
|
||||||
if (modified_date != NULL)
|
|
||||||
mz_os_file_to_unix_time(ff32.ftLastWriteTime, modified_date);
|
|
||||||
if (accessed_date != NULL)
|
|
||||||
mz_os_file_to_unix_time(ff32.ftLastAccessTime, accessed_date);
|
|
||||||
if (creation_date != NULL)
|
|
||||||
mz_os_file_to_unix_time(ff32.ftCreationTime, creation_date);
|
|
||||||
|
|
||||||
FindClose(handle);
|
|
||||||
err = MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date) {
|
|
||||||
HANDLE handle = NULL;
|
|
||||||
FILETIME ftm_creation, ftm_accessed, ftm_modified;
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
#ifdef MZ_WINRT_API
|
|
||||||
handle = CreateFile2(path_wide, GENERIC_READ | GENERIC_WRITE, 0, OPEN_EXISTING, NULL);
|
|
||||||
#else
|
|
||||||
handle = CreateFileW(path_wide, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
#endif
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
|
|
||||||
if (handle != INVALID_HANDLE_VALUE) {
|
|
||||||
GetFileTime(handle, &ftm_creation, &ftm_accessed, &ftm_modified);
|
|
||||||
|
|
||||||
if (modified_date != 0)
|
|
||||||
mz_os_unix_to_file_time(modified_date, &ftm_modified);
|
|
||||||
if (accessed_date != 0)
|
|
||||||
mz_os_unix_to_file_time(accessed_date, &ftm_accessed);
|
|
||||||
if (creation_date != 0)
|
|
||||||
mz_os_unix_to_file_time(creation_date, &ftm_creation);
|
|
||||||
|
|
||||||
if (SetFileTime(handle, &ftm_creation, &ftm_accessed, &ftm_modified) == 0)
|
|
||||||
err = MZ_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
CloseHandle(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_get_file_attribs(const char *path, uint32_t *attributes) {
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
if (path == NULL || attributes == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
*attributes = GetFileAttributesW(path_wide);
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
|
|
||||||
if (*attributes == INVALID_FILE_ATTRIBUTES)
|
|
||||||
err = MZ_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_set_file_attribs(const char *path, uint32_t attributes) {
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (SetFileAttributesW(path_wide, attributes) == 0)
|
|
||||||
err = MZ_INTERNAL_ERROR;
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_make_dir(const char *path) {
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
/* Don't try to create a drive letter */
|
|
||||||
if ((path[0] != 0) && (strlen(path) <= 3) && (path[1] == ':'))
|
|
||||||
return mz_os_is_dir(path);
|
|
||||||
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (CreateDirectoryW(path_wide, NULL) == 0) {
|
|
||||||
if (GetLastError() != ERROR_ALREADY_EXISTS)
|
|
||||||
err = MZ_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIR *mz_os_open_dir(const char *path) {
|
|
||||||
WIN32_FIND_DATAW find_data;
|
|
||||||
DIR_int *dir_int = NULL;
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
char fixed_path[320];
|
|
||||||
void *handle = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
strncpy(fixed_path, path, sizeof(fixed_path) - 1);
|
|
||||||
fixed_path[sizeof(fixed_path) - 1] = 0;
|
|
||||||
|
|
||||||
mz_path_append_slash(fixed_path, sizeof(fixed_path), MZ_PATH_SLASH_PLATFORM);
|
|
||||||
mz_path_combine(fixed_path, "*", sizeof(fixed_path));
|
|
||||||
|
|
||||||
path_wide = mz_os_unicode_string_create(fixed_path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
handle = FindFirstFileW(path_wide, &find_data);
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
|
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
dir_int = (DIR_int *)MZ_ALLOC(sizeof(DIR_int));
|
|
||||||
if (dir_int == NULL)
|
|
||||||
return NULL;
|
|
||||||
dir_int->find_handle = handle;
|
|
||||||
dir_int->end = 0;
|
|
||||||
|
|
||||||
memcpy(&dir_int->find_data, &find_data, sizeof(dir_int->find_data));
|
|
||||||
|
|
||||||
return (DIR *)dir_int;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dirent* mz_os_read_dir(DIR *dir) {
|
|
||||||
DIR_int *dir_int;
|
|
||||||
|
|
||||||
if (dir == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
dir_int = (DIR_int *)dir;
|
|
||||||
if (dir_int->end)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, dir_int->find_data.cFileName, -1,
|
|
||||||
dir_int->entry.d_name, sizeof(dir_int->entry.d_name), NULL, NULL);
|
|
||||||
|
|
||||||
if (FindNextFileW(dir_int->find_handle, &dir_int->find_data) == 0) {
|
|
||||||
if (GetLastError() != ERROR_NO_MORE_FILES)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
dir_int->end = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return &dir_int->entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_close_dir(DIR *dir) {
|
|
||||||
DIR_int *dir_int;
|
|
||||||
|
|
||||||
if (dir == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
dir_int = (DIR_int *)dir;
|
|
||||||
if (dir_int->find_handle != INVALID_HANDLE_VALUE)
|
|
||||||
FindClose(dir_int->find_handle);
|
|
||||||
MZ_FREE(dir_int);
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_is_dir(const char *path) {
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
uint32_t attribs = 0;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
attribs = GetFileAttributesW(path_wide);
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
|
|
||||||
if (attribs != 0xFFFFFFFF) {
|
|
||||||
if (attribs & FILE_ATTRIBUTE_DIRECTORY)
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_is_symlink(const char *path) {
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
uint32_t attribs = 0;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
attribs = GetFileAttributesW(path_wide);
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
|
|
||||||
if (attribs != 0xFFFFFFFF) {
|
|
||||||
if (attribs & FILE_ATTRIBUTE_REPARSE_POINT)
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_make_symlink(const char *path, const char *target_path) {
|
|
||||||
typedef BOOLEAN (WINAPI *LPCREATESYMBOLICLINKW)(LPCWSTR, LPCWSTR, DWORD);
|
|
||||||
LPCREATESYMBOLICLINKW create_symbolic_link_w = NULL;
|
|
||||||
HMODULE kernel32_mod = NULL;
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
wchar_t *target_path_wide = NULL;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
int32_t flags = 0;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
#ifdef MZ_WINRT_API
|
|
||||||
MEMORY_BASIC_INFORMATION mbi;
|
|
||||||
memset(&mbi, 0, sizeof(mbi));
|
|
||||||
VirtualQuery(VirtualQuery, &mbi, sizeof(mbi));
|
|
||||||
kernel32_mod = (HMODULE)mbi.AllocationBase;
|
|
||||||
#else
|
|
||||||
kernel32_mod = GetModuleHandleW(L"kernel32.dll");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (kernel32_mod == NULL)
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
|
|
||||||
create_symbolic_link_w = (LPCREATESYMBOLICLINKW)GetProcAddress(kernel32_mod, "CreateSymbolicLinkW");
|
|
||||||
if (create_symbolic_link_w == NULL) {
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL) {
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
target_path_wide = mz_os_unicode_string_create(target_path, MZ_ENCODING_UTF8);
|
|
||||||
if (target_path_wide != NULL) {
|
|
||||||
if (mz_path_has_slash(target_path) == MZ_OK)
|
|
||||||
flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
|
|
||||||
|
|
||||||
if (create_symbolic_link_w(path_wide, target_path_wide, flags) == FALSE)
|
|
||||||
err = MZ_SYMLINK_ERROR;
|
|
||||||
|
|
||||||
mz_os_unicode_string_delete(&target_path_wide);
|
|
||||||
} else {
|
|
||||||
err = MZ_PARAM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_os_read_symlink(const char *path, char *target_path, int32_t max_target_path) {
|
|
||||||
typedef struct _REPARSE_DATA_BUFFER {
|
|
||||||
ULONG ReparseTag;
|
|
||||||
USHORT ReparseDataLength;
|
|
||||||
USHORT Reserved;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
USHORT SubstituteNameOffset;
|
|
||||||
USHORT SubstituteNameLength;
|
|
||||||
USHORT PrintNameOffset;
|
|
||||||
USHORT PrintNameLength;
|
|
||||||
ULONG Flags;
|
|
||||||
WCHAR PathBuffer[1];
|
|
||||||
} SymbolicLinkReparseBuffer;
|
|
||||||
struct {
|
|
||||||
USHORT SubstituteNameOffset;
|
|
||||||
USHORT SubstituteNameLength;
|
|
||||||
USHORT PrintNameOffset;
|
|
||||||
USHORT PrintNameLength;
|
|
||||||
WCHAR PathBuffer[1];
|
|
||||||
} MountPointReparseBuffer;
|
|
||||||
struct {
|
|
||||||
UCHAR DataBuffer[1];
|
|
||||||
} GenericReparseBuffer;
|
|
||||||
};
|
|
||||||
} REPARSE_DATA_BUFFER;
|
|
||||||
REPARSE_DATA_BUFFER *reparse_data = NULL;
|
|
||||||
DWORD length = 0;
|
|
||||||
HANDLE handle = NULL;
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
wchar_t *target_path_wide = NULL;
|
|
||||||
uint8_t buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
|
|
||||||
int32_t target_path_len = 0;
|
|
||||||
int32_t target_path_idx = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
uint8_t *target_path_utf8 = NULL;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
#ifdef MZ_WINRT_API
|
|
||||||
CREATEFILE2_EXTENDED_PARAMETERS extended_params;
|
|
||||||
memset(&extended_params, 0, sizeof(extended_params));
|
|
||||||
extended_params.dwSize = sizeof(extended_params);
|
|
||||||
extended_params.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
|
|
||||||
extended_params.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT;
|
|
||||||
extended_params.dwSecurityQosFlags = SECURITY_ANONYMOUS;
|
|
||||||
extended_params.lpSecurityAttributes = NULL;
|
|
||||||
extended_params.hTemplateFile = NULL;
|
|
||||||
handle = CreateFile2(path_wide, FILE_READ_EA, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, &extended_params);
|
|
||||||
#else
|
|
||||||
handle = CreateFileW(path_wide, FILE_READ_EA, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
|
|
||||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (handle == INVALID_HANDLE_VALUE) {
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer, sizeof(buffer), &length, NULL) == TRUE) {
|
|
||||||
reparse_data = (REPARSE_DATA_BUFFER *)buffer;
|
|
||||||
if ((IsReparseTagMicrosoft(reparse_data->ReparseTag)) &&
|
|
||||||
(reparse_data->ReparseTag == IO_REPARSE_TAG_SYMLINK)) {
|
|
||||||
target_path_len = max_target_path * sizeof(wchar_t);
|
|
||||||
if (target_path_len > reparse_data->SymbolicLinkReparseBuffer.PrintNameLength)
|
|
||||||
target_path_len = reparse_data->SymbolicLinkReparseBuffer.PrintNameLength;
|
|
||||||
|
|
||||||
target_path_wide = (wchar_t *)MZ_ALLOC(target_path_len + sizeof(wchar_t));
|
|
||||||
if (target_path_wide) {
|
|
||||||
target_path_idx = reparse_data->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(wchar_t);
|
|
||||||
memcpy(target_path_wide, &reparse_data->SymbolicLinkReparseBuffer.PathBuffer[target_path_idx],
|
|
||||||
target_path_len);
|
|
||||||
|
|
||||||
target_path_wide[target_path_len / sizeof(wchar_t)] = 0;
|
|
||||||
target_path_utf8 = mz_os_utf8_string_create_from_unicode(target_path_wide, MZ_ENCODING_UTF8);
|
|
||||||
|
|
||||||
if (target_path_utf8) {
|
|
||||||
strncpy(target_path, (const char *)target_path_utf8, max_target_path - 1);
|
|
||||||
target_path[max_target_path - 1] = 0;
|
|
||||||
/* Ensure directories have slash at the end so we can recreate them later */
|
|
||||||
if (mz_os_is_dir((const char *)target_path_utf8) == MZ_OK)
|
|
||||||
mz_path_append_slash(target_path, max_target_path, MZ_PATH_SLASH_PLATFORM);
|
|
||||||
mz_os_utf8_string_delete(&target_path_utf8);
|
|
||||||
} else {
|
|
||||||
err = MZ_MEM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
MZ_FREE(target_path_wide);
|
|
||||||
} else {
|
|
||||||
err = MZ_MEM_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = MZ_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(handle);
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t mz_os_ms_time(void) {
|
|
||||||
SYSTEMTIME system_time;
|
|
||||||
FILETIME file_time;
|
|
||||||
uint64_t quad_file_time = 0;
|
|
||||||
|
|
||||||
GetSystemTime(&system_time);
|
|
||||||
SystemTimeToFileTime(&system_time, &file_time);
|
|
||||||
|
|
||||||
quad_file_time = file_time.dwLowDateTime;
|
|
||||||
quad_file_time |= ((uint64_t)file_time.dwHighDateTime << 32);
|
|
||||||
|
|
||||||
return quad_file_time / 10000 - 11644473600000LL;
|
|
||||||
}
|
|
|
@ -1,560 +0,0 @@
|
||||||
/* mz_strm.c -- Stream interface
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#define MZ_STREAM_FIND_SIZE (1024)
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream *strm = (mz_stream *)stream;
|
|
||||||
if (strm == NULL || strm->vtbl == NULL || strm->vtbl->open == NULL)
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
return strm->vtbl->open(strm, path, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_is_open(void *stream) {
|
|
||||||
mz_stream *strm = (mz_stream *)stream;
|
|
||||||
if (strm == NULL || strm->vtbl == NULL || strm->vtbl->is_open == NULL)
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
return strm->vtbl->is_open(strm);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_read(void *stream, void *buf, int32_t size) {
|
|
||||||
mz_stream *strm = (mz_stream *)stream;
|
|
||||||
if (strm == NULL || strm->vtbl == NULL || strm->vtbl->read == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (mz_stream_is_open(stream) != MZ_OK)
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
return strm->vtbl->read(strm, buf, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_read_value(void *stream, uint64_t *value, int32_t len) {
|
|
||||||
uint8_t buf[8];
|
|
||||||
int32_t n = 0;
|
|
||||||
int32_t i = 0;
|
|
||||||
|
|
||||||
*value = 0;
|
|
||||||
if (mz_stream_read(stream, buf, len) == len) {
|
|
||||||
for (n = 0; n < len; n += 1, i += 8)
|
|
||||||
*value += ((uint64_t)buf[n]) << i;
|
|
||||||
} else if (mz_stream_error(stream))
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
else
|
|
||||||
return MZ_END_OF_STREAM;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_read_uint8(void *stream, uint8_t *value) {
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
uint64_t value64 = 0;
|
|
||||||
|
|
||||||
*value = 0;
|
|
||||||
err = mz_stream_read_value(stream, &value64, sizeof(uint8_t));
|
|
||||||
if (err == MZ_OK)
|
|
||||||
*value = (uint8_t)value64;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_read_uint16(void *stream, uint16_t *value) {
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
uint64_t value64 = 0;
|
|
||||||
|
|
||||||
*value = 0;
|
|
||||||
err = mz_stream_read_value(stream, &value64, sizeof(uint16_t));
|
|
||||||
if (err == MZ_OK)
|
|
||||||
*value = (uint16_t)value64;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_read_uint32(void *stream, uint32_t *value) {
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
uint64_t value64 = 0;
|
|
||||||
|
|
||||||
*value = 0;
|
|
||||||
err = mz_stream_read_value(stream, &value64, sizeof(uint32_t));
|
|
||||||
if (err == MZ_OK)
|
|
||||||
*value = (uint32_t)value64;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_read_int64(void *stream, int64_t *value) {
|
|
||||||
return mz_stream_read_value(stream, (uint64_t *)value, sizeof(uint64_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_read_uint64(void *stream, uint64_t *value) {
|
|
||||||
return mz_stream_read_value(stream, value, sizeof(uint64_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
mz_stream *strm = (mz_stream *)stream;
|
|
||||||
if (size == 0)
|
|
||||||
return size;
|
|
||||||
if (strm == NULL || strm->vtbl == NULL || strm->vtbl->write == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (mz_stream_is_open(stream) != MZ_OK)
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
return strm->vtbl->write(strm, buf, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_write_value(void *stream, uint64_t value, int32_t len) {
|
|
||||||
uint8_t buf[8];
|
|
||||||
int32_t n = 0;
|
|
||||||
|
|
||||||
for (n = 0; n < len; n += 1) {
|
|
||||||
buf[n] = (uint8_t)(value & 0xff);
|
|
||||||
value >>= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value != 0) {
|
|
||||||
/* Data overflow - hack for ZIP64 (X Roche) */
|
|
||||||
for (n = 0; n < len; n += 1)
|
|
||||||
buf[n] = 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mz_stream_write(stream, buf, len) != len)
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_write_uint8(void *stream, uint8_t value) {
|
|
||||||
return mz_stream_write_value(stream, value, sizeof(uint8_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_write_uint16(void *stream, uint16_t value) {
|
|
||||||
return mz_stream_write_value(stream, value, sizeof(uint16_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_write_uint32(void *stream, uint32_t value) {
|
|
||||||
return mz_stream_write_value(stream, value, sizeof(uint32_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_write_int64(void *stream, int64_t value) {
|
|
||||||
return mz_stream_write_value(stream, (uint64_t)value, sizeof(uint64_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_write_uint64(void *stream, uint64_t value) {
|
|
||||||
return mz_stream_write_value(stream, value, sizeof(uint64_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_copy(void *target, void *source, int32_t len) {
|
|
||||||
return mz_stream_copy_stream(target, NULL, source, NULL, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_copy_to_end(void *target, void *source) {
|
|
||||||
return mz_stream_copy_stream_to_end(target, NULL, source, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_copy_stream(void *target, mz_stream_write_cb write_cb, void *source,
|
|
||||||
mz_stream_read_cb read_cb, int32_t len) {
|
|
||||||
uint8_t buf[16384];
|
|
||||||
int32_t bytes_to_copy = 0;
|
|
||||||
int32_t read = 0;
|
|
||||||
int32_t written = 0;
|
|
||||||
|
|
||||||
if (write_cb == NULL)
|
|
||||||
write_cb = mz_stream_write;
|
|
||||||
if (read_cb == NULL)
|
|
||||||
read_cb = mz_stream_read;
|
|
||||||
|
|
||||||
while (len > 0) {
|
|
||||||
bytes_to_copy = len;
|
|
||||||
if (bytes_to_copy > (int32_t)sizeof(buf))
|
|
||||||
bytes_to_copy = sizeof(buf);
|
|
||||||
read = read_cb(source, buf, bytes_to_copy);
|
|
||||||
if (read <= 0)
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
written = write_cb(target, buf, read);
|
|
||||||
if (written != read)
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
len -= read;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_copy_stream_to_end(void *target, mz_stream_write_cb write_cb, void *source,
|
|
||||||
mz_stream_read_cb read_cb) {
|
|
||||||
uint8_t buf[16384];
|
|
||||||
int32_t read = 0;
|
|
||||||
int32_t written = 0;
|
|
||||||
|
|
||||||
if (write_cb == NULL)
|
|
||||||
write_cb = mz_stream_write;
|
|
||||||
if (read_cb == NULL)
|
|
||||||
read_cb = mz_stream_read;
|
|
||||||
|
|
||||||
read = read_cb(source, buf, sizeof(buf));
|
|
||||||
while (read > 0) {
|
|
||||||
written = write_cb(target, buf, read);
|
|
||||||
if (written != read)
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
read = read_cb(source, buf, sizeof(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read < 0)
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_tell(void *stream) {
|
|
||||||
mz_stream *strm = (mz_stream *)stream;
|
|
||||||
if (strm == NULL || strm->vtbl == NULL || strm->vtbl->tell == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (mz_stream_is_open(stream) != MZ_OK)
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
return strm->vtbl->tell(strm);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
mz_stream *strm = (mz_stream *)stream;
|
|
||||||
if (strm == NULL || strm->vtbl == NULL || strm->vtbl->seek == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (mz_stream_is_open(stream) != MZ_OK)
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
if (origin == MZ_SEEK_SET && offset < 0)
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
return strm->vtbl->seek(strm, offset, origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_find(void *stream, const void *find, int32_t find_size, int64_t max_seek, int64_t *position) {
|
|
||||||
uint8_t buf[MZ_STREAM_FIND_SIZE];
|
|
||||||
int32_t buf_pos = 0;
|
|
||||||
int32_t read_size = sizeof(buf);
|
|
||||||
int32_t read = 0;
|
|
||||||
int64_t read_pos = 0;
|
|
||||||
int64_t start_pos = 0;
|
|
||||||
int64_t disk_pos = 0;
|
|
||||||
int32_t i = 0;
|
|
||||||
uint8_t first = 1;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
if (stream == NULL || find == NULL || position == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (find_size < 0 || find_size >= (int32_t)sizeof(buf))
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
*position = -1;
|
|
||||||
|
|
||||||
start_pos = mz_stream_tell(stream);
|
|
||||||
|
|
||||||
while (read_pos < max_seek) {
|
|
||||||
if (read_size > (int32_t)(max_seek - read_pos - buf_pos) && (max_seek - read_pos - buf_pos) < (int64_t)sizeof(buf))
|
|
||||||
read_size = (int32_t)(max_seek - read_pos - buf_pos);
|
|
||||||
|
|
||||||
read = mz_stream_read(stream, buf + buf_pos, read_size);
|
|
||||||
if ((read <= 0) || (read + buf_pos < find_size))
|
|
||||||
break;
|
|
||||||
|
|
||||||
for (i = 0; i <= read + buf_pos - find_size; i += 1) {
|
|
||||||
if (memcmp(&buf[i], find, find_size) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
disk_pos = mz_stream_tell(stream);
|
|
||||||
|
|
||||||
/* Seek to position on disk where the data was found */
|
|
||||||
err = mz_stream_seek(stream, disk_pos - ((int64_t)read + buf_pos - i), MZ_SEEK_SET);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
|
|
||||||
*position = start_pos + read_pos + i;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (first) {
|
|
||||||
read -= find_size;
|
|
||||||
read_size -= find_size;
|
|
||||||
buf_pos = find_size;
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memmove(buf, buf + read, find_size);
|
|
||||||
read_pos += read;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_find_reverse(void *stream, const void *find, int32_t find_size, int64_t max_seek, int64_t *position) {
|
|
||||||
uint8_t buf[MZ_STREAM_FIND_SIZE];
|
|
||||||
int32_t buf_pos = 0;
|
|
||||||
int32_t read_size = MZ_STREAM_FIND_SIZE;
|
|
||||||
int64_t read_pos = 0;
|
|
||||||
int32_t read = 0;
|
|
||||||
int64_t start_pos = 0;
|
|
||||||
int64_t disk_pos = 0;
|
|
||||||
uint8_t first = 1;
|
|
||||||
int32_t i = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
if (stream == NULL || find == NULL || position == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (find_size < 0 || find_size >= (int32_t)sizeof(buf))
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
*position = -1;
|
|
||||||
|
|
||||||
start_pos = mz_stream_tell(stream);
|
|
||||||
|
|
||||||
while (read_pos < max_seek) {
|
|
||||||
if (read_size > (int32_t)(max_seek - read_pos) && (max_seek - read_pos) < (int64_t)sizeof(buf))
|
|
||||||
read_size = (int32_t)(max_seek - read_pos);
|
|
||||||
|
|
||||||
if (mz_stream_seek(stream, start_pos - (read_pos + read_size), MZ_SEEK_SET) != MZ_OK)
|
|
||||||
break;
|
|
||||||
read = mz_stream_read(stream, buf, read_size);
|
|
||||||
if ((read <= 0) || (read + buf_pos < find_size))
|
|
||||||
break;
|
|
||||||
if (read + buf_pos < MZ_STREAM_FIND_SIZE)
|
|
||||||
memmove(buf + MZ_STREAM_FIND_SIZE - (read + buf_pos), buf, read);
|
|
||||||
|
|
||||||
for (i = find_size; i <= (read + buf_pos); i += 1) {
|
|
||||||
if (memcmp(&buf[MZ_STREAM_FIND_SIZE - i], find, find_size) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
disk_pos = mz_stream_tell(stream);
|
|
||||||
|
|
||||||
/* Seek to position on disk where the data was found */
|
|
||||||
err = mz_stream_seek(stream, disk_pos + buf_pos - i, MZ_SEEK_SET);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
|
|
||||||
*position = start_pos - (read_pos - buf_pos + i);
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (first) {
|
|
||||||
read -= find_size;
|
|
||||||
read_size -= find_size;
|
|
||||||
buf_pos = find_size;
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
memmove(buf + read_size, buf, find_size);
|
|
||||||
read_pos += read;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_close(void *stream) {
|
|
||||||
mz_stream *strm = (mz_stream *)stream;
|
|
||||||
if (strm == NULL || strm->vtbl == NULL || strm->vtbl->close == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
if (mz_stream_is_open(stream) != MZ_OK)
|
|
||||||
return MZ_STREAM_ERROR;
|
|
||||||
return strm->vtbl->close(strm);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_error(void *stream) {
|
|
||||||
mz_stream *strm = (mz_stream *)stream;
|
|
||||||
if (strm == NULL || strm->vtbl == NULL || strm->vtbl->error == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
return strm->vtbl->error(strm);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_set_base(void *stream, void *base) {
|
|
||||||
mz_stream *strm = (mz_stream *)stream;
|
|
||||||
strm->base = (mz_stream *)base;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* mz_stream_get_interface(void *stream) {
|
|
||||||
mz_stream *strm = (mz_stream *)stream;
|
|
||||||
if (strm == NULL || strm->vtbl == NULL)
|
|
||||||
return NULL;
|
|
||||||
return (void *)strm->vtbl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_get_prop_int64(void *stream, int32_t prop, int64_t *value) {
|
|
||||||
mz_stream *strm = (mz_stream *)stream;
|
|
||||||
if (strm == NULL || strm->vtbl == NULL || strm->vtbl->get_prop_int64 == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
return strm->vtbl->get_prop_int64(stream, prop, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_set_prop_int64(void *stream, int32_t prop, int64_t value) {
|
|
||||||
mz_stream *strm = (mz_stream *)stream;
|
|
||||||
if (strm == NULL || strm->vtbl == NULL || strm->vtbl->set_prop_int64 == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
return strm->vtbl->set_prop_int64(stream, prop, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_create(void **stream, mz_stream_vtbl *vtbl) {
|
|
||||||
if (stream == NULL)
|
|
||||||
return NULL;
|
|
||||||
if (vtbl == NULL || vtbl->create == NULL)
|
|
||||||
return NULL;
|
|
||||||
return vtbl->create(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_delete(void **stream) {
|
|
||||||
mz_stream *strm = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
strm = (mz_stream *)*stream;
|
|
||||||
if (strm != NULL && strm->vtbl != NULL && strm->vtbl->destroy != NULL)
|
|
||||||
strm->vtbl->destroy(stream);
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_raw_s {
|
|
||||||
mz_stream stream;
|
|
||||||
int64_t total_in;
|
|
||||||
int64_t total_out;
|
|
||||||
int64_t max_total_in;
|
|
||||||
} mz_stream_raw;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_raw_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(path);
|
|
||||||
MZ_UNUSED(mode);
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_raw_is_open(void *stream) {
|
|
||||||
mz_stream_raw *raw = (mz_stream_raw *)stream;
|
|
||||||
return mz_stream_is_open(raw->stream.base);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_raw_read(void *stream, void *buf, int32_t size) {
|
|
||||||
mz_stream_raw *raw = (mz_stream_raw *)stream;
|
|
||||||
int32_t bytes_to_read = size;
|
|
||||||
int32_t read = 0;
|
|
||||||
|
|
||||||
if (raw->max_total_in > 0) {
|
|
||||||
if ((int64_t)bytes_to_read > (raw->max_total_in - raw->total_in))
|
|
||||||
bytes_to_read = (int32_t)(raw->max_total_in - raw->total_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
read = mz_stream_read(raw->stream.base, buf, bytes_to_read);
|
|
||||||
|
|
||||||
if (read > 0) {
|
|
||||||
raw->total_in += read;
|
|
||||||
raw->total_out += read;
|
|
||||||
}
|
|
||||||
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_raw_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
mz_stream_raw *raw = (mz_stream_raw *)stream;
|
|
||||||
int32_t written = 0;
|
|
||||||
|
|
||||||
written = mz_stream_write(raw->stream.base, buf, size);
|
|
||||||
|
|
||||||
if (written > 0) {
|
|
||||||
raw->total_out += written;
|
|
||||||
raw->total_in += written;
|
|
||||||
}
|
|
||||||
|
|
||||||
return written;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_raw_tell(void *stream) {
|
|
||||||
mz_stream_raw *raw = (mz_stream_raw *)stream;
|
|
||||||
return mz_stream_tell(raw->stream.base);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_raw_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
mz_stream_raw *raw = (mz_stream_raw *)stream;
|
|
||||||
return mz_stream_seek(raw->stream.base, offset, origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_raw_close(void *stream) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_raw_error(void *stream) {
|
|
||||||
mz_stream_raw *raw = (mz_stream_raw *)stream;
|
|
||||||
return mz_stream_error(raw->stream.base);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_raw_get_prop_int64(void *stream, int32_t prop, int64_t *value) {
|
|
||||||
mz_stream_raw *raw = (mz_stream_raw *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN:
|
|
||||||
*value = raw->total_in;
|
|
||||||
return MZ_OK;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
|
||||||
*value = raw->total_out;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_raw_set_prop_int64(void *stream, int32_t prop, int64_t value) {
|
|
||||||
mz_stream_raw *raw = (mz_stream_raw *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
raw->max_total_in = value;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_raw_vtbl = {
|
|
||||||
mz_stream_raw_open,
|
|
||||||
mz_stream_raw_is_open,
|
|
||||||
mz_stream_raw_read,
|
|
||||||
mz_stream_raw_write,
|
|
||||||
mz_stream_raw_tell,
|
|
||||||
mz_stream_raw_seek,
|
|
||||||
mz_stream_raw_close,
|
|
||||||
mz_stream_raw_error,
|
|
||||||
mz_stream_raw_create,
|
|
||||||
mz_stream_raw_delete,
|
|
||||||
mz_stream_raw_get_prop_int64,
|
|
||||||
mz_stream_raw_set_prop_int64
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void *mz_stream_raw_create(void **stream) {
|
|
||||||
mz_stream_raw *raw = NULL;
|
|
||||||
|
|
||||||
raw = (mz_stream_raw *)MZ_ALLOC(sizeof(mz_stream_raw));
|
|
||||||
if (raw != NULL) {
|
|
||||||
memset(raw, 0, sizeof(mz_stream_raw));
|
|
||||||
raw->stream.vtbl = &mz_stream_raw_vtbl;
|
|
||||||
}
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = raw;
|
|
||||||
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_raw_delete(void **stream) {
|
|
||||||
mz_stream_raw *raw = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
raw = (mz_stream_raw *)*stream;
|
|
||||||
if (raw != NULL)
|
|
||||||
MZ_FREE(raw);
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
|
@ -1,132 +0,0 @@
|
||||||
/* mz_strm.h -- Stream interface
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_STREAM_H
|
|
||||||
#define MZ_STREAM_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#define MZ_STREAM_PROP_TOTAL_IN (1)
|
|
||||||
#define MZ_STREAM_PROP_TOTAL_IN_MAX (2)
|
|
||||||
#define MZ_STREAM_PROP_TOTAL_OUT (3)
|
|
||||||
#define MZ_STREAM_PROP_TOTAL_OUT_MAX (4)
|
|
||||||
#define MZ_STREAM_PROP_HEADER_SIZE (5)
|
|
||||||
#define MZ_STREAM_PROP_FOOTER_SIZE (6)
|
|
||||||
#define MZ_STREAM_PROP_DISK_SIZE (7)
|
|
||||||
#define MZ_STREAM_PROP_DISK_NUMBER (8)
|
|
||||||
#define MZ_STREAM_PROP_COMPRESS_LEVEL (9)
|
|
||||||
#define MZ_STREAM_PROP_COMPRESS_METHOD (10)
|
|
||||||
#define MZ_STREAM_PROP_COMPRESS_WINDOW (11)
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef int32_t (*mz_stream_open_cb) (void *stream, const char *path, int32_t mode);
|
|
||||||
typedef int32_t (*mz_stream_is_open_cb) (void *stream);
|
|
||||||
typedef int32_t (*mz_stream_read_cb) (void *stream, void *buf, int32_t size);
|
|
||||||
typedef int32_t (*mz_stream_write_cb) (void *stream, const void *buf, int32_t size);
|
|
||||||
typedef int64_t (*mz_stream_tell_cb) (void *stream);
|
|
||||||
typedef int32_t (*mz_stream_seek_cb) (void *stream, int64_t offset, int32_t origin);
|
|
||||||
typedef int32_t (*mz_stream_close_cb) (void *stream);
|
|
||||||
typedef int32_t (*mz_stream_error_cb) (void *stream);
|
|
||||||
typedef void* (*mz_stream_create_cb) (void **stream);
|
|
||||||
typedef void (*mz_stream_destroy_cb) (void **stream);
|
|
||||||
|
|
||||||
typedef int32_t (*mz_stream_get_prop_int64_cb) (void *stream, int32_t prop, int64_t *value);
|
|
||||||
typedef int32_t (*mz_stream_set_prop_int64_cb) (void *stream, int32_t prop, int64_t value);
|
|
||||||
|
|
||||||
typedef int32_t (*mz_stream_find_cb) (void *stream, const void *find, int32_t find_size,
|
|
||||||
int64_t max_seek, int64_t *position);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_vtbl_s {
|
|
||||||
mz_stream_open_cb open;
|
|
||||||
mz_stream_is_open_cb is_open;
|
|
||||||
mz_stream_read_cb read;
|
|
||||||
mz_stream_write_cb write;
|
|
||||||
mz_stream_tell_cb tell;
|
|
||||||
mz_stream_seek_cb seek;
|
|
||||||
mz_stream_close_cb close;
|
|
||||||
mz_stream_error_cb error;
|
|
||||||
mz_stream_create_cb create;
|
|
||||||
mz_stream_destroy_cb destroy;
|
|
||||||
|
|
||||||
mz_stream_get_prop_int64_cb get_prop_int64;
|
|
||||||
mz_stream_set_prop_int64_cb set_prop_int64;
|
|
||||||
} mz_stream_vtbl;
|
|
||||||
|
|
||||||
typedef struct mz_stream_s {
|
|
||||||
mz_stream_vtbl *vtbl;
|
|
||||||
struct mz_stream_s *base;
|
|
||||||
} mz_stream;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_open(void *stream, const char *path, int32_t mode);
|
|
||||||
int32_t mz_stream_is_open(void *stream);
|
|
||||||
int32_t mz_stream_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_read_uint8(void *stream, uint8_t *value);
|
|
||||||
int32_t mz_stream_read_uint16(void *stream, uint16_t *value);
|
|
||||||
int32_t mz_stream_read_uint32(void *stream, uint32_t *value);
|
|
||||||
int32_t mz_stream_read_int64(void *stream, int64_t *value);
|
|
||||||
int32_t mz_stream_read_uint64(void *stream, uint64_t *value);
|
|
||||||
int32_t mz_stream_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_write_uint8(void *stream, uint8_t value);
|
|
||||||
int32_t mz_stream_write_uint16(void *stream, uint16_t value);
|
|
||||||
int32_t mz_stream_write_uint32(void *stream, uint32_t value);
|
|
||||||
int32_t mz_stream_write_int64(void *stream, int64_t value);
|
|
||||||
int32_t mz_stream_write_uint64(void *stream, uint64_t value);
|
|
||||||
int32_t mz_stream_copy(void *target, void *source, int32_t len);
|
|
||||||
int32_t mz_stream_copy_to_end(void *target, void *source);
|
|
||||||
int32_t mz_stream_copy_stream(void *target, mz_stream_write_cb write_cb, void *source, mz_stream_read_cb read_cb, int32_t len);
|
|
||||||
int32_t mz_stream_copy_stream_to_end(void *target, mz_stream_write_cb write_cb, void *source, mz_stream_read_cb read_cb);
|
|
||||||
int64_t mz_stream_tell(void *stream);
|
|
||||||
int32_t mz_stream_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_find(void *stream, const void *find, int32_t find_size, int64_t max_seek, int64_t *position);
|
|
||||||
int32_t mz_stream_find_reverse(void *stream, const void *find, int32_t find_size, int64_t max_seek, int64_t *position);
|
|
||||||
int32_t mz_stream_close(void *stream);
|
|
||||||
int32_t mz_stream_error(void *stream);
|
|
||||||
|
|
||||||
int32_t mz_stream_set_base(void *stream, void *base);
|
|
||||||
void* mz_stream_get_interface(void *stream);
|
|
||||||
int32_t mz_stream_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
|
||||||
int32_t mz_stream_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
|
||||||
|
|
||||||
void* mz_stream_create(void **stream, mz_stream_vtbl *vtbl);
|
|
||||||
void mz_stream_delete(void **stream);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_raw_open(void *stream, const char *filename, int32_t mode);
|
|
||||||
int32_t mz_stream_raw_is_open(void *stream);
|
|
||||||
int32_t mz_stream_raw_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_raw_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int64_t mz_stream_raw_tell(void *stream);
|
|
||||||
int32_t mz_stream_raw_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_raw_close(void *stream);
|
|
||||||
int32_t mz_stream_raw_error(void *stream);
|
|
||||||
|
|
||||||
int32_t mz_stream_raw_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
|
||||||
int32_t mz_stream_raw_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
|
||||||
|
|
||||||
void* mz_stream_raw_create(void **stream);
|
|
||||||
void mz_stream_raw_delete(void **stream);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,385 +0,0 @@
|
||||||
/* mz_strm_buf.c -- Stream for buffering reads/writes
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
This version of ioapi is designed to buffer IO.
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_buf.h"
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_buffered_vtbl = {
|
|
||||||
mz_stream_buffered_open,
|
|
||||||
mz_stream_buffered_is_open,
|
|
||||||
mz_stream_buffered_read,
|
|
||||||
mz_stream_buffered_write,
|
|
||||||
mz_stream_buffered_tell,
|
|
||||||
mz_stream_buffered_seek,
|
|
||||||
mz_stream_buffered_close,
|
|
||||||
mz_stream_buffered_error,
|
|
||||||
mz_stream_buffered_create,
|
|
||||||
mz_stream_buffered_delete,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_buffered_s {
|
|
||||||
mz_stream stream;
|
|
||||||
int32_t error;
|
|
||||||
char readbuf[INT16_MAX];
|
|
||||||
int32_t readbuf_len;
|
|
||||||
int32_t readbuf_pos;
|
|
||||||
int32_t readbuf_hits;
|
|
||||||
int32_t readbuf_misses;
|
|
||||||
char writebuf[INT16_MAX];
|
|
||||||
int32_t writebuf_len;
|
|
||||||
int32_t writebuf_pos;
|
|
||||||
int32_t writebuf_hits;
|
|
||||||
int32_t writebuf_misses;
|
|
||||||
int64_t position;
|
|
||||||
} mz_stream_buffered;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
# define mz_stream_buffered_print printf
|
|
||||||
#else
|
|
||||||
# define mz_stream_buffered_print(fmt,...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static int32_t mz_stream_buffered_reset(void *stream) {
|
|
||||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
||||||
|
|
||||||
buffered->readbuf_len = 0;
|
|
||||||
buffered->readbuf_pos = 0;
|
|
||||||
buffered->writebuf_len = 0;
|
|
||||||
buffered->writebuf_pos = 0;
|
|
||||||
buffered->position = 0;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_buffered_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
||||||
mz_stream_buffered_print("Buffered - Open (mode %" PRId32 ")\n", mode);
|
|
||||||
mz_stream_buffered_reset(buffered);
|
|
||||||
return mz_stream_open(buffered->stream.base, path, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_buffered_is_open(void *stream) {
|
|
||||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
||||||
return mz_stream_is_open(buffered->stream.base);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_buffered_flush(void *stream, int32_t *written) {
|
|
||||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
||||||
int32_t total_bytes_written = 0;
|
|
||||||
int32_t bytes_to_write = buffered->writebuf_len;
|
|
||||||
int32_t bytes_left_to_write = buffered->writebuf_len;
|
|
||||||
int32_t bytes_written = 0;
|
|
||||||
|
|
||||||
*written = 0;
|
|
||||||
|
|
||||||
while (bytes_left_to_write > 0) {
|
|
||||||
bytes_written = mz_stream_write(buffered->stream.base,
|
|
||||||
buffered->writebuf + (bytes_to_write - bytes_left_to_write), bytes_left_to_write);
|
|
||||||
|
|
||||||
if (bytes_written != bytes_left_to_write)
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
|
|
||||||
buffered->writebuf_misses += 1;
|
|
||||||
|
|
||||||
mz_stream_buffered_print("Buffered - Write flush (%" PRId32 ":%" PRId32 " len %" PRId32 ")\n",
|
|
||||||
bytes_to_write, bytes_left_to_write, buffered->writebuf_len);
|
|
||||||
|
|
||||||
total_bytes_written += bytes_written;
|
|
||||||
bytes_left_to_write -= bytes_written;
|
|
||||||
buffered->position += bytes_written;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffered->writebuf_len = 0;
|
|
||||||
buffered->writebuf_pos = 0;
|
|
||||||
|
|
||||||
*written = total_bytes_written;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_buffered_read(void *stream, void *buf, int32_t size) {
|
|
||||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
||||||
int32_t buf_len = 0;
|
|
||||||
int32_t bytes_to_read = 0;
|
|
||||||
int32_t bytes_to_copy = 0;
|
|
||||||
int32_t bytes_left_to_read = size;
|
|
||||||
int32_t bytes_read = 0;
|
|
||||||
int32_t bytes_flushed = 0;
|
|
||||||
|
|
||||||
mz_stream_buffered_print("Buffered - Read (size %" PRId32 " pos %" PRId64 ")\n", size, buffered->position);
|
|
||||||
|
|
||||||
if (buffered->writebuf_len > 0) {
|
|
||||||
int64_t position = buffered->position + buffered->writebuf_pos
|
|
||||||
|
|
||||||
mz_stream_buffered_print("Buffered - Switch from write to read, flushing (pos %" PRId64 ")\n", position);
|
|
||||||
|
|
||||||
mz_stream_buffered_flush(stream, &bytes_flushed);
|
|
||||||
mz_stream_buffered_seek(stream, position, MZ_SEEK_SET);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (bytes_left_to_read > 0) {
|
|
||||||
if ((buffered->readbuf_len == 0) || (buffered->readbuf_pos == buffered->readbuf_len)) {
|
|
||||||
if (buffered->readbuf_len == sizeof(buffered->readbuf)) {
|
|
||||||
buffered->readbuf_pos = 0;
|
|
||||||
buffered->readbuf_len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes_to_read = (int32_t)sizeof(buffered->readbuf) - (buffered->readbuf_len - buffered->readbuf_pos);
|
|
||||||
bytes_read = mz_stream_read(buffered->stream.base, buffered->readbuf + buffered->readbuf_pos, bytes_to_read);
|
|
||||||
if (bytes_read < 0)
|
|
||||||
return bytes_read;
|
|
||||||
|
|
||||||
buffered->readbuf_misses += 1;
|
|
||||||
buffered->readbuf_len += bytes_read;
|
|
||||||
buffered->position += bytes_read;
|
|
||||||
|
|
||||||
mz_stream_buffered_print("Buffered - Filled (read %" PRId32 "/%" PRId32 " buf %" PRId32 ":%" PRId32 " pos %" PRId64 ")\n",
|
|
||||||
bytes_read, bytes_to_read, buffered->readbuf_pos, buffered->readbuf_len, buffered->position);
|
|
||||||
|
|
||||||
if (bytes_read == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((buffered->readbuf_len - buffered->readbuf_pos) > 0) {
|
|
||||||
bytes_to_copy = buffered->readbuf_len - buffered->readbuf_pos;
|
|
||||||
if (bytes_to_copy > bytes_left_to_read)
|
|
||||||
bytes_to_copy = bytes_left_to_read;
|
|
||||||
|
|
||||||
memcpy((char *)buf + buf_len, buffered->readbuf + buffered->readbuf_pos, bytes_to_copy);
|
|
||||||
|
|
||||||
buf_len += bytes_to_copy;
|
|
||||||
bytes_left_to_read -= bytes_to_copy;
|
|
||||||
|
|
||||||
buffered->readbuf_hits += 1;
|
|
||||||
buffered->readbuf_pos += bytes_to_copy;
|
|
||||||
|
|
||||||
mz_stream_buffered_print("Buffered - Emptied (copied %" PRId32 " remaining %" PRId32 " buf %" PRId32 ":%" PRId32 " pos %" PRId64 ")\n",
|
|
||||||
bytes_to_copy, bytes_left_to_read, buffered->readbuf_pos, buffered->readbuf_len, buffered->position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return size - bytes_left_to_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_buffered_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
||||||
int32_t bytes_to_write = size;
|
|
||||||
int32_t bytes_left_to_write = size;
|
|
||||||
int32_t bytes_to_copy = 0;
|
|
||||||
int32_t bytes_used = 0;
|
|
||||||
int32_t bytes_flushed = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
|
|
||||||
mz_stream_buffered_print("Buffered - Write (size %" PRId32 " len %" PRId32 " pos %" PRId64 ")\n",
|
|
||||||
size, buffered->writebuf_len, buffered->position);
|
|
||||||
|
|
||||||
if (buffered->readbuf_len > 0) {
|
|
||||||
buffered->position -= buffered->readbuf_len;
|
|
||||||
buffered->position += buffered->readbuf_pos;
|
|
||||||
|
|
||||||
buffered->readbuf_len = 0;
|
|
||||||
buffered->readbuf_pos = 0;
|
|
||||||
|
|
||||||
mz_stream_buffered_print("Buffered - Switch from read to write (pos %" PRId64 ")\n", buffered->position);
|
|
||||||
|
|
||||||
err = mz_stream_seek(buffered->stream.base, buffered->position, MZ_SEEK_SET);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (bytes_left_to_write > 0) {
|
|
||||||
bytes_used = buffered->writebuf_len;
|
|
||||||
if (bytes_used > buffered->writebuf_pos)
|
|
||||||
bytes_used = buffered->writebuf_pos;
|
|
||||||
bytes_to_copy = (int32_t)sizeof(buffered->writebuf) - bytes_used;
|
|
||||||
if (bytes_to_copy > bytes_left_to_write)
|
|
||||||
bytes_to_copy = bytes_left_to_write;
|
|
||||||
|
|
||||||
if (bytes_to_copy == 0) {
|
|
||||||
err = mz_stream_buffered_flush(stream, &bytes_flushed);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
if (bytes_flushed == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(buffered->writebuf + buffered->writebuf_pos,
|
|
||||||
(const char *)buf + (bytes_to_write - bytes_left_to_write), bytes_to_copy);
|
|
||||||
|
|
||||||
mz_stream_buffered_print("Buffered - Write copy (remaining %" PRId32 " write %" PRId32 ":%" PRId32 " len %" PRId32 ")\n",
|
|
||||||
bytes_to_copy, bytes_to_write, bytes_left_to_write, buffered->writebuf_len);
|
|
||||||
|
|
||||||
bytes_left_to_write -= bytes_to_copy;
|
|
||||||
|
|
||||||
buffered->writebuf_pos += bytes_to_copy;
|
|
||||||
buffered->writebuf_hits += 1;
|
|
||||||
if (buffered->writebuf_pos > buffered->writebuf_len)
|
|
||||||
buffered->writebuf_len += buffered->writebuf_pos - buffered->writebuf_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size - bytes_left_to_write;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_buffered_tell(void *stream) {
|
|
||||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
||||||
int64_t position = mz_stream_tell(buffered->stream.base);
|
|
||||||
|
|
||||||
buffered->position = position;
|
|
||||||
|
|
||||||
mz_stream_buffered_print("Buffered - Tell (pos %" PRId64 " readpos %" PRId32 " writepos %" PRId32 ")\n",
|
|
||||||
buffered->position, buffered->readbuf_pos, buffered->writebuf_pos);
|
|
||||||
|
|
||||||
if (buffered->readbuf_len > 0)
|
|
||||||
position -= ((int64_t)buffered->readbuf_len - buffered->readbuf_pos);
|
|
||||||
if (buffered->writebuf_len > 0)
|
|
||||||
position += buffered->writebuf_pos;
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_buffered_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
||||||
int32_t bytes_flushed = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
mz_stream_buffered_print("Buffered - Seek (origin %" PRId32 " offset %" PRId64 " pos %" PRId64 ")\n",
|
|
||||||
origin, offset, buffered->position);
|
|
||||||
|
|
||||||
switch (origin) {
|
|
||||||
case MZ_SEEK_SET:
|
|
||||||
|
|
||||||
if ((buffered->readbuf_len > 0) && (offset < buffered->position) &&
|
|
||||||
(offset >= buffered->position - buffered->readbuf_len)) {
|
|
||||||
buffered->readbuf_pos = (int32_t)(offset - (buffered->position - buffered->readbuf_len));
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
if (buffered->writebuf_len > 0) {
|
|
||||||
if ((offset >= buffered->position) && (offset <= buffered->position + buffered->writebuf_len)) {
|
|
||||||
buffered->writebuf_pos = (int32_t)(offset - buffered->position);
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mz_stream_buffered_flush(stream, &bytes_flushed);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
buffered->position = offset;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MZ_SEEK_CUR:
|
|
||||||
|
|
||||||
if (buffered->readbuf_len > 0) {
|
|
||||||
if (offset <= ((int64_t)buffered->readbuf_len - buffered->readbuf_pos)) {
|
|
||||||
buffered->readbuf_pos += (uint32_t)offset;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
offset -= ((int64_t)buffered->readbuf_len - buffered->readbuf_pos);
|
|
||||||
buffered->position += offset;
|
|
||||||
}
|
|
||||||
if (buffered->writebuf_len > 0) {
|
|
||||||
if (offset <= ((int64_t)buffered->writebuf_len - buffered->writebuf_pos)) {
|
|
||||||
buffered->writebuf_pos += (uint32_t)offset;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
/* offset -= (buffered->writebuf_len - buffered->writebuf_pos); */
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mz_stream_buffered_flush(stream, &bytes_flushed);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MZ_SEEK_END:
|
|
||||||
|
|
||||||
if (buffered->writebuf_len > 0) {
|
|
||||||
buffered->writebuf_pos = buffered->writebuf_len;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffered->readbuf_len = 0;
|
|
||||||
buffered->readbuf_pos = 0;
|
|
||||||
buffered->writebuf_len = 0;
|
|
||||||
buffered->writebuf_pos = 0;
|
|
||||||
|
|
||||||
return mz_stream_seek(buffered->stream.base, offset, origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_buffered_close(void *stream) {
|
|
||||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
||||||
int32_t bytes_flushed = 0;
|
|
||||||
|
|
||||||
mz_stream_buffered_flush(stream, &bytes_flushed);
|
|
||||||
mz_stream_buffered_print("Buffered - Close (flushed %" PRId32 ")\n", bytes_flushed);
|
|
||||||
|
|
||||||
if (buffered->readbuf_hits + buffered->readbuf_misses > 0) {
|
|
||||||
mz_stream_buffered_print("Buffered - Read efficiency %.02f%%\n",
|
|
||||||
(buffered->readbuf_hits / ((float)buffered->readbuf_hits + buffered->readbuf_misses)) * 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffered->writebuf_hits + buffered->writebuf_misses > 0) {
|
|
||||||
mz_stream_buffered_print("Buffered - Write efficiency %.02f%%\n",
|
|
||||||
(buffered->writebuf_hits / ((float)buffered->writebuf_hits + buffered->writebuf_misses)) * 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_stream_buffered_reset(buffered);
|
|
||||||
|
|
||||||
return mz_stream_close(buffered->stream.base);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_buffered_error(void *stream) {
|
|
||||||
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
||||||
return mz_stream_error(buffered->stream.base);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_buffered_create(void **stream) {
|
|
||||||
mz_stream_buffered *buffered = NULL;
|
|
||||||
|
|
||||||
buffered = (mz_stream_buffered *)MZ_ALLOC(sizeof(mz_stream_buffered));
|
|
||||||
if (buffered != NULL) {
|
|
||||||
memset(buffered, 0, sizeof(mz_stream_buffered));
|
|
||||||
buffered->stream.vtbl = &mz_stream_buffered_vtbl;
|
|
||||||
}
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = buffered;
|
|
||||||
|
|
||||||
return buffered;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_buffered_delete(void **stream) {
|
|
||||||
mz_stream_buffered *buffered = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
buffered = (mz_stream_buffered *)*stream;
|
|
||||||
if (buffered != NULL)
|
|
||||||
MZ_FREE(buffered);
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_buffered_get_interface(void) {
|
|
||||||
return (void *)&mz_stream_buffered_vtbl;
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
/* mz_strm_buf.h -- Stream for buffering reads/writes
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
This version of ioapi is designed to buffer IO.
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_STREAM_BUFFERED_H
|
|
||||||
#define MZ_STREAM_BUFFERED_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_buffered_open(void *stream, const char *path, int32_t mode);
|
|
||||||
int32_t mz_stream_buffered_is_open(void *stream);
|
|
||||||
int32_t mz_stream_buffered_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_buffered_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int64_t mz_stream_buffered_tell(void *stream);
|
|
||||||
int32_t mz_stream_buffered_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_buffered_close(void *stream);
|
|
||||||
int32_t mz_stream_buffered_error(void *stream);
|
|
||||||
|
|
||||||
void* mz_stream_buffered_create(void **stream);
|
|
||||||
void mz_stream_buffered_delete(void **stream);
|
|
||||||
|
|
||||||
void* mz_stream_buffered_get_interface(void);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,374 +0,0 @@
|
||||||
/* mz_strm_bzip.c -- Stream for bzip inflate/deflate
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_bzip.h"
|
|
||||||
|
|
||||||
#include "bzlib.h"
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_bzip_vtbl = {
|
|
||||||
mz_stream_bzip_open,
|
|
||||||
mz_stream_bzip_is_open,
|
|
||||||
mz_stream_bzip_read,
|
|
||||||
mz_stream_bzip_write,
|
|
||||||
mz_stream_bzip_tell,
|
|
||||||
mz_stream_bzip_seek,
|
|
||||||
mz_stream_bzip_close,
|
|
||||||
mz_stream_bzip_error,
|
|
||||||
mz_stream_bzip_create,
|
|
||||||
mz_stream_bzip_delete,
|
|
||||||
mz_stream_bzip_get_prop_int64,
|
|
||||||
mz_stream_bzip_set_prop_int64
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_bzip_s {
|
|
||||||
mz_stream stream;
|
|
||||||
bz_stream bzstream;
|
|
||||||
int32_t mode;
|
|
||||||
int32_t error;
|
|
||||||
uint8_t buffer[INT16_MAX];
|
|
||||||
int32_t buffer_len;
|
|
||||||
int16_t stream_end;
|
|
||||||
int64_t total_in;
|
|
||||||
int64_t total_out;
|
|
||||||
int64_t max_total_in;
|
|
||||||
int8_t initialized;
|
|
||||||
int16_t level;
|
|
||||||
} mz_stream_bzip;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_bzip_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
|
||||||
|
|
||||||
MZ_UNUSED(path);
|
|
||||||
|
|
||||||
bzip->bzstream.bzalloc = 0;
|
|
||||||
bzip->bzstream.bzfree = 0;
|
|
||||||
bzip->bzstream.opaque = 0;
|
|
||||||
bzip->bzstream.total_in_lo32 = 0;
|
|
||||||
bzip->bzstream.total_in_hi32 = 0;
|
|
||||||
bzip->bzstream.total_out_lo32 = 0;
|
|
||||||
bzip->bzstream.total_out_hi32 = 0;
|
|
||||||
|
|
||||||
bzip->total_in = 0;
|
|
||||||
bzip->total_out = 0;
|
|
||||||
|
|
||||||
if (mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
bzip->bzstream.next_out = (char *)bzip->buffer;
|
|
||||||
bzip->bzstream.avail_out = sizeof(bzip->buffer);
|
|
||||||
|
|
||||||
bzip->error = BZ2_bzCompressInit(&bzip->bzstream, bzip->level, 0, 0);
|
|
||||||
#endif
|
|
||||||
} else if (mode & MZ_OPEN_MODE_READ) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
bzip->bzstream.next_in = (char *)bzip->buffer;
|
|
||||||
bzip->bzstream.avail_in = 0;
|
|
||||||
|
|
||||||
bzip->error = BZ2_bzDecompressInit(&bzip->bzstream, 0, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bzip->error != BZ_OK)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
|
|
||||||
bzip->initialized = 1;
|
|
||||||
bzip->stream_end = 0;
|
|
||||||
bzip->mode = mode;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_bzip_is_open(void *stream) {
|
|
||||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
|
||||||
if (bzip->initialized != 1)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_bzip_read(void *stream, void *buf, int32_t size) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(buf);
|
|
||||||
MZ_UNUSED(size);
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
|
||||||
uint64_t total_in_before = 0;
|
|
||||||
uint64_t total_out_before = 0;
|
|
||||||
uint64_t total_in_after = 0;
|
|
||||||
uint64_t total_out_after = 0;
|
|
||||||
int32_t total_in = 0;
|
|
||||||
int32_t total_out = 0;
|
|
||||||
int32_t in_bytes = 0;
|
|
||||||
int32_t out_bytes = 0;
|
|
||||||
int32_t bytes_to_read = sizeof(bzip->buffer);
|
|
||||||
int32_t read = 0;
|
|
||||||
int32_t err = BZ_OK;
|
|
||||||
|
|
||||||
|
|
||||||
if (bzip->stream_end)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
bzip->bzstream.next_out = (char *)buf;
|
|
||||||
bzip->bzstream.avail_out = (unsigned int)size;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (bzip->bzstream.avail_in == 0) {
|
|
||||||
if (bzip->max_total_in > 0) {
|
|
||||||
if ((int64_t)bytes_to_read > (bzip->max_total_in - bzip->total_in))
|
|
||||||
bytes_to_read = (int32_t)(bzip->max_total_in - bzip->total_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
read = mz_stream_read(bzip->stream.base, bzip->buffer, bytes_to_read);
|
|
||||||
|
|
||||||
if (read < 0)
|
|
||||||
return read;
|
|
||||||
|
|
||||||
bzip->bzstream.next_in = (char *)bzip->buffer;
|
|
||||||
bzip->bzstream.avail_in = (uint32_t)read;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_in_before = bzip->bzstream.avail_in;
|
|
||||||
total_out_before = bzip->bzstream.total_out_lo32 +
|
|
||||||
(((uint64_t)bzip->bzstream.total_out_hi32) << 32);
|
|
||||||
|
|
||||||
err = BZ2_bzDecompress(&bzip->bzstream);
|
|
||||||
|
|
||||||
total_in_after = bzip->bzstream.avail_in;
|
|
||||||
total_out_after = bzip->bzstream.total_out_lo32 +
|
|
||||||
(((uint64_t)bzip->bzstream.total_out_hi32) << 32);
|
|
||||||
|
|
||||||
in_bytes = (int32_t)(total_in_before - total_in_after);
|
|
||||||
out_bytes = (int32_t)(total_out_after - total_out_before);
|
|
||||||
|
|
||||||
total_in += in_bytes;
|
|
||||||
total_out += out_bytes;
|
|
||||||
|
|
||||||
bzip->total_in += in_bytes;
|
|
||||||
bzip->total_out += out_bytes;
|
|
||||||
|
|
||||||
if (err == BZ_STREAM_END) {
|
|
||||||
bzip->stream_end = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (err != BZ_OK && err != BZ_RUN_OK) {
|
|
||||||
bzip->error = err;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (bzip->bzstream.avail_out > 0);
|
|
||||||
|
|
||||||
if (bzip->error != 0)
|
|
||||||
return MZ_DATA_ERROR;
|
|
||||||
|
|
||||||
return total_out;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef MZ_ZIP_NO_COMPRESSION
|
|
||||||
static int32_t mz_stream_bzip_flush(void *stream) {
|
|
||||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
|
||||||
if (mz_stream_write(bzip->stream.base, bzip->buffer, bzip->buffer_len) != bzip->buffer_len)
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_bzip_compress(void *stream, int flush) {
|
|
||||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
|
||||||
uint64_t total_out_before = 0;
|
|
||||||
uint64_t total_out_after = 0;
|
|
||||||
uint32_t out_bytes = 0;
|
|
||||||
int32_t err = BZ_OK;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (bzip->bzstream.avail_out == 0) {
|
|
||||||
err = mz_stream_bzip_flush(bzip);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
bzip->bzstream.avail_out = sizeof(bzip->buffer);
|
|
||||||
bzip->bzstream.next_out = (char *)bzip->buffer;
|
|
||||||
|
|
||||||
bzip->buffer_len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_out_before = bzip->bzstream.total_out_lo32 +
|
|
||||||
(((uint64_t)bzip->bzstream.total_out_hi32) << 32);
|
|
||||||
|
|
||||||
err = BZ2_bzCompress(&bzip->bzstream, flush);
|
|
||||||
|
|
||||||
total_out_after = bzip->bzstream.total_out_lo32 +
|
|
||||||
(((uint64_t)bzip->bzstream.total_out_hi32) << 32);
|
|
||||||
|
|
||||||
out_bytes = (uint32_t)(total_out_after - total_out_before);
|
|
||||||
|
|
||||||
bzip->buffer_len += out_bytes;
|
|
||||||
bzip->total_out += out_bytes;
|
|
||||||
|
|
||||||
if (err == BZ_STREAM_END)
|
|
||||||
break;
|
|
||||||
if (err < 0) {
|
|
||||||
bzip->error = err;
|
|
||||||
return MZ_DATA_ERROR;
|
|
||||||
}
|
|
||||||
} while ((bzip->bzstream.avail_in > 0) || (flush == BZ_FINISH && err == BZ_FINISH_OK));
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int32_t mz_stream_bzip_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(buf);
|
|
||||||
MZ_UNUSED(size);
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
bzip->bzstream.next_in = (char *)(intptr_t)buf;
|
|
||||||
bzip->bzstream.avail_in = (unsigned int)size;
|
|
||||||
|
|
||||||
err = mz_stream_bzip_compress(stream, BZ_RUN);
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
bzip->total_in += size;
|
|
||||||
return size;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_bzip_tell(void *stream) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
|
|
||||||
return MZ_TELL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_bzip_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(offset);
|
|
||||||
MZ_UNUSED(origin);
|
|
||||||
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_bzip_close(void *stream) {
|
|
||||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
|
||||||
|
|
||||||
if (bzip->mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_bzip_compress(stream, BZ_FINISH);
|
|
||||||
mz_stream_bzip_flush(stream);
|
|
||||||
|
|
||||||
BZ2_bzCompressEnd(&bzip->bzstream);
|
|
||||||
#endif
|
|
||||||
} else if (bzip->mode & MZ_OPEN_MODE_READ) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
BZ2_bzDecompressEnd(&bzip->bzstream);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bzip->initialized = 0;
|
|
||||||
|
|
||||||
if (bzip->error != BZ_OK)
|
|
||||||
return MZ_CLOSE_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_bzip_error(void *stream) {
|
|
||||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
|
||||||
return bzip->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_bzip_get_prop_int64(void *stream, int32_t prop, int64_t *value) {
|
|
||||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN:
|
|
||||||
*value = bzip->total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
*value = bzip->max_total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
|
||||||
*value = bzip->total_out;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_HEADER_SIZE:
|
|
||||||
*value = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_bzip_set_prop_int64(void *stream, int32_t prop, int64_t value) {
|
|
||||||
mz_stream_bzip *bzip = (mz_stream_bzip *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_COMPRESS_LEVEL:
|
|
||||||
if (value < 0)
|
|
||||||
bzip->level = 6;
|
|
||||||
else
|
|
||||||
bzip->level = (int16_t)value;
|
|
||||||
return MZ_OK;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
bzip->max_total_in = value;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_bzip_create(void **stream) {
|
|
||||||
mz_stream_bzip *bzip = NULL;
|
|
||||||
|
|
||||||
bzip = (mz_stream_bzip *)MZ_ALLOC(sizeof(mz_stream_bzip));
|
|
||||||
if (bzip != NULL) {
|
|
||||||
memset(bzip, 0, sizeof(mz_stream_bzip));
|
|
||||||
bzip->stream.vtbl = &mz_stream_bzip_vtbl;
|
|
||||||
bzip->level = 6;
|
|
||||||
}
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = bzip;
|
|
||||||
|
|
||||||
return bzip;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_bzip_delete(void **stream) {
|
|
||||||
mz_stream_bzip *bzip = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
bzip = (mz_stream_bzip *)*stream;
|
|
||||||
if (bzip != NULL)
|
|
||||||
MZ_FREE(bzip);
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_bzip_get_interface(void) {
|
|
||||||
return (void *)&mz_stream_bzip_vtbl;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void bz_internal_error(int errcode) {
|
|
||||||
MZ_UNUSED(errcode);
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
/* mz_strm_bzip.h -- Stream for bzip inflate/deflate
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_STREAM_BZIP_H
|
|
||||||
#define MZ_STREAM_BZIP_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_bzip_open(void *stream, const char *filename, int32_t mode);
|
|
||||||
int32_t mz_stream_bzip_is_open(void *stream);
|
|
||||||
int32_t mz_stream_bzip_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_bzip_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int64_t mz_stream_bzip_tell(void *stream);
|
|
||||||
int32_t mz_stream_bzip_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_bzip_close(void *stream);
|
|
||||||
int32_t mz_stream_bzip_error(void *stream);
|
|
||||||
|
|
||||||
int32_t mz_stream_bzip_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
|
||||||
int32_t mz_stream_bzip_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
|
||||||
|
|
||||||
void* mz_stream_bzip_create(void **stream);
|
|
||||||
void mz_stream_bzip_delete(void **stream);
|
|
||||||
|
|
||||||
void* mz_stream_bzip_get_interface(void);
|
|
||||||
|
|
||||||
void bz_internal_error(int errcode);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,356 +0,0 @@
|
||||||
/* mz_strm_libcomp.c -- Stream for apple compression
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_libcomp.h"
|
|
||||||
|
|
||||||
#include <compression.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_libcomp_vtbl = {
|
|
||||||
mz_stream_libcomp_open,
|
|
||||||
mz_stream_libcomp_is_open,
|
|
||||||
mz_stream_libcomp_read,
|
|
||||||
mz_stream_libcomp_write,
|
|
||||||
mz_stream_libcomp_tell,
|
|
||||||
mz_stream_libcomp_seek,
|
|
||||||
mz_stream_libcomp_close,
|
|
||||||
mz_stream_libcomp_error,
|
|
||||||
mz_stream_libcomp_create,
|
|
||||||
mz_stream_libcomp_delete,
|
|
||||||
mz_stream_libcomp_get_prop_int64,
|
|
||||||
mz_stream_libcomp_set_prop_int64
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_libcomp_s {
|
|
||||||
mz_stream stream;
|
|
||||||
compression_stream
|
|
||||||
cstream;
|
|
||||||
uint8_t buffer[INT16_MAX];
|
|
||||||
int32_t buffer_len;
|
|
||||||
int64_t total_in;
|
|
||||||
int64_t total_out;
|
|
||||||
int64_t max_total_in;
|
|
||||||
int8_t initialized;
|
|
||||||
int32_t mode;
|
|
||||||
int32_t error;
|
|
||||||
int16_t method;
|
|
||||||
} mz_stream_libcomp;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_libcomp_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
|
||||||
int32_t err = 0;
|
|
||||||
int16_t operation = 0;
|
|
||||||
compression_algorithm algorithm = 0;
|
|
||||||
|
|
||||||
MZ_UNUSED(path);
|
|
||||||
|
|
||||||
if (libcomp->method == 0)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
libcomp->total_in = 0;
|
|
||||||
libcomp->total_out = 0;
|
|
||||||
|
|
||||||
if (mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
operation = COMPRESSION_STREAM_ENCODE;
|
|
||||||
#endif
|
|
||||||
} else if (mode & MZ_OPEN_MODE_READ) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
operation = COMPRESSION_STREAM_DECODE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (libcomp->method == MZ_COMPRESS_METHOD_DEFLATE)
|
|
||||||
algorithm = COMPRESSION_ZLIB;
|
|
||||||
else if (libcomp->method == MZ_COMPRESS_METHOD_XZ)
|
|
||||||
algorithm = COMPRESSION_LZMA;
|
|
||||||
else
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
|
|
||||||
err = compression_stream_init(&libcomp->cstream, (compression_stream_operation)operation, algorithm);
|
|
||||||
|
|
||||||
if (err == COMPRESSION_STATUS_ERROR) {
|
|
||||||
libcomp->error = err;
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
libcomp->initialized = 1;
|
|
||||||
libcomp->mode = mode;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_libcomp_is_open(void *stream) {
|
|
||||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
|
||||||
if (libcomp->initialized != 1)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_libcomp_read(void *stream, void *buf, int32_t size) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(buf);
|
|
||||||
MZ_UNUSED(size);
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
|
||||||
uint64_t total_in_before = 0;
|
|
||||||
uint64_t total_in_after = 0;
|
|
||||||
uint64_t total_out_before = 0;
|
|
||||||
uint64_t total_out_after = 0;
|
|
||||||
int32_t total_in = 0;
|
|
||||||
int32_t total_out = 0;
|
|
||||||
int32_t in_bytes = 0;
|
|
||||||
int32_t out_bytes = 0;
|
|
||||||
int32_t bytes_to_read = sizeof(libcomp->buffer);
|
|
||||||
int32_t read = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
int16_t flags = 0;
|
|
||||||
|
|
||||||
libcomp->cstream.dst_ptr = buf;
|
|
||||||
libcomp->cstream.dst_size = (size_t)size;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (libcomp->cstream.src_size == 0) {
|
|
||||||
if (libcomp->max_total_in > 0) {
|
|
||||||
if ((int64_t)bytes_to_read > (libcomp->max_total_in - libcomp->total_in))
|
|
||||||
bytes_to_read = (int32_t)(libcomp->max_total_in - libcomp->total_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
read = mz_stream_read(libcomp->stream.base, libcomp->buffer, bytes_to_read);
|
|
||||||
|
|
||||||
if (read < 0)
|
|
||||||
return read;
|
|
||||||
if (read == 0)
|
|
||||||
flags = COMPRESSION_STREAM_FINALIZE;
|
|
||||||
|
|
||||||
libcomp->cstream.src_ptr = libcomp->buffer;
|
|
||||||
libcomp->cstream.src_size = (size_t)read;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_in_before = libcomp->cstream.src_size;
|
|
||||||
total_out_before = libcomp->cstream.dst_size;
|
|
||||||
|
|
||||||
err = compression_stream_process(&libcomp->cstream, flags);
|
|
||||||
if (err == COMPRESSION_STATUS_ERROR) {
|
|
||||||
libcomp->error = err;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_in_after = libcomp->cstream.src_size;
|
|
||||||
total_out_after = libcomp->cstream.dst_size;
|
|
||||||
|
|
||||||
in_bytes = (int32_t)(total_in_before - total_in_after);
|
|
||||||
out_bytes = (int32_t)(total_out_before - total_out_after);
|
|
||||||
|
|
||||||
total_in += in_bytes;
|
|
||||||
total_out += out_bytes;
|
|
||||||
|
|
||||||
libcomp->total_in += in_bytes;
|
|
||||||
libcomp->total_out += out_bytes;
|
|
||||||
|
|
||||||
if (err == COMPRESSION_STATUS_END)
|
|
||||||
break;
|
|
||||||
if (err != COMPRESSION_STATUS_OK) {
|
|
||||||
libcomp->error = err;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (libcomp->cstream.dst_size > 0);
|
|
||||||
|
|
||||||
if (libcomp->error != 0)
|
|
||||||
return MZ_DATA_ERROR;
|
|
||||||
|
|
||||||
return total_out;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_libcomp_flush(void *stream) {
|
|
||||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
|
||||||
if (mz_stream_write(libcomp->stream.base, libcomp->buffer, libcomp->buffer_len) != libcomp->buffer_len)
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_libcomp_deflate(void *stream, int flush) {
|
|
||||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
|
||||||
uint64_t total_out_before = 0;
|
|
||||||
uint64_t total_out_after = 0;
|
|
||||||
uint32_t out_bytes = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (libcomp->cstream.dst_size == 0) {
|
|
||||||
err = mz_stream_libcomp_flush(libcomp);
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
libcomp->error = err;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
libcomp->cstream.dst_size = sizeof(libcomp->buffer);
|
|
||||||
libcomp->cstream.dst_ptr = libcomp->buffer;
|
|
||||||
|
|
||||||
libcomp->buffer_len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_out_before = libcomp->cstream.dst_size;
|
|
||||||
err = compression_stream_process(&libcomp->cstream, flush);
|
|
||||||
total_out_after = libcomp->cstream.dst_size;
|
|
||||||
|
|
||||||
out_bytes = (uint32_t)(total_out_before - total_out_after);
|
|
||||||
|
|
||||||
libcomp->buffer_len += out_bytes;
|
|
||||||
libcomp->total_out += out_bytes;
|
|
||||||
|
|
||||||
if (err == COMPRESSION_STATUS_END)
|
|
||||||
break;
|
|
||||||
if (err != COMPRESSION_STATUS_OK) {
|
|
||||||
libcomp->error = err;
|
|
||||||
return MZ_DATA_ERROR;
|
|
||||||
}
|
|
||||||
} while ((libcomp->cstream.src_size > 0) || (flush == COMPRESSION_STREAM_FINALIZE && err == COMPRESSION_STATUS_OK));
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_libcomp_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
|
||||||
int32_t err = size;
|
|
||||||
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
MZ_UNUSED(libcomp);
|
|
||||||
err = MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
libcomp->cstream.src_ptr = buf;
|
|
||||||
libcomp->cstream.src_size = (size_t)size;
|
|
||||||
|
|
||||||
mz_stream_libcomp_deflate(stream, 0);
|
|
||||||
|
|
||||||
libcomp->total_in += size;
|
|
||||||
#endif
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_libcomp_tell(void *stream) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
|
|
||||||
return MZ_TELL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_libcomp_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(offset);
|
|
||||||
MZ_UNUSED(origin);
|
|
||||||
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_libcomp_close(void *stream) {
|
|
||||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
|
||||||
|
|
||||||
|
|
||||||
if (libcomp->mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_libcomp_deflate(stream, COMPRESSION_STREAM_FINALIZE);
|
|
||||||
mz_stream_libcomp_flush(stream);
|
|
||||||
#endif
|
|
||||||
} else if (libcomp->mode & MZ_OPEN_MODE_READ) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
compression_stream_destroy(&libcomp->cstream);
|
|
||||||
|
|
||||||
libcomp->initialized = 0;
|
|
||||||
|
|
||||||
if (libcomp->error != MZ_OK)
|
|
||||||
return MZ_CLOSE_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_libcomp_error(void *stream) {
|
|
||||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
|
||||||
return libcomp->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_libcomp_get_prop_int64(void *stream, int32_t prop, int64_t *value) {
|
|
||||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN:
|
|
||||||
*value = libcomp->total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
*value = libcomp->max_total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
|
||||||
*value = libcomp->total_out;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_HEADER_SIZE:
|
|
||||||
*value = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_libcomp_set_prop_int64(void *stream, int32_t prop, int64_t value) {
|
|
||||||
mz_stream_libcomp *libcomp = (mz_stream_libcomp *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_COMPRESS_METHOD:
|
|
||||||
libcomp->method = (int16_t)value;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
libcomp->max_total_in = value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_libcomp_create(void **stream) {
|
|
||||||
mz_stream_libcomp *libcomp = NULL;
|
|
||||||
|
|
||||||
libcomp = (mz_stream_libcomp *)MZ_ALLOC(sizeof(mz_stream_libcomp));
|
|
||||||
if (libcomp != NULL) {
|
|
||||||
memset(libcomp, 0, sizeof(mz_stream_libcomp));
|
|
||||||
libcomp->stream.vtbl = &mz_stream_libcomp_vtbl;
|
|
||||||
}
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = libcomp;
|
|
||||||
|
|
||||||
return libcomp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_libcomp_delete(void **stream) {
|
|
||||||
mz_stream_libcomp *libcomp = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
libcomp = (mz_stream_libcomp *)*stream;
|
|
||||||
if (libcomp != NULL)
|
|
||||||
MZ_FREE(libcomp);
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
/* mz_strm_libcomp.h -- Stream for apple compression
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_STREAM_LIBCOMP_H
|
|
||||||
#define MZ_STREAM_LIBCOMP_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_libcomp_open(void *stream, const char *filename, int32_t mode);
|
|
||||||
int32_t mz_stream_libcomp_is_open(void *stream);
|
|
||||||
int32_t mz_stream_libcomp_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_libcomp_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int64_t mz_stream_libcomp_tell(void *stream);
|
|
||||||
int32_t mz_stream_libcomp_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_libcomp_close(void *stream);
|
|
||||||
int32_t mz_stream_libcomp_error(void *stream);
|
|
||||||
|
|
||||||
int32_t mz_stream_libcomp_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
|
||||||
int32_t mz_stream_libcomp_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
|
||||||
|
|
||||||
void* mz_stream_libcomp_create(void **stream);
|
|
||||||
void mz_stream_libcomp_delete(void **stream);
|
|
||||||
|
|
||||||
void* mz_stream_libcomp_get_interface(void);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,470 +0,0 @@
|
||||||
/* mz_strm_lzma.c -- Stream for lzma inflate/deflate
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_lzma.h"
|
|
||||||
|
|
||||||
#include "lzma.h"
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#define MZ_LZMA_MAGIC_SIZE (4)
|
|
||||||
#define MZ_LZMA_ZIP_HEADER_SIZE (5)
|
|
||||||
#define MZ_LZMA_ALONE_HEADER_SIZE (MZ_LZMA_ZIP_HEADER_SIZE + 8)
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_lzma_vtbl = {
|
|
||||||
mz_stream_lzma_open,
|
|
||||||
mz_stream_lzma_is_open,
|
|
||||||
mz_stream_lzma_read,
|
|
||||||
mz_stream_lzma_write,
|
|
||||||
mz_stream_lzma_tell,
|
|
||||||
mz_stream_lzma_seek,
|
|
||||||
mz_stream_lzma_close,
|
|
||||||
mz_stream_lzma_error,
|
|
||||||
mz_stream_lzma_create,
|
|
||||||
mz_stream_lzma_delete,
|
|
||||||
mz_stream_lzma_get_prop_int64,
|
|
||||||
mz_stream_lzma_set_prop_int64
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_lzma_s {
|
|
||||||
mz_stream stream;
|
|
||||||
lzma_stream lstream;
|
|
||||||
int32_t mode;
|
|
||||||
int32_t error;
|
|
||||||
uint8_t buffer[INT16_MAX];
|
|
||||||
int32_t buffer_len;
|
|
||||||
int64_t total_in;
|
|
||||||
int64_t total_out;
|
|
||||||
int64_t max_total_in;
|
|
||||||
int64_t max_total_out;
|
|
||||||
int8_t initialized;
|
|
||||||
int8_t header;
|
|
||||||
int32_t header_size;
|
|
||||||
uint32_t preset;
|
|
||||||
int16_t method;
|
|
||||||
} mz_stream_lzma;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_lzma_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
|
||||||
lzma_filter filters[LZMA_FILTERS_MAX + 1];
|
|
||||||
lzma_options_lzma opt_lzma;
|
|
||||||
uint32_t size = 0;
|
|
||||||
uint8_t major = 0;
|
|
||||||
uint8_t minor = 0;
|
|
||||||
|
|
||||||
MZ_UNUSED(path);
|
|
||||||
|
|
||||||
memset(&opt_lzma, 0, sizeof(opt_lzma));
|
|
||||||
|
|
||||||
lzma->lstream.total_in = 0;
|
|
||||||
lzma->lstream.total_out = 0;
|
|
||||||
|
|
||||||
lzma->total_in = 0;
|
|
||||||
lzma->total_out = 0;
|
|
||||||
lzma->header = 0;
|
|
||||||
|
|
||||||
if (mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
MZ_UNUSED(filters);
|
|
||||||
MZ_UNUSED(major);
|
|
||||||
MZ_UNUSED(minor);
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
lzma->lstream.next_out = lzma->buffer;
|
|
||||||
lzma->lstream.avail_out = sizeof(lzma->buffer);
|
|
||||||
|
|
||||||
if (lzma_lzma_preset(&opt_lzma, lzma->preset))
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
|
|
||||||
memset(&filters, 0, sizeof(filters));
|
|
||||||
|
|
||||||
if (lzma->method == MZ_COMPRESS_METHOD_LZMA)
|
|
||||||
filters[0].id = LZMA_FILTER_LZMA1;
|
|
||||||
else if (lzma->method == MZ_COMPRESS_METHOD_XZ)
|
|
||||||
filters[0].id = LZMA_FILTER_LZMA2;
|
|
||||||
|
|
||||||
filters[0].options = &opt_lzma;
|
|
||||||
filters[1].id = LZMA_VLI_UNKNOWN;
|
|
||||||
|
|
||||||
lzma_properties_size(&size, (lzma_filter *)&filters);
|
|
||||||
|
|
||||||
if (lzma->method == MZ_COMPRESS_METHOD_LZMA) {
|
|
||||||
mz_stream_write_uint8(lzma->stream.base, LZMA_VERSION_MAJOR);
|
|
||||||
mz_stream_write_uint8(lzma->stream.base, LZMA_VERSION_MINOR);
|
|
||||||
mz_stream_write_uint16(lzma->stream.base, (uint16_t)size);
|
|
||||||
|
|
||||||
lzma->header = 1;
|
|
||||||
lzma->total_out += MZ_LZMA_MAGIC_SIZE;
|
|
||||||
|
|
||||||
lzma->error = lzma_alone_encoder(&lzma->lstream, &opt_lzma);
|
|
||||||
} else if (lzma->method == MZ_COMPRESS_METHOD_XZ)
|
|
||||||
lzma->error = lzma_stream_encoder(&lzma->lstream, filters, LZMA_CHECK_CRC64);
|
|
||||||
#endif
|
|
||||||
} else if (mode & MZ_OPEN_MODE_READ) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
MZ_UNUSED(filters);
|
|
||||||
MZ_UNUSED(major);
|
|
||||||
MZ_UNUSED(minor);
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
lzma->lstream.next_in = lzma->buffer;
|
|
||||||
lzma->lstream.avail_in = 0;
|
|
||||||
|
|
||||||
if (lzma->method == MZ_COMPRESS_METHOD_LZMA) {
|
|
||||||
mz_stream_read_uint8(lzma->stream.base, &major);
|
|
||||||
mz_stream_read_uint8(lzma->stream.base, &minor);
|
|
||||||
mz_stream_read_uint16(lzma->stream.base, (uint16_t *)&size);
|
|
||||||
|
|
||||||
lzma->header = 1;
|
|
||||||
lzma->total_in += MZ_LZMA_MAGIC_SIZE;
|
|
||||||
|
|
||||||
lzma->error = lzma_alone_decoder(&lzma->lstream, UINT64_MAX);
|
|
||||||
} else if (lzma->method == MZ_COMPRESS_METHOD_XZ)
|
|
||||||
lzma->error = lzma_stream_decoder(&lzma->lstream, UINT64_MAX, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lzma->error != LZMA_OK)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
|
|
||||||
lzma->initialized = 1;
|
|
||||||
lzma->mode = mode;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_lzma_is_open(void *stream) {
|
|
||||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
|
||||||
if (lzma->initialized != 1)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_lzma_read(void *stream, void *buf, int32_t size) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(buf);
|
|
||||||
MZ_UNUSED(size);
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
|
||||||
uint64_t total_in_before = 0;
|
|
||||||
uint64_t total_out_before = 0;
|
|
||||||
uint64_t total_in_after = 0;
|
|
||||||
uint64_t total_out_after = 0;
|
|
||||||
int32_t total_in = 0;
|
|
||||||
int32_t total_out = 0;
|
|
||||||
int32_t in_bytes = 0;
|
|
||||||
int32_t out_bytes = 0;
|
|
||||||
int32_t bytes_to_read = sizeof(lzma->buffer);
|
|
||||||
int32_t read = 0;
|
|
||||||
int32_t err = LZMA_OK;
|
|
||||||
|
|
||||||
|
|
||||||
lzma->lstream.next_out = (uint8_t*)buf;
|
|
||||||
lzma->lstream.avail_out = (size_t)size;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (lzma->lstream.avail_in == 0) {
|
|
||||||
if (lzma->max_total_in > 0) {
|
|
||||||
if ((int64_t)bytes_to_read > (lzma->max_total_in - lzma->total_in))
|
|
||||||
bytes_to_read = (int32_t)(lzma->max_total_in - lzma->total_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lzma->header) {
|
|
||||||
bytes_to_read = MZ_LZMA_ZIP_HEADER_SIZE - lzma->header_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
read = mz_stream_read(lzma->stream.base, lzma->buffer, bytes_to_read);
|
|
||||||
|
|
||||||
if (read < 0)
|
|
||||||
return read;
|
|
||||||
|
|
||||||
/* Write uncompressed size for lzma alone header not in zip format */
|
|
||||||
if (lzma->header) {
|
|
||||||
lzma->header_size += read;
|
|
||||||
|
|
||||||
if (lzma->header_size == MZ_LZMA_ZIP_HEADER_SIZE) {
|
|
||||||
uint64_t uncompressed_size = UINT64_MAX;
|
|
||||||
|
|
||||||
memcpy(lzma->buffer + MZ_LZMA_ZIP_HEADER_SIZE, &uncompressed_size, sizeof(uncompressed_size));
|
|
||||||
|
|
||||||
read += sizeof(uncompressed_size);
|
|
||||||
bytes_to_read = sizeof(lzma->buffer);
|
|
||||||
|
|
||||||
lzma->total_in -= sizeof(uncompressed_size);
|
|
||||||
lzma->header = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lzma->lstream.next_in = lzma->buffer;
|
|
||||||
lzma->lstream.avail_in = (size_t)read;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_in_before = lzma->lstream.avail_in;
|
|
||||||
total_out_before = lzma->lstream.total_out;
|
|
||||||
|
|
||||||
err = lzma_code(&lzma->lstream, LZMA_RUN);
|
|
||||||
|
|
||||||
total_in_after = lzma->lstream.avail_in;
|
|
||||||
total_out_after = lzma->lstream.total_out;
|
|
||||||
if ((lzma->max_total_out != -1) && (int64_t)total_out_after > lzma->max_total_out)
|
|
||||||
total_out_after = (uint64_t)lzma->max_total_out;
|
|
||||||
|
|
||||||
in_bytes = (int32_t)(total_in_before - total_in_after);
|
|
||||||
out_bytes = (int32_t)(total_out_after - total_out_before);
|
|
||||||
|
|
||||||
total_in += in_bytes;
|
|
||||||
total_out += out_bytes;
|
|
||||||
|
|
||||||
lzma->total_in += in_bytes;
|
|
||||||
lzma->total_out += out_bytes;
|
|
||||||
|
|
||||||
if (err == LZMA_STREAM_END)
|
|
||||||
break;
|
|
||||||
if (err != LZMA_OK) {
|
|
||||||
lzma->error = err;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (lzma->lstream.avail_out > 0);
|
|
||||||
|
|
||||||
if (lzma->error != 0)
|
|
||||||
return MZ_DATA_ERROR;
|
|
||||||
|
|
||||||
return total_out;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef MZ_ZIP_NO_COMPRESSION
|
|
||||||
static int32_t mz_stream_lzma_flush(void *stream) {
|
|
||||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
|
||||||
int32_t buffer_len = lzma->buffer_len;
|
|
||||||
uint8_t *buffer = lzma->buffer;
|
|
||||||
|
|
||||||
/* Skip writing lzma_alone header uncompressed size for zip format */
|
|
||||||
if (lzma->header) {
|
|
||||||
uint64_t uncompressed_size = 0;
|
|
||||||
|
|
||||||
if (lzma->buffer_len < MZ_LZMA_ALONE_HEADER_SIZE)
|
|
||||||
return MZ_OK;
|
|
||||||
|
|
||||||
if (mz_stream_write(lzma->stream.base, buffer, MZ_LZMA_ZIP_HEADER_SIZE) != MZ_LZMA_ZIP_HEADER_SIZE)
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
|
|
||||||
buffer += MZ_LZMA_ALONE_HEADER_SIZE;
|
|
||||||
buffer_len -= MZ_LZMA_ALONE_HEADER_SIZE;
|
|
||||||
|
|
||||||
lzma->buffer_len -= sizeof(uncompressed_size);
|
|
||||||
lzma->total_out -= sizeof(uncompressed_size);
|
|
||||||
lzma->header = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mz_stream_write(lzma->stream.base, buffer, buffer_len) != buffer_len)
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_lzma_code(void *stream, int32_t flush) {
|
|
||||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
|
||||||
uint64_t total_out_before = 0;
|
|
||||||
uint64_t total_out_after = 0;
|
|
||||||
uint32_t out_bytes = 0;
|
|
||||||
int32_t err = LZMA_OK;
|
|
||||||
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (lzma->lstream.avail_out == 0) {
|
|
||||||
err = mz_stream_lzma_flush(lzma);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
lzma->lstream.avail_out = sizeof(lzma->buffer);
|
|
||||||
lzma->lstream.next_out = lzma->buffer;
|
|
||||||
|
|
||||||
lzma->buffer_len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_out_before = lzma->lstream.total_out;
|
|
||||||
err = lzma_code(&lzma->lstream, (lzma_action)flush);
|
|
||||||
total_out_after = lzma->lstream.total_out;
|
|
||||||
|
|
||||||
out_bytes = (uint32_t)(total_out_after - total_out_before);
|
|
||||||
|
|
||||||
if (err != LZMA_OK && err != LZMA_STREAM_END) {
|
|
||||||
lzma->error = err;
|
|
||||||
return MZ_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
lzma->buffer_len += out_bytes;
|
|
||||||
lzma->total_out += out_bytes;
|
|
||||||
} while ((lzma->lstream.avail_in > 0) || (flush == LZMA_FINISH && err == LZMA_OK));
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int32_t mz_stream_lzma_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(buf);
|
|
||||||
MZ_UNUSED(size);
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
lzma->lstream.next_in = (uint8_t*)(intptr_t)buf;
|
|
||||||
lzma->lstream.avail_in = (size_t)size;
|
|
||||||
|
|
||||||
err = mz_stream_lzma_code(stream, LZMA_RUN);
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
lzma->total_in += size;
|
|
||||||
return size;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_lzma_tell(void *stream) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
|
|
||||||
return MZ_TELL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_lzma_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(offset);
|
|
||||||
MZ_UNUSED(origin);
|
|
||||||
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_lzma_close(void *stream) {
|
|
||||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
|
||||||
|
|
||||||
if (lzma->mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_lzma_code(stream, LZMA_FINISH);
|
|
||||||
mz_stream_lzma_flush(stream);
|
|
||||||
|
|
||||||
lzma_end(&lzma->lstream);
|
|
||||||
#endif
|
|
||||||
} else if (lzma->mode & MZ_OPEN_MODE_READ) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
lzma_end(&lzma->lstream);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
lzma->initialized = 0;
|
|
||||||
|
|
||||||
if (lzma->error != LZMA_OK)
|
|
||||||
return MZ_CLOSE_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_lzma_error(void *stream) {
|
|
||||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
|
||||||
return lzma->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_lzma_get_prop_int64(void *stream, int32_t prop, int64_t *value) {
|
|
||||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN:
|
|
||||||
*value = lzma->total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
*value = lzma->max_total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
|
||||||
*value = lzma->total_out;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_OUT_MAX:
|
|
||||||
*value = lzma->max_total_out;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_HEADER_SIZE:
|
|
||||||
*value = MZ_LZMA_MAGIC_SIZE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_lzma_set_prop_int64(void *stream, int32_t prop, int64_t value) {
|
|
||||||
mz_stream_lzma *lzma = (mz_stream_lzma *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_COMPRESS_LEVEL:
|
|
||||||
if (value >= 9)
|
|
||||||
lzma->preset = LZMA_PRESET_EXTREME;
|
|
||||||
else
|
|
||||||
lzma->preset = LZMA_PRESET_DEFAULT;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_COMPRESS_METHOD:
|
|
||||||
lzma->method = (int16_t)value;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
lzma->max_total_in = value;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_OUT_MAX:
|
|
||||||
if (value < -1)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
lzma->max_total_out = value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_lzma_create(void **stream) {
|
|
||||||
mz_stream_lzma *lzma = NULL;
|
|
||||||
|
|
||||||
lzma = (mz_stream_lzma *)MZ_ALLOC(sizeof(mz_stream_lzma));
|
|
||||||
if (lzma != NULL) {
|
|
||||||
memset(lzma, 0, sizeof(mz_stream_lzma));
|
|
||||||
lzma->stream.vtbl = &mz_stream_lzma_vtbl;
|
|
||||||
lzma->method = MZ_COMPRESS_METHOD_LZMA;
|
|
||||||
lzma->preset = LZMA_PRESET_DEFAULT;
|
|
||||||
lzma->max_total_out = -1;
|
|
||||||
}
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = lzma;
|
|
||||||
|
|
||||||
return lzma;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_lzma_delete(void **stream) {
|
|
||||||
mz_stream_lzma *lzma = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
lzma = (mz_stream_lzma *)*stream;
|
|
||||||
if (lzma != NULL)
|
|
||||||
MZ_FREE(lzma);
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_lzma_get_interface(void) {
|
|
||||||
return (void *)&mz_stream_lzma_vtbl;
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/* mz_strm_lzma.h -- Stream for lzma inflate/deflate
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as lzma.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_STREAM_LZMA_H
|
|
||||||
#define MZ_STREAM_LZMA_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_lzma_open(void *stream, const char *filename, int32_t mode);
|
|
||||||
int32_t mz_stream_lzma_is_open(void *stream);
|
|
||||||
int32_t mz_stream_lzma_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_lzma_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int64_t mz_stream_lzma_tell(void *stream);
|
|
||||||
int32_t mz_stream_lzma_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_lzma_close(void *stream);
|
|
||||||
int32_t mz_stream_lzma_error(void *stream);
|
|
||||||
|
|
||||||
int32_t mz_stream_lzma_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
|
||||||
int32_t mz_stream_lzma_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
|
||||||
|
|
||||||
void* mz_stream_lzma_create(void **stream);
|
|
||||||
void mz_stream_lzma_delete(void **stream);
|
|
||||||
|
|
||||||
void* mz_stream_lzma_get_interface(void);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,272 +0,0 @@
|
||||||
/* mz_strm_mem.c -- Stream for memory access
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
This interface is designed to access memory rather than files.
|
|
||||||
We do use a region of memory to put data in to and take it out of.
|
|
||||||
|
|
||||||
Based on Unzip ioapi.c version 0.22, May 19th, 2003
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
Copyright (C) 2003 Justin Fletcher
|
|
||||||
Copyright (C) 1998-2003 Gilles Vollant
|
|
||||||
https://www.winimage.com/zLibDll/minizip.html
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_mem.h"
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_mem_vtbl = {
|
|
||||||
mz_stream_mem_open,
|
|
||||||
mz_stream_mem_is_open,
|
|
||||||
mz_stream_mem_read,
|
|
||||||
mz_stream_mem_write,
|
|
||||||
mz_stream_mem_tell,
|
|
||||||
mz_stream_mem_seek,
|
|
||||||
mz_stream_mem_close,
|
|
||||||
mz_stream_mem_error,
|
|
||||||
mz_stream_mem_create,
|
|
||||||
mz_stream_mem_delete,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_mem_s {
|
|
||||||
mz_stream stream;
|
|
||||||
int32_t mode;
|
|
||||||
uint8_t *buffer; /* Memory buffer pointer */
|
|
||||||
int32_t size; /* Size of the memory buffer */
|
|
||||||
int32_t limit; /* Furthest we've written */
|
|
||||||
int32_t position; /* Current position in the memory */
|
|
||||||
int32_t grow_size; /* Size to grow when full */
|
|
||||||
} mz_stream_mem;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static int32_t mz_stream_mem_set_size(void *stream, int32_t size) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
int32_t new_size = size;
|
|
||||||
uint8_t *new_buf = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
new_buf = (uint8_t *)MZ_ALLOC((uint32_t)new_size);
|
|
||||||
if (new_buf == NULL)
|
|
||||||
return MZ_BUF_ERROR;
|
|
||||||
|
|
||||||
if (mem->buffer) {
|
|
||||||
memcpy(new_buf, mem->buffer, mem->size);
|
|
||||||
MZ_FREE(mem->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
mem->buffer = new_buf;
|
|
||||||
mem->size = new_size;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_mem_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
MZ_UNUSED(path);
|
|
||||||
|
|
||||||
mem->mode = mode;
|
|
||||||
mem->limit = 0;
|
|
||||||
mem->position = 0;
|
|
||||||
|
|
||||||
if (mem->mode & MZ_OPEN_MODE_CREATE)
|
|
||||||
err = mz_stream_mem_set_size(stream, mem->grow_size);
|
|
||||||
else
|
|
||||||
mem->limit = mem->size;
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_mem_is_open(void *stream) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
if (mem->buffer == NULL)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_mem_read(void *stream, void *buf, int32_t size) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
|
|
||||||
if (size > mem->size - mem->position)
|
|
||||||
size = mem->size - mem->position;
|
|
||||||
if (mem->position + size > mem->limit)
|
|
||||||
size = mem->limit - mem->position;
|
|
||||||
|
|
||||||
if (size <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
memcpy(buf, mem->buffer + mem->position, size);
|
|
||||||
mem->position += size;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_mem_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
int32_t new_size = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
return size;
|
|
||||||
|
|
||||||
if (size > mem->size - mem->position) {
|
|
||||||
if (mem->mode & MZ_OPEN_MODE_CREATE) {
|
|
||||||
new_size = mem->size;
|
|
||||||
if (size < mem->grow_size)
|
|
||||||
new_size += mem->grow_size;
|
|
||||||
else
|
|
||||||
new_size += size;
|
|
||||||
|
|
||||||
err = mz_stream_mem_set_size(stream, new_size);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
} else {
|
|
||||||
size = mem->size - mem->position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(mem->buffer + mem->position, buf, size);
|
|
||||||
|
|
||||||
mem->position += size;
|
|
||||||
if (mem->position > mem->limit)
|
|
||||||
mem->limit = mem->position;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_mem_tell(void *stream) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
return mem->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_mem_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
int64_t new_pos = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
switch (origin) {
|
|
||||||
case MZ_SEEK_CUR:
|
|
||||||
new_pos = mem->position + offset;
|
|
||||||
break;
|
|
||||||
case MZ_SEEK_END:
|
|
||||||
new_pos = mem->limit + offset;
|
|
||||||
break;
|
|
||||||
case MZ_SEEK_SET:
|
|
||||||
new_pos = offset;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_pos > mem->size) {
|
|
||||||
if ((mem->mode & MZ_OPEN_MODE_CREATE) == 0)
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
|
|
||||||
err = mz_stream_mem_set_size(stream, (int32_t)new_pos);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
} else if (new_pos < 0) {
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
mem->position = (int32_t)new_pos;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_mem_close(void *stream) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
|
|
||||||
/* We never return errors */
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_mem_error(void *stream) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
|
|
||||||
/* We never return errors */
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_mem_set_buffer(void *stream, void *buf, int32_t size) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
mem->buffer = (uint8_t *)buf;
|
|
||||||
mem->size = size;
|
|
||||||
mem->limit = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_mem_get_buffer(void *stream, const void **buf) {
|
|
||||||
return mz_stream_mem_get_buffer_at(stream, 0, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_mem_get_buffer_at(void *stream, int64_t position, const void **buf) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
if (buf == NULL || position < 0 || mem->size < position || mem->buffer == NULL)
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
*buf = mem->buffer + position;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_mem_get_buffer_at_current(void *stream, const void **buf) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
return mz_stream_mem_get_buffer_at(stream, mem->position, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_mem_get_buffer_length(void *stream, int32_t *length) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
*length = mem->limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_mem_set_buffer_limit(void *stream, int32_t limit) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
mem->limit = limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_mem_set_grow_size(void *stream, int32_t grow_size) {
|
|
||||||
mz_stream_mem *mem = (mz_stream_mem *)stream;
|
|
||||||
mem->grow_size = grow_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_mem_create(void **stream) {
|
|
||||||
mz_stream_mem *mem = NULL;
|
|
||||||
|
|
||||||
mem = (mz_stream_mem *)MZ_ALLOC(sizeof(mz_stream_mem));
|
|
||||||
if (mem != NULL) {
|
|
||||||
memset(mem, 0, sizeof(mz_stream_mem));
|
|
||||||
mem->stream.vtbl = &mz_stream_mem_vtbl;
|
|
||||||
mem->grow_size = 4096;
|
|
||||||
}
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = mem;
|
|
||||||
|
|
||||||
return mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_mem_delete(void **stream) {
|
|
||||||
mz_stream_mem *mem = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
mem = (mz_stream_mem *)*stream;
|
|
||||||
if (mem != NULL) {
|
|
||||||
if ((mem->mode & MZ_OPEN_MODE_CREATE) && (mem->buffer != NULL))
|
|
||||||
MZ_FREE(mem->buffer);
|
|
||||||
MZ_FREE(mem);
|
|
||||||
}
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_mem_get_interface(void) {
|
|
||||||
return (void *)&mz_stream_mem_vtbl;
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
/* mz_strm_mem.h -- Stream for memory access
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_STREAM_MEM_H
|
|
||||||
#define MZ_STREAM_MEM_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_mem_open(void *stream, const char *filename, int32_t mode);
|
|
||||||
int32_t mz_stream_mem_is_open(void *stream);
|
|
||||||
int32_t mz_stream_mem_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_mem_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int64_t mz_stream_mem_tell(void *stream);
|
|
||||||
int32_t mz_stream_mem_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_mem_close(void *stream);
|
|
||||||
int32_t mz_stream_mem_error(void *stream);
|
|
||||||
|
|
||||||
void mz_stream_mem_set_buffer(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_mem_get_buffer(void *stream, const void **buf);
|
|
||||||
int32_t mz_stream_mem_get_buffer_at(void *stream, int64_t position, const void **buf);
|
|
||||||
int32_t mz_stream_mem_get_buffer_at_current(void *stream, const void **buf);
|
|
||||||
void mz_stream_mem_get_buffer_length(void *stream, int32_t *length);
|
|
||||||
void mz_stream_mem_set_buffer_limit(void *stream, int32_t limit);
|
|
||||||
void mz_stream_mem_set_grow_size(void *stream, int32_t grow_size);
|
|
||||||
|
|
||||||
void* mz_stream_mem_create(void **stream);
|
|
||||||
void mz_stream_mem_delete(void **stream);
|
|
||||||
|
|
||||||
void* mz_stream_mem_get_interface(void);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,40 +0,0 @@
|
||||||
/* mz_sstrm_os.h -- Stream for filesystem access
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_STREAM_OS_H
|
|
||||||
#define MZ_STREAM_OS_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_os_open(void *stream, const char *path, int32_t mode);
|
|
||||||
int32_t mz_stream_os_is_open(void *stream);
|
|
||||||
int32_t mz_stream_os_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_os_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int64_t mz_stream_os_tell(void *stream);
|
|
||||||
int32_t mz_stream_os_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_os_close(void *stream);
|
|
||||||
int32_t mz_stream_os_error(void *stream);
|
|
||||||
|
|
||||||
void* mz_stream_os_create(void **stream);
|
|
||||||
void mz_stream_os_delete(void **stream);
|
|
||||||
|
|
||||||
void* mz_stream_os_get_interface(void);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,206 +0,0 @@
|
||||||
/* mz_strm_posix.c -- Stream for filesystem access for posix/linux
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
Modifications for Zip64 support
|
|
||||||
Copyright (C) 2009-2010 Mathias Svensson
|
|
||||||
http://result42.com
|
|
||||||
Copyright (C) 1998-2010 Gilles Vollant
|
|
||||||
https://www.winimage.com/zLibDll/minizip.html
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_os.h"
|
|
||||||
|
|
||||||
#include <stdio.h> /* fopen, fread.. */
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#define fopen64 fopen
|
|
||||||
#ifndef MZ_FILE32_API
|
|
||||||
# ifndef NO_FSEEKO
|
|
||||||
# define ftello64 ftello
|
|
||||||
# define fseeko64 fseeko
|
|
||||||
# elif defined(_MSC_VER) && (_MSC_VER >= 1400)
|
|
||||||
# define ftello64 _ftelli64
|
|
||||||
# define fseeko64 _fseeki64
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#ifndef ftello64
|
|
||||||
# define ftello64 ftell
|
|
||||||
#endif
|
|
||||||
#ifndef fseeko64
|
|
||||||
# define fseeko64 fseek
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_os_vtbl = {
|
|
||||||
mz_stream_os_open,
|
|
||||||
mz_stream_os_is_open,
|
|
||||||
mz_stream_os_read,
|
|
||||||
mz_stream_os_write,
|
|
||||||
mz_stream_os_tell,
|
|
||||||
mz_stream_os_seek,
|
|
||||||
mz_stream_os_close,
|
|
||||||
mz_stream_os_error,
|
|
||||||
mz_stream_os_create,
|
|
||||||
mz_stream_os_delete,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_posix_s {
|
|
||||||
mz_stream stream;
|
|
||||||
int32_t error;
|
|
||||||
FILE *handle;
|
|
||||||
} mz_stream_posix;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_os_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream_posix *posix = (mz_stream_posix *)stream;
|
|
||||||
const char *mode_fopen = NULL;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if ((mode & MZ_OPEN_MODE_READWRITE) == MZ_OPEN_MODE_READ)
|
|
||||||
mode_fopen = "rb";
|
|
||||||
else if (mode & MZ_OPEN_MODE_APPEND)
|
|
||||||
mode_fopen = "r+b";
|
|
||||||
else if (mode & MZ_OPEN_MODE_CREATE)
|
|
||||||
mode_fopen = "wb";
|
|
||||||
else
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
|
|
||||||
posix->handle = fopen64(path, mode_fopen);
|
|
||||||
if (posix->handle == NULL) {
|
|
||||||
posix->error = errno;
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode & MZ_OPEN_MODE_APPEND)
|
|
||||||
return mz_stream_os_seek(stream, 0, MZ_SEEK_END);
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_os_is_open(void *stream) {
|
|
||||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
|
||||||
if (posix->handle == NULL)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_os_read(void *stream, void *buf, int32_t size) {
|
|
||||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
|
||||||
int32_t read = (int32_t)fread(buf, 1, (size_t)size, posix->handle);
|
|
||||||
if (read < size && ferror(posix->handle)) {
|
|
||||||
posix->error = errno;
|
|
||||||
return MZ_READ_ERROR;
|
|
||||||
}
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_os_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
|
||||||
int32_t written = (int32_t)fwrite(buf, 1, (size_t)size, posix->handle);
|
|
||||||
if (written < size && ferror(posix->handle)) {
|
|
||||||
posix->error = errno;
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
}
|
|
||||||
return written;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_os_tell(void *stream) {
|
|
||||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
|
||||||
int64_t position = ftello64(posix->handle);
|
|
||||||
if (position == -1) {
|
|
||||||
posix->error = errno;
|
|
||||||
return MZ_TELL_ERROR;
|
|
||||||
}
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_os_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
|
||||||
int32_t fseek_origin = 0;
|
|
||||||
|
|
||||||
switch (origin) {
|
|
||||||
case MZ_SEEK_CUR:
|
|
||||||
fseek_origin = SEEK_CUR;
|
|
||||||
break;
|
|
||||||
case MZ_SEEK_END:
|
|
||||||
fseek_origin = SEEK_END;
|
|
||||||
break;
|
|
||||||
case MZ_SEEK_SET:
|
|
||||||
fseek_origin = SEEK_SET;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fseeko64(posix->handle, offset, fseek_origin) != 0) {
|
|
||||||
posix->error = errno;
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_os_close(void *stream) {
|
|
||||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
|
||||||
int32_t closed = 0;
|
|
||||||
if (posix->handle != NULL) {
|
|
||||||
closed = fclose(posix->handle);
|
|
||||||
posix->handle = NULL;
|
|
||||||
}
|
|
||||||
if (closed != 0) {
|
|
||||||
posix->error = errno;
|
|
||||||
return MZ_CLOSE_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_os_error(void *stream) {
|
|
||||||
mz_stream_posix *posix = (mz_stream_posix*)stream;
|
|
||||||
return posix->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_os_create(void **stream) {
|
|
||||||
mz_stream_posix *posix = NULL;
|
|
||||||
|
|
||||||
posix = (mz_stream_posix *)MZ_ALLOC(sizeof(mz_stream_posix));
|
|
||||||
if (posix != NULL) {
|
|
||||||
memset(posix, 0, sizeof(mz_stream_posix));
|
|
||||||
posix->stream.vtbl = &mz_stream_os_vtbl;
|
|
||||||
}
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = posix;
|
|
||||||
|
|
||||||
return posix;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_os_delete(void **stream) {
|
|
||||||
mz_stream_posix *posix = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
posix = (mz_stream_posix *)*stream;
|
|
||||||
if (posix != NULL)
|
|
||||||
MZ_FREE(posix);
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_os_get_interface(void) {
|
|
||||||
return (void *)&mz_stream_os_vtbl;
|
|
||||||
}
|
|
|
@ -1,296 +0,0 @@
|
||||||
/* mz_strm_win32.c -- Stream for filesystem access for windows
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
Copyright (C) 2009-2010 Mathias Svensson
|
|
||||||
Modifications for Zip64 support
|
|
||||||
http://result42.com
|
|
||||||
Copyright (C) 1998-2010 Gilles Vollant
|
|
||||||
https://www.winimage.com/zLibDll/minizip.html
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_os.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_os.h"
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifndef INVALID_HANDLE_VALUE
|
|
||||||
# define INVALID_HANDLE_VALUE (0xFFFFFFFF)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef INVALID_SET_FILE_POINTER
|
|
||||||
# define INVALID_SET_FILE_POINTER ((DWORD)-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(WINAPI_FAMILY_ONE_PARTITION) && !defined(MZ_WINRT_API)
|
|
||||||
# if WINAPI_FAMILY_ONE_PARTITION(WINAPI_FAMILY, WINAPI_PARTITION_APP)
|
|
||||||
# define MZ_WINRT_API 1
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_os_vtbl = {
|
|
||||||
mz_stream_os_open,
|
|
||||||
mz_stream_os_is_open,
|
|
||||||
mz_stream_os_read,
|
|
||||||
mz_stream_os_write,
|
|
||||||
mz_stream_os_tell,
|
|
||||||
mz_stream_os_seek,
|
|
||||||
mz_stream_os_close,
|
|
||||||
mz_stream_os_error,
|
|
||||||
mz_stream_os_create,
|
|
||||||
mz_stream_os_delete,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_win32_s {
|
|
||||||
mz_stream stream;
|
|
||||||
HANDLE handle;
|
|
||||||
int32_t error;
|
|
||||||
} mz_stream_win32;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
# define mz_stream_os_print printf
|
|
||||||
#else
|
|
||||||
# define mz_stream_os_print(fmt,...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_os_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
|
||||||
uint32_t desired_access = 0;
|
|
||||||
uint32_t creation_disposition = 0;
|
|
||||||
uint32_t share_mode = FILE_SHARE_READ;
|
|
||||||
uint32_t flags_attribs = FILE_ATTRIBUTE_NORMAL;
|
|
||||||
wchar_t *path_wide = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
/* Some use cases require write sharing as well */
|
|
||||||
share_mode |= FILE_SHARE_WRITE;
|
|
||||||
|
|
||||||
if ((mode & MZ_OPEN_MODE_READWRITE) == MZ_OPEN_MODE_READ) {
|
|
||||||
desired_access = GENERIC_READ;
|
|
||||||
creation_disposition = OPEN_EXISTING;
|
|
||||||
} else if (mode & MZ_OPEN_MODE_APPEND) {
|
|
||||||
desired_access = GENERIC_WRITE | GENERIC_READ;
|
|
||||||
creation_disposition = OPEN_EXISTING;
|
|
||||||
} else if (mode & MZ_OPEN_MODE_CREATE) {
|
|
||||||
desired_access = GENERIC_WRITE | GENERIC_READ;
|
|
||||||
creation_disposition = CREATE_ALWAYS;
|
|
||||||
} else {
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_stream_os_print("Win32 - Open - %s (mode %" PRId32 ")\n", path);
|
|
||||||
|
|
||||||
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
|
|
||||||
if (path_wide == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
#ifdef MZ_WINRT_API
|
|
||||||
win32->handle = CreateFile2(path_wide, desired_access, share_mode,
|
|
||||||
creation_disposition, NULL);
|
|
||||||
#else
|
|
||||||
win32->handle = CreateFileW(path_wide, desired_access, share_mode, NULL,
|
|
||||||
creation_disposition, flags_attribs, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mz_os_unicode_string_delete(&path_wide);
|
|
||||||
|
|
||||||
if (mz_stream_os_is_open(stream) != MZ_OK) {
|
|
||||||
win32->error = GetLastError();
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode & MZ_OPEN_MODE_APPEND)
|
|
||||||
return mz_stream_os_seek(stream, 0, MZ_SEEK_END);
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_os_is_open(void *stream) {
|
|
||||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
|
||||||
if (win32->handle == NULL || win32->handle == INVALID_HANDLE_VALUE)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_os_read(void *stream, void *buf, int32_t size) {
|
|
||||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
|
||||||
uint32_t read = 0;
|
|
||||||
|
|
||||||
if (mz_stream_os_is_open(stream) != MZ_OK)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
|
|
||||||
if (!ReadFile(win32->handle, buf, size, (DWORD *)&read, NULL)) {
|
|
||||||
win32->error = GetLastError();
|
|
||||||
if (win32->error == ERROR_HANDLE_EOF)
|
|
||||||
win32->error = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_stream_os_print("Win32 - Read - %" PRId32 "\n", read);
|
|
||||||
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_os_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
|
||||||
int32_t written = 0;
|
|
||||||
|
|
||||||
if (mz_stream_os_is_open(stream) != MZ_OK)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
|
|
||||||
if (!WriteFile(win32->handle, buf, size, (DWORD *)&written, NULL)) {
|
|
||||||
win32->error = GetLastError();
|
|
||||||
if (win32->error == ERROR_HANDLE_EOF)
|
|
||||||
win32->error = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_stream_os_print("Win32 - Write - %" PRId32 "\n", written);
|
|
||||||
|
|
||||||
return written;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_os_seekinternal(HANDLE handle, LARGE_INTEGER large_pos,
|
|
||||||
LARGE_INTEGER *new_pos, uint32_t move_method) {
|
|
||||||
#ifdef MZ_WINRT_API
|
|
||||||
BOOL success = FALSE;
|
|
||||||
success = SetFilePointerEx(handle, large_pos, new_pos, move_method);
|
|
||||||
if ((success == FALSE) && (GetLastError() != NO_ERROR))
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
#else
|
|
||||||
LONG high_part = 0;
|
|
||||||
uint32_t pos = 0;
|
|
||||||
|
|
||||||
high_part = large_pos.HighPart;
|
|
||||||
pos = SetFilePointer(handle, large_pos.LowPart, &high_part, move_method);
|
|
||||||
|
|
||||||
if ((pos == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
|
|
||||||
if (new_pos != NULL) {
|
|
||||||
new_pos->LowPart = pos;
|
|
||||||
new_pos->HighPart = high_part;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_os_tell(void *stream) {
|
|
||||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
|
||||||
LARGE_INTEGER large_pos;
|
|
||||||
|
|
||||||
if (mz_stream_os_is_open(stream) != MZ_OK)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
|
|
||||||
large_pos.QuadPart = 0;
|
|
||||||
|
|
||||||
if (mz_stream_os_seekinternal(win32->handle, large_pos, &large_pos, FILE_CURRENT) != MZ_OK)
|
|
||||||
win32->error = GetLastError();
|
|
||||||
|
|
||||||
mz_stream_os_print("Win32 - Tell - %" PRId64 "\n", large_pos.QuadPart);
|
|
||||||
|
|
||||||
return large_pos.QuadPart;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_os_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
|
||||||
uint32_t move_method = 0xFFFFFFFF;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
LARGE_INTEGER large_pos;
|
|
||||||
|
|
||||||
|
|
||||||
if (mz_stream_os_is_open(stream) != MZ_OK)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
|
|
||||||
switch (origin) {
|
|
||||||
case MZ_SEEK_CUR:
|
|
||||||
move_method = FILE_CURRENT;
|
|
||||||
break;
|
|
||||||
case MZ_SEEK_END:
|
|
||||||
move_method = FILE_END;
|
|
||||||
break;
|
|
||||||
case MZ_SEEK_SET:
|
|
||||||
move_method = FILE_BEGIN;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_stream_os_print("Win32 - Seek - %" PRId64 " (origin %" PRId32 ")\n", offset, origin);
|
|
||||||
|
|
||||||
large_pos.QuadPart = offset;
|
|
||||||
|
|
||||||
err = mz_stream_os_seekinternal(win32->handle, large_pos, NULL, move_method);
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
win32->error = GetLastError();
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_os_close(void *stream) {
|
|
||||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
|
||||||
|
|
||||||
if (win32->handle != NULL)
|
|
||||||
CloseHandle(win32->handle);
|
|
||||||
mz_stream_os_print("Win32 - Close\n");
|
|
||||||
win32->handle = NULL;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_os_error(void *stream) {
|
|
||||||
mz_stream_win32 *win32 = (mz_stream_win32 *)stream;
|
|
||||||
return win32->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_os_create(void **stream) {
|
|
||||||
mz_stream_win32 *win32 = NULL;
|
|
||||||
|
|
||||||
win32 = (mz_stream_win32 *)MZ_ALLOC(sizeof(mz_stream_win32));
|
|
||||||
if (win32 != NULL) {
|
|
||||||
memset(win32, 0, sizeof(mz_stream_win32));
|
|
||||||
win32->stream.vtbl = &mz_stream_os_vtbl;
|
|
||||||
}
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = win32;
|
|
||||||
|
|
||||||
return win32;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_os_delete(void **stream) {
|
|
||||||
mz_stream_win32 *win32 = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
win32 = (mz_stream_win32 *)*stream;
|
|
||||||
if (win32 != NULL)
|
|
||||||
MZ_FREE(win32);
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_os_get_interface(void) {
|
|
||||||
return (void *)&mz_stream_os_vtbl;
|
|
||||||
}
|
|
|
@ -1,338 +0,0 @@
|
||||||
/* mz_strm_pkcrypt.c -- Code for traditional PKWARE encryption
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
Copyright (C) 1998-2005 Gilles Vollant
|
|
||||||
Modifications for Info-ZIP crypting
|
|
||||||
https://www.winimage.com/zLibDll/minizip.html
|
|
||||||
Copyright (C) 2003 Terry Thorsen
|
|
||||||
|
|
||||||
This code is a modified version of crypting code in Info-ZIP distribution
|
|
||||||
|
|
||||||
Copyright (C) 1990-2000 Info-ZIP. All rights reserved.
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
|
|
||||||
This encryption code is a direct transcription of the algorithm from
|
|
||||||
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
|
|
||||||
file (appnote.txt) is distributed with the PKZIP program (even in the
|
|
||||||
version without encryption capabilities).
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_crypt.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_pkcrypt.h"
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_pkcrypt_vtbl = {
|
|
||||||
mz_stream_pkcrypt_open,
|
|
||||||
mz_stream_pkcrypt_is_open,
|
|
||||||
mz_stream_pkcrypt_read,
|
|
||||||
mz_stream_pkcrypt_write,
|
|
||||||
mz_stream_pkcrypt_tell,
|
|
||||||
mz_stream_pkcrypt_seek,
|
|
||||||
mz_stream_pkcrypt_close,
|
|
||||||
mz_stream_pkcrypt_error,
|
|
||||||
mz_stream_pkcrypt_create,
|
|
||||||
mz_stream_pkcrypt_delete,
|
|
||||||
mz_stream_pkcrypt_get_prop_int64,
|
|
||||||
mz_stream_pkcrypt_set_prop_int64
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_pkcrypt_s {
|
|
||||||
mz_stream stream;
|
|
||||||
int32_t error;
|
|
||||||
int16_t initialized;
|
|
||||||
uint8_t buffer[UINT16_MAX];
|
|
||||||
int64_t total_in;
|
|
||||||
int64_t max_total_in;
|
|
||||||
int64_t total_out;
|
|
||||||
uint32_t keys[3]; /* keys defining the pseudo-random sequence */
|
|
||||||
uint8_t verify1;
|
|
||||||
uint8_t verify2;
|
|
||||||
const char *password;
|
|
||||||
} mz_stream_pkcrypt;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#define mz_stream_pkcrypt_decode(strm, c) \
|
|
||||||
(mz_stream_pkcrypt_update_keys(strm, \
|
|
||||||
c ^= mz_stream_pkcrypt_decrypt_byte(strm)))
|
|
||||||
|
|
||||||
#define mz_stream_pkcrypt_encode(strm, c, t) \
|
|
||||||
(t = mz_stream_pkcrypt_decrypt_byte(strm), \
|
|
||||||
mz_stream_pkcrypt_update_keys(strm, (uint8_t)c), (uint8_t)(t^(c)))
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static uint8_t mz_stream_pkcrypt_decrypt_byte(void *stream) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
|
|
||||||
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an */
|
|
||||||
/* unpredictable manner on 16-bit systems; not a problem */
|
|
||||||
/* with any known compiler so far, though. */
|
|
||||||
|
|
||||||
temp = pkcrypt->keys[2] | 2;
|
|
||||||
return (uint8_t)(((temp * (temp ^ 1)) >> 8) & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t mz_stream_pkcrypt_update_keys(void *stream, uint8_t c) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
uint8_t buf = c;
|
|
||||||
|
|
||||||
pkcrypt->keys[0] = (uint32_t)~mz_crypt_crc32_update(~pkcrypt->keys[0], &buf, 1);
|
|
||||||
|
|
||||||
pkcrypt->keys[1] += pkcrypt->keys[0] & 0xff;
|
|
||||||
pkcrypt->keys[1] *= 134775813L;
|
|
||||||
pkcrypt->keys[1] += 1;
|
|
||||||
|
|
||||||
buf = (uint8_t)(pkcrypt->keys[1] >> 24);
|
|
||||||
pkcrypt->keys[2] = (uint32_t)~mz_crypt_crc32_update(~pkcrypt->keys[2], &buf, 1);
|
|
||||||
|
|
||||||
return (uint8_t)c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mz_stream_pkcrypt_init_keys(void *stream, const char *password) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
|
|
||||||
pkcrypt->keys[0] = 305419896L;
|
|
||||||
pkcrypt->keys[1] = 591751049L;
|
|
||||||
pkcrypt->keys[2] = 878082192L;
|
|
||||||
|
|
||||||
while (*password != 0) {
|
|
||||||
mz_stream_pkcrypt_update_keys(stream, (uint8_t)*password);
|
|
||||||
password += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_pkcrypt_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
uint16_t t = 0;
|
|
||||||
int16_t i = 0;
|
|
||||||
uint8_t verify1 = 0;
|
|
||||||
uint8_t verify2 = 0;
|
|
||||||
uint8_t header[MZ_PKCRYPT_HEADER_SIZE];
|
|
||||||
const char *password = path;
|
|
||||||
|
|
||||||
pkcrypt->total_in = 0;
|
|
||||||
pkcrypt->total_out = 0;
|
|
||||||
pkcrypt->initialized = 0;
|
|
||||||
|
|
||||||
if (mz_stream_is_open(pkcrypt->stream.base) != MZ_OK)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
|
|
||||||
if (password == NULL)
|
|
||||||
password = pkcrypt->password;
|
|
||||||
if (password == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
mz_stream_pkcrypt_init_keys(stream, password);
|
|
||||||
|
|
||||||
if (mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
/* First generate RAND_HEAD_LEN - 2 random bytes. */
|
|
||||||
mz_crypt_rand(header, MZ_PKCRYPT_HEADER_SIZE - 2);
|
|
||||||
|
|
||||||
/* Encrypt random header (last two bytes is high word of crc) */
|
|
||||||
for (i = 0; i < MZ_PKCRYPT_HEADER_SIZE - 2; i++)
|
|
||||||
header[i] = mz_stream_pkcrypt_encode(stream, header[i], t);
|
|
||||||
|
|
||||||
header[i++] = mz_stream_pkcrypt_encode(stream, pkcrypt->verify1, t);
|
|
||||||
header[i++] = mz_stream_pkcrypt_encode(stream, pkcrypt->verify2, t);
|
|
||||||
|
|
||||||
if (mz_stream_write(pkcrypt->stream.base, header, sizeof(header)) != sizeof(header))
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
|
|
||||||
pkcrypt->total_out += MZ_PKCRYPT_HEADER_SIZE;
|
|
||||||
} else if (mode & MZ_OPEN_MODE_READ) {
|
|
||||||
if (mz_stream_read(pkcrypt->stream.base, header, sizeof(header)) != sizeof(header))
|
|
||||||
return MZ_READ_ERROR;
|
|
||||||
|
|
||||||
for (i = 0; i < MZ_PKCRYPT_HEADER_SIZE - 2; i++)
|
|
||||||
header[i] = mz_stream_pkcrypt_decode(stream, header[i]);
|
|
||||||
|
|
||||||
verify1 = mz_stream_pkcrypt_decode(stream, header[i++]);
|
|
||||||
verify2 = mz_stream_pkcrypt_decode(stream, header[i++]);
|
|
||||||
|
|
||||||
/* Older versions used 2 byte check, newer versions use 1 byte check. */
|
|
||||||
MZ_UNUSED(verify1);
|
|
||||||
if ((verify2 != 0) && (verify2 != pkcrypt->verify2))
|
|
||||||
return MZ_PASSWORD_ERROR;
|
|
||||||
|
|
||||||
pkcrypt->total_in += MZ_PKCRYPT_HEADER_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pkcrypt->initialized = 1;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_pkcrypt_is_open(void *stream) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
if (pkcrypt->initialized == 0)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_pkcrypt_read(void *stream, void *buf, int32_t size) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
uint8_t *buf_ptr = (uint8_t *)buf;
|
|
||||||
int32_t bytes_to_read = size;
|
|
||||||
int32_t read = 0;
|
|
||||||
int32_t i = 0;
|
|
||||||
|
|
||||||
|
|
||||||
if ((int64_t)bytes_to_read > (pkcrypt->max_total_in - pkcrypt->total_in))
|
|
||||||
bytes_to_read = (int32_t)(pkcrypt->max_total_in - pkcrypt->total_in);
|
|
||||||
|
|
||||||
read = mz_stream_read(pkcrypt->stream.base, buf, bytes_to_read);
|
|
||||||
|
|
||||||
for (i = 0; i < read; i++)
|
|
||||||
buf_ptr[i] = mz_stream_pkcrypt_decode(stream, buf_ptr[i]);
|
|
||||||
|
|
||||||
if (read > 0)
|
|
||||||
pkcrypt->total_in += read;
|
|
||||||
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_pkcrypt_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
const uint8_t *buf_ptr = (const uint8_t *)buf;
|
|
||||||
int32_t bytes_to_write = sizeof(pkcrypt->buffer);
|
|
||||||
int32_t total_written = 0;
|
|
||||||
int32_t written = 0;
|
|
||||||
int32_t i = 0;
|
|
||||||
uint16_t t = 0;
|
|
||||||
|
|
||||||
if (size < 0)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (bytes_to_write > (size - total_written))
|
|
||||||
bytes_to_write = (size - total_written);
|
|
||||||
|
|
||||||
for (i = 0; i < bytes_to_write; i += 1) {
|
|
||||||
pkcrypt->buffer[i] = mz_stream_pkcrypt_encode(stream, *buf_ptr, t);
|
|
||||||
buf_ptr += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
written = mz_stream_write(pkcrypt->stream.base, pkcrypt->buffer, bytes_to_write);
|
|
||||||
if (written < 0)
|
|
||||||
return written;
|
|
||||||
|
|
||||||
total_written += written;
|
|
||||||
} while (total_written < size && written > 0);
|
|
||||||
|
|
||||||
pkcrypt->total_out += total_written;
|
|
||||||
return total_written;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_pkcrypt_tell(void *stream) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
return mz_stream_tell(pkcrypt->stream.base);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_pkcrypt_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
return mz_stream_seek(pkcrypt->stream.base, offset, origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_pkcrypt_close(void *stream) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
pkcrypt->initialized = 0;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_pkcrypt_error(void *stream) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
return pkcrypt->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_pkcrypt_set_password(void *stream, const char *password) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
pkcrypt->password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_pkcrypt_set_verify(void *stream, uint8_t verify1, uint8_t verify2) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
pkcrypt->verify1 = verify1;
|
|
||||||
pkcrypt->verify2 = verify2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_pkcrypt_get_verify(void *stream, uint8_t *verify1, uint8_t *verify2) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
*verify1 = pkcrypt->verify1;
|
|
||||||
*verify2 = pkcrypt->verify2;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_pkcrypt_get_prop_int64(void *stream, int32_t prop, int64_t *value) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN:
|
|
||||||
*value = pkcrypt->total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
|
||||||
*value = pkcrypt->total_out;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
*value = pkcrypt->max_total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_HEADER_SIZE:
|
|
||||||
*value = MZ_PKCRYPT_HEADER_SIZE;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_FOOTER_SIZE:
|
|
||||||
*value = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_pkcrypt_set_prop_int64(void *stream, int32_t prop, int64_t value) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
pkcrypt->max_total_in = value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_pkcrypt_create(void **stream) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = NULL;
|
|
||||||
|
|
||||||
pkcrypt = (mz_stream_pkcrypt *)MZ_ALLOC(sizeof(mz_stream_pkcrypt));
|
|
||||||
if (pkcrypt != NULL) {
|
|
||||||
memset(pkcrypt, 0, sizeof(mz_stream_pkcrypt));
|
|
||||||
pkcrypt->stream.vtbl = &mz_stream_pkcrypt_vtbl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = pkcrypt;
|
|
||||||
return pkcrypt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_pkcrypt_delete(void **stream) {
|
|
||||||
mz_stream_pkcrypt *pkcrypt = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
pkcrypt = (mz_stream_pkcrypt *)*stream;
|
|
||||||
if (pkcrypt != NULL)
|
|
||||||
MZ_FREE(pkcrypt);
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_pkcrypt_get_interface(void) {
|
|
||||||
return (void *)&mz_stream_pkcrypt_vtbl;
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
/* mz_strm_pkcrypt.h -- Code for traditional PKWARE encryption
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_STREAM_PKCRYPT_H
|
|
||||||
#define MZ_STREAM_PKCRYPT_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_pkcrypt_open(void *stream, const char *filename, int32_t mode);
|
|
||||||
int32_t mz_stream_pkcrypt_is_open(void *stream);
|
|
||||||
int32_t mz_stream_pkcrypt_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_pkcrypt_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int64_t mz_stream_pkcrypt_tell(void *stream);
|
|
||||||
int32_t mz_stream_pkcrypt_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_pkcrypt_close(void *stream);
|
|
||||||
int32_t mz_stream_pkcrypt_error(void *stream);
|
|
||||||
|
|
||||||
void mz_stream_pkcrypt_set_password(void *stream, const char *password);
|
|
||||||
void mz_stream_pkcrypt_set_verify(void *stream, uint8_t verify1, uint8_t verify2);
|
|
||||||
void mz_stream_pkcrypt_get_verify(void *stream, uint8_t *verify1, uint8_t *verify2);
|
|
||||||
int32_t mz_stream_pkcrypt_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
|
||||||
int32_t mz_stream_pkcrypt_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
|
||||||
|
|
||||||
void* mz_stream_pkcrypt_create(void **stream);
|
|
||||||
void mz_stream_pkcrypt_delete(void **stream);
|
|
||||||
|
|
||||||
void* mz_stream_pkcrypt_get_interface(void);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,438 +0,0 @@
|
||||||
/* mz_strm_split.c -- Stream for split files
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_os.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_split.h"
|
|
||||||
|
|
||||||
#include <stdio.h> /* snprintf */
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
|
||||||
# define snprintf _snprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#define MZ_ZIP_MAGIC_DISKHEADER (0x08074b50)
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_split_vtbl = {
|
|
||||||
mz_stream_split_open,
|
|
||||||
mz_stream_split_is_open,
|
|
||||||
mz_stream_split_read,
|
|
||||||
mz_stream_split_write,
|
|
||||||
mz_stream_split_tell,
|
|
||||||
mz_stream_split_seek,
|
|
||||||
mz_stream_split_close,
|
|
||||||
mz_stream_split_error,
|
|
||||||
mz_stream_split_create,
|
|
||||||
mz_stream_split_delete,
|
|
||||||
mz_stream_split_get_prop_int64,
|
|
||||||
mz_stream_split_set_prop_int64
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_split_s {
|
|
||||||
mz_stream stream;
|
|
||||||
int32_t is_open;
|
|
||||||
int64_t disk_size;
|
|
||||||
int64_t total_in;
|
|
||||||
int64_t total_in_disk;
|
|
||||||
int64_t total_out;
|
|
||||||
int64_t total_out_disk;
|
|
||||||
int32_t mode;
|
|
||||||
char *path_cd;
|
|
||||||
uint32_t path_cd_size;
|
|
||||||
char *path_disk;
|
|
||||||
uint32_t path_disk_size;
|
|
||||||
int32_t number_disk;
|
|
||||||
int32_t current_disk;
|
|
||||||
int64_t current_disk_size;
|
|
||||||
int32_t reached_end;
|
|
||||||
} mz_stream_split;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
# define mz_stream_split_print printf
|
|
||||||
#else
|
|
||||||
# define mz_stream_split_print(fmt,...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static int32_t mz_stream_split_open_disk(void *stream, int32_t number_disk) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
uint32_t magic = 0;
|
|
||||||
int64_t position = 0;
|
|
||||||
int32_t i = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
int16_t disk_part = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/* Check if we are reading or writing a disk part or the cd disk */
|
|
||||||
if (number_disk >= 0) {
|
|
||||||
if ((split->mode & MZ_OPEN_MODE_WRITE) == 0)
|
|
||||||
disk_part = MZ_OPEN_MODE_READ;
|
|
||||||
else if (split->disk_size > 0)
|
|
||||||
disk_part = MZ_OPEN_MODE_WRITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Construct disk path */
|
|
||||||
if (disk_part > 0) {
|
|
||||||
for (i = (int32_t)strlen(split->path_disk) - 1; i >= 0; i -= 1) {
|
|
||||||
if (split->path_disk[i] != '.')
|
|
||||||
continue;
|
|
||||||
snprintf(&split->path_disk[i], split->path_disk_size - (uint32_t)i,
|
|
||||||
".z%02" PRId32, number_disk + 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
strncpy(split->path_disk, split->path_cd, split->path_disk_size - 1);
|
|
||||||
split->path_disk[split->path_disk_size - 1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mz_stream_split_print("Split - Goto disk - %s (disk %" PRId32 ")\n", split->path_disk, number_disk);
|
|
||||||
|
|
||||||
/* If disk part doesn't exist during reading then return MZ_EXIST_ERROR */
|
|
||||||
if (disk_part == MZ_OPEN_MODE_READ)
|
|
||||||
err = mz_os_file_exists(split->path_disk);
|
|
||||||
|
|
||||||
if (err == MZ_OK)
|
|
||||||
err = mz_stream_open(split->stream.base, split->path_disk, split->mode);
|
|
||||||
|
|
||||||
if (err == MZ_OK) {
|
|
||||||
split->total_in_disk = 0;
|
|
||||||
split->total_out_disk = 0;
|
|
||||||
split->current_disk = number_disk;
|
|
||||||
|
|
||||||
if (split->mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
if ((split->current_disk == 0) && (split->disk_size > 0)) {
|
|
||||||
err = mz_stream_write_uint32(split->stream.base, MZ_ZIP_MAGIC_DISKHEADER);
|
|
||||||
|
|
||||||
split->total_out_disk += 4;
|
|
||||||
split->total_out += split->total_out_disk;
|
|
||||||
}
|
|
||||||
} else if (split->mode & MZ_OPEN_MODE_READ) {
|
|
||||||
if (split->current_disk == 0) {
|
|
||||||
err = mz_stream_read_uint32(split->stream.base, &magic);
|
|
||||||
if (magic != MZ_ZIP_MAGIC_DISKHEADER)
|
|
||||||
err = MZ_FORMAT_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err == MZ_OK) {
|
|
||||||
/* Get the size of the current disk we are on */
|
|
||||||
position = mz_stream_tell(split->stream.base);
|
|
||||||
mz_stream_seek(split->stream.base, 0, MZ_SEEK_END);
|
|
||||||
split->current_disk_size = mz_stream_tell(split->stream.base);
|
|
||||||
mz_stream_seek(split->stream.base, position, MZ_SEEK_SET);
|
|
||||||
|
|
||||||
split->is_open = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_split_close_disk(void *stream) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
|
|
||||||
if (mz_stream_is_open(split->stream.base) != MZ_OK)
|
|
||||||
return MZ_OK;
|
|
||||||
|
|
||||||
mz_stream_split_print("Split - Close disk\n");
|
|
||||||
return mz_stream_close(split->stream.base);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_split_goto_disk(void *stream, int32_t number_disk) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
int32_t err_is_open = MZ_OK;
|
|
||||||
|
|
||||||
err_is_open = mz_stream_is_open(split->stream.base);
|
|
||||||
|
|
||||||
if ((split->disk_size == 0) && (split->mode & MZ_OPEN_MODE_WRITE)) {
|
|
||||||
if (err_is_open != MZ_OK)
|
|
||||||
err = mz_stream_split_open_disk(stream, number_disk);
|
|
||||||
} else if ((number_disk != split->current_disk) || (err_is_open != MZ_OK)) {
|
|
||||||
err = mz_stream_split_close_disk(stream);
|
|
||||||
if (err == MZ_OK) {
|
|
||||||
err = mz_stream_split_open_disk(stream, number_disk);
|
|
||||||
if (err == MZ_OK)
|
|
||||||
split->number_disk = number_disk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_split_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
int32_t number_disk = 0;
|
|
||||||
|
|
||||||
split->mode = mode;
|
|
||||||
|
|
||||||
split->path_cd_size = (uint32_t)strlen(path) + 1;
|
|
||||||
split->path_cd = (char *)MZ_ALLOC(split->path_cd_size);
|
|
||||||
|
|
||||||
if (split->path_cd == NULL)
|
|
||||||
return MZ_MEM_ERROR;
|
|
||||||
|
|
||||||
strncpy(split->path_cd, path, split->path_cd_size - 1);
|
|
||||||
split->path_cd[split->path_cd_size - 1] = 0;
|
|
||||||
|
|
||||||
mz_stream_split_print("Split - Open - %s (disk %" PRId32 ")\n", split->path_cd, number_disk);
|
|
||||||
|
|
||||||
split->path_disk_size = (uint32_t)strlen(path) + 10;
|
|
||||||
split->path_disk = (char *)MZ_ALLOC(split->path_disk_size);
|
|
||||||
|
|
||||||
if (split->path_disk == NULL) {
|
|
||||||
MZ_FREE(split->path_cd);
|
|
||||||
return MZ_MEM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(split->path_disk, path, split->path_disk_size - 1);
|
|
||||||
split->path_disk[split->path_disk_size - 1] = 0;
|
|
||||||
|
|
||||||
if ((mode & MZ_OPEN_MODE_WRITE) && ((mode & MZ_OPEN_MODE_APPEND) == 0)) {
|
|
||||||
number_disk = 0;
|
|
||||||
split->current_disk = -1;
|
|
||||||
} else {
|
|
||||||
number_disk = -1;
|
|
||||||
split->current_disk = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mz_stream_split_goto_disk(stream, number_disk);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_split_is_open(void *stream) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
if (split->is_open != 1)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_split_read(void *stream, void *buf, int32_t size) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
int32_t bytes_left = size;
|
|
||||||
int32_t read = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
uint8_t *buf_ptr = (uint8_t *)buf;
|
|
||||||
|
|
||||||
err = mz_stream_split_goto_disk(stream, split->number_disk);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
while (bytes_left > 0) {
|
|
||||||
read = mz_stream_read(split->stream.base, buf_ptr, bytes_left);
|
|
||||||
|
|
||||||
mz_stream_split_print("Split - Read disk - %" PRId32 "\n", read);
|
|
||||||
|
|
||||||
if (read < 0)
|
|
||||||
return read;
|
|
||||||
if (read == 0) {
|
|
||||||
if (split->current_disk < 0) /* No more disks to goto */
|
|
||||||
break;
|
|
||||||
err = mz_stream_split_goto_disk(stream, split->current_disk + 1);
|
|
||||||
if (err == MZ_EXIST_ERROR) {
|
|
||||||
split->current_disk = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes_left -= read;
|
|
||||||
buf_ptr += read;
|
|
||||||
split->total_in += read;
|
|
||||||
split->total_in_disk += read;
|
|
||||||
}
|
|
||||||
return size - bytes_left;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_split_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
int64_t position = 0;
|
|
||||||
int32_t written = 0;
|
|
||||||
int32_t bytes_left = size;
|
|
||||||
int32_t bytes_to_write = 0;
|
|
||||||
int32_t bytes_avail = 0;
|
|
||||||
int32_t number_disk = -1;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
const uint8_t *buf_ptr = (const uint8_t *)buf;
|
|
||||||
|
|
||||||
position = mz_stream_tell(split->stream.base);
|
|
||||||
|
|
||||||
while (bytes_left > 0) {
|
|
||||||
bytes_to_write = bytes_left;
|
|
||||||
|
|
||||||
if (split->disk_size > 0) {
|
|
||||||
if ((split->total_out_disk == split->disk_size && split->total_out > 0) ||
|
|
||||||
(split->number_disk == -1 && split->number_disk != split->current_disk)) {
|
|
||||||
if (split->number_disk != -1)
|
|
||||||
number_disk = split->current_disk + 1;
|
|
||||||
|
|
||||||
err = mz_stream_split_goto_disk(stream, number_disk);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (split->number_disk != -1) {
|
|
||||||
bytes_avail = (int32_t)(split->disk_size - split->total_out_disk);
|
|
||||||
if (bytes_to_write > bytes_avail)
|
|
||||||
bytes_to_write = bytes_avail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
written = mz_stream_write(split->stream.base, buf_ptr, bytes_to_write);
|
|
||||||
if (written != bytes_to_write)
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
|
|
||||||
mz_stream_split_print("Split - Write disk - %" PRId32 "\n", written);
|
|
||||||
|
|
||||||
bytes_left -= written;
|
|
||||||
buf_ptr += written;
|
|
||||||
|
|
||||||
split->total_out += written;
|
|
||||||
split->total_out_disk += written;
|
|
||||||
|
|
||||||
if (position == split->current_disk_size) {
|
|
||||||
split->current_disk_size += written;
|
|
||||||
position = split->current_disk_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return size - bytes_left;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_split_tell(void *stream) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
err = mz_stream_split_goto_disk(stream, split->number_disk);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
return mz_stream_tell(split->stream.base);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_split_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
int64_t disk_left = 0;
|
|
||||||
int64_t position = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
err = mz_stream_split_goto_disk(stream, split->number_disk);
|
|
||||||
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
mz_stream_split_print("Split - Seek disk - %" PRId64 " (origin %" PRId32 ")\n", offset, origin);
|
|
||||||
|
|
||||||
if ((origin == MZ_SEEK_CUR) && (split->number_disk != -1)) {
|
|
||||||
position = mz_stream_tell(split->stream.base);
|
|
||||||
disk_left = split->current_disk_size - position;
|
|
||||||
|
|
||||||
while (offset > disk_left) {
|
|
||||||
err = mz_stream_split_goto_disk(stream, split->current_disk + 1);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
offset -= disk_left;
|
|
||||||
disk_left = split->current_disk_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mz_stream_seek(split->stream.base, offset, origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_split_close(void *stream) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
err = mz_stream_split_close_disk(stream);
|
|
||||||
split->is_open = 0;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_split_error(void *stream) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
return mz_stream_error(split->stream.base);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_split_get_prop_int64(void *stream, int32_t prop, int64_t *value) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
|
||||||
*value = split->total_out;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_DISK_NUMBER:
|
|
||||||
*value = split->number_disk;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_DISK_SIZE:
|
|
||||||
*value = split->disk_size;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_split_set_prop_int64(void *stream, int32_t prop, int64_t value) {
|
|
||||||
mz_stream_split *split = (mz_stream_split *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_DISK_NUMBER:
|
|
||||||
split->number_disk = (int32_t)value;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_DISK_SIZE:
|
|
||||||
split->disk_size = value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_split_create(void **stream) {
|
|
||||||
mz_stream_split *split = NULL;
|
|
||||||
|
|
||||||
split = (mz_stream_split *)MZ_ALLOC(sizeof(mz_stream_split));
|
|
||||||
if (split != NULL) {
|
|
||||||
memset(split, 0, sizeof(mz_stream_split));
|
|
||||||
split->stream.vtbl = &mz_stream_split_vtbl;
|
|
||||||
}
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = split;
|
|
||||||
|
|
||||||
return split;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_split_delete(void **stream) {
|
|
||||||
mz_stream_split *split = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
split = (mz_stream_split *)*stream;
|
|
||||||
if (split != NULL) {
|
|
||||||
if (split->path_cd)
|
|
||||||
MZ_FREE(split->path_cd);
|
|
||||||
if (split->path_disk)
|
|
||||||
MZ_FREE(split->path_disk);
|
|
||||||
|
|
||||||
MZ_FREE(split);
|
|
||||||
}
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_split_get_interface(void) {
|
|
||||||
return (void *)&mz_stream_split_vtbl;
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/* mz_strm_split.h -- Stream for split files
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_STREAM_SPLIT_H
|
|
||||||
#define MZ_STREAM_SPLIT_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_split_open(void *stream, const char *filename, int32_t mode);
|
|
||||||
int32_t mz_stream_split_is_open(void *stream);
|
|
||||||
int32_t mz_stream_split_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_split_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int64_t mz_stream_split_tell(void *stream);
|
|
||||||
int32_t mz_stream_split_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_split_close(void *stream);
|
|
||||||
int32_t mz_stream_split_error(void *stream);
|
|
||||||
|
|
||||||
int32_t mz_stream_split_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
|
||||||
int32_t mz_stream_split_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
|
||||||
|
|
||||||
void* mz_stream_split_create(void **stream);
|
|
||||||
void mz_stream_split_delete(void **stream);
|
|
||||||
|
|
||||||
void* mz_stream_split_get_interface(void);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,362 +0,0 @@
|
||||||
/* mz_strm_wzaes.c -- Stream for WinZip AES encryption
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
Copyright (C) 1998-2010 Brian Gladman, Worcester, UK
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_crypt.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_wzaes.h"
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#define MZ_AES_KEYING_ITERATIONS (1000)
|
|
||||||
#define MZ_AES_SALT_LENGTH(MODE) (4 * (MODE & 3) + 4)
|
|
||||||
#define MZ_AES_SALT_LENGTH_MAX (16)
|
|
||||||
#define MZ_AES_PW_LENGTH_MAX (128)
|
|
||||||
#define MZ_AES_PW_VERIFY_SIZE (2)
|
|
||||||
#define MZ_AES_AUTHCODE_SIZE (10)
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_wzaes_vtbl = {
|
|
||||||
mz_stream_wzaes_open,
|
|
||||||
mz_stream_wzaes_is_open,
|
|
||||||
mz_stream_wzaes_read,
|
|
||||||
mz_stream_wzaes_write,
|
|
||||||
mz_stream_wzaes_tell,
|
|
||||||
mz_stream_wzaes_seek,
|
|
||||||
mz_stream_wzaes_close,
|
|
||||||
mz_stream_wzaes_error,
|
|
||||||
mz_stream_wzaes_create,
|
|
||||||
mz_stream_wzaes_delete,
|
|
||||||
mz_stream_wzaes_get_prop_int64,
|
|
||||||
mz_stream_wzaes_set_prop_int64
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_wzaes_s {
|
|
||||||
mz_stream stream;
|
|
||||||
int32_t mode;
|
|
||||||
int32_t error;
|
|
||||||
int16_t initialized;
|
|
||||||
uint8_t buffer[UINT16_MAX];
|
|
||||||
int64_t total_in;
|
|
||||||
int64_t max_total_in;
|
|
||||||
int64_t total_out;
|
|
||||||
int16_t encryption_mode;
|
|
||||||
const char *password;
|
|
||||||
void *aes;
|
|
||||||
uint32_t crypt_pos;
|
|
||||||
uint8_t crypt_block[MZ_AES_BLOCK_SIZE];
|
|
||||||
void *hmac;
|
|
||||||
uint8_t nonce[MZ_AES_BLOCK_SIZE];
|
|
||||||
} mz_stream_wzaes;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_wzaes_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
uint16_t salt_length = 0;
|
|
||||||
uint16_t password_length = 0;
|
|
||||||
uint16_t key_length = 0;
|
|
||||||
uint8_t kbuf[2 * MZ_AES_KEY_LENGTH_MAX + MZ_AES_PW_VERIFY_SIZE];
|
|
||||||
uint8_t verify[MZ_AES_PW_VERIFY_SIZE];
|
|
||||||
uint8_t verify_expected[MZ_AES_PW_VERIFY_SIZE];
|
|
||||||
uint8_t salt_value[MZ_AES_SALT_LENGTH_MAX];
|
|
||||||
const char *password = path;
|
|
||||||
|
|
||||||
wzaes->total_in = 0;
|
|
||||||
wzaes->total_out = 0;
|
|
||||||
wzaes->initialized = 0;
|
|
||||||
|
|
||||||
if (mz_stream_is_open(wzaes->stream.base) != MZ_OK)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
|
|
||||||
if (password == NULL)
|
|
||||||
password = wzaes->password;
|
|
||||||
if (password == NULL)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
password_length = (uint16_t)strlen(password);
|
|
||||||
if (password_length > MZ_AES_PW_LENGTH_MAX)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
if (wzaes->encryption_mode < 1 || wzaes->encryption_mode > 3)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
salt_length = MZ_AES_SALT_LENGTH(wzaes->encryption_mode);
|
|
||||||
|
|
||||||
if (mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
mz_crypt_rand(salt_value, salt_length);
|
|
||||||
} else if (mode & MZ_OPEN_MODE_READ) {
|
|
||||||
if (mz_stream_read(wzaes->stream.base, salt_value, salt_length) != salt_length)
|
|
||||||
return MZ_READ_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
key_length = MZ_AES_KEY_LENGTH(wzaes->encryption_mode);
|
|
||||||
|
|
||||||
/* Derive the encryption and authentication keys and the password verifier */
|
|
||||||
mz_crypt_pbkdf2((uint8_t *)password, password_length, salt_value, salt_length,
|
|
||||||
MZ_AES_KEYING_ITERATIONS, kbuf, 2 * key_length + MZ_AES_PW_VERIFY_SIZE);
|
|
||||||
|
|
||||||
/* Initialize the encryption nonce and buffer pos */
|
|
||||||
wzaes->crypt_pos = MZ_AES_BLOCK_SIZE;
|
|
||||||
memset(wzaes->nonce, 0, sizeof(wzaes->nonce));
|
|
||||||
|
|
||||||
/* Initialize for encryption using key 1 */
|
|
||||||
mz_crypt_aes_reset(wzaes->aes);
|
|
||||||
mz_crypt_aes_set_mode(wzaes->aes, wzaes->encryption_mode);
|
|
||||||
mz_crypt_aes_set_encrypt_key(wzaes->aes, kbuf, key_length);
|
|
||||||
|
|
||||||
/* Initialize for authentication using key 2 */
|
|
||||||
mz_crypt_hmac_reset(wzaes->hmac);
|
|
||||||
mz_crypt_hmac_set_algorithm(wzaes->hmac, MZ_HASH_SHA1);
|
|
||||||
mz_crypt_hmac_init(wzaes->hmac, kbuf + key_length, key_length);
|
|
||||||
|
|
||||||
memcpy(verify, kbuf + (2 * key_length), MZ_AES_PW_VERIFY_SIZE);
|
|
||||||
|
|
||||||
if (mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
if (mz_stream_write(wzaes->stream.base, salt_value, salt_length) != salt_length)
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
|
|
||||||
wzaes->total_out += salt_length;
|
|
||||||
|
|
||||||
if (mz_stream_write(wzaes->stream.base, verify, MZ_AES_PW_VERIFY_SIZE) != MZ_AES_PW_VERIFY_SIZE)
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
|
|
||||||
wzaes->total_out += MZ_AES_PW_VERIFY_SIZE;
|
|
||||||
} else if (mode & MZ_OPEN_MODE_READ) {
|
|
||||||
wzaes->total_in += salt_length;
|
|
||||||
|
|
||||||
if (mz_stream_read(wzaes->stream.base, verify_expected, MZ_AES_PW_VERIFY_SIZE) != MZ_AES_PW_VERIFY_SIZE)
|
|
||||||
return MZ_READ_ERROR;
|
|
||||||
|
|
||||||
wzaes->total_in += MZ_AES_PW_VERIFY_SIZE;
|
|
||||||
|
|
||||||
if (memcmp(verify_expected, verify, MZ_AES_PW_VERIFY_SIZE) != 0)
|
|
||||||
return MZ_PASSWORD_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
wzaes->mode = mode;
|
|
||||||
wzaes->initialized = 1;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_wzaes_is_open(void *stream) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
if (wzaes->initialized == 0)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_wzaes_ctr_encrypt(void *stream, uint8_t *buf, int32_t size) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
uint32_t pos = wzaes->crypt_pos;
|
|
||||||
uint32_t i = 0;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
while (i < (uint32_t)size) {
|
|
||||||
if (pos == MZ_AES_BLOCK_SIZE) {
|
|
||||||
uint32_t j = 0;
|
|
||||||
|
|
||||||
/* Increment encryption nonce */
|
|
||||||
while (j < 8 && !++wzaes->nonce[j])
|
|
||||||
j += 1;
|
|
||||||
|
|
||||||
/* Encrypt the nonce to form next xor buffer */
|
|
||||||
memcpy(wzaes->crypt_block, wzaes->nonce, MZ_AES_BLOCK_SIZE);
|
|
||||||
mz_crypt_aes_encrypt(wzaes->aes, wzaes->crypt_block, sizeof(wzaes->crypt_block));
|
|
||||||
pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[i++] ^= wzaes->crypt_block[pos++];
|
|
||||||
}
|
|
||||||
|
|
||||||
wzaes->crypt_pos = pos;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_wzaes_read(void *stream, void *buf, int32_t size) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
int64_t max_total_in = 0;
|
|
||||||
int32_t bytes_to_read = size;
|
|
||||||
int32_t read = 0;
|
|
||||||
|
|
||||||
max_total_in = wzaes->max_total_in - MZ_AES_FOOTER_SIZE;
|
|
||||||
if ((int64_t)bytes_to_read > (max_total_in - wzaes->total_in))
|
|
||||||
bytes_to_read = (int32_t)(max_total_in - wzaes->total_in);
|
|
||||||
|
|
||||||
read = mz_stream_read(wzaes->stream.base, buf, bytes_to_read);
|
|
||||||
|
|
||||||
if (read > 0) {
|
|
||||||
mz_crypt_hmac_update(wzaes->hmac, (uint8_t *)buf, read);
|
|
||||||
mz_stream_wzaes_ctr_encrypt(stream, (uint8_t *)buf, read);
|
|
||||||
|
|
||||||
wzaes->total_in += read;
|
|
||||||
}
|
|
||||||
|
|
||||||
return read;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_wzaes_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
const uint8_t *buf_ptr = (const uint8_t *)buf;
|
|
||||||
int32_t bytes_to_write = sizeof(wzaes->buffer);
|
|
||||||
int32_t total_written = 0;
|
|
||||||
int32_t written = 0;
|
|
||||||
|
|
||||||
if (size < 0)
|
|
||||||
return MZ_PARAM_ERROR;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (bytes_to_write > (size - total_written))
|
|
||||||
bytes_to_write = (size - total_written);
|
|
||||||
|
|
||||||
memcpy(wzaes->buffer, buf_ptr, bytes_to_write);
|
|
||||||
buf_ptr += bytes_to_write;
|
|
||||||
|
|
||||||
mz_stream_wzaes_ctr_encrypt(stream, (uint8_t *)wzaes->buffer, bytes_to_write);
|
|
||||||
mz_crypt_hmac_update(wzaes->hmac, wzaes->buffer, bytes_to_write);
|
|
||||||
|
|
||||||
written = mz_stream_write(wzaes->stream.base, wzaes->buffer, bytes_to_write);
|
|
||||||
if (written < 0)
|
|
||||||
return written;
|
|
||||||
|
|
||||||
total_written += written;
|
|
||||||
} while (total_written < size && written > 0);
|
|
||||||
|
|
||||||
wzaes->total_out += total_written;
|
|
||||||
return total_written;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_wzaes_tell(void *stream) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
return mz_stream_tell(wzaes->stream.base);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_wzaes_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
return mz_stream_seek(wzaes->stream.base, offset, origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_wzaes_close(void *stream) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
uint8_t expected_hash[MZ_AES_AUTHCODE_SIZE];
|
|
||||||
uint8_t computed_hash[MZ_HASH_SHA1_SIZE];
|
|
||||||
|
|
||||||
mz_crypt_hmac_end(wzaes->hmac, computed_hash, sizeof(computed_hash));
|
|
||||||
|
|
||||||
if (wzaes->mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
if (mz_stream_write(wzaes->stream.base, computed_hash, MZ_AES_AUTHCODE_SIZE) != MZ_AES_AUTHCODE_SIZE)
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
|
|
||||||
wzaes->total_out += MZ_AES_AUTHCODE_SIZE;
|
|
||||||
} else if (wzaes->mode & MZ_OPEN_MODE_READ) {
|
|
||||||
if (mz_stream_read(wzaes->stream.base, expected_hash, MZ_AES_AUTHCODE_SIZE) != MZ_AES_AUTHCODE_SIZE)
|
|
||||||
return MZ_READ_ERROR;
|
|
||||||
|
|
||||||
wzaes->total_in += MZ_AES_AUTHCODE_SIZE;
|
|
||||||
|
|
||||||
/* If entire entry was not read this will fail */
|
|
||||||
if (memcmp(computed_hash, expected_hash, MZ_AES_AUTHCODE_SIZE) != 0)
|
|
||||||
return MZ_CRC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
wzaes->initialized = 0;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_wzaes_error(void *stream) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
return wzaes->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_wzaes_set_password(void *stream, const char *password) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
wzaes->password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_wzaes_set_encryption_mode(void *stream, int16_t encryption_mode) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
wzaes->encryption_mode = encryption_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_wzaes_get_prop_int64(void *stream, int32_t prop, int64_t *value) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN:
|
|
||||||
*value = wzaes->total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
|
||||||
*value = wzaes->total_out;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
*value = wzaes->max_total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_HEADER_SIZE:
|
|
||||||
*value = MZ_AES_SALT_LENGTH((int64_t)wzaes->encryption_mode) + MZ_AES_PW_VERIFY_SIZE;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_FOOTER_SIZE:
|
|
||||||
*value = MZ_AES_AUTHCODE_SIZE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_wzaes_set_prop_int64(void *stream, int32_t prop, int64_t value) {
|
|
||||||
mz_stream_wzaes *wzaes = (mz_stream_wzaes *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
wzaes->max_total_in = value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_wzaes_create(void **stream) {
|
|
||||||
mz_stream_wzaes *wzaes = NULL;
|
|
||||||
|
|
||||||
wzaes = (mz_stream_wzaes *)MZ_ALLOC(sizeof(mz_stream_wzaes));
|
|
||||||
if (wzaes != NULL) {
|
|
||||||
memset(wzaes, 0, sizeof(mz_stream_wzaes));
|
|
||||||
wzaes->stream.vtbl = &mz_stream_wzaes_vtbl;
|
|
||||||
wzaes->encryption_mode = MZ_AES_ENCRYPTION_MODE_256;
|
|
||||||
|
|
||||||
mz_crypt_hmac_create(&wzaes->hmac);
|
|
||||||
mz_crypt_aes_create(&wzaes->aes);
|
|
||||||
}
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = wzaes;
|
|
||||||
|
|
||||||
return wzaes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_wzaes_delete(void **stream) {
|
|
||||||
mz_stream_wzaes *wzaes = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
wzaes = (mz_stream_wzaes *)*stream;
|
|
||||||
if (wzaes != NULL) {
|
|
||||||
mz_crypt_aes_delete(&wzaes->aes);
|
|
||||||
mz_crypt_hmac_delete(&wzaes->hmac);
|
|
||||||
MZ_FREE(wzaes);
|
|
||||||
}
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_wzaes_get_interface(void) {
|
|
||||||
return (void *)&mz_stream_wzaes_vtbl;
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
/* mz_strm_wzaes.h -- Stream for WinZIP AES encryption
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_STREAM_WZAES_SHA1_H
|
|
||||||
#define MZ_STREAM_WZAES_SHA1_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_wzaes_open(void *stream, const char *filename, int32_t mode);
|
|
||||||
int32_t mz_stream_wzaes_is_open(void *stream);
|
|
||||||
int32_t mz_stream_wzaes_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_wzaes_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int64_t mz_stream_wzaes_tell(void *stream);
|
|
||||||
int32_t mz_stream_wzaes_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_wzaes_close(void *stream);
|
|
||||||
int32_t mz_stream_wzaes_error(void *stream);
|
|
||||||
|
|
||||||
void mz_stream_wzaes_set_password(void *stream, const char *password);
|
|
||||||
void mz_stream_wzaes_set_encryption_mode(void *stream, int16_t encryption_mode);
|
|
||||||
|
|
||||||
int32_t mz_stream_wzaes_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
|
||||||
int32_t mz_stream_wzaes_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
|
||||||
|
|
||||||
void* mz_stream_wzaes_create(void **stream);
|
|
||||||
void mz_stream_wzaes_delete(void **stream);
|
|
||||||
|
|
||||||
void* mz_stream_wzaes_get_interface(void);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,393 +0,0 @@
|
||||||
/* mz_strm_zlib.c -- Stream for zlib inflate/deflate
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_zlib.h"
|
|
||||||
|
|
||||||
#include "zlib.h"
|
|
||||||
#if defined(ZLIBNG_VERNUM) && !defined(ZLIB_COMPAT)
|
|
||||||
# include "zlib-ng.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#if defined(ZLIBNG_VERNUM) && !defined(ZLIB_COMPAT)
|
|
||||||
# define ZLIB_PREFIX(x) zng_ ## x
|
|
||||||
typedef zng_stream zlib_stream;
|
|
||||||
#else
|
|
||||||
# define ZLIB_PREFIX(x) x
|
|
||||||
typedef z_stream zlib_stream;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(DEF_MEM_LEVEL)
|
|
||||||
# if MAX_MEM_LEVEL >= 8
|
|
||||||
# define DEF_MEM_LEVEL 8
|
|
||||||
# else
|
|
||||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_zlib_vtbl = {
|
|
||||||
mz_stream_zlib_open,
|
|
||||||
mz_stream_zlib_is_open,
|
|
||||||
mz_stream_zlib_read,
|
|
||||||
mz_stream_zlib_write,
|
|
||||||
mz_stream_zlib_tell,
|
|
||||||
mz_stream_zlib_seek,
|
|
||||||
mz_stream_zlib_close,
|
|
||||||
mz_stream_zlib_error,
|
|
||||||
mz_stream_zlib_create,
|
|
||||||
mz_stream_zlib_delete,
|
|
||||||
mz_stream_zlib_get_prop_int64,
|
|
||||||
mz_stream_zlib_set_prop_int64
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_zlib_s {
|
|
||||||
mz_stream stream;
|
|
||||||
zlib_stream zstream;
|
|
||||||
uint8_t buffer[INT16_MAX];
|
|
||||||
int32_t buffer_len;
|
|
||||||
int64_t total_in;
|
|
||||||
int64_t total_out;
|
|
||||||
int64_t max_total_in;
|
|
||||||
int8_t initialized;
|
|
||||||
int16_t level;
|
|
||||||
int32_t window_bits;
|
|
||||||
int32_t mode;
|
|
||||||
int32_t error;
|
|
||||||
} mz_stream_zlib;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_zlib_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream_zlib *zlib = (mz_stream_zlib *)stream;
|
|
||||||
|
|
||||||
MZ_UNUSED(path);
|
|
||||||
|
|
||||||
zlib->zstream.data_type = Z_BINARY;
|
|
||||||
zlib->zstream.zalloc = Z_NULL;
|
|
||||||
zlib->zstream.zfree = Z_NULL;
|
|
||||||
zlib->zstream.opaque = Z_NULL;
|
|
||||||
zlib->zstream.total_in = 0;
|
|
||||||
zlib->zstream.total_out = 0;
|
|
||||||
|
|
||||||
zlib->total_in = 0;
|
|
||||||
zlib->total_out = 0;
|
|
||||||
|
|
||||||
if (mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
zlib->zstream.next_out = zlib->buffer;
|
|
||||||
zlib->zstream.avail_out = sizeof(zlib->buffer);
|
|
||||||
|
|
||||||
zlib->error = ZLIB_PREFIX(deflateInit2)(&zlib->zstream, (int8_t)zlib->level, Z_DEFLATED,
|
|
||||||
zlib->window_bits, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
|
|
||||||
#endif
|
|
||||||
} else if (mode & MZ_OPEN_MODE_READ) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
zlib->zstream.next_in = zlib->buffer;
|
|
||||||
zlib->zstream.avail_in = 0;
|
|
||||||
|
|
||||||
zlib->error = ZLIB_PREFIX(inflateInit2)(&zlib->zstream, zlib->window_bits);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zlib->error != Z_OK)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
|
|
||||||
zlib->initialized = 1;
|
|
||||||
zlib->mode = mode;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zlib_is_open(void *stream) {
|
|
||||||
mz_stream_zlib *zlib = (mz_stream_zlib *)stream;
|
|
||||||
if (zlib->initialized != 1)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zlib_read(void *stream, void *buf, int32_t size) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(buf);
|
|
||||||
MZ_UNUSED(size);
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_zlib *zlib = (mz_stream_zlib *)stream;
|
|
||||||
uint64_t total_in_before = 0;
|
|
||||||
uint64_t total_in_after = 0;
|
|
||||||
uint64_t total_out_before = 0;
|
|
||||||
uint64_t total_out_after = 0;
|
|
||||||
uint32_t total_in = 0;
|
|
||||||
uint32_t total_out = 0;
|
|
||||||
uint32_t in_bytes = 0;
|
|
||||||
uint32_t out_bytes = 0;
|
|
||||||
int32_t bytes_to_read = sizeof(zlib->buffer);
|
|
||||||
int32_t read = 0;
|
|
||||||
int32_t err = Z_OK;
|
|
||||||
|
|
||||||
|
|
||||||
zlib->zstream.next_out = (Bytef*)buf;
|
|
||||||
zlib->zstream.avail_out = (uInt)size;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (zlib->zstream.avail_in == 0) {
|
|
||||||
if (zlib->max_total_in > 0) {
|
|
||||||
if ((int64_t)bytes_to_read > (zlib->max_total_in - zlib->total_in))
|
|
||||||
bytes_to_read = (int32_t)(zlib->max_total_in - zlib->total_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
read = mz_stream_read(zlib->stream.base, zlib->buffer, bytes_to_read);
|
|
||||||
|
|
||||||
if (read < 0)
|
|
||||||
return read;
|
|
||||||
|
|
||||||
zlib->zstream.next_in = zlib->buffer;
|
|
||||||
zlib->zstream.avail_in = read;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_in_before = zlib->zstream.avail_in;
|
|
||||||
total_out_before = zlib->zstream.total_out;
|
|
||||||
|
|
||||||
err = ZLIB_PREFIX(inflate)(&zlib->zstream, Z_SYNC_FLUSH);
|
|
||||||
if ((err >= Z_OK) && (zlib->zstream.msg != NULL)) {
|
|
||||||
zlib->error = Z_DATA_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_in_after = zlib->zstream.avail_in;
|
|
||||||
total_out_after = zlib->zstream.total_out;
|
|
||||||
|
|
||||||
in_bytes = (uint32_t)(total_in_before - total_in_after);
|
|
||||||
out_bytes = (uint32_t)(total_out_after - total_out_before);
|
|
||||||
|
|
||||||
total_in += in_bytes;
|
|
||||||
total_out += out_bytes;
|
|
||||||
|
|
||||||
zlib->total_in += in_bytes;
|
|
||||||
zlib->total_out += out_bytes;
|
|
||||||
|
|
||||||
if (err == Z_STREAM_END)
|
|
||||||
break;
|
|
||||||
if (err != Z_OK) {
|
|
||||||
zlib->error = err;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (zlib->zstream.avail_out > 0);
|
|
||||||
|
|
||||||
if (zlib->error != 0) {
|
|
||||||
/* Zlib errors are compatible with MZ */
|
|
||||||
return zlib->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return total_out;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef MZ_ZIP_NO_COMPRESSION
|
|
||||||
static int32_t mz_stream_zlib_flush(void *stream) {
|
|
||||||
mz_stream_zlib *zlib = (mz_stream_zlib *)stream;
|
|
||||||
if (mz_stream_write(zlib->stream.base, zlib->buffer, zlib->buffer_len) != zlib->buffer_len)
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_zlib_deflate(void *stream, int flush) {
|
|
||||||
mz_stream_zlib *zlib = (mz_stream_zlib *)stream;
|
|
||||||
uint64_t total_out_before = 0;
|
|
||||||
uint64_t total_out_after = 0;
|
|
||||||
int32_t out_bytes = 0;
|
|
||||||
int32_t err = Z_OK;
|
|
||||||
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (zlib->zstream.avail_out == 0) {
|
|
||||||
err = mz_stream_zlib_flush(zlib);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
zlib->zstream.avail_out = sizeof(zlib->buffer);
|
|
||||||
zlib->zstream.next_out = zlib->buffer;
|
|
||||||
|
|
||||||
zlib->buffer_len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_out_before = zlib->zstream.total_out;
|
|
||||||
err = ZLIB_PREFIX(deflate)(&zlib->zstream, flush);
|
|
||||||
total_out_after = zlib->zstream.total_out;
|
|
||||||
|
|
||||||
out_bytes = (uint32_t)(total_out_after - total_out_before);
|
|
||||||
|
|
||||||
zlib->buffer_len += out_bytes;
|
|
||||||
zlib->total_out += out_bytes;
|
|
||||||
|
|
||||||
if (err == Z_STREAM_END)
|
|
||||||
break;
|
|
||||||
if (err != Z_OK) {
|
|
||||||
zlib->error = err;
|
|
||||||
return MZ_DATA_ERROR;
|
|
||||||
}
|
|
||||||
} while ((zlib->zstream.avail_in > 0) || (flush == Z_FINISH && err == Z_OK));
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int32_t mz_stream_zlib_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(buf);
|
|
||||||
MZ_UNUSED(size);
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_zlib *zlib = (mz_stream_zlib *)stream;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
zlib->zstream.next_in = (Bytef*)(intptr_t)buf;
|
|
||||||
zlib->zstream.avail_in = (uInt)size;
|
|
||||||
|
|
||||||
err = mz_stream_zlib_deflate(stream, Z_NO_FLUSH);
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
zlib->total_in += size;
|
|
||||||
return size;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_zlib_tell(void *stream) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
|
|
||||||
return MZ_TELL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zlib_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(offset);
|
|
||||||
MZ_UNUSED(origin);
|
|
||||||
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zlib_close(void *stream) {
|
|
||||||
mz_stream_zlib *zlib = (mz_stream_zlib *)stream;
|
|
||||||
|
|
||||||
|
|
||||||
if (zlib->mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_zlib_deflate(stream, Z_FINISH);
|
|
||||||
mz_stream_zlib_flush(stream);
|
|
||||||
|
|
||||||
ZLIB_PREFIX(deflateEnd)(&zlib->zstream);
|
|
||||||
#endif
|
|
||||||
} else if (zlib->mode & MZ_OPEN_MODE_READ) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
ZLIB_PREFIX(inflateEnd)(&zlib->zstream);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
zlib->initialized = 0;
|
|
||||||
|
|
||||||
if (zlib->error != Z_OK)
|
|
||||||
return MZ_CLOSE_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zlib_error(void *stream) {
|
|
||||||
mz_stream_zlib *zlib = (mz_stream_zlib *)stream;
|
|
||||||
return zlib->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zlib_get_prop_int64(void *stream, int32_t prop, int64_t *value) {
|
|
||||||
mz_stream_zlib *zlib = (mz_stream_zlib *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN:
|
|
||||||
*value = zlib->total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
*value = zlib->max_total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
|
||||||
*value = zlib->total_out;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_HEADER_SIZE:
|
|
||||||
*value = 0;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_COMPRESS_WINDOW:
|
|
||||||
*value = zlib->window_bits;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zlib_set_prop_int64(void *stream, int32_t prop, int64_t value) {
|
|
||||||
mz_stream_zlib *zlib = (mz_stream_zlib *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_COMPRESS_LEVEL:
|
|
||||||
zlib->level = (int16_t)value;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
zlib->max_total_in = value;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_COMPRESS_WINDOW:
|
|
||||||
zlib->window_bits = (int32_t)value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_zlib_create(void **stream) {
|
|
||||||
mz_stream_zlib *zlib = NULL;
|
|
||||||
|
|
||||||
zlib = (mz_stream_zlib *)MZ_ALLOC(sizeof(mz_stream_zlib));
|
|
||||||
if (zlib != NULL) {
|
|
||||||
memset(zlib, 0, sizeof(mz_stream_zlib));
|
|
||||||
zlib->stream.vtbl = &mz_stream_zlib_vtbl;
|
|
||||||
zlib->level = Z_DEFAULT_COMPRESSION;
|
|
||||||
zlib->window_bits = -MAX_WBITS;
|
|
||||||
}
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = zlib;
|
|
||||||
|
|
||||||
return zlib;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_zlib_delete(void **stream) {
|
|
||||||
mz_stream_zlib *zlib = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
zlib = (mz_stream_zlib *)*stream;
|
|
||||||
if (zlib != NULL)
|
|
||||||
MZ_FREE(zlib);
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_zlib_get_interface(void) {
|
|
||||||
return (void *)&mz_stream_zlib_vtbl;
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/* mz_strm_zlib.h -- Stream for zlib inflate/deflate
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_STREAM_ZLIB_H
|
|
||||||
#define MZ_STREAM_ZLIB_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_zlib_open(void *stream, const char *filename, int32_t mode);
|
|
||||||
int32_t mz_stream_zlib_is_open(void *stream);
|
|
||||||
int32_t mz_stream_zlib_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_zlib_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int64_t mz_stream_zlib_tell(void *stream);
|
|
||||||
int32_t mz_stream_zlib_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_zlib_close(void *stream);
|
|
||||||
int32_t mz_stream_zlib_error(void *stream);
|
|
||||||
|
|
||||||
int32_t mz_stream_zlib_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
|
||||||
int32_t mz_stream_zlib_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
|
||||||
|
|
||||||
void* mz_stream_zlib_create(void **stream);
|
|
||||||
void mz_stream_zlib_delete(void **stream);
|
|
||||||
|
|
||||||
void* mz_stream_zlib_get_interface(void);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,351 +0,0 @@
|
||||||
/* mz_strm_zstd.c -- Stream for zstd compress/decompress
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
Authors: Force Charlie
|
|
||||||
https://github.com/fcharlie
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mz.h"
|
|
||||||
#include "mz_strm.h"
|
|
||||||
#include "mz_strm_zstd.h"
|
|
||||||
|
|
||||||
#include <zstd.h>
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
static mz_stream_vtbl mz_stream_zstd_vtbl = {
|
|
||||||
mz_stream_zstd_open,
|
|
||||||
mz_stream_zstd_is_open,
|
|
||||||
mz_stream_zstd_read,
|
|
||||||
mz_stream_zstd_write,
|
|
||||||
mz_stream_zstd_tell,
|
|
||||||
mz_stream_zstd_seek,
|
|
||||||
mz_stream_zstd_close,
|
|
||||||
mz_stream_zstd_error,
|
|
||||||
mz_stream_zstd_create,
|
|
||||||
mz_stream_zstd_delete,
|
|
||||||
mz_stream_zstd_get_prop_int64,
|
|
||||||
mz_stream_zstd_set_prop_int64
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_stream_zstd_s {
|
|
||||||
mz_stream stream;
|
|
||||||
ZSTD_CStream *zcstream;
|
|
||||||
ZSTD_DStream *zdstream;
|
|
||||||
ZSTD_outBuffer out;
|
|
||||||
ZSTD_inBuffer in;
|
|
||||||
int32_t mode;
|
|
||||||
int32_t error;
|
|
||||||
uint8_t buffer[INT16_MAX];
|
|
||||||
int32_t buffer_len;
|
|
||||||
int64_t total_in;
|
|
||||||
int64_t total_out;
|
|
||||||
int64_t max_total_in;
|
|
||||||
int64_t max_total_out;
|
|
||||||
int8_t initialized;
|
|
||||||
uint32_t preset;
|
|
||||||
} mz_stream_zstd;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_zstd_open(void *stream, const char *path, int32_t mode) {
|
|
||||||
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
|
||||||
|
|
||||||
MZ_UNUSED(path);
|
|
||||||
|
|
||||||
if (mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
zstd->zcstream = ZSTD_createCStream();
|
|
||||||
zstd->out.dst = zstd->buffer;
|
|
||||||
zstd->out.size = sizeof(zstd->buffer);
|
|
||||||
zstd->out.pos = 0;
|
|
||||||
#endif
|
|
||||||
} else if (mode & MZ_OPEN_MODE_READ) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
zstd->zdstream = ZSTD_createDStream();
|
|
||||||
memset(&zstd->out, 0, sizeof(ZSTD_outBuffer));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&zstd->in, 0, sizeof(ZSTD_inBuffer));
|
|
||||||
|
|
||||||
zstd->initialized = 1;
|
|
||||||
zstd->mode = mode;
|
|
||||||
zstd->error = MZ_OK;
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zstd_is_open(void *stream) {
|
|
||||||
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
|
||||||
if (zstd->initialized != 1)
|
|
||||||
return MZ_OPEN_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zstd_read(void *stream, void *buf, int32_t size) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(buf);
|
|
||||||
MZ_UNUSED(size);
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
|
||||||
uint64_t total_in_before = 0;
|
|
||||||
uint64_t total_in_after = 0;
|
|
||||||
uint64_t total_out_before = 0;
|
|
||||||
uint64_t total_out_after = 0;
|
|
||||||
int32_t total_in = 0;
|
|
||||||
int32_t total_out = 0;
|
|
||||||
int32_t in_bytes = 0;
|
|
||||||
int32_t out_bytes = 0;
|
|
||||||
int32_t bytes_to_read = sizeof(zstd->buffer);
|
|
||||||
int32_t read = 0;
|
|
||||||
size_t result = 0;
|
|
||||||
|
|
||||||
zstd->out.dst = (void*)buf;
|
|
||||||
zstd->out.size = (size_t)size;
|
|
||||||
zstd->out.pos = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (zstd->in.pos == zstd->in.size) {
|
|
||||||
if (zstd->max_total_in > 0) {
|
|
||||||
if ((int64_t)bytes_to_read > (zstd->max_total_in - zstd->total_in))
|
|
||||||
bytes_to_read = (int32_t)(zstd->max_total_in - zstd->total_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
read = mz_stream_read(zstd->stream.base, zstd->buffer, bytes_to_read);
|
|
||||||
|
|
||||||
if (read < 0)
|
|
||||||
return read;
|
|
||||||
|
|
||||||
zstd->in.src = (const void*)zstd->buffer;
|
|
||||||
zstd->in.pos = 0;
|
|
||||||
zstd->in.size = (size_t)read;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_in_before = zstd->in.pos;
|
|
||||||
total_out_before = zstd->out.pos;
|
|
||||||
|
|
||||||
result = ZSTD_decompressStream(zstd->zdstream, &zstd->out, &zstd->in);
|
|
||||||
|
|
||||||
if (ZSTD_isError(result)) {
|
|
||||||
zstd->error = (int32_t)result;
|
|
||||||
return MZ_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_in_after = zstd->in.pos;
|
|
||||||
total_out_after = zstd->out.pos;
|
|
||||||
if ((zstd->max_total_out != -1) && (int64_t)total_out_after > zstd->max_total_out)
|
|
||||||
total_out_after = (uint64_t)zstd->max_total_out;
|
|
||||||
|
|
||||||
in_bytes = (int32_t)(total_in_after - total_in_before);
|
|
||||||
out_bytes = (int32_t)(total_out_after - total_out_before);
|
|
||||||
|
|
||||||
total_in += in_bytes;
|
|
||||||
total_out += out_bytes;
|
|
||||||
|
|
||||||
zstd->total_in += in_bytes;
|
|
||||||
zstd->total_out += out_bytes;
|
|
||||||
|
|
||||||
} while ((zstd->in.size > 0 || out_bytes > 0) && (zstd->out.pos < zstd->out.size));
|
|
||||||
|
|
||||||
return total_out;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef MZ_ZIP_NO_COMPRESSION
|
|
||||||
static int32_t mz_stream_zstd_flush(void *stream) {
|
|
||||||
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
|
||||||
if (mz_stream_write(zstd->stream.base, zstd->buffer, zstd->buffer_len) != zstd->buffer_len)
|
|
||||||
return MZ_WRITE_ERROR;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t mz_stream_zstd_compress(void *stream, ZSTD_EndDirective flush) {
|
|
||||||
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
|
||||||
uint64_t total_out_before = 0;
|
|
||||||
uint64_t total_out_after = 0;
|
|
||||||
int32_t out_bytes = 0;
|
|
||||||
size_t result = 0;
|
|
||||||
int32_t err = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (zstd->out.pos == zstd->out.size) {
|
|
||||||
err = mz_stream_zstd_flush(zstd);
|
|
||||||
if (err != MZ_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
zstd->out.dst = zstd->buffer;
|
|
||||||
zstd->out.size = sizeof(zstd->buffer);
|
|
||||||
zstd->out.pos = 0;
|
|
||||||
|
|
||||||
zstd->buffer_len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_out_before = zstd->out.pos;
|
|
||||||
|
|
||||||
result = ZSTD_compressStream2(zstd->zcstream, &zstd->out, &zstd->in, flush);
|
|
||||||
|
|
||||||
total_out_after = zstd->out.pos;
|
|
||||||
|
|
||||||
out_bytes = (uint32_t)(total_out_after - total_out_before);
|
|
||||||
|
|
||||||
zstd->buffer_len += out_bytes;
|
|
||||||
zstd->total_out += out_bytes;
|
|
||||||
|
|
||||||
if (ZSTD_isError(result)) {
|
|
||||||
zstd->error = (int32_t)result;
|
|
||||||
return MZ_DATA_ERROR;
|
|
||||||
}
|
|
||||||
} while ((zstd->in.pos < zstd->in.size) || (flush == ZSTD_e_end && result != 0));
|
|
||||||
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int32_t mz_stream_zstd_write(void *stream, const void *buf, int32_t size) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(buf);
|
|
||||||
MZ_UNUSED(size);
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
|
||||||
int32_t err = MZ_OK;
|
|
||||||
|
|
||||||
zstd->in.src = buf;
|
|
||||||
zstd->in.pos = 0;
|
|
||||||
zstd->in.size = size;
|
|
||||||
|
|
||||||
err = mz_stream_zstd_compress(stream, ZSTD_e_continue);
|
|
||||||
if (err != MZ_OK) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
zstd->total_in += size;
|
|
||||||
return size;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t mz_stream_zstd_tell(void *stream) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
|
|
||||||
return MZ_TELL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zstd_seek(void *stream, int64_t offset, int32_t origin) {
|
|
||||||
MZ_UNUSED(stream);
|
|
||||||
MZ_UNUSED(offset);
|
|
||||||
MZ_UNUSED(origin);
|
|
||||||
|
|
||||||
return MZ_SEEK_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zstd_close(void *stream) {
|
|
||||||
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
|
||||||
|
|
||||||
if (zstd->mode & MZ_OPEN_MODE_WRITE) {
|
|
||||||
#ifdef MZ_ZIP_NO_COMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
mz_stream_zstd_compress(stream, ZSTD_e_end);
|
|
||||||
mz_stream_zstd_flush(stream);
|
|
||||||
|
|
||||||
ZSTD_freeCStream(zstd->zcstream);
|
|
||||||
zstd->zcstream = NULL;
|
|
||||||
#endif
|
|
||||||
} else if (zstd->mode & MZ_OPEN_MODE_READ) {
|
|
||||||
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
|
||||||
return MZ_SUPPORT_ERROR;
|
|
||||||
#else
|
|
||||||
ZSTD_freeDStream(zstd->zdstream);
|
|
||||||
zstd->zdstream = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
zstd->initialized = 0;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zstd_error(void *stream) {
|
|
||||||
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
|
||||||
return zstd->error;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zstd_get_prop_int64(void *stream, int32_t prop, int64_t *value) {
|
|
||||||
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN:
|
|
||||||
*value = zstd->total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
*value = zstd->max_total_in;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_OUT:
|
|
||||||
*value = zstd->total_out;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_OUT_MAX:
|
|
||||||
*value = zstd->max_total_out;
|
|
||||||
break;
|
|
||||||
case MZ_STREAM_PROP_HEADER_SIZE:
|
|
||||||
*value = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mz_stream_zstd_set_prop_int64(void *stream, int32_t prop, int64_t value) {
|
|
||||||
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
|
||||||
switch (prop) {
|
|
||||||
case MZ_STREAM_PROP_COMPRESS_LEVEL:
|
|
||||||
if (value < 0)
|
|
||||||
zstd->preset = 6;
|
|
||||||
else
|
|
||||||
zstd->preset = (int16_t)value;
|
|
||||||
return MZ_OK;
|
|
||||||
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
|
||||||
zstd->max_total_in = value;
|
|
||||||
return MZ_OK;
|
|
||||||
}
|
|
||||||
return MZ_EXIST_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_zstd_create(void **stream) {
|
|
||||||
mz_stream_zstd *zstd = NULL;
|
|
||||||
zstd = (mz_stream_zstd *)MZ_ALLOC(sizeof(mz_stream_zstd));
|
|
||||||
if (zstd != NULL) {
|
|
||||||
memset(zstd, 0, sizeof(mz_stream_zstd));
|
|
||||||
zstd->stream.vtbl = &mz_stream_zstd_vtbl;
|
|
||||||
zstd->max_total_out = -1;
|
|
||||||
}
|
|
||||||
if (stream != NULL)
|
|
||||||
*stream = zstd;
|
|
||||||
return zstd;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mz_stream_zstd_delete(void **stream) {
|
|
||||||
mz_stream_zstd *zstd = NULL;
|
|
||||||
if (stream == NULL)
|
|
||||||
return;
|
|
||||||
zstd = (mz_stream_zstd *)*stream;
|
|
||||||
if (zstd != NULL)
|
|
||||||
MZ_FREE(zstd);
|
|
||||||
*stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mz_stream_zstd_get_interface(void) {
|
|
||||||
return (void *)&mz_stream_zstd_vtbl;
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
/* mz_strm_zlib.h -- Stream for zlib inflate/deflate
|
|
||||||
Version 2.9.2, February 12, 2020
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_STREAM_ZSTD_H
|
|
||||||
#define MZ_STREAM_ZSTD_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_stream_zstd_open(void *stream, const char *filename, int32_t mode);
|
|
||||||
int32_t mz_stream_zstd_is_open(void *stream);
|
|
||||||
int32_t mz_stream_zstd_read(void *stream, void *buf, int32_t size);
|
|
||||||
int32_t mz_stream_zstd_write(void *stream, const void *buf, int32_t size);
|
|
||||||
int64_t mz_stream_zstd_tell(void *stream);
|
|
||||||
int32_t mz_stream_zstd_seek(void *stream, int64_t offset, int32_t origin);
|
|
||||||
int32_t mz_stream_zstd_close(void *stream);
|
|
||||||
int32_t mz_stream_zstd_error(void *stream);
|
|
||||||
|
|
||||||
int32_t mz_stream_zstd_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
|
||||||
int32_t mz_stream_zstd_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
|
||||||
|
|
||||||
void* mz_stream_zstd_create(void **stream);
|
|
||||||
void mz_stream_zstd_delete(void **stream);
|
|
||||||
|
|
||||||
void* mz_stream_zstd_get_interface(void);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,259 +0,0 @@
|
||||||
/* mz_zip.h -- Zip manipulation
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
Copyright (C) 2009-2010 Mathias Svensson
|
|
||||||
Modifications for Zip64 support
|
|
||||||
http://result42.com
|
|
||||||
Copyright (C) 1998-2010 Gilles Vollant
|
|
||||||
https://www.winimage.com/zLibDll/minizip.html
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_ZIP_H
|
|
||||||
#define MZ_ZIP_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef struct mz_zip_file_s {
|
|
||||||
uint16_t version_madeby; /* version made by */
|
|
||||||
uint16_t version_needed; /* version needed to extract */
|
|
||||||
uint16_t flag; /* general purpose bit flag */
|
|
||||||
uint16_t compression_method; /* compression method */
|
|
||||||
time_t modified_date; /* last modified date in unix time */
|
|
||||||
time_t accessed_date; /* last accessed date in unix time */
|
|
||||||
time_t creation_date; /* creation date in unix time */
|
|
||||||
uint32_t crc; /* crc-32 */
|
|
||||||
int64_t compressed_size; /* compressed size */
|
|
||||||
int64_t uncompressed_size; /* uncompressed size */
|
|
||||||
uint16_t filename_size; /* filename length */
|
|
||||||
uint16_t extrafield_size; /* extra field length */
|
|
||||||
uint16_t comment_size; /* file comment length */
|
|
||||||
uint32_t disk_number; /* disk number start */
|
|
||||||
int64_t disk_offset; /* relative offset of local header */
|
|
||||||
uint16_t internal_fa; /* internal file attributes */
|
|
||||||
uint32_t external_fa; /* external file attributes */
|
|
||||||
|
|
||||||
const char *filename; /* filename utf8 null-terminated string */
|
|
||||||
const uint8_t *extrafield; /* extrafield data */
|
|
||||||
const char *comment; /* comment utf8 null-terminated string */
|
|
||||||
const char *linkname; /* sym-link filename utf8 null-terminated string */
|
|
||||||
|
|
||||||
uint16_t zip64; /* zip64 extension mode */
|
|
||||||
uint16_t aes_version; /* winzip aes extension if not 0 */
|
|
||||||
uint8_t aes_encryption_mode; /* winzip aes encryption mode */
|
|
||||||
uint16_t pk_verify; /* pkware encryption verifier */
|
|
||||||
|
|
||||||
} mz_zip_file, mz_zip_entry;
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef int32_t (*mz_zip_locate_entry_cb)(void *handle, void *userdata, mz_zip_file *file_info);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void * mz_zip_create(void **handle);
|
|
||||||
/* Create zip instance for opening */
|
|
||||||
|
|
||||||
void mz_zip_delete(void **handle);
|
|
||||||
/* Delete zip object */
|
|
||||||
|
|
||||||
int32_t mz_zip_open(void *handle, void *stream, int32_t mode);
|
|
||||||
/* Create a zip file, no delete file in zip functionality */
|
|
||||||
|
|
||||||
int32_t mz_zip_close(void *handle);
|
|
||||||
/* Close the zip file */
|
|
||||||
|
|
||||||
int32_t mz_zip_get_comment(void *handle, const char **comment);
|
|
||||||
/* Get a pointer to the global comment */
|
|
||||||
|
|
||||||
int32_t mz_zip_set_comment(void *handle, const char *comment);
|
|
||||||
/* Sets the global comment used for writing zip file */
|
|
||||||
|
|
||||||
int32_t mz_zip_get_version_madeby(void *handle, uint16_t *version_madeby);
|
|
||||||
/* Get the version made by */
|
|
||||||
|
|
||||||
int32_t mz_zip_set_version_madeby(void *handle, uint16_t version_madeby);
|
|
||||||
/* Sets the version made by used for writing zip file */
|
|
||||||
|
|
||||||
int32_t mz_zip_set_recover(void *handle, uint8_t recover);
|
|
||||||
/* Sets the ability to recover the central dir by reading local file headers */
|
|
||||||
|
|
||||||
int32_t mz_zip_set_data_descriptor(void *handle, uint8_t data_descriptor);
|
|
||||||
/* Sets the use of data descriptor flag when writing zip entries */
|
|
||||||
|
|
||||||
int32_t mz_zip_get_stream(void *handle, void **stream);
|
|
||||||
/* Get a pointer to the stream used to open */
|
|
||||||
|
|
||||||
int32_t mz_zip_set_cd_stream(void *handle, int64_t cd_start_pos, void *cd_stream);
|
|
||||||
/* Sets the stream to use for reading the central dir */
|
|
||||||
|
|
||||||
int32_t mz_zip_get_cd_mem_stream(void *handle, void **cd_mem_stream);
|
|
||||||
/* Get a pointer to the stream used to store the central dir in memory */
|
|
||||||
|
|
||||||
int32_t mz_zip_set_number_entry(void *handle, uint64_t number_entry);
|
|
||||||
/* Sets the total number of entries */
|
|
||||||
|
|
||||||
int32_t mz_zip_get_number_entry(void *handle, uint64_t *number_entry);
|
|
||||||
/* Get the total number of entries */
|
|
||||||
|
|
||||||
int32_t mz_zip_set_disk_number_with_cd(void *handle, uint32_t disk_number_with_cd);
|
|
||||||
/* Sets the disk number containing the central directory record */
|
|
||||||
|
|
||||||
int32_t mz_zip_get_disk_number_with_cd(void *handle, uint32_t *disk_number_with_cd);
|
|
||||||
/* Get the disk number containing the central directory record */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_is_open(void *handle);
|
|
||||||
/* Check to see if entry is open for read/write */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_read_open(void *handle, uint8_t raw, const char *password);
|
|
||||||
/* Open for reading the current file in the zip file */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_read(void *handle, void *buf, int32_t len);
|
|
||||||
/* Read bytes from the current file in the zip file */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_read_close(void *handle, uint32_t *crc32, int64_t *compressed_size,
|
|
||||||
int64_t *uncompressed_size);
|
|
||||||
/* Close the current file for reading and get data descriptor values */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_write_open(void *handle, const mz_zip_file *file_info,
|
|
||||||
int16_t compress_level, uint8_t raw, const char *password);
|
|
||||||
/* Open for writing the current file in the zip file */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_write(void *handle, const void *buf, int32_t len);
|
|
||||||
/* Write bytes from the current file in the zip file */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_write_close(void *handle, uint32_t crc32, int64_t compressed_size,
|
|
||||||
int64_t uncompressed_size);
|
|
||||||
/* Close the current file for writing and set data descriptor values */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_seek_local_header(void *handle);
|
|
||||||
/* Seeks to the local header for the entry */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_close_raw(void *handle, int64_t uncompressed_size, uint32_t crc32);
|
|
||||||
/* Close the current file in the zip file where raw is compressed data */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_close(void *handle);
|
|
||||||
/* Close the current file in the zip file */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_is_dir(void *handle);
|
|
||||||
/* Checks to see if the entry is a directory */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_is_symlink(void *handle);
|
|
||||||
/* Checks to see if the entry is a symbolic link */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_get_info(void *handle, mz_zip_file **file_info);
|
|
||||||
/* Get info about the current file, only valid while current entry is open */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_get_local_info(void *handle, mz_zip_file **local_file_info);
|
|
||||||
/* Get local info about the current file, only valid while current entry is being read */
|
|
||||||
|
|
||||||
int32_t mz_zip_entry_set_extrafield(void *handle, const uint8_t *extrafield, uint16_t extrafield_size);
|
|
||||||
/* Sets or updates the extra field for the entry to be used before writing cd */
|
|
||||||
|
|
||||||
int64_t mz_zip_get_entry(void *handle);
|
|
||||||
/* Return offset of the current entry in the zip file */
|
|
||||||
|
|
||||||
int32_t mz_zip_goto_entry(void *handle, int64_t cd_pos);
|
|
||||||
/* Go to specified entry in the zip file */
|
|
||||||
|
|
||||||
int32_t mz_zip_goto_first_entry(void *handle);
|
|
||||||
/* Go to the first entry in the zip file */
|
|
||||||
|
|
||||||
int32_t 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 */
|
|
||||||
|
|
||||||
int32_t mz_zip_locate_entry(void *handle, const char *filename, uint8_t ignore_case);
|
|
||||||
/* Locate the file with the specified name in the zip file or MZ_END_LIST if not found */
|
|
||||||
|
|
||||||
int32_t mz_zip_locate_first_entry(void *handle, void *userdata, mz_zip_locate_entry_cb cb);
|
|
||||||
/* Locate the first matching entry based on a match callback */
|
|
||||||
|
|
||||||
int32_t mz_zip_locate_next_entry(void *handle, void *userdata, mz_zip_locate_entry_cb cb);
|
|
||||||
/* Locate the next matching entry based on a match callback */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_attrib_is_dir(uint32_t attrib, int32_t version_madeby);
|
|
||||||
/* Checks to see if the attribute is a directory based on platform */
|
|
||||||
|
|
||||||
int32_t mz_zip_attrib_is_symlink(uint32_t attrib, int32_t version_madeby);
|
|
||||||
/* Checks to see if the attribute is a symbolic link based on platform */
|
|
||||||
|
|
||||||
int32_t mz_zip_attrib_convert(uint8_t src_sys, uint32_t src_attrib, uint8_t target_sys,
|
|
||||||
uint32_t *target_attrib);
|
|
||||||
/* Converts file attributes from one host system to another */
|
|
||||||
|
|
||||||
int32_t mz_zip_attrib_posix_to_win32(uint32_t posix_attrib, uint32_t *win32_attrib);
|
|
||||||
/* Converts posix file attributes to win32 file attributes */
|
|
||||||
|
|
||||||
int32_t mz_zip_attrib_win32_to_posix(uint32_t win32_attrib, uint32_t *posix_attrib);
|
|
||||||
/* Converts win32 file attributes to posix file attributes */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_extrafield_find(void *stream, uint16_t type, int32_t max_seek, uint16_t *length);
|
|
||||||
/* Seeks to extra field by its type and returns its length */
|
|
||||||
|
|
||||||
int32_t mz_zip_extrafield_contains(const uint8_t *extrafield, int32_t extrafield_size,
|
|
||||||
uint16_t type, uint16_t *length);
|
|
||||||
/* Gets whether an extrafield exists and its size */
|
|
||||||
|
|
||||||
int32_t mz_zip_extrafield_read(void *stream, uint16_t *type, uint16_t *length);
|
|
||||||
/* Reads an extrafield header from a stream */
|
|
||||||
|
|
||||||
int32_t mz_zip_extrafield_write(void *stream, uint16_t type, uint16_t length);
|
|
||||||
/* Writes an extrafield header to a stream */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_dosdate_to_tm(uint64_t dos_date, struct tm *ptm);
|
|
||||||
/* Convert dos date/time format to struct tm */
|
|
||||||
|
|
||||||
time_t mz_zip_dosdate_to_time_t(uint64_t dos_date);
|
|
||||||
/* Convert dos date/time format to time_t */
|
|
||||||
|
|
||||||
int32_t mz_zip_time_t_to_tm(time_t unix_time, struct tm *ptm);
|
|
||||||
/* Convert time_t to time struct */
|
|
||||||
|
|
||||||
uint32_t mz_zip_time_t_to_dos_date(time_t unix_time);
|
|
||||||
/* Convert time_t to dos date/time format */
|
|
||||||
|
|
||||||
uint32_t mz_zip_tm_to_dosdate(const struct tm *ptm);
|
|
||||||
/* Convert struct tm to dos date/time format */
|
|
||||||
|
|
||||||
int32_t mz_zip_ntfs_to_unix_time(uint64_t ntfs_time, time_t *unix_time);
|
|
||||||
/* Convert ntfs time to unix time */
|
|
||||||
|
|
||||||
int32_t mz_zip_unix_to_ntfs_time(time_t unix_time, uint64_t *ntfs_time);
|
|
||||||
/* Convert unix time to ntfs time */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_path_compare(const char *path1, const char *path2, uint8_t ignore_case);
|
|
||||||
/* Compare two paths without regard to slashes */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
const
|
|
||||||
char* mz_zip_get_compression_method_string(int32_t compression_method);
|
|
||||||
/* Gets a string representing the compression method */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _ZIP_H */
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,285 +0,0 @@
|
||||||
/* mz_zip_rw.h -- Zip reader/writer
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
Copyright (C) 2010-2021 Nathan Moinvaziri
|
|
||||||
https://github.com/zlib-ng/minizip-ng
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_ZIP_RW_H
|
|
||||||
#define MZ_ZIP_RW_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef int32_t (*mz_zip_reader_overwrite_cb)(void *handle, void *userdata, mz_zip_file *file_info, const char *path);
|
|
||||||
typedef int32_t (*mz_zip_reader_password_cb)(void *handle, void *userdata, mz_zip_file *file_info, char *password, int32_t max_password);
|
|
||||||
typedef int32_t (*mz_zip_reader_progress_cb)(void *handle, void *userdata, mz_zip_file *file_info, int64_t position);
|
|
||||||
typedef int32_t (*mz_zip_reader_entry_cb)(void *handle, void *userdata, mz_zip_file *file_info, const char *path);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_is_open(void *handle);
|
|
||||||
/* Checks to see if the zip file is open */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_open(void *handle, void *stream);
|
|
||||||
/* Opens zip file from stream */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_open_file(void *handle, const char *path);
|
|
||||||
/* Opens zip file from a file path */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_open_file_in_memory(void *handle, const char *path);
|
|
||||||
/* Opens zip file from a file path into memory for faster access */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_open_buffer(void *handle, uint8_t *buf, int32_t len, uint8_t copy);
|
|
||||||
/* Opens zip file from memory buffer */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_close(void *handle);
|
|
||||||
/* Closes the zip file */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_unzip_cd(void *handle);
|
|
||||||
/* Unzip the central directory */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_goto_first_entry(void *handle);
|
|
||||||
/* Goto the first entry in the zip file that matches the pattern */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_goto_next_entry(void *handle);
|
|
||||||
/* Goto the next entry in the zip file that matches the pattern */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_locate_entry(void *handle, const char *filename, uint8_t ignore_case);
|
|
||||||
/* Locates an entry by filename */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_open(void *handle);
|
|
||||||
/* Opens an entry for reading */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_close(void *handle);
|
|
||||||
/* Closes an entry */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_read(void *handle, void *buf, int32_t len);
|
|
||||||
/* Reads and entry after being opened */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_has_sign(void *handle);
|
|
||||||
/* Checks to see if the entry has a signature */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_sign_verify(void *handle);
|
|
||||||
/* Verifies a signature stored with the entry */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_get_hash(void *handle, uint16_t algorithm, uint8_t *digest, int32_t digest_size);
|
|
||||||
/* Gets a hash algorithm from the entry's extra field */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_get_first_hash(void *handle, uint16_t *algorithm, uint16_t *digest_size);
|
|
||||||
/* Gets the most secure hash algorithm from the entry's extra field */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_get_info(void *handle, mz_zip_file **file_info);
|
|
||||||
/* Gets the current entry file info */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_is_dir(void *handle);
|
|
||||||
/* Gets the current entry is a directory */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_save(void *handle, void *stream, mz_stream_write_cb write_cb);
|
|
||||||
/* Save the current entry to a stream */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_save_process(void *handle, void *stream, mz_stream_write_cb write_cb);
|
|
||||||
/* Saves a portion of the current entry to a stream callback */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_save_file(void *handle, const char *path);
|
|
||||||
/* Save the current entry to a file */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_save_buffer(void *handle, void *buf, int32_t len);
|
|
||||||
/* Save the current entry to a memory buffer */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_entry_save_buffer_length(void *handle);
|
|
||||||
/* Gets the length of the buffer required to save */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_save_all(void *handle, const char *destination_dir);
|
|
||||||
/* Save all files into a directory */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void mz_zip_reader_set_pattern(void *handle, const char *pattern, uint8_t ignore_case);
|
|
||||||
/* Sets the match pattern for entries in the zip file, if null all entries are matched */
|
|
||||||
|
|
||||||
void mz_zip_reader_set_password(void *handle, const char *password);
|
|
||||||
/* Sets the password required for extraction */
|
|
||||||
|
|
||||||
void mz_zip_reader_set_raw(void *handle, uint8_t raw);
|
|
||||||
/* Sets whether or not it should save the entry raw */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_get_raw(void *handle, uint8_t *raw);
|
|
||||||
/* Gets whether or not it should save the entry raw */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_get_zip_cd(void *handle, uint8_t *zip_cd);
|
|
||||||
/* Gets whether or not the archive has a zipped central directory */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_get_comment(void *handle, const char **comment);
|
|
||||||
/* Gets the comment for the central directory */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_set_recover(void *handle, uint8_t recover);
|
|
||||||
/* Sets the ability to recover the central dir by reading local file headers */
|
|
||||||
|
|
||||||
void mz_zip_reader_set_encoding(void *handle, int32_t encoding);
|
|
||||||
/* Sets whether or not it should support a special character encoding in zip file names. */
|
|
||||||
|
|
||||||
void mz_zip_reader_set_sign_required(void *handle, uint8_t sign_required);
|
|
||||||
/* Sets whether or not it a signature is required */
|
|
||||||
|
|
||||||
void mz_zip_reader_set_overwrite_cb(void *handle, void *userdata, mz_zip_reader_overwrite_cb cb);
|
|
||||||
/* Callback for what to do when a file is being overwritten */
|
|
||||||
|
|
||||||
void mz_zip_reader_set_password_cb(void *handle, void *userdata, mz_zip_reader_password_cb cb);
|
|
||||||
/* Callback for when a password is required and hasn't been set */
|
|
||||||
|
|
||||||
void mz_zip_reader_set_progress_cb(void *handle, void *userdata, mz_zip_reader_progress_cb cb);
|
|
||||||
/* Callback for extraction progress */
|
|
||||||
|
|
||||||
void mz_zip_reader_set_progress_interval(void *handle, uint32_t milliseconds);
|
|
||||||
/* Let at least milliseconds pass between calls to progress callback */
|
|
||||||
|
|
||||||
void mz_zip_reader_set_entry_cb(void *handle, void *userdata, mz_zip_reader_entry_cb cb);
|
|
||||||
/* Callback for zip file entries */
|
|
||||||
|
|
||||||
int32_t mz_zip_reader_get_zip_handle(void *handle, void **zip_handle);
|
|
||||||
/* Gets the underlying zip instance handle */
|
|
||||||
|
|
||||||
void* mz_zip_reader_create(void **handle);
|
|
||||||
/* Create new instance of zip reader */
|
|
||||||
|
|
||||||
void mz_zip_reader_delete(void **handle);
|
|
||||||
/* Delete instance of zip reader */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
typedef int32_t (*mz_zip_writer_overwrite_cb)(void *handle, void *userdata, const char *path);
|
|
||||||
typedef int32_t (*mz_zip_writer_password_cb)(void *handle, void *userdata, mz_zip_file *file_info, char *password, int32_t max_password);
|
|
||||||
typedef int32_t (*mz_zip_writer_progress_cb)(void *handle, void *userdata, mz_zip_file *file_info, int64_t position);
|
|
||||||
typedef int32_t (*mz_zip_writer_entry_cb)(void *handle, void *userdata, mz_zip_file *file_info);
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_is_open(void *handle);
|
|
||||||
/* Checks to see if the zip file is open */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_open(void *handle, void *stream, uint8_t append);
|
|
||||||
/* Opens zip file from stream */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_open_file(void *handle, const char *path, int64_t disk_size, uint8_t append);
|
|
||||||
/* Opens zip file from a file path */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_open_file_in_memory(void *handle, const char *path);
|
|
||||||
/* Opens zip file from a file path into memory for faster access */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_close(void *handle);
|
|
||||||
/* Closes the zip file */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_entry_open(void *handle, mz_zip_file *file_info);
|
|
||||||
/* Opens an entry in the zip file for writing */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_entry_close(void *handle);
|
|
||||||
/* Closes entry in zip file */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_entry_write(void *handle, const void *buf, int32_t len);
|
|
||||||
/* Writes data into entry for zip */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_add(void *handle, void *stream, mz_stream_read_cb read_cb);
|
|
||||||
/* Writes all data to the currently open entry in the zip */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_add_process(void *handle, void *stream, mz_stream_read_cb read_cb);
|
|
||||||
/* Writes a portion of data to the currently open entry in the zip */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_add_info(void *handle, void *stream, mz_stream_read_cb read_cb, mz_zip_file *file_info);
|
|
||||||
/* Adds an entry to the zip based on the info */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_add_buffer(void *handle, void *buf, int32_t len, mz_zip_file *file_info);
|
|
||||||
/* Adds an entry to the zip with a memory buffer */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_add_file(void *handle, const char *path, const char *filename_in_zip);
|
|
||||||
/* Adds an entry to the zip from a file */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_add_path(void *handle, const char *path, const char *root_path, uint8_t include_path,
|
|
||||||
uint8_t recursive);
|
|
||||||
/* Enumerates a directory or pattern and adds entries to the zip */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_copy_from_reader(void *handle, void *reader);
|
|
||||||
/* Adds an entry from a zip reader instance */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
void mz_zip_writer_set_password(void *handle, const char *password);
|
|
||||||
/* Password to use for encrypting files in the zip */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_comment(void *handle, const char *comment);
|
|
||||||
/* Comment to use for the archive */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_raw(void *handle, uint8_t raw);
|
|
||||||
/* Sets whether or not we should write the entry raw */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_get_raw(void *handle, uint8_t *raw);
|
|
||||||
/* Gets whether or not we should write the entry raw */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_aes(void *handle, uint8_t aes);
|
|
||||||
/* Use aes encryption when adding files in zip */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_compress_method(void *handle, uint16_t compress_method);
|
|
||||||
/* Sets the compression method when adding files in zip */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_compress_level(void *handle, int16_t compress_level);
|
|
||||||
/* Sets the compression level when adding files in zip */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_follow_links(void *handle, uint8_t follow_links);
|
|
||||||
/* Follow symbolic links when traversing directories and files to add */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_store_links(void *handle, uint8_t store_links);
|
|
||||||
/* Store symbolic links in zip file */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_zip_cd(void *handle, uint8_t zip_cd);
|
|
||||||
/* Sets whether or not central directory should be zipped */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_set_certificate(void *handle, const char *cert_path, const char *cert_pwd);
|
|
||||||
/* Sets the certificate and timestamp url to use for signing when adding files in zip */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_overwrite_cb(void *handle, void *userdata, mz_zip_writer_overwrite_cb cb);
|
|
||||||
/* Callback for what to do when zip file already exists */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_password_cb(void *handle, void *userdata, mz_zip_writer_password_cb cb);
|
|
||||||
/* Callback for ask if a password is required for adding */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_progress_cb(void *handle, void *userdata, mz_zip_writer_progress_cb cb);
|
|
||||||
/* Callback for compression progress */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_progress_interval(void *handle, uint32_t milliseconds);
|
|
||||||
/* Let at least milliseconds pass between calls to progress callback */
|
|
||||||
|
|
||||||
void mz_zip_writer_set_entry_cb(void *handle, void *userdata, mz_zip_writer_entry_cb cb);
|
|
||||||
/* Callback for zip file entries */
|
|
||||||
|
|
||||||
int32_t mz_zip_writer_get_zip_handle(void *handle, void **zip_handle);
|
|
||||||
/* Gets the underlying zip handle */
|
|
||||||
|
|
||||||
void* mz_zip_writer_create(void **handle);
|
|
||||||
/* Create new instance of zip writer */
|
|
||||||
|
|
||||||
void mz_zip_writer_delete(void **handle);
|
|
||||||
/* Delete instance of zip writer */
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,13 +0,0 @@
|
||||||
/* unzip.h -- Compatibility layer shim
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_COMPAT_UNZIP
|
|
||||||
#define MZ_COMPAT_UNZIP
|
|
||||||
|
|
||||||
#include "mz_compat.h"
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,13 +0,0 @@
|
||||||
/* zip.h -- Compatibility layer shim
|
|
||||||
part of the minizip-ng project
|
|
||||||
|
|
||||||
This program is distributed under the terms of the same license as zlib.
|
|
||||||
See the accompanying LICENSE file for the full text of the license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MZ_COMPAT_ZIP
|
|
||||||
#define MZ_COMPAT_ZIP
|
|
||||||
|
|
||||||
#include "mz_compat.h"
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -50,7 +50,7 @@
|
||||||
<Import Project="$(ExternalsDir)mbedtls\exports.props" />
|
<Import Project="$(ExternalsDir)mbedtls\exports.props" />
|
||||||
<Import Project="$(ExternalsDir)mGBA\exports.props" />
|
<Import Project="$(ExternalsDir)mGBA\exports.props" />
|
||||||
<Import Project="$(ExternalsDir)miniupnpc\exports.props" />
|
<Import Project="$(ExternalsDir)miniupnpc\exports.props" />
|
||||||
<Import Project="$(ExternalsDir)minizip\exports.props" />
|
<Import Project="$(ExternalsDir)minizip-ng\exports.props" />
|
||||||
<Import Project="$(ExternalsDir)picojson\exports.props" />
|
<Import Project="$(ExternalsDir)picojson\exports.props" />
|
||||||
<Import Project="$(ExternalsDir)pugixml\exports.props" />
|
<Import Project="$(ExternalsDir)pugixml\exports.props" />
|
||||||
<Import Project="$(ExternalsDir)rcheevos\exports.props" />
|
<Import Project="$(ExternalsDir)rcheevos\exports.props" />
|
||||||
|
|
|
@ -65,7 +65,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSurround", "..\External
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "discord-rpc", "..\Externals\discord-rpc\src\discord-rpc.vcxproj", "{4482FD2A-EC43-3FFB-AC20-2E5C54B05EAD}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "discord-rpc", "..\Externals\discord-rpc\src\discord-rpc.vcxproj", "{4482FD2A-EC43-3FFB-AC20-2E5C54B05EAD}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "..\Externals\minizip\minizip.vcxproj", "{23114507-079A-4418-9707-CFA81A03CA99}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip-ng", "..\Externals\minizip-ng\minizip-ng.vcxproj", "{23114507-079A-4418-9707-CFA81A03CA99}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imgui", "..\Externals\imgui\imgui.vcxproj", "{4C3B2264-EA73-4A7B-9CFE-65B0FD635EBB}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imgui", "..\Externals\imgui\imgui.vcxproj", "{4C3B2264-EA73-4A7B-9CFE-65B0FD635EBB}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|
Loading…
Reference in New Issue