// zip_util.h : include utilities for manage zip/unzip // // Author: Gongbing // // Date: 2016-09-25 #pragma once #ifndef _INCLUDED_REF_ #define _INCLUDED_REF_ #include "../ref/ref.h" #endif ///////////////////////////////////////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////////////////////////////////// // #pragma pack(push) #pragma pack(1) typedef struct zip_local_file_header { unsigned signature; // 0x04034B50 unsigned short ver; unsigned short flag; unsigned short compression; unsigned short last_modify_time; unsigned short last_modify_date; unsigned crc; unsigned compressed_size; unsigned uncompressed_size; unsigned short name_len; unsigned short ext_len; char name[0]; char* extension() { char *ext = NULL; if (ext_len) { ext = (char*)this; ext += sizeof(struct zip_local_file_header); ext += name_len; } return ext; } }ZIPLFH, *LPZIPLFH; typedef struct zip_centeral_file_header { unsigned signature; // 0x02014B50 unsigned short ver_zip; unsigned short ver_unzip; unsigned short flag; unsigned short compression; unsigned short last_modify_time; unsigned short last_modify_date; unsigned crc; unsigned compressed_size; unsigned uncompressed_size; unsigned short name_len; unsigned short ext_len; unsigned short comment_len; unsigned short start_disk_number; unsigned short inter_file_attr; unsigned outer_file_attr; unsigned lfh_rva; char file_name[0]; // follwing by extra & comment }ZIPCFH, *LPZIPCFH; #pragma pack(pop) namespace zip_util { __declspec(novtable) struct IUnzipPack : public ref_util::IRef { // open a local packet file COM_API_DECLARE(int, open(const wchar_t* path_file, const char* pwd = NULL)); // open a memory packet content COM_API_DECLARE(int, open(void* data, size_t len, const char* pwd = NULL)); // files: to receive all items include folder // folders: to receive folders in this packet // total_size: to receive every file size(exclude folder) // return: result statu code, ERROR_SUCCESS or other error code COM_API_DECLARE(int, get_files(int *files, int* folders, UINT64* total_size)); // index: ZERO-based index in this packet // size: to receive the item bytes data in returned buffer // name: to receive the item name, maybe with relative path. call free_zip_buffer to free it // cont: to receive the content, call free_zip_buffer to free it // attr: to receive the item attribute // create_time: to receive the item created time // modi_time: to receive the item last modified time // acc_time: to receive the item last accessed time COM_API_DECLARE(int, get_item(int index, DWORD* attr, wchar_t** name = NULL, char** cont = NULL, UINT64* size = NULL , FILETIME* create_time = NULL, FILETIME* modi_time = NULL, FILETIME* acc_time = NULL)); // Function: unzip this packet to an existing local directory. caller should ensure the path local_dir is existing already // prog: data - points to a wchar_t* buffer contains the current file path // len - current file bytes of data if flag was DATA_FLAG_FINAL, when flag is DATA_FLAG_ERROR then contains error: // ERROR_ALREADY_EXISTS, return SET_RESULT_DISCARD to reserve the file; SET_RESULT_CONTINUE to overwrite // ERROR_CREATE_FAILED, create local file failed, parameter 'total' is GetLastError // ERROR_DATA_CHECKSUM_ERROR, unzip the file failed, the (wchar_t*)data is unreliable // total- all data bytes to be unzipped // flag - be DATA_FLAG_FINAL always in normal or DATA_FLAG_ERROR if error occurs // param- be prog_param always COM_API_DECLARE(int, unzip_to(const wchar_t* local_dir, inter_module_data::set_data prog, void* prog_param)); COM_API_DECLARE(int, close(void)); }; __declspec(novtable) struct IZipPack : public ref_util::IRef { // add a local file or directory into the packet, rel_path is relative to the packet // rel_path: relative to the packet, only file name if NULL. e.g. 'first\\data.txt' or 'data.txt' COM_API_DECLARE(int, add_local_file(const wchar_t* path_file, const wchar_t* rel_path = NULL)); // add memory data into the packet, rel_path_name is relative to the packet // rel_path_name: e.g. 'first\\data.txt' or 'data.txt' COM_API_DECLARE(int, add_data(void* data, size_t len, const wchar_t* rel_path_name)); // add a folder into the packet, only folder, no data. path is relative to the packet // add local directory into the packet, use add_local_file // folder_rel_path_name: e.g. 'folder' or 'top\\folder' COM_API_DECLARE(int, add_folder(const wchar_t* folder_rel_path_name)); // if you create a memory packet, this will return the start buffer and data length. // the buffer 'data' is caller passed in COM_API_DECLARE(int, get_memory_data(void** data, UINT64* len)); COM_API_DECLARE(int, close(void)); }; // Function: zip data into stream which leading by 0x1f, 0x8b, ... // data: should be zipped data // len: bytes of data // return: error code PORT_API(int) gzip_zip(const char* data, ULONGLONG len, inter_module_data::set_data result, void* result_param); // Function: unzip the gzip data which leading by 0x1f, 0x8b, ... // data: should be unzipped data // len: bytes of data // return: error code PORT_API(int) gzip_unzip(const char* data, ULONGLONG len, inter_module_data::set_data result, void* result_param); PORT_API(IZipPack*) create_zip_file(const wchar_t* local_file, const char* pwd = NULL); PORT_API(IZipPack*) create_zip_memory(void* buf, UINT64 len, const char* pwd = NULL); PORT_API(IUnzipPack*) open_zip(const wchar_t* local_file, const char* pwd = NULL); PORT_API(IUnzipPack*) open_zip(void* buf, UINT64 len, const char* pwd = NULL); };