updated 7zip to 23.01

This commit is contained in:
DavidXanatos 2023-09-14 17:51:54 +02:00
parent 555cb59a69
commit 4ee146430f
44 changed files with 7871 additions and 1028 deletions

View File

@ -5,6 +5,17 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [1.11.3 / 5.66.3] - 2023-09-
### Added
### Changed
- updated 7z library to 23.01
## [1.11.2 / 5.66.2] - 2023-09-09
### Added

View File

@ -1,4 +1,4 @@
mkdir %~dp0\7-Zip
curl -L --url https://github.com/DavidXanatos/7z/releases/download/22.00/7z2201.zip -o %~dp0\7-Zip\7z2201.zip --ssl-no-revoke
"C:\Program Files\7-Zip\7z.exe" x -bd -o%~dp0\7-Zip\ %~dp0\7-Zip\7z2201.zip
curl -L --url https://github.com/DavidXanatos/7z/releases/download/23.01/7z2301.zip -o %~dp0\7-Zip\7z2301.zip --ssl-no-revoke
"C:\Program Files\7-Zip\7z.exe" x -bd -o%~dp0\7-Zip\ %~dp0\7-Zip\7z2301.zip

View File

@ -21,8 +21,8 @@
#ifndef _MY_VERSION_H
#define _MY_VERSION_H
#define MY_VERSION_BINARY 5,66,2
#define MY_VERSION_STRING "5.66.2"
#define MY_VERSION_BINARY 5,66,3
#define MY_VERSION_STRING "5.66.3"
#define MY_ABI_VERSION 0x56500
// These #defines are used by either Resource Compiler or NSIS installer

View File

@ -0,0 +1,597 @@
/* 7zTypes.h -- Basic types
2023-04-02 : Igor Pavlov : Public domain */
#ifndef ZIP7_7Z_TYPES_H
#define ZIP7_7Z_TYPES_H
#ifdef _WIN32
/* #include <windows.h> */
#else
#include <errno.h>
#endif
#include <stddef.h>
#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif
#endif
EXTERN_C_BEGIN
#define SZ_OK 0
#define SZ_ERROR_DATA 1
#define SZ_ERROR_MEM 2
#define SZ_ERROR_CRC 3
#define SZ_ERROR_UNSUPPORTED 4
#define SZ_ERROR_PARAM 5
#define SZ_ERROR_INPUT_EOF 6
#define SZ_ERROR_OUTPUT_EOF 7
#define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9
#define SZ_ERROR_PROGRESS 10
#define SZ_ERROR_FAIL 11
#define SZ_ERROR_THREAD 12
#define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17
typedef int SRes;
#ifdef _MSC_VER
#if _MSC_VER > 1200
#define MY_ALIGN(n) __declspec(align(n))
#else
#define MY_ALIGN(n)
#endif
#else
/*
// C11/C++11:
#include <stdalign.h>
#define MY_ALIGN(n) alignas(n)
*/
#define MY_ALIGN(n) __attribute__ ((aligned(n)))
#endif
#ifdef _WIN32
/* typedef DWORD WRes; */
typedef unsigned WRes;
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
// #define MY_HRES_ERROR_INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR)
#else // _WIN32
// #define ENV_HAVE_LSTAT
typedef int WRes;
// (FACILITY_ERRNO = 0x800) is 7zip's FACILITY constant to represent (errno) errors in HRESULT
#define MY_FACILITY_ERRNO 0x800
#define MY_FACILITY_WIN32 7
#define MY_FACILITY_WRes MY_FACILITY_ERRNO
#define MY_HRESULT_FROM_errno_CONST_ERROR(x) ((HRESULT)( \
( (HRESULT)(x) & 0x0000FFFF) \
| (MY_FACILITY_WRes << 16) \
| (HRESULT)0x80000000 ))
#define MY_SRes_HRESULT_FROM_WRes(x) \
((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : MY_HRESULT_FROM_errno_CONST_ERROR(x))
// we call macro HRESULT_FROM_WIN32 for system errors (WRes) that are (errno)
#define HRESULT_FROM_WIN32(x) MY_SRes_HRESULT_FROM_WRes(x)
/*
#define ERROR_FILE_NOT_FOUND 2L
#define ERROR_ACCESS_DENIED 5L
#define ERROR_NO_MORE_FILES 18L
#define ERROR_LOCK_VIOLATION 33L
#define ERROR_FILE_EXISTS 80L
#define ERROR_DISK_FULL 112L
#define ERROR_NEGATIVE_SEEK 131L
#define ERROR_ALREADY_EXISTS 183L
#define ERROR_DIRECTORY 267L
#define ERROR_TOO_MANY_POSTS 298L
#define ERROR_INTERNAL_ERROR 1359L
#define ERROR_INVALID_REPARSE_DATA 4392L
#define ERROR_REPARSE_TAG_INVALID 4393L
#define ERROR_REPARSE_TAG_MISMATCH 4394L
*/
// we use errno equivalents for some WIN32 errors:
#define ERROR_INVALID_PARAMETER EINVAL
#define ERROR_INVALID_FUNCTION EINVAL
#define ERROR_ALREADY_EXISTS EEXIST
#define ERROR_FILE_EXISTS EEXIST
#define ERROR_PATH_NOT_FOUND ENOENT
#define ERROR_FILE_NOT_FOUND ENOENT
#define ERROR_DISK_FULL ENOSPC
// #define ERROR_INVALID_HANDLE EBADF
// we use FACILITY_WIN32 for errors that has no errno equivalent
// Too many posts were made to a semaphore.
#define ERROR_TOO_MANY_POSTS ((HRESULT)0x8007012AL)
#define ERROR_INVALID_REPARSE_DATA ((HRESULT)0x80071128L)
#define ERROR_REPARSE_TAG_INVALID ((HRESULT)0x80071129L)
// if (MY_FACILITY_WRes != FACILITY_WIN32),
// we use FACILITY_WIN32 for COM errors:
#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
#define E_INVALIDARG ((HRESULT)0x80070057L)
#define MY_E_ERROR_NEGATIVE_SEEK ((HRESULT)0x80070083L)
/*
// we can use FACILITY_ERRNO for some COM errors, that have errno equivalents:
#define E_OUTOFMEMORY MY_HRESULT_FROM_errno_CONST_ERROR(ENOMEM)
#define E_INVALIDARG MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL)
#define MY_E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL)
*/
#define TEXT(quote) quote
#define FILE_ATTRIBUTE_READONLY 0x0001
#define FILE_ATTRIBUTE_HIDDEN 0x0002
#define FILE_ATTRIBUTE_SYSTEM 0x0004
#define FILE_ATTRIBUTE_DIRECTORY 0x0010
#define FILE_ATTRIBUTE_ARCHIVE 0x0020
#define FILE_ATTRIBUTE_DEVICE 0x0040
#define FILE_ATTRIBUTE_NORMAL 0x0080
#define FILE_ATTRIBUTE_TEMPORARY 0x0100
#define FILE_ATTRIBUTE_SPARSE_FILE 0x0200
#define FILE_ATTRIBUTE_REPARSE_POINT 0x0400
#define FILE_ATTRIBUTE_COMPRESSED 0x0800
#define FILE_ATTRIBUTE_OFFLINE 0x1000
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x2000
#define FILE_ATTRIBUTE_ENCRYPTED 0x4000
#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 /* trick for Unix */
#endif
#ifndef RINOK
#define RINOK(x) { const int _result_ = (x); if (_result_ != 0) return _result_; }
#endif
#ifndef RINOK_WRes
#define RINOK_WRes(x) { const WRes _result_ = (x); if (_result_ != 0) return _result_; }
#endif
typedef unsigned char Byte;
typedef short Int16;
typedef unsigned short UInt16;
#ifdef Z7_DECL_Int32_AS_long
typedef long Int32;
typedef unsigned long UInt32;
#else
typedef int Int32;
typedef unsigned int UInt32;
#endif
#ifndef _WIN32
typedef int INT;
typedef Int32 INT32;
typedef unsigned int UINT;
typedef UInt32 UINT32;
typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit for _WIN32 compatibility
typedef UINT32 ULONG;
#undef DWORD
typedef UINT32 DWORD;
#define VOID void
#define HRESULT LONG
typedef void *LPVOID;
// typedef void VOID;
// typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
// gcc / clang on Unix : sizeof(long==sizeof(void*) in 32 or 64 bits)
typedef long INT_PTR;
typedef unsigned long UINT_PTR;
typedef long LONG_PTR;
typedef unsigned long DWORD_PTR;
typedef size_t SIZE_T;
#endif // _WIN32
#define MY_HRES_ERROR_INTERNAL_ERROR ((HRESULT)0x8007054FL)
#ifdef Z7_DECL_Int64_AS_long
typedef long Int64;
typedef unsigned long UInt64;
#else
#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(__clang__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#else
#if defined(__clang__) || defined(__GNUC__)
#include <stdint.h>
typedef int64_t Int64;
typedef uint64_t UInt64;
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
// #define UINT64_CONST(n) n ## ULL
#endif
#endif
#endif
#define UINT64_CONST(n) n
#ifdef Z7_DECL_SizeT_AS_unsigned_int
typedef unsigned int SizeT;
#else
typedef size_t SizeT;
#endif
/*
#if (defined(_MSC_VER) && _MSC_VER <= 1200)
typedef size_t MY_uintptr_t;
#else
#include <stdint.h>
typedef uintptr_t MY_uintptr_t;
#endif
*/
typedef int BoolInt;
/* typedef BoolInt Bool; */
#define True 1
#define False 0
#ifdef _WIN32
#define Z7_STDCALL __stdcall
#else
#define Z7_STDCALL
#endif
#ifdef _MSC_VER
#if _MSC_VER >= 1300
#define Z7_NO_INLINE __declspec(noinline)
#else
#define Z7_NO_INLINE
#endif
#define Z7_FORCE_INLINE __forceinline
#define Z7_CDECL __cdecl
#define Z7_FASTCALL __fastcall
#else // _MSC_VER
#if (defined(__GNUC__) && (__GNUC__ >= 4)) \
|| (defined(__clang__) && (__clang_major__ >= 4)) \
|| defined(__INTEL_COMPILER) \
|| defined(__xlC__)
#define Z7_NO_INLINE __attribute__((noinline))
#define Z7_FORCE_INLINE __attribute__((always_inline)) inline
#else
#define Z7_NO_INLINE
#define Z7_FORCE_INLINE
#endif
#define Z7_CDECL
#if defined(_M_IX86) \
|| defined(__i386__)
// #define Z7_FASTCALL __attribute__((fastcall))
// #define Z7_FASTCALL __attribute__((cdecl))
#define Z7_FASTCALL
#elif defined(MY_CPU_AMD64)
// #define Z7_FASTCALL __attribute__((ms_abi))
#define Z7_FASTCALL
#else
#define Z7_FASTCALL
#endif
#endif // _MSC_VER
/* The following interfaces use first parameter as pointer to structure */
// #define Z7_C_IFACE_CONST_QUAL
#define Z7_C_IFACE_CONST_QUAL const
#define Z7_C_IFACE_DECL(a) \
struct a ## _; \
typedef Z7_C_IFACE_CONST_QUAL struct a ## _ * a ## Ptr; \
typedef struct a ## _ a; \
struct a ## _
Z7_C_IFACE_DECL (IByteIn)
{
Byte (*Read)(IByteInPtr p); /* reads one byte, returns 0 in case of EOF or error */
};
#define IByteIn_Read(p) (p)->Read(p)
Z7_C_IFACE_DECL (IByteOut)
{
void (*Write)(IByteOutPtr p, Byte b);
};
#define IByteOut_Write(p, b) (p)->Write(p, b)
Z7_C_IFACE_DECL (ISeqInStream)
{
SRes (*Read)(ISeqInStreamPtr p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
};
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
/* try to read as much as avail in stream and limited by (*processedSize) */
SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize);
/* it can return SZ_ERROR_INPUT_EOF */
// SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size);
// SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf);
Z7_C_IFACE_DECL (ISeqOutStream)
{
size_t (*Write)(ISeqOutStreamPtr p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
};
#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
typedef enum
{
SZ_SEEK_SET = 0,
SZ_SEEK_CUR = 1,
SZ_SEEK_END = 2
} ESzSeek;
Z7_C_IFACE_DECL (ISeekInStream)
{
SRes (*Read)(ISeekInStreamPtr p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(ISeekInStreamPtr p, Int64 *pos, ESzSeek origin);
};
#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
Z7_C_IFACE_DECL (ILookInStream)
{
SRes (*Look)(ILookInStreamPtr p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */
SRes (*Skip)(ILookInStreamPtr p, size_t offset);
/* offset must be <= output(*size) of Look */
SRes (*Read)(ILookInStreamPtr p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(ILookInStreamPtr p, Int64 *pos, ESzSeek origin);
};
#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset);
/* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size);
typedef struct
{
ILookInStream vt;
ISeekInStreamPtr realStream;
size_t pos;
size_t size; /* it's data size */
/* the following variables must be set outside */
Byte *buf;
size_t bufSize;
} CLookToRead2;
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
#define LookToRead2_INIT(p) { (p)->pos = (p)->size = 0; }
typedef struct
{
ISeqInStream vt;
ILookInStreamPtr realStream;
} CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p);
typedef struct
{
ISeqInStream vt;
ILookInStreamPtr realStream;
} CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p);
Z7_C_IFACE_DECL (ICompressProgress)
{
SRes (*Progress)(ICompressProgressPtr p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
};
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
typedef struct ISzAlloc ISzAlloc;
typedef const ISzAlloc * ISzAllocPtr;
struct ISzAlloc
{
void *(*Alloc)(ISzAllocPtr p, size_t size);
void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
};
#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
#define ISzAlloc_Free(p, a) (p)->Free(p, a)
/* deprecated */
#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
#ifndef MY_offsetof
#ifdef offsetof
#define MY_offsetof(type, m) offsetof(type, m)
/*
#define MY_offsetof(type, m) FIELD_OFFSET(type, m)
*/
#else
#define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
#endif
#endif
#ifndef Z7_container_of
/*
#define Z7_container_of(ptr, type, m) container_of(ptr, type, m)
#define Z7_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
#define Z7_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
#define Z7_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
*/
/*
GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
GCC 3.4.4 : classes with constructor
GCC 4.8.1 : classes with non-public variable members"
*/
#define Z7_container_of(ptr, type, m) \
((type *)(void *)((char *)(void *) \
(1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m)))
#define Z7_container_of_CONST(ptr, type, m) \
((const type *)(const void *)((const char *)(const void *) \
(1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m)))
/*
#define Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) \
((type *)(void *)(const void *)((const char *)(const void *) \
(1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m)))
*/
#endif
#define Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(void *)(ptr))
// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
#define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of(ptr, type, m)
// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m)
#define Z7_CONTAINER_FROM_VTBL_CONST(ptr, type, m) Z7_container_of_CONST(ptr, type, m)
#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
/*
#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL(ptr, type, m)
*/
#if defined (__clang__) || defined(__GNUC__)
#define Z7_DIAGNOSCTIC_IGNORE_BEGIN_CAST_QUAL \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
#define Z7_DIAGNOSCTIC_IGNORE_END_CAST_QUAL \
_Pragma("GCC diagnostic pop")
#else
#define Z7_DIAGNOSCTIC_IGNORE_BEGIN_CAST_QUAL
#define Z7_DIAGNOSCTIC_IGNORE_END_CAST_QUAL
#endif
#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(ptr, type, m, p) \
Z7_DIAGNOSCTIC_IGNORE_BEGIN_CAST_QUAL \
type *p = Z7_CONTAINER_FROM_VTBL(ptr, type, m); \
Z7_DIAGNOSCTIC_IGNORE_END_CAST_QUAL
#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(type) \
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(pp, type, vt, p)
// #define ZIP7_DECLARE_HANDLE(name) typedef void *name;
#define Z7_DECLARE_HANDLE(name) struct name##_dummy{int unused;}; typedef struct name##_dummy *name;
#define Z7_memset_0_ARRAY(a) memset((a), 0, sizeof(a))
#ifndef Z7_ARRAY_SIZE
#define Z7_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif
#ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\'
#define WCHAR_PATH_SEPARATOR L'\\'
#define STRING_PATH_SEPARATOR "\\"
#define WSTRING_PATH_SEPARATOR L"\\"
#else
#define CHAR_PATH_SEPARATOR '/'
#define WCHAR_PATH_SEPARATOR L'/'
#define STRING_PATH_SEPARATOR "/"
#define WSTRING_PATH_SEPARATOR L"/"
#endif
#define k_PropVar_TimePrec_0 0
#define k_PropVar_TimePrec_Unix 1
#define k_PropVar_TimePrec_DOS 2
#define k_PropVar_TimePrec_HighPrec 3
#define k_PropVar_TimePrec_Base 16
#define k_PropVar_TimePrec_100ns (k_PropVar_TimePrec_Base + 7)
#define k_PropVar_TimePrec_1ns (k_PropVar_TimePrec_Base + 9)
EXTERN_C_END
#endif
/*
#ifndef Z7_ST
#ifdef _7ZIP_ST
#define Z7_ST
#endif
#endif
*/

View File

@ -0,0 +1,101 @@
/* 7zWindows.h -- StdAfx
2023-04-02 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_7Z_WINDOWS_H
#define ZIP7_INC_7Z_WINDOWS_H
#ifdef _WIN32
#if defined(__clang__)
# pragma clang diagnostic push
#endif
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4668) // '_WIN32_WINNT' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
#if _MSC_VER == 1900
// for old kit10 versions
// #pragma warning(disable : 4255) // winuser.h(13979): warning C4255: 'GetThreadDpiAwarenessContext':
#endif
// win10 Windows Kit:
#endif // _MSC_VER
#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64)
// for msvc6 without sdk2003
#define RPC_NO_WINDOWS_H
#endif
#if defined(__MINGW32__) || defined(__MINGW64__)
// #if defined(__GNUC__) && !defined(__clang__)
#include <windows.h>
#else
#include <Windows.h>
#endif
// #include <basetsd.h>
// #include <wtypes.h>
// but if precompiled with clang-cl then we need
// #include <windows.h>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#if defined(__clang__)
# pragma clang diagnostic pop
#endif
#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64)
#ifndef _W64
typedef long LONG_PTR, *PLONG_PTR;
typedef unsigned long ULONG_PTR, *PULONG_PTR;
typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
#define Z7_OLD_WIN_SDK
#endif // _W64
#endif // _MSC_VER == 1200
#ifdef Z7_OLD_WIN_SDK
#ifndef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
#ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
#endif
#ifndef FILE_SPECIAL_ACCESS
#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS)
#endif
// ShlObj.h:
// #define BIF_NEWDIALOGSTYLE 0x0040
#pragma warning(disable : 4201)
// #pragma warning(disable : 4115)
#undef VARIANT_TRUE
#define VARIANT_TRUE ((VARIANT_BOOL)-1)
#endif
#endif // Z7_OLD_WIN_SDK
#ifdef UNDER_CE
#undef VARIANT_TRUE
#define VARIANT_TRUE ((VARIANT_BOOL)-1)
#endif
#if defined(_MSC_VER)
#if _MSC_VER >= 1400 && _MSC_VER <= 1600
// BaseTsd.h(148) : 'HandleToULong' : unreferenced inline function has been removed
// string.h
// #pragma warning(disable : 4514)
#endif
#endif
/* #include "7zTypes.h" */
#endif

View File

@ -0,0 +1,159 @@
/* Compiler.h : Compiler specific defines and pragmas
2023-04-02 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_COMPILER_H
#define ZIP7_INC_COMPILER_H
#if defined(__clang__)
# define Z7_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#endif
#if defined(__clang__) && defined(__apple_build_version__)
# define Z7_APPLE_CLANG_VERSION Z7_CLANG_VERSION
#elif defined(__clang__)
# define Z7_LLVM_CLANG_VERSION Z7_CLANG_VERSION
#elif defined(__GNUC__)
# define Z7_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
#ifdef _MSC_VER
#if !defined(__clang__) && !defined(__GNUC__)
#define Z7_MSC_VER_ORIGINAL _MSC_VER
#endif
#endif
#if defined(__MINGW32__) || defined(__MINGW64__)
#define Z7_MINGW
#endif
// #pragma GCC diagnostic ignored "-Wunknown-pragmas"
#ifdef __clang__
// padding size of '' with 4 bytes to alignment boundary
#pragma GCC diagnostic ignored "-Wpadded"
#endif
#ifdef _MSC_VER
#ifdef UNDER_CE
#define RPC_NO_WINDOWS_H
/* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */
#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
#pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1800
#pragma warning(disable : 4464) // relative include path contains '..'
#endif
// == 1200 : -O1 : for __forceinline
// >= 1900 : -O1 : for printf
#pragma warning(disable : 4710) // function not inlined
#if _MSC_VER < 1900
// winnt.h: 'Int64ShllMod32'
#pragma warning(disable : 4514) // unreferenced inline function has been removed
#endif
#if _MSC_VER < 1300
// #pragma warning(disable : 4702) // unreachable code
// Bra.c : -O1:
#pragma warning(disable : 4714) // function marked as __forceinline not inlined
#endif
/*
#if _MSC_VER > 1400 && _MSC_VER <= 1900
// strcat: This function or variable may be unsafe
// sysinfoapi.h: kit10: GetVersion was declared deprecated
#pragma warning(disable : 4996)
#endif
*/
#if _MSC_VER > 1200
// -Wall warnings
#pragma warning(disable : 4711) // function selected for automatic inline expansion
#pragma warning(disable : 4820) // '2' bytes padding added after data member
#if _MSC_VER >= 1400 && _MSC_VER < 1920
// 1400: string.h: _DBG_MEMCPY_INLINE_
// 1600 - 191x : smmintrin.h __cplusplus'
// is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
#pragma warning(disable : 4668)
// 1400 - 1600 : WinDef.h : 'FARPROC' :
// 1900 - 191x : immintrin.h: _readfsbase_u32
// no function prototype given : converting '()' to '(void)'
#pragma warning(disable : 4255)
#endif
#if _MSC_VER >= 1914
// Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
#pragma warning(disable : 5045)
#endif
#endif // _MSC_VER > 1200
#endif // _MSC_VER
#if defined(__clang__) && (__clang_major__ >= 4)
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \
_Pragma("clang loop unroll(disable)") \
_Pragma("clang loop vectorize(disable)")
#define Z7_ATTRIB_NO_VECTORIZE
#elif defined(__GNUC__) && (__GNUC__ >= 5)
#define Z7_ATTRIB_NO_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
// __attribute__((optimize("no-unroll-loops")));
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE
#elif defined(_MSC_VER) && (_MSC_VER >= 1920)
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \
_Pragma("loop( no_vector )")
#define Z7_ATTRIB_NO_VECTORIZE
#else
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE
#define Z7_ATTRIB_NO_VECTORIZE
#endif
#if defined(MY_CPU_X86_OR_AMD64) && ( \
defined(__clang__) && (__clang_major__ >= 4) \
|| defined(__GNUC__) && (__GNUC__ >= 5))
#define Z7_ATTRIB_NO_SSE __attribute__((__target__("no-sse")))
#else
#define Z7_ATTRIB_NO_SSE
#endif
#define Z7_ATTRIB_NO_VECTOR \
Z7_ATTRIB_NO_VECTORIZE \
Z7_ATTRIB_NO_SSE
#if defined(__clang__) && (__clang_major__ >= 8) \
|| defined(__GNUC__) && (__GNUC__ >= 1000) \
/* || defined(_MSC_VER) && (_MSC_VER >= 1920) */
// GCC is not good for __builtin_expect()
#define Z7_LIKELY(x) (__builtin_expect((x), 1))
#define Z7_UNLIKELY(x) (__builtin_expect((x), 0))
// #define Z7_unlikely [[unlikely]]
// #define Z7_likely [[likely]]
#else
#define Z7_LIKELY(x) (x)
#define Z7_UNLIKELY(x) (x)
// #define Z7_likely
#endif
#if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 36000))
#define Z7_DIAGNOSCTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wreserved-macro-identifier\"")
#define Z7_DIAGNOSCTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER \
_Pragma("GCC diagnostic pop")
#else
#define Z7_DIAGNOSCTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
#define Z7_DIAGNOSCTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
#endif
#define UNUSED_VAR(x) (void)x;
/* #define UNUSED_VAR(x) x=x; */
#endif

View File

@ -1,254 +0,0 @@
/* Types.h -- Basic types
2010-10-09 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
#include <stddef.h>
#ifdef _WIN32
#include <windows.h>
#endif
#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif
#endif
EXTERN_C_BEGIN
#define SZ_OK 0
#define SZ_ERROR_DATA 1
#define SZ_ERROR_MEM 2
#define SZ_ERROR_CRC 3
#define SZ_ERROR_UNSUPPORTED 4
#define SZ_ERROR_PARAM 5
#define SZ_ERROR_INPUT_EOF 6
#define SZ_ERROR_OUTPUT_EOF 7
#define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9
#define SZ_ERROR_PROGRESS 10
#define SZ_ERROR_FAIL 11
#define SZ_ERROR_THREAD 12
#define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17
typedef int SRes;
#ifdef _WIN32
typedef DWORD WRes;
#else
typedef int WRes;
#endif
#ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif
typedef unsigned char Byte;
typedef short Int16;
typedef unsigned short UInt16;
#ifdef _LZMA_UINT32_IS_ULONG
typedef long Int32;
typedef unsigned long UInt32;
#else
typedef int Int32;
typedef unsigned int UInt32;
#endif
#ifdef _SZ_NO_INT_64
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
NOTES: Some code will work incorrectly in that case! */
typedef long Int64;
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#define UINT64_CONST(n) n
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n ## ULL
#endif
#endif
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
typedef size_t SizeT;
#endif
typedef int Bool;
#define True 1
#define False 0
#ifdef _WIN32
#define MY_STD_CALL __stdcall
#else
#define MY_STD_CALL
#endif
#ifdef _MSC_VER
#if _MSC_VER >= 1300
#define MY_NO_INLINE __declspec(noinline)
#else
#define MY_NO_INLINE
#endif
#define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall
#else
#define MY_CDECL
#define MY_FAST_CALL
#endif
/* The following interfaces use first parameter as pointer to structure */
typedef struct
{
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
} IByteIn;
typedef struct
{
void (*Write)(void *p, Byte b);
} IByteOut;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
} ISeqInStream;
/* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
typedef struct
{
size_t (*Write)(void *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
} ISeqOutStream;
typedef enum
{
SZ_SEEK_SET = 0,
SZ_SEEK_CUR = 1,
SZ_SEEK_END = 2
} ESzSeek;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ISeekInStream;
typedef struct
{
SRes (*Look)(void *p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */
SRes (*Skip)(void *p, size_t offset);
/* offset must be <= output(*size) of Look */
SRes (*Read)(void *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ILookInStream;
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
#define LookToRead_BUF_SIZE (1 << 14)
typedef struct
{
ILookInStream s;
ISeekInStream *realStream;
size_t pos;
size_t size;
Byte buf[LookToRead_BUF_SIZE];
} CLookToRead;
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
void LookToRead_Init(CLookToRead *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
} CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
} CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p);
typedef struct
{
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
} ICompressProgress;
typedef struct
{
void *(*Alloc)(void *p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */
} ISzAlloc;
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
#ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\'
#define WCHAR_PATH_SEPARATOR L'\\'
#define STRING_PATH_SEPARATOR "\\"
#define WSTRING_PATH_SEPARATOR L"\\"
#else
#define CHAR_PATH_SEPARATOR '/'
#define WCHAR_PATH_SEPARATOR L'/'
#define STRING_PATH_SEPARATOR "/"
#define WSTRING_PATH_SEPARATOR L"/"
#endif
EXTERN_C_END
#endif

View File

@ -1,39 +1,120 @@
// IArchive.h
#ifndef __IARCHIVE_H
#define __IARCHIVE_H
#ifndef ZIP7_INC_IARCHIVE_H
#define ZIP7_INC_IARCHIVE_H
#include "../IProgress.h"
#include "../IStream.h"
#include "../PropID.h"
#define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x)
#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x)
Z7_PURE_INTERFACES_BEGIN
#define Z7_IFACE_CONSTR_ARCHIVE_SUB(i, base, n) \
Z7_DECL_IFACE_7ZIP_SUB(i, base, 6, n) \
{ Z7_IFACE_COM7_PURE(i) };
#define Z7_IFACE_CONSTR_ARCHIVE(i, n) \
Z7_IFACE_CONSTR_ARCHIVE_SUB(i, IUnknown, n)
/*
How the function in 7-Zip returns object for output parameter via pointer
1) The caller sets the value of variable before function call:
PROPVARIANT : vt = VT_EMPTY
BSTR : NULL
IUnknown* and derived interfaces : NULL
another scalar types : any non-initialized value is allowed
2) The callee in current 7-Zip code now can free input object for output parameter:
PROPVARIANT : the callee calls VariantClear(propvaiant_ptr) for input
value stored in variable
another types : the callee ignores stored value.
3) The callee writes new value to variable for output parameter and
returns execution to caller.
4) The caller must free or release object returned by the callee:
PROPVARIANT : VariantClear(&propvaiant)
BSTR : SysFreeString(bstr)
IUnknown* and derived interfaces : if (ptr) ptr->Relase()
*/
namespace NFileTimeType
{
enum EEnum
{
kWindows,
kNotDefined = -1,
kWindows = 0,
kUnix,
kDOS
kDOS,
k1ns
};
}
namespace NArcInfoFlags
{
const UInt32 kKeepName = 1 << 0; // keep name of file in archive name
const UInt32 kAltStreams = 1 << 1; // the handler supports alt streams
const UInt32 kNtSecure = 1 << 2; // the handler supports NT security
const UInt32 kFindSignature = 1 << 3; // the handler can find start of archive
const UInt32 kMultiSignature = 1 << 4; // there are several signatures
const UInt32 kUseGlobalOffset = 1 << 5; // the seek position of stream must be set as global offset
const UInt32 kStartOpen = 1 << 6; // call handler for each start position
const UInt32 kPureStartOpen = 1 << 7; // call handler only for start of file
const UInt32 kBackwardOpen = 1 << 8; // archive can be open backward
const UInt32 kPreArc = 1 << 9; // such archive can be stored before real archive (like SFX stub)
const UInt32 kSymLinks = 1 << 10; // the handler supports symbolic links
const UInt32 kHardLinks = 1 << 11; // the handler supports hard links
const UInt32 kByExtOnlyOpen = 1 << 12; // call handler only if file extension matches
const UInt32 kHashHandler = 1 << 13; // the handler contains the hashes (checksums)
const UInt32 kCTime = 1 << 14;
const UInt32 kCTime_Default = 1 << 15;
const UInt32 kATime = 1 << 16;
const UInt32 kATime_Default = 1 << 17;
const UInt32 kMTime = 1 << 18;
const UInt32 kMTime_Default = 1 << 19;
// const UInt32 kTTime_Reserved = 1 << 20;
// const UInt32 kTTime_Reserved_Default = 1 << 21;
}
namespace NArcInfoTimeFlags
{
const unsigned kTime_Prec_Mask_bit_index = 0;
const unsigned kTime_Prec_Mask_num_bits = 26;
const unsigned kTime_Prec_Default_bit_index = 27;
const unsigned kTime_Prec_Default_num_bits = 5;
}
#define TIME_PREC_TO_ARC_FLAGS_MASK(v) \
((UInt32)1 << (NArcInfoTimeFlags::kTime_Prec_Mask_bit_index + (v)))
#define TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT(v) \
((UInt32)(v) << NArcInfoTimeFlags::kTime_Prec_Default_bit_index)
namespace NArchive
{
namespace NHandlerPropID
{
enum
{
kName = 0,
kClassID,
kExtension,
kAddExtension,
kUpdate,
kKeepName,
kStartSignature,
kFinishSignature,
kAssociate
kName = 0, // VT_BSTR
kClassID, // binary GUID in VT_BSTR
kExtension, // VT_BSTR
kAddExtension, // VT_BSTR
kUpdate, // VT_BOOL
kKeepName, // VT_BOOL
kSignature, // binary in VT_BSTR
kMultiSignature, // binary in VT_BSTR
kSignatureOffset, // VT_UI4
kAltStreams, // VT_BOOL
kNtSecure, // VT_BOOL
kFlags, // VT_UI4
kTimeFlags // VT_UI4
};
}
namespace NExtract
{
@ -43,192 +124,581 @@ namespace NArchive
{
kExtract = 0,
kTest,
kSkip
kSkip,
kReadExternal
};
}
namespace NOperationResult
{
enum
{
kOK = 0,
kUnSupportedMethod,
kUnsupportedMethod,
kDataError,
kCRCError
kCRCError,
kUnavailable,
kUnexpectedEnd,
kDataAfterEnd,
kIsNotArc,
kHeadersError,
kWrongPassword
// , kMemError
};
}
}
namespace NEventIndexType
{
enum
{
kNoIndex = 0,
kInArcIndex,
kBlockIndex,
kOutArcIndex
// kArcProp
};
}
namespace NUpdate
{
namespace NOperationResult
{
enum
{
kOK = 0,
kError
kOK = 0
// kError = 1,
// kError_FileChanged
};
}
}
}
#define INTERFACE_IArchiveOpenCallback(x) \
STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \
STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \
#define Z7_IFACEM_IArchiveOpenCallback(x) \
x(SetTotal(const UInt64 *files, const UInt64 *bytes)) \
x(SetCompleted(const UInt64 *files, const UInt64 *bytes)) \
ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)
Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenCallback, 0x10)
/*
IArchiveExtractCallback::
7-Zip doesn't call IArchiveExtractCallback functions
GetStream()
PrepareOperation()
SetOperationResult()
from different threads simultaneously.
But 7-Zip can call functions for IProgress or ICompressProgressInfo functions
from another threads simultaneously with calls for IArchiveExtractCallback interface.
IArchiveExtractCallback::GetStream()
UInt32 index - index of item in Archive
Int32 askExtractMode (Extract::NAskMode)
if (askMode != NExtract::NAskMode::kExtract)
{
then the callee doesn't write data to stream: (*outStream == NULL)
}
Out:
(*outStream == NULL) - for directories
(*outStream == NULL) - if link (hard link or symbolic link) was created
if (*outStream == NULL && askMode == NExtract::NAskMode::kExtract)
{
then the caller must skip extracting of that file.
}
returns:
S_OK : OK
S_FALSE : data error (for decoders)
if (IProgress::SetTotal() was called)
{
INTERFACE_IArchiveOpenCallback(PURE);
};
#define INTERFACE_IArchiveExtractCallback(x) \
INTERFACE_IProgress(x) \
STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \
STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \
STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) x; \
ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20)
IProgress::SetCompleted(completeValue) uses
packSize - for some stream formats (xz, gz, bz2, lzma, z, ppmd).
unpackSize - for another formats.
}
else
{
INTERFACE_IArchiveExtractCallback(PURE)
};
IProgress::SetCompleted(completeValue) uses packSize.
}
SetOperationResult()
7-Zip calls SetOperationResult at the end of extracting,
so the callee can close the file, set attributes, timestamps and security information.
#define INTERFACE_IArchiveOpenVolumeCallback(x) \
STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \
STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \
Int32 opRes (NExtract::NOperationResult)
*/
ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30)
{
INTERFACE_IArchiveOpenVolumeCallback(PURE);
};
// INTERFACE_IProgress(x)
#define Z7_IFACEM_IArchiveExtractCallback(x) \
x(GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)) \
x(PrepareOperation(Int32 askExtractMode)) \
x(SetOperationResult(Int32 opRes)) \
ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40)
{
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE;
};
Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallback, IProgress, 0x20)
ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50)
{
STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE;
};
/*
v23:
IArchiveExtractCallbackMessage2 can be requested from IArchiveExtractCallback object
by Extract() or UpdateItems() functions to report about extracting errors
ReportExtractResult()
UInt32 indexType (NEventIndexType)
UInt32 index
Int32 opRes (NExtract::NOperationResult)
*/
/*
before v23:
#define Z7_IFACEM_IArchiveExtractCallbackMessage(x) \
x(ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes))
Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallbackMessage, IProgress, 0x21)
*/
#define Z7_IFACEM_IArchiveExtractCallbackMessage2(x) \
x(ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes))
Z7_IFACE_CONSTR_ARCHIVE(IArchiveExtractCallbackMessage2, 0x22)
#define Z7_IFACEM_IArchiveOpenVolumeCallback(x) \
x(GetProperty(PROPID propID, PROPVARIANT *value)) \
x(GetStream(const wchar_t *name, IInStream **inStream))
Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenVolumeCallback, 0x30)
#define Z7_IFACEM_IInArchiveGetStream(x) \
x(GetStream(UInt32 index, ISequentialInStream **stream))
Z7_IFACE_CONSTR_ARCHIVE(IInArchiveGetStream, 0x40)
#define Z7_IFACEM_IArchiveOpenSetSubArchiveName(x) \
x(SetSubArchiveName(const wchar_t *name))
Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenSetSubArchiveName, 0x50)
/*
IInArchive::Open
stream
if (kUseGlobalOffset), stream current position can be non 0.
if (!kUseGlobalOffset), stream current position is 0.
if (maxCheckStartPosition == NULL), the handler can try to search archive start in stream
if (*maxCheckStartPosition == 0), the handler must check only current position as archive start
IInArchive::Extract:
indices must be sorted
numItems = 0xFFFFFFFF means "all files"
numItems = (UInt32)(Int32)-1 = 0xFFFFFFFF means "all files"
testMode != 0 means "test files without writing to outStream"
IInArchive::GetArchiveProperty:
kpidOffset - start offset of archive.
VT_EMPTY : means offset = 0.
VT_UI4, VT_UI8, VT_I8 : result offset; negative values is allowed
kpidPhySize - size of archive. VT_EMPTY means unknown size.
kpidPhySize is allowed to be larger than file size. In that case it must show
supposed size.
kpidIsDeleted:
kpidIsAltStream:
kpidIsAux:
kpidINode:
must return VARIANT_TRUE (VT_BOOL), if archive can support that property in GetProperty.
Notes:
Don't call IInArchive functions for same IInArchive object from different threads simultaneously.
Some IInArchive handlers will work incorrectly in that case.
*/
#define INTERFACE_IInArchive(x) \
STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \
STDMETHOD(Close)() x; \
STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \
STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \
STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x;
#if defined(_MSC_VER) && !defined(__clang__)
#define MY_NO_THROW_DECL_ONLY Z7_COM7F_E
#else
#define MY_NO_THROW_DECL_ONLY
#endif
ARCHIVE_INTERFACE(IInArchive, 0x60)
#define Z7_IFACEM_IInArchive(x) \
x(Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback)) \
x(Close()) \
x(GetNumberOfItems(UInt32 *numItems)) \
x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \
x(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) \
x(GetArchiveProperty(PROPID propID, PROPVARIANT *value)) \
x(GetNumberOfProperties(UInt32 *numProps)) \
x(GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \
x(GetNumberOfArchiveProperties(UInt32 *numProps)) \
x(GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \
Z7_IFACE_CONSTR_ARCHIVE(IInArchive, 0x60)
namespace NParentType
{
INTERFACE_IInArchive(PURE)
enum
{
kDir = 0,
kAltStream
};
}
namespace NPropDataType
{
const UInt32 kMask_ZeroEnd = 1 << 4;
// const UInt32 kMask_BigEndian = 1 << 5;
const UInt32 kMask_Utf = 1 << 6;
const UInt32 kMask_Utf8 = kMask_Utf | 0;
const UInt32 kMask_Utf16 = kMask_Utf | 1;
// const UInt32 kMask_Utf32 = kMask_Utf | 2;
const UInt32 kNotDefined = 0;
const UInt32 kRaw = 1;
const UInt32 kUtf8z = kMask_Utf8 | kMask_ZeroEnd;
const UInt32 kUtf16z = kMask_Utf16 | kMask_ZeroEnd;
}
// UTF string (pointer to wchar_t) with zero end and little-endian.
#define PROP_DATA_TYPE_wchar_t_PTR_Z_LE ((NPropDataType::kMask_Utf | NPropDataType::kMask_ZeroEnd) + (sizeof(wchar_t) >> 1))
/*
GetRawProp:
Result:
S_OK - even if property is not set
*/
#define Z7_IFACEM_IArchiveGetRawProps(x) \
x(GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) \
x(GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) \
x(GetNumRawProps(UInt32 *numProps)) \
x(GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID))
Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetRawProps, 0x70)
#define Z7_IFACEM_IArchiveGetRootProps(x) \
x(GetRootProp(PROPID propID, PROPVARIANT *value)) \
x(GetRootRawProp(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) \
Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetRootProps, 0x71)
#define Z7_IFACEM_IArchiveOpenSeq(x) \
x(OpenSeq(ISequentialInStream *stream)) \
Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenSeq, 0x61)
/*
OpenForSize
Result:
S_FALSE - is not archive
? - DATA error
*/
/*
const UInt32 kOpenFlags_RealPhySize = 1 << 0;
const UInt32 kOpenFlags_NoSeek = 1 << 1;
// const UInt32 kOpenFlags_BeforeExtract = 1 << 2;
*/
/*
Flags:
0 - opens archive with IInStream, if IInStream interface is supported
- if phySize is not available, it doesn't try to make full parse to get phySize
kOpenFlags_NoSeek - ArcOpen2 function doesn't use IInStream interface, even if it's available
kOpenFlags_RealPhySize - the handler will try to get PhySize, even if it requires full decompression for file
if handler is not allowed to use IInStream and the flag kOpenFlags_RealPhySize is not specified,
the handler can return S_OK, but it doesn't check even Signature.
So next Extract can be called for that sequential stream.
*/
/*
#define Z7_IFACEM_IArchiveOpen2(x) \
x(ArcOpen2(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback))
Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpen2, 0x62)
*/
// ---------- UPDATE ----------
/*
GetUpdateItemInfo outs:
*newData *newProps
0 0 - Copy data and properties from archive
0 1 - Copy data from archive, request new properties
1 0 - that combination is unused now
1 1 - Request new data and new properties. It can be used even for folders
indexInArchive = -1 if there is no item in archive, or if it doesn't matter.
GetStream out:
Result:
S_OK:
(*inStream == NULL) - only for directories
- the bug was fixed in 9.33: (*Stream == NULL) was in case of anti-file
(*inStream != NULL) - for any file, even for empty file or anti-file
S_FALSE - skip that file (don't add item to archive) - (client code can't open stream of that file by some reason)
(*inStream == NULL)
The order of calling for hard links:
- GetStream()
- GetProperty(kpidHardLink)
SetOperationResult()
Int32 opRes (NExtract::NOperationResult::kOK)
*/
// INTERFACE_IProgress(x)
#define Z7_IFACEM_IArchiveUpdateCallback(x) \
x(GetUpdateItemInfo(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)) \
x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \
x(GetStream(UInt32 index, ISequentialInStream **inStream)) \
x(SetOperationResult(Int32 operationResult)) \
Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveUpdateCallback, IProgress, 0x80)
// INTERFACE_IArchiveUpdateCallback(x)
#define Z7_IFACEM_IArchiveUpdateCallback2(x) \
x(GetVolumeSize(UInt32 index, UInt64 *size)) \
x(GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)) \
Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
namespace NUpdateNotifyOp
{
enum
{
kAdd = 0,
kUpdate,
kAnalyze,
kReplicate,
kRepack,
kSkip,
kDelete,
kHeader,
kHashRead,
kInFileChanged
// , kOpFinished
// , kNumDefined
};
}
/*
IArchiveUpdateCallbackFile::ReportOperation
UInt32 indexType (NEventIndexType)
UInt32 index
UInt32 notifyOp (NUpdateNotifyOp)
*/
#define Z7_IFACEM_IArchiveUpdateCallbackFile(x) \
x(GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 notifyOp)) \
x(ReportOperation(UInt32 indexType, UInt32 index, UInt32 notifyOp)) \
Z7_IFACE_CONSTR_ARCHIVE(IArchiveUpdateCallbackFile, 0x83)
#define Z7_IFACEM_IArchiveGetDiskProperty(x) \
x(GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \
Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetDiskProperty, 0x84)
/*
#define Z7_IFACEM_IArchiveUpdateCallbackArcProp(x) \
x(ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value)) \
x(ReportRawProp(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)) \
x(ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)) \
x(DoNeedArcProp(PROPID propID, Int32 *answer)) \
Z7_IFACE_CONSTR_ARCHIVE(IArchiveUpdateCallbackArcProp, 0x85)
*/
/*
UpdateItems()
-------------
outStream: output stream. (the handler) MUST support the case when
Seek position in outStream is not ZERO.
but the caller calls with empty outStream and seek position is ZERO??
archives with stub:
If archive is open and the handler and (Offset > 0), then the handler
knows about stub size.
UpdateItems():
1) the handler MUST copy that stub to outStream
2) the caller MUST NOT copy the stub to outStream, if
"rsfx" property is set with SetProperties
the handler must support the case where
ISequentialOutStream *outStream
*/
#define Z7_IFACEM_IOutArchive(x) \
x(UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback)) \
x(GetFileTimeType(UInt32 *type))
Z7_IFACE_CONSTR_ARCHIVE(IOutArchive, 0xA0)
/*
ISetProperties::SetProperties()
PROPVARIANT values[i].vt:
VT_EMPTY
VT_BOOL
VT_UI4 - if 32-bit number
VT_UI8 - if 64-bit number
VT_BSTR
*/
#define Z7_IFACEM_ISetProperties(x) \
x(SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
Z7_IFACE_CONSTR_ARCHIVE(ISetProperties, 0x03)
#define Z7_IFACEM_IArchiveKeepModeForNextOpen(x) \
x(KeepModeForNextOpen()) \
Z7_IFACE_CONSTR_ARCHIVE(IArchiveKeepModeForNextOpen, 0x04)
/* Exe handler: the handler for executable format (PE, ELF, Mach-O).
SFX archive: executable stub + some tail data.
before 9.31: exe handler didn't parse SFX archives as executable format.
for 9.31+: exe handler parses SFX archives as executable format, only if AllowTail(1) was called */
#define Z7_IFACEM_IArchiveAllowTail(x) \
x(AllowTail(Int32 allowTail)) \
Z7_IFACE_CONSTR_ARCHIVE(IArchiveAllowTail, 0x05)
struct CStatProp
{
const char *Name;
UInt32 PropID;
VARTYPE vt;
};
ARCHIVE_INTERFACE(IArchiveOpenSeq, 0x61)
{
STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE;
};
#define INTERFACE_IArchiveUpdateCallback(x) \
INTERFACE_IProgress(x); \
STDMETHOD(GetUpdateItemInfo)(UInt32 index, \
Int32 *newData, /*1 - new data, 0 - old data */ \
Int32 *newProperties, /* 1 - new properties, 0 - old properties */ \
UInt32 *indexInArchive /* -1 if there is no in archive, or if doesn't matter */ \
) x; \
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \
STDMETHOD(SetOperationResult)(Int32 operationResult) x; \
ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80)
{
INTERFACE_IArchiveUpdateCallback(PURE);
};
#define INTERFACE_IArchiveUpdateCallback2(x) \
INTERFACE_IArchiveUpdateCallback(x) \
STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \
STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \
ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
{
INTERFACE_IArchiveUpdateCallback2(PURE);
};
namespace NWindows {
namespace NCOM {
// PropVariant.cpp
BSTR AllocBstrFromAscii(const char *s) throw();
}}
#define INTERFACE_IOutArchive(x) \
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \
STDMETHOD(GetFileTimeType)(UInt32 *type) x;
#define IMP_IInArchive_GetProp_Base(fn, f, k) \
Z7_COM7F_IMF(CHandler::fn(UInt32 *numProps)) \
{ *numProps = Z7_ARRAY_SIZE(k); return S_OK; } \
Z7_COM7F_IMF(CHandler::f(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \
{ if (index >= Z7_ARRAY_SIZE(k)) return E_INVALIDARG; \
ARCHIVE_INTERFACE(IOutArchive, 0xA0)
{
INTERFACE_IOutArchive(PURE)
};
#define IMP_IInArchive_GetProp_NO_NAME(fn, f, k) \
IMP_IInArchive_GetProp_Base(fn, f, k) \
*propID = k[index]; \
*varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; \
*name = NULL; return S_OK; } \
#define IMP_IInArchive_GetProp_WITH_NAME(fn, f, k) \
IMP_IInArchive_GetProp_Base(fn, f, k) \
const CStatProp &prop = k[index]; \
*propID = (PROPID)prop.PropID; \
*varType = prop.vt; \
*name = NWindows::NCOM::AllocBstrFromAscii(prop.Name); return S_OK; } \
ARCHIVE_INTERFACE(ISetProperties, 0x03)
{
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE;
};
#define IMP_IInArchive_GetProp(k) \
(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
{ if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
const STATPROPSTG &srcItem = k[index]; \
*propID = srcItem.propid; *varType = srcItem.vt; *name = 0; return S_OK; } \
#define IMP_IInArchive_GetProp_WITH_NAME(k) \
(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
{ if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
const STATPROPSTG &srcItem = k[index]; \
*propID = srcItem.propid; *varType = srcItem.vt; \
if (srcItem.lpwstrName == 0) *name = 0; else *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } \
#define IMP_IInArchive_Props \
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
{ *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps)
IMP_IInArchive_GetProp_NO_NAME(GetNumberOfProperties, GetPropertyInfo, kProps)
#define IMP_IInArchive_Props_WITH_NAME \
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
{ *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps)
IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfProperties, GetPropertyInfo, kProps)
#define IMP_IInArchive_ArcProps \
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
{ *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps)
IMP_IInArchive_GetProp_NO_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps)
#define IMP_IInArchive_ArcProps_WITH_NAME \
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
{ *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps)
IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps)
#define IMP_IInArchive_ArcProps_NO_Table \
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
{ *numProperties = 0; return S_OK; } \
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \
Z7_COM7F_IMF(CHandler::GetNumberOfArchiveProperties(UInt32 *numProps)) \
{ *numProps = 0; return S_OK; } \
Z7_COM7F_IMF(CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *)) \
{ return E_NOTIMPL; } \
#define IMP_IInArchive_ArcProps_NO \
IMP_IInArchive_ArcProps_NO_Table \
STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \
Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value)) \
{ value->vt = VT_EMPTY; return S_OK; }
#define Z7_class_CHandler_final \
Z7_class_final(CHandler)
#define Z7_CLASS_IMP_CHandler_IInArchive_0 \
Z7_CLASS_IMP_COM_1(CHandler, IInArchive)
#define Z7_CLASS_IMP_CHandler_IInArchive_1(i1) \
Z7_CLASS_IMP_COM_2(CHandler, IInArchive, i1)
#define Z7_CLASS_IMP_CHandler_IInArchive_2(i1, i2) \
Z7_CLASS_IMP_COM_3(CHandler, IInArchive, i1, i2)
#define Z7_CLASS_IMP_CHandler_IInArchive_3(i1, i2, i3) \
Z7_CLASS_IMP_COM_4(CHandler, IInArchive, i1, i2, i3)
#define Z7_CLASS_IMP_CHandler_IInArchive_4(i1, i2, i3, i4) \
Z7_CLASS_IMP_COM_5(CHandler, IInArchive, i1, i2, i3, i4)
#define Z7_CLASS_IMP_CHandler_IInArchive_5(i1, i2, i3, i4, i5) \
Z7_CLASS_IMP_COM_6(CHandler, IInArchive, i1, i2, i3, i4, i5)
#define k_IsArc_Res_NO 0
#define k_IsArc_Res_YES 1
#define k_IsArc_Res_NEED_MORE 2
// #define k_IsArc_Res_YES_LOW_PROB 3
#define API_FUNC_IsArc EXTERN_C UInt32 WINAPI
#define API_FUNC_static_IsArc extern "C" { static UInt32 WINAPI
extern "C"
{
typedef HRESULT (WINAPI *Func_CreateObject)(const GUID *clsID, const GUID *iid, void **outObject);
typedef UInt32 (WINAPI *Func_IsArc)(const Byte *p, size_t size);
typedef HRESULT (WINAPI *Func_GetIsArc)(UInt32 formatIndex, Func_IsArc *isArc);
typedef HRESULT (WINAPI *Func_GetNumberOfFormats)(UInt32 *numFormats);
typedef HRESULT (WINAPI *Func_GetHandlerProperty)(PROPID propID, PROPVARIANT *value);
typedef HRESULT (WINAPI *Func_GetHandlerProperty2)(UInt32 index, PROPID propID, PROPVARIANT *value);
typedef HRESULT (WINAPI *Func_SetCaseSensitive)(Int32 caseSensitive);
typedef HRESULT (WINAPI *Func_SetLargePageMode)();
// typedef HRESULT (WINAPI *Func_SetClientVersion)(UInt32 version);
typedef IOutArchive * (*Func_CreateOutArchive)();
typedef IInArchive * (*Func_CreateInArchive)();
}
/*
if there is no time in archive, external MTime of archive
will be used instead of _item.Time from archive.
For 7-zip before 22.00 we need to return some supported value.
But (kpidTimeType > kDOS) is not allowed in 7-Zip before 22.00.
So we return highest precision value supported by old 7-Zip.
new 7-Zip 22.00 doesn't use that value in usual cases.
*/
#define DECLARE_AND_SET_CLIENT_VERSION_VAR
#define GET_FileTimeType_NotDefined_for_GetFileTimeType \
NFileTimeType::kWindows
/*
extern UInt32 g_ClientVersion;
#define GET_CLIENT_VERSION(major, minor) \
((UInt32)(((UInt32)(major) << 16) | (UInt32)(minor)))
#define DECLARE_AND_SET_CLIENT_VERSION_VAR \
UInt32 g_ClientVersion = GET_CLIENT_VERSION(MY_VER_MAJOR, MY_VER_MINOR);
#define GET_FileTimeType_NotDefined_for_GetFileTimeType \
((UInt32)(g_ClientVersion >= GET_CLIENT_VERSION(22, 0) ? \
(UInt32)(Int32)NFileTimeType::kNotDefined : \
NFileTimeType::kWindows))
*/
Z7_PURE_INTERFACES_END
#endif

View File

@ -1,172 +1,404 @@
// ICoder.h
#ifndef __ICODER_H
#define __ICODER_H
#ifndef ZIP7_INC_ICODER_H
#define ZIP7_INC_ICODER_H
#include "IStream.h"
#define CODER_INTERFACE(i, x) DECL_INTERFACE(i, 4, x)
Z7_PURE_INTERFACES_BEGIN
CODER_INTERFACE(ICompressProgressInfo, 0x04)
{
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE;
};
#define Z7_IFACE_CONSTR_CODER(i, n) \
Z7_DECL_IFACE_7ZIP(i, 4, n) \
{ Z7_IFACE_COM7_PURE(i) };
CODER_INTERFACE(ICompressCoder, 0x05)
{
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress) PURE;
};
#define Z7_IFACEM_ICompressProgressInfo(x) \
x(SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
Z7_IFACE_CONSTR_CODER(ICompressProgressInfo, 0x04)
/*
SetRatioInfo()
(inSize) can be NULL, if unknown
(outSize) can be NULL, if unknown
returns:
S_OK
E_ABORT : Break by user
another error codes
*/
#define Z7_IFACEM_ICompressCoder(x) \
x(Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, \
const UInt64 *inSize, const UInt64 *outSize, \
ICompressProgressInfo *progress))
Z7_IFACE_CONSTR_CODER(ICompressCoder, 0x05)
#define Z7_IFACEM_ICompressCoder2(x) \
x(Code(ISequentialInStream * const *inStreams, const UInt64 *const *inSizes, UInt32 numInStreams, \
ISequentialOutStream *const *outStreams, const UInt64 *const *outSizes, UInt32 numOutStreams, \
ICompressProgressInfo *progress))
Z7_IFACE_CONSTR_CODER(ICompressCoder2, 0x18)
/*
ICompressCoder::Code
ICompressCoder2::Code
returns:
S_OK : OK
S_FALSE : data error (for decoders)
E_OUTOFMEMORY : memory allocation error
E_NOTIMPL : unsupported encoding method (for decoders)
another error code : some error. For example, it can be error code received from inStream or outStream function.
Parameters:
(inStream != NULL)
(outStream != NULL)
if (inSize != NULL)
{
Encoders in 7-Zip ignore (inSize).
Decoder can use (*inSize) to check that stream was decoded correctly.
Some decoders in 7-Zip check it, if (full_decoding mode was set via ICompressSetFinishMode)
}
If it's required to limit the reading from input stream (inStream), it can
be done with ISequentialInStream implementation.
if (outSize != NULL)
{
Encoders in 7-Zip ignore (outSize).
Decoder unpacks no more than (*outSize) bytes.
}
(progress == NULL) is allowed.
Decoding with Code() function
-----------------------------
You can request some interfaces before decoding
- ICompressSetDecoderProperties2
- ICompressSetFinishMode
If you need to decode full stream:
{
1) try to set full_decoding mode with ICompressSetFinishMode::SetFinishMode(1);
2) call the Code() function with specified (inSize) and (outSize), if these sizes are known.
}
If you need to decode only part of stream:
{
1) try to set partial_decoding mode with ICompressSetFinishMode::SetFinishMode(0);
2) Call the Code() function with specified (inSize = NULL) and specified (outSize).
}
Encoding with Code() function
-----------------------------
You can request some interfaces :
- ICompressSetCoderProperties - use it before encoding to set properties
- ICompressWriteCoderProperties - use it before or after encoding to request encoded properties.
ICompressCoder2 is used when (numInStreams != 1 || numOutStreams != 1)
The rules are similar to ICompressCoder rules
*/
CODER_INTERFACE(ICompressCoder2, 0x18)
{
STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams,
ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams,
ICompressProgressInfo *progress) PURE;
};
namespace NCoderPropID
{
enum EEnum
{
kDefaultProp = 0,
kDictionarySize,
kUsedMemorySize,
kOrder,
kBlockSize,
kPosStateBits,
kLitContextBits,
kLitPosBits,
kNumFastBytes,
kMatchFinder,
kMatchFinderCycles,
kNumPasses,
kAlgorithm,
kNumThreads,
kEndMarker
kDictionarySize, // VT_UI4
kUsedMemorySize, // VT_UI4
kOrder, // VT_UI4
kBlockSize, // VT_UI4 or VT_UI8
kPosStateBits, // VT_UI4
kLitContextBits, // VT_UI4
kLitPosBits, // VT_UI4
kNumFastBytes, // VT_UI4
kMatchFinder, // VT_BSTR
kMatchFinderCycles, // VT_UI4
kNumPasses, // VT_UI4
kAlgorithm, // VT_UI4
kNumThreads, // VT_UI4
kEndMarker, // VT_BOOL
kLevel, // VT_UI4
kReduceSize, // VT_UI8 : it's estimated size of largest data stream that will be compressed
// encoder can use this value to reduce dictionary size and allocate data buffers
kExpectedDataSize, // VT_UI8 : for ICompressSetCoderPropertiesOpt :
// it's estimated size of current data stream
// real data size can differ from that size
// encoder can use this value to optimize encoder initialization
kBlockSize2, // VT_UI4 or VT_UI8
kCheckSize, // VT_UI4 : size of digest in bytes
kFilter, // VT_BSTR
kMemUse, // VT_UI8
kAffinity, // VT_UI8
kBranchOffset, // VT_UI4
kHashBits, // VT_UI4
/*
// kHash3Bits, // VT_UI4
// kHash2Bits, // VT_UI4
// kChainBits, // VT_UI4
kChainSize, // VT_UI4
kNativeLevel, // VT_UI4
kFast, // VT_UI4
kMinMatch, // VT_UI4 The minimum slen is 3 and the maximum is 7.
kOverlapLog, // VT_UI4 The minimum ovlog is 0 and the maximum is 9. (default: 6)
kRowMatchFinder, // VT_BOOL
kLdmEnable, // VT_BOOL
// kLdmWindowSizeLog, // VT_UI4
kLdmWindowSize, // VT_UI4
kLdmHashLog, // VT_UI4 The minimum ldmhlog is 6 and the maximum is 26 (default: 20).
kLdmMinMatchLength, // VT_UI4 The minimum ldmslen is 4 and the maximum is 4096 (default: 64).
kLdmBucketSizeLog, // VT_UI4 The minimum ldmblog is 0 and the maximum is 8 (default: 3).
kLdmHashRateLog, // VT_UI4 The default value is wlog - ldmhlog.
kWriteUnpackSizeFlag, // VT_BOOL
kUsePledged, // VT_BOOL
kUseSizeHintPledgedForSmall, // VT_BOOL
kUseSizeHintForEach, // VT_BOOL
kUseSizeHintGlobal, // VT_BOOL
kParamSelectMode, // VT_UI4
// kSearchLog, // VT_UI4 The minimum slog is 1 and the maximum is 26
// kTargetLen, // VT_UI4 The minimum tlen is 0 and the maximum is 999.
*/
k_NUM_DEFINED
};
}
CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
{
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) PURE;
};
#define Z7_IFACEM_ICompressSetCoderPropertiesOpt(x) \
x(SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps))
Z7_IFACE_CONSTR_CODER(ICompressSetCoderPropertiesOpt, 0x1F)
#define Z7_IFACEM_ICompressSetCoderProperties(x) \
x(SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps))
Z7_IFACE_CONSTR_CODER(ICompressSetCoderProperties, 0x20)
/*
CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
{
STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
};
#define Z7_IFACEM_ICompressSetDecoderProperties(x) \
x(SetDecoderProperties(ISequentialInStream *inStream))
Z7_IFACE_CONSTR_CODER(ICompressSetDecoderProperties, 0x21)
*/
CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
{
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
};
#define Z7_IFACEM_ICompressSetDecoderProperties2(x) \
x(SetDecoderProperties2(const Byte *data, UInt32 size))
Z7_IFACE_CONSTR_CODER(ICompressSetDecoderProperties2, 0x22)
/* returns:
S_OK
E_NOTIMP : unsupported properties
E_INVALIDARG : incorrect (or unsupported) properties
E_OUTOFMEMORY : memory allocation error
*/
CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)
{
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream) PURE;
};
CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
{
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
};
#define Z7_IFACEM_ICompressWriteCoderProperties(x) \
x(WriteCoderProperties(ISequentialOutStream *outStream))
Z7_IFACE_CONSTR_CODER(ICompressWriteCoderProperties, 0x23)
CODER_INTERFACE(ICompressSetCoderMt, 0x25)
{
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;
};
#define Z7_IFACEM_ICompressGetInStreamProcessedSize(x) \
x(GetInStreamProcessedSize(UInt64 *value))
Z7_IFACE_CONSTR_CODER(ICompressGetInStreamProcessedSize, 0x24)
CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
{
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
};
#define Z7_IFACEM_ICompressSetCoderMt(x) \
x(SetNumberOfThreads(UInt32 numThreads))
Z7_IFACE_CONSTR_CODER(ICompressSetCoderMt, 0x25)
CODER_INTERFACE(ICompressSetInStream, 0x31)
{
STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;
STDMETHOD(ReleaseInStream)() PURE;
};
#define Z7_IFACEM_ICompressSetFinishMode(x) \
x(SetFinishMode(UInt32 finishMode))
Z7_IFACE_CONSTR_CODER(ICompressSetFinishMode, 0x26)
/* finishMode:
0 : partial decoding is allowed. It's default mode for ICompressCoder::Code(), if (outSize) is defined.
1 : full decoding. The stream must be finished at the end of decoding. */
CODER_INTERFACE(ICompressSetOutStream, 0x32)
{
STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;
STDMETHOD(ReleaseOutStream)() PURE;
};
#define Z7_IFACEM_ICompressGetInStreamProcessedSize2(x) \
x(GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value))
Z7_IFACE_CONSTR_CODER(ICompressGetInStreamProcessedSize2, 0x27)
CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
{
STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
};
#define Z7_IFACEM_ICompressSetMemLimit(x) \
x(SetMemLimit(UInt64 memUsage))
Z7_IFACE_CONSTR_CODER(ICompressSetMemLimit, 0x28)
CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
{
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
};
CODER_INTERFACE(ICompressSetBufSize, 0x35)
{
STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size) PURE;
STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size) PURE;
};
CODER_INTERFACE(ICompressFilter, 0x40)
{
STDMETHOD(Init)() PURE;
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE;
// Filter converts as most as possible bytes
// Filter return outSize (UInt32)
// if (outSize <= size): Filter have converted outSize bytes
// if (outSize > size): Filter have not converted anything.
// and it needs at least outSize bytes to convert one block
// (it's for crypto block algorithms).
};
CODER_INTERFACE(ICompressCodecsInfo, 0x60)
{
STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods) PURE;
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder) PURE;
STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder) PURE;
};
CODER_INTERFACE(ISetCompressCodecsInfo, 0x61)
{
STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo) PURE;
};
CODER_INTERFACE(ICryptoProperties, 0x80)
{
STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE;
STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE;
};
/*
CODER_INTERFACE(ICryptoResetSalt, 0x88)
{
STDMETHOD(ResetSalt)() PURE;
};
ICompressReadUnusedFromInBuf is supported by ICoder object
call ReadUnusedFromInBuf() after ICoder::Code(inStream, ...).
ICoder::Code(inStream, ...) decodes data, and the ICoder object is allowed
to read from inStream to internal buffers more data than minimal data required for decoding.
So we can call ReadUnusedFromInBuf() from same ICoder object to read unused input
data from the internal buffer.
in ReadUnusedFromInBuf(): the Coder is not allowed to use (ISequentialInStream *inStream) object, that was sent to ICoder::Code().
*/
#define Z7_IFACEM_ICompressReadUnusedFromInBuf(x) \
x(ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize))
Z7_IFACE_CONSTR_CODER(ICompressReadUnusedFromInBuf, 0x29)
#define Z7_IFACEM_ICompressGetSubStreamSize(x) \
x(GetSubStreamSize(UInt64 subStream, UInt64 *value))
Z7_IFACE_CONSTR_CODER(ICompressGetSubStreamSize, 0x30)
/* returns:
S_OK : (*value) contains the size or estimated size (can be incorrect size)
S_FALSE : size is undefined
E_NOTIMP : the feature is not implemented
Let's (read_size) is size of data that was already read by ISequentialInStream::Read().
The caller should call GetSubStreamSize() after each Read() and check sizes:
if (start_of_subStream + *value < read_size)
{
// (*value) is correct, and it's allowed to call GetSubStreamSize() for next subStream:
start_of_subStream += *value;
subStream++;
}
*/
#define Z7_IFACEM_ICompressSetInStream(x) \
x(SetInStream(ISequentialInStream *inStream)) \
x(ReleaseInStream())
Z7_IFACE_CONSTR_CODER(ICompressSetInStream, 0x31)
#define Z7_IFACEM_ICompressSetOutStream(x) \
x(SetOutStream(ISequentialOutStream *outStream)) \
x(ReleaseOutStream())
Z7_IFACE_CONSTR_CODER(ICompressSetOutStream, 0x32)
/*
#define Z7_IFACEM_ICompressSetInStreamSize(x) \
x(SetInStreamSize(const UInt64 *inSize)) \
Z7_IFACE_CONSTR_CODER(ICompressSetInStreamSize, 0x33)
*/
CODER_INTERFACE(ICryptoResetInitVector, 0x8C)
{
STDMETHOD(ResetInitVector)() PURE;
};
#define Z7_IFACEM_ICompressSetOutStreamSize(x) \
x(SetOutStreamSize(const UInt64 *outSize))
Z7_IFACE_CONSTR_CODER(ICompressSetOutStreamSize, 0x34)
/* That function initializes decoder structures.
Call this function only for stream version of decoder.
if (outSize == NULL), then output size is unknown
if (outSize != NULL), then the decoder must stop decoding after (*outSize) bytes. */
CODER_INTERFACE(ICryptoSetPassword, 0x90)
{
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;
};
#define Z7_IFACEM_ICompressSetBufSize(x) \
x(SetInBufSize(UInt32 streamIndex, UInt32 size)) \
x(SetOutBufSize(UInt32 streamIndex, UInt32 size))
Z7_IFACE_CONSTR_CODER(ICompressSetBufSize, 0x35)
#define Z7_IFACEM_ICompressInitEncoder(x) \
x(InitEncoder())
Z7_IFACE_CONSTR_CODER(ICompressInitEncoder, 0x36)
/* That function initializes encoder structures.
Call this function only for stream version of encoder. */
#define Z7_IFACEM_ICompressSetInStream2(x) \
x(SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream)) \
x(ReleaseInStream2(UInt32 streamIndex))
Z7_IFACE_CONSTR_CODER(ICompressSetInStream2, 0x37)
/*
#define Z7_IFACEM_ICompressSetOutStream2(x) \
x(SetOutStream2(UInt32 streamIndex, ISequentialOutStream *outStream))
x(ReleaseOutStream2(UInt32 streamIndex))
Z7_IFACE_CONSTR_CODER(ICompressSetOutStream2, 0x38)
#define Z7_IFACEM_ICompressSetInStreamSize2(x) \
x(SetInStreamSize2(UInt32 streamIndex, const UInt64 *inSize))
Z7_IFACE_CONSTR_CODER(ICompressSetInStreamSize2, 0x39)
*/
/*
#define Z7_IFACEM_ICompressInSubStreams(x) \
x(GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream))
Z7_IFACE_CONSTR_CODER(ICompressInSubStreams, 0x3A)
#define Z7_IFACEM_ICompressOutSubStreams(x) \
x(GetNextOutSubStream(UInt64 *streamIndexRes, ISequentialOutStream **stream))
Z7_IFACE_CONSTR_CODER(ICompressOutSubStreams, 0x3B)
*/
/*
ICompressFilter
Filter(Byte *data, UInt32 size)
(size)
converts as most as possible bytes required for fast processing.
Some filters have (smallest_fast_block).
For example, (smallest_fast_block == 16) for AES CBC/CTR filters.
If data stream is not finished, caller must call Filter() for larger block:
where (size >= smallest_fast_block).
if (size >= smallest_fast_block)
{
The filter can leave some bytes at the end of data without conversion:
if there are data alignment reasons or speed reasons.
The caller can read additional data from stream and call Filter() again.
}
If data stream was finished, caller can call Filter() for (size < smallest_fast_block)
(data) parameter:
Some filters require alignment for any Filter() call:
1) (stream_offset % alignment_size) == (data % alignment_size)
2) (alignment_size == 2^N)
where (stream_offset) - is the number of bytes that were already filtered before.
The callers of Filter() are required to meet these requirements.
(alignment_size) can be different:
16 : for AES filters
4 or 2 : for some branch convert filters
1 : for another filters
(alignment_size >= 16) is enough for all current filters of 7-Zip.
But the caller can use larger (alignment_size).
Recommended alignment for (data) of Filter() call is (alignment_size == 64).
Also it's recommended to use aligned value for (size):
(size % alignment_size == 0),
if it's not last call of Filter() for current stream.
returns: (outSize):
if (outSize == 0) : Filter have not converted anything.
So the caller can stop processing, if data stream was finished.
if (outSize <= size) : Filter have converted outSize bytes
if (outSize > size) : Filter have not converted anything.
and it needs at least outSize bytes to convert one block
(it's for crypto block algorithms).
*/
#define Z7_IFACEM_ICompressFilter(x) \
x(Init()) \
x##2(UInt32, Filter(Byte *data, UInt32 size))
Z7_IFACE_CONSTR_CODER(ICompressFilter, 0x40)
#define Z7_IFACEM_ICompressCodecsInfo(x) \
x(GetNumMethods(UInt32 *numMethods)) \
x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \
x(CreateDecoder(UInt32 index, const GUID *iid, void* *coder)) \
x(CreateEncoder(UInt32 index, const GUID *iid, void* *coder))
Z7_IFACE_CONSTR_CODER(ICompressCodecsInfo, 0x60)
#define Z7_IFACEM_ISetCompressCodecsInfo(x) \
x(SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo))
Z7_IFACE_CONSTR_CODER(ISetCompressCodecsInfo, 0x61)
#define Z7_IFACEM_ICryptoProperties(x) \
x(SetKey(const Byte *data, UInt32 size)) \
x(SetInitVector(const Byte *data, UInt32 size))
Z7_IFACE_CONSTR_CODER(ICryptoProperties, 0x80)
/*
x(ResetSalt())
Z7_IFACE_CONSTR_CODER(ICryptoResetSalt, 0x88)
*/
#define Z7_IFACEM_ICryptoResetInitVector(x) \
x(ResetInitVector())
Z7_IFACE_CONSTR_CODER(ICryptoResetInitVector, 0x8C)
/* Call ResetInitVector() only for encoding.
Call ResetInitVector() before encoding and before WriteCoderProperties().
Crypto encoder can create random IV in that function. */
#define Z7_IFACEM_ICryptoSetPassword(x) \
x(CryptoSetPassword(const Byte *data, UInt32 size))
Z7_IFACE_CONSTR_CODER(ICryptoSetPassword, 0x90)
#define Z7_IFACEM_ICryptoSetCRC(x) \
x(CryptoSetCRC(UInt32 crc))
Z7_IFACE_CONSTR_CODER(ICryptoSetCRC, 0xA0)
CODER_INTERFACE(ICryptoSetCRC, 0xA0)
{
STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
};
//////////////////////
// It's for DLL file
namespace NMethodPropID
{
enum EEnum
@ -175,12 +407,71 @@ namespace NMethodPropID
kName,
kDecoder,
kEncoder,
kInStreams,
kOutStreams,
kPackStreams,
kUnpackStreams,
kDescription,
kDecoderIsAssigned,
kEncoderIsAssigned
kEncoderIsAssigned,
kDigestSize,
kIsFilter
};
}
namespace NModuleInterfaceType
{
/*
virtual destructor in IUnknown:
- no : 7-Zip (Windows)
- no : 7-Zip (Linux) (v23) in default mode
- yes : p7zip
- yes : 7-Zip (Linux) before v23
- yes : 7-Zip (Linux) (v23), if Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN is defined
*/
const UInt32 k_IUnknown_VirtDestructor_No = 0;
const UInt32 k_IUnknown_VirtDestructor_Yes = 1;
const UInt32 k_IUnknown_VirtDestructor_ThisModule =
#if !defined(_WIN32) && defined(Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN)
k_IUnknown_VirtDestructor_Yes;
#else
k_IUnknown_VirtDestructor_No;
#endif
}
namespace NModulePropID
{
enum EEnum
{
kInterfaceType, // VT_UI4
kVersion // VT_UI4
};
}
#define Z7_IFACEM_IHasher(x) \
x##2(void, Init()) \
x##2(void, Update(const void *data, UInt32 size)) \
x##2(void, Final(Byte *digest)) \
x##2(UInt32, GetDigestSize())
Z7_IFACE_CONSTR_CODER(IHasher, 0xC0)
#define Z7_IFACEM_IHashers(x) \
x##2(UInt32, GetNumHashers()) \
x(GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)) \
x(CreateHasher(UInt32 index, IHasher **hasher))
Z7_IFACE_CONSTR_CODER(IHashers, 0xC1)
extern "C"
{
typedef HRESULT (WINAPI *Func_GetNumberOfMethods)(UInt32 *numMethods);
typedef HRESULT (WINAPI *Func_GetMethodProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
typedef HRESULT (WINAPI *Func_CreateDecoder)(UInt32 index, const GUID *iid, void **outObject);
typedef HRESULT (WINAPI *Func_CreateEncoder)(UInt32 index, const GUID *iid, void **outObject);
typedef HRESULT (WINAPI *Func_GetHashers)(IHashers **hashers);
typedef HRESULT (WINAPI *Func_SetCodecs)(ICompressCodecsInfo *compressCodecsInfo);
typedef HRESULT (WINAPI *Func_GetModuleProp)(PROPID propID, PROPVARIANT *value);
}
Z7_PURE_INTERFACES_END
#endif

View File

@ -1,15 +1,76 @@
// IDecl.h
#ifndef __IDECL_H
#define __IDECL_H
#ifndef ZIP7_INC_IDECL_H
#define ZIP7_INC_IDECL_H
#include "../Common/Common.h"
#include "../Common/MyUnknown.h"
#define DECL_INTERFACE_SUB(i, base, groupId, subId) \
DEFINE_GUID(IID_ ## i, \
0x23170F69, 0x40C1, 0x278A, 0, 0, 0, (groupId), 0, (subId), 0, 0); \
struct i: public base
#define k_7zip_GUID_Data1 0x23170F69
#define k_7zip_GUID_Data2 0x40C1
#define DECL_INTERFACE(i, groupId, subId) DECL_INTERFACE_SUB(i, IUnknown, groupId, subId)
#define k_7zip_GUID_Data3_Common 0x278A
#define k_7zip_GUID_Data3_Decoder 0x2790
#define k_7zip_GUID_Data3_Encoder 0x2791
#define k_7zip_GUID_Data3_Hasher 0x2792
#define Z7_DECL_IFACE_7ZIP_SUB(i, _base, groupId, subId) \
Z7_DEFINE_GUID(IID_ ## i, \
k_7zip_GUID_Data1, \
k_7zip_GUID_Data2, \
k_7zip_GUID_Data3_Common, \
0, 0, 0, (groupId), 0, (subId), 0, 0); \
struct Z7_DECLSPEC_NOVTABLE i: public _base
#define Z7_DECL_IFACE_7ZIP(i, groupId, subId) \
Z7_DECL_IFACE_7ZIP_SUB(i, IUnknown, groupId, subId)
#ifdef COM_DECLSPEC_NOTHROW
#define Z7_COMWF_B COM_DECLSPEC_NOTHROW STDMETHODIMP
#define Z7_COMWF_B_(t) COM_DECLSPEC_NOTHROW STDMETHODIMP_(t)
#else
#define Z7_COMWF_B STDMETHODIMP
#define Z7_COMWF_B_(t) STDMETHODIMP_(t)
#endif
#if defined(_MSC_VER) && !defined(COM_DECLSPEC_NOTHROW)
#define Z7_COM7F_B __declspec(nothrow) STDMETHODIMP
#define Z7_COM7F_B_(t) __declspec(nothrow) STDMETHODIMP_(t)
#else
#define Z7_COM7F_B Z7_COMWF_B
#define Z7_COM7F_B_(t) Z7_COMWF_B_(t)
#endif
// #define Z7_COM7F_E Z7_noexcept
#define Z7_COM7F_E throw()
#define Z7_COM7F_EO Z7_COM7F_E Z7_override
#define Z7_COM7F_EOF Z7_COM7F_EO Z7_final
#define Z7_COM7F_IMF(f) Z7_COM7F_B f Z7_COM7F_E
#define Z7_COM7F_IMF2(t, f) Z7_COM7F_B_(t) f Z7_COM7F_E
#define Z7_COM7F_PURE(f) virtual Z7_COM7F_IMF(f) =0;
#define Z7_COM7F_PURE2(t, f) virtual Z7_COM7F_IMF2(t, f) =0;
#define Z7_COM7F_IMP(f) Z7_COM7F_IMF(f) Z7_override Z7_final;
#define Z7_COM7F_IMP2(t, f) Z7_COM7F_IMF2(t, f) Z7_override Z7_final;
#define Z7_COM7F_IMP_NONFINAL(f) Z7_COM7F_IMF(f) Z7_override;
#define Z7_COM7F_IMP_NONFINAL2(t, f) Z7_COM7F_IMF2(t, f) Z7_override;
#define Z7_IFACE_PURE(name) Z7_IFACEN_ ## name(=0;)
#define Z7_IFACE_IMP(name) Z7_IFACEN_ ## name(Z7_override Z7_final;)
#define Z7_IFACE_COM7_PURE(name) Z7_IFACEM_ ## name(Z7_COM7F_PURE)
#define Z7_IFACE_COM7_IMP(name) Z7_IFACEM_ ## name(Z7_COM7F_IMP)
#define Z7_IFACE_COM7_IMP_NONFINAL(name) Z7_IFACEM_ ## name(Z7_COM7F_IMP_NONFINAL)
#define Z7_IFACE_DECL_PURE(name) \
DECLARE_INTERFACE(name) \
{ Z7_IFACE_PURE(name) };
#define Z7_IFACE_DECL_PURE_(name, baseiface) \
DECLARE_INTERFACE_(name, baseiface) \
{ Z7_IFACE_PURE(name) };
#endif

View File

@ -1,24 +1,54 @@
// IPassword.h
#ifndef __IPASSWORD_H
#define __IPASSWORD_H
#ifndef ZIP7_INC_IPASSWORD_H
#define ZIP7_INC_IPASSWORD_H
#include "../Common/MyUnknown.h"
#include "../Common/Types.h"
#include "../Common/MyTypes.h"
#include "IDecl.h"
#define PASSWORD_INTERFACE(i, x) DECL_INTERFACE(i, 5, x)
Z7_PURE_INTERFACES_BEGIN
PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10)
{
STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE;
};
#define Z7_IFACE_CONSTR_PASSWORD(i, n) \
Z7_DECL_IFACE_7ZIP(i, 5, n) \
{ Z7_IFACE_COM7_PURE(i) };
PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11)
{
STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE;
};
/*
How to use output parameter (BSTR *password):
in: The caller is required to set BSTR value as NULL (no string).
The callee (in 7-Zip code) ignores the input value stored in BSTR variable,
out: The callee rewrites BSTR variable (*password) with new allocated string pointer.
The caller must free BSTR string with function SysFreeString();
*/
#define Z7_IFACEM_ICryptoGetTextPassword(x) \
x(CryptoGetTextPassword(BSTR *password))
Z7_IFACE_CONSTR_PASSWORD(ICryptoGetTextPassword, 0x10)
/*
CryptoGetTextPassword2()
in:
The caller is required to set BSTR value as NULL (no string).
The caller is not required to set (*passwordIsDefined) value.
out:
Return code: != S_OK : error code
Return code: S_OK : success
if (*passwordIsDefined == 1), the variable (*password) contains password string
if (*passwordIsDefined == 0), the password is not defined,
but the callee still could set (*password) to some allocated string, for example, as empty string.
The caller must free BSTR string with function SysFreeString()
*/
#define Z7_IFACEM_ICryptoGetTextPassword2(x) \
x(CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password))
Z7_IFACE_CONSTR_PASSWORD(ICryptoGetTextPassword2, 0x11)
Z7_PURE_INTERFACES_END
#endif

View File

@ -1,33 +1,20 @@
// Interface/IProgress.h
// IProgress.h
#ifndef __IPROGRESS_H
#define __IPROGRESS_H
#ifndef ZIP7_INC_IPROGRESS_H
#define ZIP7_INC_IPROGRESS_H
#include "../Common/MyUnknown.h"
#include "../Common/Types.h"
#include "../Common/MyTypes.h"
#include "IDecl.h"
#define INTERFACE_IProgress(x) \
STDMETHOD(SetTotal)(UInt64 total) x; \
STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \
Z7_PURE_INTERFACES_BEGIN
DECL_INTERFACE(IProgress, 0, 5)
{
INTERFACE_IProgress(PURE)
};
#define Z7_IFACEM_IProgress(x) \
x(SetTotal(UInt64 total)) \
x(SetCompleted(const UInt64 *completeValue)) \
/*
// {23170F69-40C1-278A-0000-000000050002}
DEFINE_GUID(IID_IProgress2,
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02);
MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050002")
IProgress2: public IUnknown
{
public:
STDMETHOD(SetTotal)(const UInt64 *total) PURE;
STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE;
};
*/
Z7_DECL_IFACE_7ZIP(IProgress, 0, 5)
{ Z7_IFACE_COM7_PURE(IProgress) };
Z7_PURE_INTERFACES_END
#endif

View File

@ -1,58 +1,207 @@
// IStream.h
#ifndef __ISTREAM_H
#define __ISTREAM_H
#ifndef ZIP7_INC_ISTREAM_H
#define ZIP7_INC_ISTREAM_H
#include "../Common/MyUnknown.h"
#include "../Common/Types.h"
#include "../Common/MyTypes.h"
#include "../Common/MyWindows.h"
#include "IDecl.h"
#define STREAM_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 3, x)
#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x)
Z7_PURE_INTERFACES_BEGIN
STREAM_INTERFACE(ISequentialInStream, 0x01)
{
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;
/*
Out: if size != 0, return_value = S_OK and (*processedSize == 0),
then there are no more bytes in stream.
if (size > 0) && there are bytes in stream,
this function must read at least 1 byte.
This function is allowed to read less than number of remaining bytes in stream.
You must call Read function in loop, if you need exact amount of data
*/
};
#define Z7_IFACE_CONSTR_STREAM_SUB(i, base, n) \
Z7_DECL_IFACE_7ZIP_SUB(i, base, 3, n) \
{ Z7_IFACE_COM7_PURE(i) };
STREAM_INTERFACE(ISequentialOutStream, 0x02)
{
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE;
/*
if (size > 0) this function must write at least 1 byte.
This function is allowed to write less than "size".
You must call Write function in loop, if you need to write exact amount of data
*/
};
#define Z7_IFACE_CONSTR_STREAM(i, n) \
Z7_IFACE_CONSTR_STREAM_SUB(i, IUnknown, n)
STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
{
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
};
STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04)
{
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
STDMETHOD(SetSize)(UInt64 newSize) PURE;
};
/*
ISequentialInStream::Read()
The requirement for caller: (processedSize != NULL).
The callee can allow (processedSize == NULL) for compatibility reasons.
STREAM_INTERFACE(IStreamGetSize, 0x06)
{
STDMETHOD(GetSize)(UInt64 *size) PURE;
};
if (size == 0), this function returns S_OK and (*processedSize) is set to 0.
STREAM_INTERFACE(IOutStreamFlush, 0x07)
{
STDMETHOD(Flush)() PURE;
};
if (size != 0)
{
Partial read is allowed: (*processedSize <= avail_size && *processedSize <= size),
where (avail_size) is the size of remaining bytes in stream.
If (avail_size != 0), this function must read at least 1 byte: (*processedSize > 0).
You must call Read() in loop, if you need to read exact amount of data.
}
If seek pointer before Read() call was changed to position past the end of stream:
if (seek_pointer >= stream_size), this function returns S_OK and (*processedSize) is set to 0.
ERROR CASES:
If the function returns error code, then (*processedSize) is size of
data written to (data) buffer (it can be data before error or data with errors).
The recommended way for callee to work with reading errors:
1) write part of data before error to (data) buffer and return S_OK.
2) return error code for further calls of Read().
*/
#define Z7_IFACEM_ISequentialInStream(x) \
x(Read(void *data, UInt32 size, UInt32 *processedSize))
Z7_IFACE_CONSTR_STREAM(ISequentialInStream, 0x01)
/*
ISequentialOutStream::Write()
The requirement for caller: (processedSize != NULL).
The callee can allow (processedSize == NULL) for compatibility reasons.
if (size != 0)
{
Partial write is allowed: (*processedSize <= size),
but this function must write at least 1 byte: (*processedSize > 0).
You must call Write() in loop, if you need to write exact amount of data.
}
ERROR CASES:
If the function returns error code, then (*processedSize) is size of
data written from (data) buffer.
*/
#define Z7_IFACEM_ISequentialOutStream(x) \
x(Write(const void *data, UInt32 size, UInt32 *processedSize))
Z7_IFACE_CONSTR_STREAM(ISequentialOutStream, 0x02)
#ifdef _WIN32
#ifdef __HRESULT_FROM_WIN32
#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK)
#else
#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK)
#endif
#else
#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK MY_E_ERROR_NEGATIVE_SEEK
#endif
/*
IInStream::Seek() / IOutStream::Seek()
If you seek to position before the beginning of the stream,
Seek() function returns error code:
Recommended error code is __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK).
or STG_E_INVALIDFUNCTION
It is allowed to seek past the end of the stream.
if Seek() returns error, then the value of *newPosition is undefined.
*/
#define Z7_IFACEM_IInStream(x) \
x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
Z7_IFACE_CONSTR_STREAM_SUB(IInStream, ISequentialInStream, 0x03)
#define Z7_IFACEM_IOutStream(x) \
x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) \
x(SetSize(UInt64 newSize))
Z7_IFACE_CONSTR_STREAM_SUB(IOutStream, ISequentialOutStream, 0x04)
#define Z7_IFACEM_IStreamGetSize(x) \
x(GetSize(UInt64 *size))
Z7_IFACE_CONSTR_STREAM(IStreamGetSize, 0x06)
#define Z7_IFACEM_IOutStreamFinish(x) \
x(OutStreamFinish())
Z7_IFACE_CONSTR_STREAM(IOutStreamFinish, 0x07)
#define Z7_IFACEM_IStreamGetProps(x) \
x(GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib))
Z7_IFACE_CONSTR_STREAM(IStreamGetProps, 0x08)
struct CStreamFileProps
{
UInt64 Size;
UInt64 VolID;
UInt64 FileID_Low;
UInt64 FileID_High;
UInt32 NumLinks;
UInt32 Attrib;
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
};
#define Z7_IFACEM_IStreamGetProps2(x) \
x(GetProps2(CStreamFileProps *props))
Z7_IFACE_CONSTR_STREAM(IStreamGetProps2, 0x09)
#define Z7_IFACEM_IStreamGetProp(x) \
x(GetProperty(PROPID propID, PROPVARIANT *value)) \
x(ReloadProps())
Z7_IFACE_CONSTR_STREAM(IStreamGetProp, 0x0a)
/*
IStreamSetRestriction::SetRestriction(UInt64 begin, UInt64 end)
It sets region of data in output stream that is restricted.
For restricted region it's expected (or allowed)
to change data with different calls of Write()/SetSize().
Another regions of output stream will be supposed as non-restricted:
- The callee usually doesn't flush the data in restricted region.
- The callee usually can flush data from non-restricted region.
inputs:
(begin > end) is not allowed, and returns E_FAIL;
if (begin == end)
{
it means that there is no region restriction for flushing.
The callee is allowed to flush already written data and
is allowed to flush all data in future calls of
ISequentialOutStream::Write(), but before next call of SetRestriction().
The pair of values (begin == 0 && end == 0) is recommended to
remove all restrictions.
}
if (begin < end)
{
it means that callee must NOT to flush any data in region [begin, end).
The caller is allowed to Seek() to that region and rewrite the
data in that restriction region.
if (end == (UInt64(Int64)-1)
{
there is no upper bound for restricted region.
So non-restricted region will be [0, begin) in that case
}
Note: it's not expected that some already written region was marked as
non-restricted by old call SetRestriction() and later the part of
that region was marked as restricted with new call SetRestriction().
For example, for different calls with non-empty restricted regions:
(begin_new >= begin_old) is expected :
{
SetRestriction(begin_old, ...)
...
SetRestriction(begin_new, ...)
}
}
returns:
- if (begin > end) it return ERROR code (E_FAIL)
- S_OK : if no errors.
- Also the call of SetRestriction() can initiate the flushing of already written data.
So it can return the result of that flushing.
Note: IOutStream::SetSize() also can change the data.
So it's not expected the call
IOutStream::SetSize() to unrestricted already written region.
*/
#define Z7_IFACEM_IStreamSetRestriction(x) \
x(SetRestriction(UInt64 begin, UInt64 end)) \
Z7_IFACE_CONSTR_STREAM(IStreamSetRestriction, 0x10)
Z7_PURE_INTERFACES_END
#endif

View File

@ -1,13 +1,15 @@
// PropID.h
#ifndef __7ZIP_PROPID_H
#define __7ZIP_PROPID_H
#ifndef ZIP7_INC_7ZIP_PROP_ID_H
#define ZIP7_INC_7ZIP_PROP_ID_H
#include "../Common/MyTypes.h"
enum
{
kpidNoProperty = 0,
kpidMainSubfile = 1,
kpidHandlerItemIndex = 2,
kpidMainSubfile,
kpidHandlerItemIndex,
kpidPath,
kpidName,
kpidExtension,
@ -59,18 +61,118 @@ enum
kpidCreatorApp,
kpidSectorSize,
kpidPosixAttrib,
kpidLink,
kpidSymLink,
kpidError,
kpidTotalSize = 0x1100,
kpidTotalSize,
kpidFreeSpace,
kpidClusterSize,
kpidVolumeName,
kpidLocalName = 0x1200,
kpidLocalName,
kpidProvider,
kpidNtSecure,
kpidIsAltStream,
kpidIsAux,
kpidIsDeleted,
kpidIsTree,
kpidSha1,
kpidSha256,
kpidErrorType,
kpidNumErrors,
kpidErrorFlags,
kpidWarningFlags,
kpidWarning,
kpidNumStreams,
kpidNumAltStreams,
kpidAltStreamsSize,
kpidVirtualSize,
kpidUnpackSize,
kpidTotalPhySize,
kpidVolumeIndex,
kpidSubType,
kpidShortComment,
kpidCodePage,
kpidIsNotArcType,
kpidPhySizeCantBeDetected,
kpidZerosTailIsAllowed,
kpidTailSize,
kpidEmbeddedStubSize,
kpidNtReparse,
kpidHardLink,
kpidINode,
kpidStreamId,
kpidReadOnly,
kpidOutName,
kpidCopyLink,
kpidArcFileName,
kpidIsHash,
kpidChangeTime,
kpidUserId,
kpidGroupId,
kpidDeviceMajor,
kpidDeviceMinor,
kpidDevMajor,
kpidDevMinor,
kpid_NUM_DEFINED,
kpidUserDefined = 0x10000
};
extern const Byte k7z_PROPID_To_VARTYPE[kpid_NUM_DEFINED]; // VARTYPE
const UInt32 kpv_ErrorFlags_IsNotArc = 1 << 0;
const UInt32 kpv_ErrorFlags_HeadersError = 1 << 1;
const UInt32 kpv_ErrorFlags_EncryptedHeadersError = 1 << 2;
const UInt32 kpv_ErrorFlags_UnavailableStart = 1 << 3;
const UInt32 kpv_ErrorFlags_UnconfirmedStart = 1 << 4;
const UInt32 kpv_ErrorFlags_UnexpectedEnd = 1 << 5;
const UInt32 kpv_ErrorFlags_DataAfterEnd = 1 << 6;
const UInt32 kpv_ErrorFlags_UnsupportedMethod = 1 << 7;
const UInt32 kpv_ErrorFlags_UnsupportedFeature = 1 << 8;
const UInt32 kpv_ErrorFlags_DataError = 1 << 9;
const UInt32 kpv_ErrorFlags_CrcError = 1 << 10;
// const UInt32 kpv_ErrorFlags_Unsupported = 1 << 11;
/*
linux ctime :
file metadata was last changed.
changing the file modification time
counts as a metadata change, so will also have the side effect of updating the ctime.
PROPVARIANT for timestamps in 7-Zip:
{
vt = VT_FILETIME
wReserved1: set precision level
0 : base value (backward compatibility value)
only filetime is used (7 digits precision).
wReserved2 and wReserved3 can contain random data
1 : Unix (1 sec)
2 : DOS (2 sec)
3 : High Precision (1 ns)
16 - 3 : (reserved) = 1 day
16 - 2 : (reserved) = 1 hour
16 - 1 : (reserved) = 1 minute
16 + 0 : 1 sec (0 digits after point)
16 + (1,2,3,4,5,6,7,8,9) : set subsecond precision level :
(number of decimal digits after point)
16 + 9 : 1 ns (9 digits after point)
wReserved2 = ns % 100 : if (8 or 9 digits pecision)
= 0 : if not (8 or 9 digits pecision)
wReserved3 = 0;
filetime
}
NOTE: TAR-PAX archives created by GNU TAR don't keep
whole information about original level of precision,
and timestamp are stored in reduced form, where tail zero
digits after point are removed.
So 7-Zip can return different precision levels for different items for such TAR archives.
*/
/*
TimePrec returned by IOutArchive::GetFileTimeType()
is used only for updating, when we compare MTime timestamp
from archive with timestamp from directory.
*/
#endif

View File

@ -0,0 +1,313 @@
// Common.h
#if defined(_MSC_VER) && _MSC_VER >= 1800
#pragma warning(disable : 4464) // relative include path contains '..'
#endif
#ifndef ZIP7_INC_COMMON_H
#define ZIP7_INC_COMMON_H
#include "../../C/Compiler.h"
/*
This file is included to all cpp files in 7-Zip.
Each folder contains StdAfx.h file that includes "Common.h".
So 7-Zip includes "Common.h" in both modes:
with precompiled StdAfx.h
and
without precompiled StdAfx.h
If you use 7-Zip code, you must include "Common.h" before other h files of 7-zip.
If you don't need some things that are used in 7-Zip,
you can change this h file or h files included in this file.
*/
#ifdef _MSC_VER
#pragma warning(disable : 4710) // function not inlined
// 'CUncopyable::CUncopyable':
#pragma warning(disable : 4514) // unreferenced inline function has been removed
#if _MSC_VER < 1300
#pragma warning(disable : 4702) // unreachable code
#pragma warning(disable : 4714) // function marked as __forceinline not inlined
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
#endif
#if _MSC_VER < 1400
#pragma warning(disable : 4511) // copy constructor could not be generated // #pragma warning(disable : 4512) // assignment operator could not be generated
#pragma warning(disable : 4512) // assignment operator could not be generated
#endif
#if _MSC_VER > 1400 && _MSC_VER <= 1900
// #pragma warning(disable : 4996)
// strcat: This function or variable may be unsafe
// GetVersion was declared deprecated
#endif
#if _MSC_VER > 1200
// -Wall warnings
#if _MSC_VER <= 1600
#pragma warning(disable : 4917) // 'OLE_HANDLE' : a GUID can only be associated with a class, interface or namespace
#endif
// #pragma warning(disable : 4061) // enumerator '' in switch of enum '' is not explicitly handled by a case label
// #pragma warning(disable : 4266) // no override available for virtual member function from base ''; function is hidden
#pragma warning(disable : 4625) // copy constructor was implicitly defined as deleted
#pragma warning(disable : 4626) // assignment operator was implicitly defined as deleted
#if _MSC_VER >= 1600 && _MSC_VER < 1920
#pragma warning(disable : 4571) // Informational: catch(...) semantics changed since Visual C++ 7.1; structured exceptions (SEH) are no longer caught
#endif
#if _MSC_VER >= 1600
#pragma warning(disable : 4365) // 'initializing' : conversion from 'int' to 'unsigned int', signed / unsigned mismatch
#endif
#if _MSC_VER < 1800
// we disable the warning, if we don't use 'final' in class
#pragma warning(disable : 4265) // class has virtual functions, but destructor is not virtual
#endif
#if _MSC_VER >= 1900
#pragma warning(disable : 5026) // move constructor was implicitly defined as deleted
#pragma warning(disable : 5027) // move assignment operator was implicitly defined as deleted
#endif
#if _MSC_VER >= 1912
#pragma warning(disable : 5039) // pointer or reference to potentially throwing function passed to 'extern "C"' function under - EHc.Undefined behavior may occur if this function throws an exception.
#endif
#if _MSC_VER >= 1925
// #pragma warning(disable : 5204) // 'ISequentialInStream' : class has virtual functions, but its trivial destructor is not virtual; instances of objects derived from this class may not be destructed correctly
#endif
#if _MSC_VER >= 1934
// #pragma warning(disable : 5264) // const variable is not used
#endif
#endif // _MSC_VER > 1200
#endif // _MSC_VER
#if defined(_MSC_VER) // && !defined(__clang__)
#define Z7_DECLSPEC_NOTHROW __declspec(nothrow)
#elif defined(__clang__) || defined(__GNUC__)
#define Z7_DECLSPEC_NOTHROW __attribute__((nothrow))
#else
#define Z7_DECLSPEC_NOTHROW
#endif
/*
#if defined (_MSC_VER) && _MSC_VER >= 1900 \
|| defined(__clang__) && __clang_major__ >= 6 \
|| defined(__GNUC__) && __GNUC__ >= 6
#define Z7_noexcept noexcept
#else
#define Z7_noexcept throw()
#endif
*/
#if defined(__clang__)
// noexcept, final, = delete
#pragma GCC diagnostic ignored "-Wc++98-compat"
#if __clang_major__ >= 4
// throw() dynamic exception specifications are deprecated
#pragma GCC diagnostic ignored "-Wdeprecated-dynamic-exception-spec"
#endif
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
// #pragma GCC diagnostic ignored "-Wunused-private-field"
// #pragma GCC diagnostic ignored "-Wnonportable-system-include-path"
// #pragma GCC diagnostic ignored "-Wsuggest-override"
// #pragma GCC diagnostic ignored "-Wsign-conversion"
// #pragma GCC diagnostic ignored "-Winconsistent-missing-override"
// #pragma GCC diagnostic ignored "-Wsuggest-destructor-override"
// #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
// #pragma GCC diagnostic ignored "-Wdeprecated-copy-with-user-provided-dtor"
// #pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
// #ifndef _WIN32
// #pragma GCC diagnostic ignored "-Wweak-vtables"
// #endif
/*
#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40400) \
|| defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30000)
// enumeration values not explicitly handled in switch
#pragma GCC diagnostic ignored "-Wswitch-enum"
#endif
*/
#endif // __clang__
#ifdef __GNUC__
// #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
#endif
/* There is BUG in MSVC 6.0 compiler for operator new[]:
It doesn't check overflow, when it calculates size in bytes for allocated array.
So we can use Z7_ARRAY_NEW macro instead of new[] operator. */
#if defined(_MSC_VER) && (_MSC_VER == 1200) && !defined(_WIN64)
#define Z7_ARRAY_NEW(p, T, size) p = new T[((size) > (unsigned)0xFFFFFFFF / sizeof(T)) ? (unsigned)0xFFFFFFFF / sizeof(T) : (size)];
#else
#define Z7_ARRAY_NEW(p, T, size) p = new T[size];
#endif
#if (defined(__GNUC__) && (__GNUC__ >= 8))
#define Z7_ATTR_NORETURN __attribute__((noreturn))
#elif (defined(__clang__) && (__clang_major__ >= 3))
#if __has_feature(cxx_attributes)
#define Z7_ATTR_NORETURN [[noreturn]]
#else
#define Z7_ATTR_NORETURN __attribute__((noreturn))
#endif
#elif (defined(_MSC_VER) && (_MSC_VER >= 1900))
#define Z7_ATTR_NORETURN [[noreturn]]
#else
#define Z7_ATTR_NORETURN
#endif
// final in "GCC 4.7.0"
// In C++98 and C++03 code the alternative spelling __final can be used instead (this is a GCC extension.)
#if defined (__cplusplus) && __cplusplus >= 201103L \
|| defined(_MSC_VER) && _MSC_VER >= 1800 \
|| defined(__clang__) && __clang_major__ >= 4 \
/* || defined(__GNUC__) && __GNUC__ >= 9 */
#define Z7_final final
#if defined(__clang__) && __cplusplus < 201103L
#pragma GCC diagnostic ignored "-Wc++11-extensions"
#endif
#elif defined (__cplusplus) && __cplusplus >= 199711L \
&& defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__)
#define Z7_final __final
#else
#define Z7_final
#if defined(__clang__) && __clang_major__ >= 4 \
|| defined(__GNUC__) && __GNUC__ >= 4
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
#endif
#endif
#define Z7_class_final(c) class c Z7_final
#if defined (__cplusplus) && __cplusplus >= 201103L \
|| (defined(_MSC_VER) && _MSC_VER >= 1800)
#define Z7_CPP_IS_SUPPORTED_default
#define Z7_eq_delete = delete
// #define Z7_DECL_DEFAULT_COPY_CONSTRUCTOR_IF_SUPPORTED(c) c(const c& k) = default;
#else
#define Z7_eq_delete
// #define Z7_DECL_DEFAULT_COPY_CONSTRUCTOR_IF_SUPPORTED(c)
#endif
#if defined(__cplusplus) && (__cplusplus >= 201103L) \
|| defined(_MSC_VER) && (_MSC_VER >= 1400) /* && (_MSC_VER != 1600) */ \
|| defined(__clang__) && __clang_major__ >= 4
#if defined(_MSC_VER) && (_MSC_VER == 1600) /* && (_MSC_VER != 1600) */
#pragma warning(disable : 4481) // nonstandard extension used: override specifier 'override'
#define Z7_DESTRUCTOR_override
#else
#define Z7_DESTRUCTOR_override override
#endif
#define Z7_override override
#else
#define Z7_override
#define Z7_DESTRUCTOR_override
#endif
#define Z7_CLASS_NO_COPY(cls) \
private: \
cls(const cls &) Z7_eq_delete; \
cls &operator=(const cls &) Z7_eq_delete;
class CUncopyable
{
protected:
CUncopyable() {} // allow constructor
// ~CUncopyable() {}
Z7_CLASS_NO_COPY(CUncopyable)
};
#define MY_UNCOPYABLE :private CUncopyable
// #define MY_UNCOPYABLE
typedef void (*Z7_void_Function)(void);
#if defined(__clang__) || defined(__GNUC__)
#define Z7_CAST_FUNC(t, e) reinterpret_cast<t>(reinterpret_cast<Z7_void_Function>(e))
#else
#define Z7_CAST_FUNC(t, e) reinterpret_cast<t>(reinterpret_cast<void*>(e))
// #define Z7_CAST_FUNC(t, e) reinterpret_cast<t>(e)
#endif
#define Z7_GET_PROC_ADDRESS(func_type, hmodule, func_name) \
Z7_CAST_FUNC(func_type, GetProcAddress(hmodule, func_name))
// || defined(__clang__)
// || defined(__GNUC__)
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
#define Z7_DECLSPEC_NOVTABLE __declspec(novtable)
#else
#define Z7_DECLSPEC_NOVTABLE
#endif
#ifdef __clang__
#define Z7_PURE_INTERFACES_BEGIN \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wnon-virtual-dtor\"")
_Pragma("GCC diagnostic ignored \"-Wweak-vtables\"")
#define Z7_PURE_INTERFACES_END \
_Pragma("GCC diagnostic pop")
#else
#define Z7_PURE_INTERFACES_BEGIN
#define Z7_PURE_INTERFACES_END
#endif
// NewHandler.h and NewHandler.cpp redefine operator new() to throw exceptions, if compiled with old MSVC compilers
#include "NewHandler.h"
/*
// #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) Z7_ARRAY_SIZE(a)
#endif
*/
#endif // ZIP7_INC_COMMON_H
// #define Z7_REDEFINE_NULL
#if defined(Z7_REDEFINE_NULL) /* && (!defined(__clang__) || defined(_MSC_VER)) */
// NULL is defined in <stddef.h>
#include <stddef.h>
#undef NULL
#ifdef __cplusplus
#if defined (__cplusplus) && __cplusplus >= 201103L \
|| (defined(_MSC_VER) && _MSC_VER >= 1800)
#define NULL nullptr
#else
#define NULL 0
#endif
#else
#define NULL ((void *)0)
#endif
#else // Z7_REDEFINE_NULL
#if defined(__clang__) && __clang_major__ >= 5
#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif
#endif // Z7_REDEFINE_NULL
// for precompiler:
#include "MyWindows.h"

View File

@ -1,20 +1,16 @@
// Common/Defs.h
#ifndef __COMMON_DEFS_H
#define __COMMON_DEFS_H
#ifndef ZIP7_INC_COMMON_DEFS_H
#define ZIP7_INC_COMMON_DEFS_H
template <class T> inline T MyMin(T a, T b)
{ return a < b ? a : b; }
template <class T> inline T MyMax(T a, T b)
{ return a > b ? a : b; }
template <class T> inline T MyMin(T a, T b) { return a < b ? a : b; }
template <class T> inline T MyMax(T a, T b) { return a > b ? a : b; }
template <class T> inline int MyCompare(T a, T b)
{ return a < b ? -1 : (a == b ? 0 : 1); }
{ return a == b ? 0 : (a < b ? -1 : 1); }
inline int BoolToInt(bool value)
{ return (value ? 1: 0); }
inline bool IntToBool(int value)
{ return (value != 0); }
inline int BoolToInt(bool v) { return (v ? 1 : 0); }
inline unsigned BoolToUInt(bool v) { return (v ? 1u : 0u); }
inline bool IntToBool(int v) { return (v != 0); }
#endif

View File

@ -1,27 +1,19 @@
// MyCom.h
#ifndef __MYCOM_H
#define __MYCOM_H
#ifndef ZIP7_INC_MY_COM_H
#define ZIP7_INC_MY_COM_H
#include "MyWindows.h"
#ifndef RINOK
#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; }
#endif
#include "MyTypes.h"
template <class T>
class CMyComPtr
{
T* _p;
public:
// typedef T _PtrClass;
CMyComPtr() { _p = NULL;}
CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
CMyComPtr(const CMyComPtr<T>& lp)
{
if ((_p = lp._p) != NULL)
_p->AddRef();
}
CMyComPtr(): _p(NULL) {}
CMyComPtr(T* p) throw() { if ((_p = p) != NULL) p->AddRef(); }
CMyComPtr(const CMyComPtr<T>& lp) throw() { if ((_p = lp._p) != NULL) _p->AddRef(); }
~CMyComPtr() { if (_p) _p->Release(); }
void Release() { if (_p) { _p->Release(); _p = NULL; } }
operator T*() const { return (T*)_p; }
@ -30,7 +22,7 @@ public:
T* operator->() const { return _p; }
T* operator=(T* p)
{
if (p != 0)
if (p)
p->AddRef();
if (_p)
_p->Release();
@ -40,7 +32,6 @@ public:
T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
bool operator!() const { return (_p == NULL); }
// bool operator==(T* pT) const { return _p == pT; }
// Compare two objects for equivalence
void Attach(T* p2)
{
Release();
@ -70,29 +61,54 @@ public:
}
*/
template <class Q>
HRESULT QueryInterface(REFGUID iid, Q** pp) const
HRESULT QueryInterface(REFGUID iid, Q** pp) const throw()
{
// if (*pp) throw 20220216; // for debug
return _p->QueryInterface(iid, (void**)pp);
}
};
#define Z7_DECL_CMyComPtr_QI_FROM(i, v, unk) \
CMyComPtr<i> v; (unk)->QueryInterface(IID_ ## i, (void **)&v);
//////////////////////////////////////////////////////////
inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr)
{
*bstr = ::SysAllocString(src);
return (*bstr != 0) ? S_OK : E_OUTOFMEMORY;
return (*bstr) ? S_OK : E_OUTOFMEMORY;
}
class CMyComBSTR
{
public:
BSTR m_str;
Z7_CLASS_NO_COPY(CMyComBSTR)
public:
CMyComBSTR(): m_str(NULL) {}
~CMyComBSTR() { ::SysFreeString(m_str); }
BSTR* operator&() { return &m_str; }
operator LPCOLESTR() const { return m_str; }
// operator bool() const { return m_str != NULL; }
// bool operator!() const { return m_str == NULL; }
void Wipe_and_Free()
{
if (m_str)
{
memset(m_str, 0, ::SysStringLen(m_str) * sizeof(*m_str));
Empty();
}
}
private:
// operator BSTR() const { return m_str; }
CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); }
// CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
// CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
// CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
/*
CMyComBSTR(REFGUID src)
{
@ -102,7 +118,8 @@ public:
CoTaskMemFree(szGuid);
}
*/
~CMyComBSTR() { ::SysFreeString(m_str); }
/*
CMyComBSTR& operator=(const CMyComBSTR& src)
{
if (m_str != src.m_str)
@ -113,22 +130,30 @@ public:
}
return *this;
}
*/
CMyComBSTR& operator=(LPCOLESTR src)
{
::SysFreeString(m_str);
m_str = ::SysAllocString(src);
return *this;
}
unsigned int Length() const { return ::SysStringLen(m_str); }
operator BSTR() const { return m_str; }
BSTR* operator&() { return &m_str; }
unsigned Len() const { return ::SysStringLen(m_str); }
BSTR MyCopy() const
{
int byteLen = ::SysStringByteLen(m_str);
// We don't support Byte BSTRs here
return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
/*
UINT byteLen = ::SysStringByteLen(m_str);
BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
if (res && byteLen != 0 && m_str)
memcpy(res, m_str, byteLen);
return res;
*/
}
/*
void Attach(BSTR src) { m_str = src; }
BSTR Detach()
@ -138,88 +163,347 @@ public:
return s;
}
*/
void Empty()
{
::SysFreeString(m_str);
m_str = NULL;
}
bool operator!() const { return (m_str == NULL); }
};
//////////////////////////////////////////////////////////
class CMyComBSTR_Wipe: public CMyComBSTR
{
Z7_CLASS_NO_COPY(CMyComBSTR_Wipe)
public:
CMyComBSTR_Wipe(): CMyComBSTR() {}
~CMyComBSTR_Wipe() { Wipe_and_Free(); }
};
/*
If CMyUnknownImp doesn't use virtual destructor, the code size is smaller.
But if some class_1 derived from CMyUnknownImp
uses Z7_COM_ADDREF_RELEASE and IUnknown::Release()
and some another class_2 is derived from class_1,
then class_1 must use virtual destructor:
virtual ~class_1();
In that case, class_1::Release() calls correct destructor of class_2.
We can use virtual ~CMyUnknownImp() to disable warning
"class has virtual functions, but destructor is not virtual".
Also we can use virtual ~IUnknown() {} in MyWindows.h
*/
class CMyUnknownImp
{
public:
ULONG __m_RefCount;
CMyUnknownImp(): __m_RefCount(0) {}
Z7_CLASS_NO_COPY(CMyUnknownImp)
protected:
ULONG _m_RefCount;
CMyUnknownImp(): _m_RefCount(0) {}
#ifdef _WIN32
#if defined(__GNUC__) || defined(__clang__)
// virtual ~CMyUnknownImp() {} // to disable GCC/CLANG varnings
#endif
#endif
};
#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
(REFGUID iid, void **outObject) {
#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
{ *outObject = (void *)(i *)this; AddRef(); return S_OK; }
#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \
{ *outObject = (void *)(IUnknown *)(i *)this; AddRef(); return S_OK; }
#define Z7_COM_QI_BEGIN \
private: STDMETHOD(QueryInterface) (REFGUID iid, void **outObject) throw() Z7_override Z7_final \
{ *outObject = NULL;
#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
MY_QUERYINTERFACE_ENTRY(i)
#define Z7_COM_QI_ENTRY(i) \
else if (iid == IID_ ## i) \
{ i *ti = this; *outObject = ti; }
// { *outObject = (void *)(i *)this; }
#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
#define Z7_COM_QI_ENTRY_UNKNOWN_0 \
if (iid == IID_IUnknown) \
{ IUnknown *tu = this; *outObject = tu; }
#define MY_ADDREF_RELEASE \
STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
return __m_RefCount; delete this; return 0; }
#define Z7_COM_QI_ENTRY_UNKNOWN(i) \
if (iid == IID_IUnknown) \
{ i *ti = this; IUnknown *tu = ti; *outObject = tu; }
// { *outObject = (void *)(IUnknown *)(i *)this; }
#define MY_UNKNOWN_IMP_SPEC(i) \
MY_QUERYINTERFACE_BEGIN \
#define Z7_COM_QI_BEGIN2(i) \
Z7_COM_QI_BEGIN \
Z7_COM_QI_ENTRY_UNKNOWN(i) \
Z7_COM_QI_ENTRY(i)
#define Z7_COM_QI_END \
else return E_NOINTERFACE; \
++_m_RefCount; /* AddRef(); */ return S_OK; }
#define Z7_COM_ADDREF_RELEASE \
private: \
STDMETHOD_(ULONG, AddRef)() throw() Z7_override Z7_final \
{ return ++_m_RefCount; } \
STDMETHOD_(ULONG, Release)() throw() Z7_override Z7_final \
{ if (--_m_RefCount != 0) return _m_RefCount; delete this; return 0; } \
#define Z7_COM_UNKNOWN_IMP_SPEC(i) \
Z7_COM_QI_BEGIN \
i \
MY_QUERYINTERFACE_END \
MY_ADDREF_RELEASE
Z7_COM_QI_END \
Z7_COM_ADDREF_RELEASE
#define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \
MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \
MY_QUERYINTERFACE_END \
MY_ADDREF_RELEASE
#define Z7_COM_UNKNOWN_IMP_0 \
Z7_COM_QI_BEGIN \
Z7_COM_QI_ENTRY_UNKNOWN_0 \
Z7_COM_QI_END \
Z7_COM_ADDREF_RELEASE
#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
MY_QUERYINTERFACE_ENTRY(i) \
#define Z7_COM_UNKNOWN_IMP_1(i) \
Z7_COM_UNKNOWN_IMP_SPEC( \
Z7_COM_QI_ENTRY_UNKNOWN(i) \
Z7_COM_QI_ENTRY(i) \
)
#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
MY_QUERYINTERFACE_ENTRY(i1) \
MY_QUERYINTERFACE_ENTRY(i2) \
#define Z7_COM_UNKNOWN_IMP_2(i1, i2) \
Z7_COM_UNKNOWN_IMP_SPEC( \
Z7_COM_QI_ENTRY_UNKNOWN(i1) \
Z7_COM_QI_ENTRY(i1) \
Z7_COM_QI_ENTRY(i2) \
)
#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
MY_QUERYINTERFACE_ENTRY(i1) \
MY_QUERYINTERFACE_ENTRY(i2) \
MY_QUERYINTERFACE_ENTRY(i3) \
#define Z7_COM_UNKNOWN_IMP_3(i1, i2, i3) \
Z7_COM_UNKNOWN_IMP_SPEC( \
Z7_COM_QI_ENTRY_UNKNOWN(i1) \
Z7_COM_QI_ENTRY(i1) \
Z7_COM_QI_ENTRY(i2) \
Z7_COM_QI_ENTRY(i3) \
)
#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
MY_QUERYINTERFACE_ENTRY(i1) \
MY_QUERYINTERFACE_ENTRY(i2) \
MY_QUERYINTERFACE_ENTRY(i3) \
MY_QUERYINTERFACE_ENTRY(i4) \
#define Z7_COM_UNKNOWN_IMP_4(i1, i2, i3, i4) \
Z7_COM_UNKNOWN_IMP_SPEC( \
Z7_COM_QI_ENTRY_UNKNOWN(i1) \
Z7_COM_QI_ENTRY(i1) \
Z7_COM_QI_ENTRY(i2) \
Z7_COM_QI_ENTRY(i3) \
Z7_COM_QI_ENTRY(i4) \
)
#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
MY_QUERYINTERFACE_ENTRY(i1) \
MY_QUERYINTERFACE_ENTRY(i2) \
MY_QUERYINTERFACE_ENTRY(i3) \
MY_QUERYINTERFACE_ENTRY(i4) \
MY_QUERYINTERFACE_ENTRY(i5) \
#define Z7_COM_UNKNOWN_IMP_5(i1, i2, i3, i4, i5) \
Z7_COM_UNKNOWN_IMP_SPEC( \
Z7_COM_QI_ENTRY_UNKNOWN(i1) \
Z7_COM_QI_ENTRY(i1) \
Z7_COM_QI_ENTRY(i2) \
Z7_COM_QI_ENTRY(i3) \
Z7_COM_QI_ENTRY(i4) \
Z7_COM_QI_ENTRY(i5) \
)
#define Z7_COM_UNKNOWN_IMP_6(i1, i2, i3, i4, i5, i6) \
Z7_COM_UNKNOWN_IMP_SPEC( \
Z7_COM_QI_ENTRY_UNKNOWN(i1) \
Z7_COM_QI_ENTRY(i1) \
Z7_COM_QI_ENTRY(i2) \
Z7_COM_QI_ENTRY(i3) \
Z7_COM_QI_ENTRY(i4) \
Z7_COM_QI_ENTRY(i5) \
Z7_COM_QI_ENTRY(i6) \
)
#define Z7_COM_UNKNOWN_IMP_7(i1, i2, i3, i4, i5, i6, i7) \
Z7_COM_UNKNOWN_IMP_SPEC( \
Z7_COM_QI_ENTRY_UNKNOWN(i1) \
Z7_COM_QI_ENTRY(i1) \
Z7_COM_QI_ENTRY(i2) \
Z7_COM_QI_ENTRY(i3) \
Z7_COM_QI_ENTRY(i4) \
Z7_COM_QI_ENTRY(i5) \
Z7_COM_QI_ENTRY(i6) \
Z7_COM_QI_ENTRY(i7) \
)
#define Z7_IFACES_IMP_UNK_1(i1) \
Z7_COM_UNKNOWN_IMP_1(i1) \
Z7_IFACE_COM7_IMP(i1) \
#define Z7_IFACES_IMP_UNK_2(i1, i2) \
Z7_COM_UNKNOWN_IMP_2(i1, i2) \
Z7_IFACE_COM7_IMP(i1) \
Z7_IFACE_COM7_IMP(i2) \
#define Z7_IFACES_IMP_UNK_3(i1, i2, i3) \
Z7_COM_UNKNOWN_IMP_3(i1, i2, i3) \
Z7_IFACE_COM7_IMP(i1) \
Z7_IFACE_COM7_IMP(i2) \
Z7_IFACE_COM7_IMP(i3) \
#define Z7_IFACES_IMP_UNK_4(i1, i2, i3, i4) \
Z7_COM_UNKNOWN_IMP_4(i1, i2, i3, i4) \
Z7_IFACE_COM7_IMP(i1) \
Z7_IFACE_COM7_IMP(i2) \
Z7_IFACE_COM7_IMP(i3) \
Z7_IFACE_COM7_IMP(i4) \
#define Z7_IFACES_IMP_UNK_5(i1, i2, i3, i4, i5) \
Z7_COM_UNKNOWN_IMP_5(i1, i2, i3, i4, i5) \
Z7_IFACE_COM7_IMP(i1) \
Z7_IFACE_COM7_IMP(i2) \
Z7_IFACE_COM7_IMP(i3) \
Z7_IFACE_COM7_IMP(i4) \
Z7_IFACE_COM7_IMP(i5) \
#define Z7_IFACES_IMP_UNK_6(i1, i2, i3, i4, i5, i6) \
Z7_COM_UNKNOWN_IMP_6(i1, i2, i3, i4, i5, i6) \
Z7_IFACE_COM7_IMP(i1) \
Z7_IFACE_COM7_IMP(i2) \
Z7_IFACE_COM7_IMP(i3) \
Z7_IFACE_COM7_IMP(i4) \
Z7_IFACE_COM7_IMP(i5) \
Z7_IFACE_COM7_IMP(i6) \
#define Z7_CLASS_IMP_COM_0(c) \
Z7_class_final(c) : \
public IUnknown, \
public CMyUnknownImp { \
Z7_COM_UNKNOWN_IMP_0 \
private:
#define Z7_CLASS_IMP_COM_1(c, i1) \
Z7_class_final(c) : \
public i1, \
public CMyUnknownImp { \
Z7_IFACES_IMP_UNK_1(i1) \
private:
#define Z7_CLASS_IMP_COM_2(c, i1, i2) \
Z7_class_final(c) : \
public i1, \
public i2, \
public CMyUnknownImp { \
Z7_IFACES_IMP_UNK_2(i1, i2) \
private:
#define Z7_CLASS_IMP_COM_3(c, i1, i2, i3) \
Z7_class_final(c) : \
public i1, \
public i2, \
public i3, \
public CMyUnknownImp { \
Z7_IFACES_IMP_UNK_3(i1, i2, i3) \
private:
#define Z7_CLASS_IMP_COM_4(c, i1, i2, i3, i4) \
Z7_class_final(c) : \
public i1, \
public i2, \
public i3, \
public i4, \
public CMyUnknownImp { \
Z7_IFACES_IMP_UNK_4(i1, i2, i3, i4) \
private:
#define Z7_CLASS_IMP_COM_5(c, i1, i2, i3, i4, i5) \
Z7_class_final(c) : \
public i1, \
public i2, \
public i3, \
public i4, \
public i5, \
public CMyUnknownImp { \
Z7_IFACES_IMP_UNK_5(i1, i2, i3, i4, i5) \
private:
#define Z7_CLASS_IMP_COM_6(c, i1, i2, i3, i4, i5, i6) \
Z7_class_final(c) : \
public i1, \
public i2, \
public i3, \
public i4, \
public i5, \
public i6, \
public CMyUnknownImp { \
Z7_IFACES_IMP_UNK_6(i1, i2, i3, i4, i5, i6) \
private:
/*
#define Z7_CLASS_IMP_NOQIB_0(c) \
Z7_class_final(c) : \
public IUnknown, \
public CMyUnknownImp { \
Z7_COM_UNKNOWN_IMP_0 \
private:
*/
#define Z7_CLASS_IMP_NOQIB_1(c, i1) \
Z7_class_final(c) : \
public i1, \
public CMyUnknownImp { \
Z7_COM_UNKNOWN_IMP_0 \
Z7_IFACE_COM7_IMP(i1) \
private:
#define Z7_CLASS_IMP_NOQIB_2(c, i1, i2) \
Z7_class_final(c) : \
public i1, \
public i2, \
public CMyUnknownImp { \
Z7_COM_UNKNOWN_IMP_1(i2) \
Z7_IFACE_COM7_IMP(i1) \
Z7_IFACE_COM7_IMP(i2) \
private:
#define Z7_CLASS_IMP_NOQIB_3(c, i1, i2, i3) \
Z7_class_final(c) : \
public i1, \
public i2, \
public i3, \
public CMyUnknownImp { \
Z7_COM_UNKNOWN_IMP_2(i2, i3) \
Z7_IFACE_COM7_IMP(i1) \
Z7_IFACE_COM7_IMP(i2) \
Z7_IFACE_COM7_IMP(i3) \
private:
#define Z7_CLASS_IMP_NOQIB_4(c, i1, i2, i3, i4) \
Z7_class_final(c) : \
public i1, \
public i2, \
public i3, \
public i4, \
public CMyUnknownImp { \
Z7_COM_UNKNOWN_IMP_3(i2, i3, i4) \
Z7_IFACE_COM7_IMP(i1) \
Z7_IFACE_COM7_IMP(i2) \
Z7_IFACE_COM7_IMP(i3) \
Z7_IFACE_COM7_IMP(i4) \
/*
#define Z7_CLASS_IMP_NOQIB_5(c, i1, i2, i3, i4, i5) \
Z7_class_final(c) : \
public i1, \
public i2, \
public i3, \
public i4, \
public i5, \
public CMyUnknownImp { \
Z7_COM_UNKNOWN_IMP_4(i2, i3, i4, i5) \
Z7_IFACE_COM7_IMP(i1) \
Z7_IFACE_COM7_IMP(i2) \
Z7_IFACE_COM7_IMP(i3) \
Z7_IFACE_COM7_IMP(i4) \
Z7_IFACE_COM7_IMP(i5) \
*/
#define Z7_CLASS_IMP_IInStream(c) \
class c Z7_final : \
public IInStream, \
public CMyUnknownImp { \
Z7_IFACES_IMP_UNK_2(ISequentialInStream, IInStream) \
#define k_My_HRESULT_WritingWasCut 0x20000010
#endif

View File

@ -1,22 +1,57 @@
// Common/MyInitGuid.h
#ifndef __COMMON_MY_INITGUID_H
#define __COMMON_MY_INITGUID_H
#ifndef ZIP7_INC_COMMON_MY_INITGUID_H
#define ZIP7_INC_COMMON_MY_INITGUID_H
/*
This file must be included only to one C++ file in project before
declarations of COM interfaces with DEFINE_GUID macro.
Each GUID must be initialized exactly once in project.
There are two different versions of the DEFINE_GUID macro in guiddef.h (MyGuidDef.h):
- if INITGUID is not defined: DEFINE_GUID declares an external reference to the symbol name.
- if INITGUID is defined: DEFINE_GUID initializes the symbol name to the value of the GUID.
Also we need IID_IUnknown that is initialized in some file for linking:
MSVC: by default the linker uses some lib file that contains IID_IUnknown
MinGW: add -luuid switch for linker
WinCE: we define IID_IUnknown in this file
Other: we define IID_IUnknown in this file
*/
// #include "Common.h"
/* vc6 without sdk needs <objbase.h> before <initguid.h>,
but it doesn't work in new msvc.
So we include full "MyWindows.h" instead of <objbase.h> */
// #include <objbase.h>
#include "MyWindows.h"
#ifdef _WIN32
#ifdef __clang__
// #pragma GCC diagnostic ignored "-Wmissing-variable-declarations"
#endif
#ifdef UNDER_CE
#include <basetyps.h>
#endif
// for vc6 without sdk we must define INITGUID here
#define INITGUID
#include <initguid.h>
#ifdef UNDER_CE
DEFINE_GUID(IID_IUnknown,
0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
#endif
#else
#else // _WIN32
#define INITGUID
#include "MyGuidDef.h"
DEFINE_GUID(IID_IUnknown,
0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
#endif
#endif // _WIN32
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
// Common/MyTypes.h
#ifndef ZIP7_INC_COMMON_MY_TYPES_H
#define ZIP7_INC_COMMON_MY_TYPES_H
#include "../../C/7zTypes.h"
#include "Common.h"
typedef int HRes;
struct CBoolPair
{
bool Val;
bool Def;
CBoolPair(): Val(false), Def(false) {}
void Init()
{
Val = false;
Def = false;
}
void SetTrueTrue()
{
Val = true;
Def = true;
}
void SetVal_as_Defined(bool val)
{
Val = val;
Def = true;
}
};
#endif

View File

@ -1,13 +1,8 @@
// MyUnknown.h
#ifndef __MY_UNKNOWN_H
#define __MY_UNKNOWN_H
#ifndef ZIP7_INC_MY_UNKNOWN_H
#define ZIP7_INC_MY_UNKNOWN_H
#ifdef _WIN32
#include <basetyps.h>
#include <unknwn.h>
#else
#include "MyWindows.h"
#endif
#endif

View File

@ -0,0 +1,3 @@
// Common/MyVector.cpp
#include "StdAfx.h"

View File

@ -0,0 +1,710 @@
// Common/MyVector.h
#ifndef ZIP7_INC_COMMON_MY_VECTOR_H
#define ZIP7_INC_COMMON_MY_VECTOR_H
#include <string.h>
#include "Common.h"
const unsigned k_VectorSizeMax = ((unsigned)1 << 31) - 1;
template <class T>
class CRecordVector
{
T *_items;
unsigned _size;
unsigned _capacity;
void MoveItems(unsigned destIndex, unsigned srcIndex)
{
memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T));
}
void ReAllocForNewCapacity(const unsigned newCapacity)
{
T *p;
Z7_ARRAY_NEW(p, T, newCapacity)
// p = new T[newCapacity];
if (_size != 0)
memcpy(p, _items, (size_t)_size * sizeof(T));
delete []_items;
_items = p;
_capacity = newCapacity;
}
public:
void ReserveOnePosition()
{
if (_size != _capacity)
return;
if (_capacity >= k_VectorSizeMax)
throw 2021;
const unsigned rem = k_VectorSizeMax - _capacity;
unsigned add = (_capacity >> 2) + 1;
if (add > rem)
add = rem;
ReAllocForNewCapacity(_capacity + add);
}
CRecordVector(): _items(NULL), _size(0), _capacity(0) {}
CRecordVector(const CRecordVector &v): _items(NULL), _size(0), _capacity(0)
{
const unsigned size = v.Size();
if (size != 0)
{
// Z7_ARRAY_NEW(_items, T, size)
_items = new T[size];
_size = size;
_capacity = size;
memcpy(_items, v._items, (size_t)size * sizeof(T));
}
}
unsigned Size() const { return _size; }
bool IsEmpty() const { return _size == 0; }
void ConstructReserve(unsigned size)
{
if (size != 0)
{
Z7_ARRAY_NEW(_items, T, size)
// _items = new T[size];
_capacity = size;
}
}
void Reserve(unsigned newCapacity)
{
if (newCapacity > _capacity)
{
if (newCapacity > k_VectorSizeMax)
throw 2021;
ReAllocForNewCapacity(newCapacity);
}
}
void ChangeSize_KeepData(unsigned newSize)
{
Reserve(newSize);
_size = newSize;
}
void ClearAndReserve(unsigned newCapacity)
{
Clear();
if (newCapacity > _capacity)
{
if (newCapacity > k_VectorSizeMax)
throw 2021;
delete []_items;
_items = NULL;
_capacity = 0;
Z7_ARRAY_NEW(_items, T, newCapacity)
// _items = new T[newCapacity];
_capacity = newCapacity;
}
}
void ClearAndSetSize(unsigned newSize)
{
ClearAndReserve(newSize);
_size = newSize;
}
void ReserveDown()
{
if (_size == _capacity)
return;
T *p = NULL;
if (_size != 0)
{
// Z7_ARRAY_NEW(p, T, _size)
p = new T[_size];
memcpy(p, _items, (size_t)_size * sizeof(T));
}
delete []_items;
_items = p;
_capacity = _size;
}
~CRecordVector() { delete []_items; }
void ClearAndFree()
{
delete []_items;
_items = NULL;
_size = 0;
_capacity = 0;
}
void Clear() { _size = 0; }
void DeleteBack() { _size--; }
void DeleteFrom(unsigned index)
{
// if (index <= _size)
_size = index;
}
void DeleteFrontal(unsigned num)
{
if (num != 0)
{
MoveItems(0, num);
_size -= num;
}
}
void Delete(unsigned index)
{
MoveItems(index, index + 1);
_size -= 1;
}
/*
void Delete(unsigned index, unsigned num)
{
if (num > 0)
{
MoveItems(index, index + num);
_size -= num;
}
}
*/
CRecordVector& operator=(const CRecordVector &v)
{
if (&v == this)
return *this;
const unsigned size = v.Size();
if (size > _capacity)
{
delete []_items;
_capacity = 0;
_size = 0;
_items = NULL;
_items = new T[size];
_capacity = size;
}
_size = size;
if (size != 0)
memcpy(_items, v._items, (size_t)size * sizeof(T));
return *this;
}
CRecordVector& operator+=(const CRecordVector &v)
{
const unsigned size = v.Size();
if (size != 0)
{
if (_size >= k_VectorSizeMax || size > k_VectorSizeMax - _size)
throw 2021;
const unsigned newSize = _size + size;
Reserve(newSize);
memcpy(_items + _size, v._items, (size_t)size * sizeof(T));
_size = newSize;
}
return *this;
}
unsigned Add(const T item)
{
ReserveOnePosition();
const unsigned size = _size;
_size = size + 1;
_items[size] = item;
return size;
}
/*
unsigned Add2(const T &item)
{
ReserveOnePosition();
const unsigned size = _size;
_size = size + 1;
_items[size] = item;
return size;
}
*/
unsigned AddInReserved(const T item)
{
const unsigned size = _size;
_size = size + 1;
_items[size] = item;
return size;
}
void Insert(unsigned index, const T item)
{
ReserveOnePosition();
MoveItems(index + 1, index);
_items[index] = item;
_size++;
}
void InsertInReserved(unsigned index, const T item)
{
MoveItems(index + 1, index);
_items[index] = item;
_size++;
}
void MoveToFront(unsigned index)
{
if (index != 0)
{
T temp = _items[index];
memmove(_items + 1, _items, (size_t)index * sizeof(T));
_items[0] = temp;
}
}
const T& operator[](unsigned index) const { return _items[index]; }
T& operator[](unsigned index) { return _items[index]; }
const T& operator[](int index) const { return _items[(unsigned)index]; }
T& operator[](int index) { return _items[(unsigned)index]; }
const T& Front() const { return _items[0]; }
T& Front() { return _items[0]; }
const T& Back() const { return _items[(size_t)_size - 1]; }
T& Back() { return _items[(size_t)_size - 1]; }
/*
void Swap(unsigned i, unsigned j)
{
T temp = _items[i];
_items[i] = _items[j];
_items[j] = temp;
}
*/
int FindInSorted(const T item, unsigned left, unsigned right) const
{
while (left != right)
{
// const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
const unsigned mid = (left + right) / 2;
const T midVal = (*this)[mid];
if (item == midVal)
return (int)mid;
if (item < midVal)
right = mid;
else
left = mid + 1;
}
return -1;
}
int FindInSorted2(const T &item, unsigned left, unsigned right) const
{
while (left != right)
{
// const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
const unsigned mid = (left + right) / 2;
const T& midVal = (*this)[mid];
const int comp = item.Compare(midVal);
if (comp == 0)
return (int)mid;
if (comp < 0)
right = mid;
else
left = mid + 1;
}
return -1;
}
int FindInSorted(const T item) const
{
return FindInSorted(item, 0, _size);
}
int FindInSorted2(const T &item) const
{
return FindInSorted2(item, 0, _size);
}
unsigned AddToUniqueSorted(const T item)
{
unsigned left = 0, right = _size;
while (left != right)
{
// const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
const unsigned mid = (left + right) / 2;
const T midVal = (*this)[mid];
if (item == midVal)
return mid;
if (item < midVal)
right = mid;
else
left = mid + 1;
}
Insert(right, item);
return right;
}
unsigned AddToUniqueSorted2(const T &item)
{
unsigned left = 0, right = _size;
while (left != right)
{
// const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
const unsigned mid = (left + right) / 2;
const T& midVal = (*this)[mid];
const int comp = item.Compare(midVal);
if (comp == 0)
return mid;
if (comp < 0)
right = mid;
else
left = mid + 1;
}
Insert(right, item);
return right;
}
static void SortRefDown(T* p, unsigned k, unsigned size, int (*compare)(const T*, const T*, void *), void *param)
{
T temp = p[k];
for (;;)
{
unsigned s = (k << 1);
if (s > size)
break;
if (s < size && compare(p + s + 1, p + s, param) > 0)
s++;
if (compare(&temp, p + s, param) >= 0)
break;
p[k] = p[s];
k = s;
}
p[k] = temp;
}
void Sort(int (*compare)(const T*, const T*, void *), void *param)
{
unsigned size = _size;
if (size <= 1)
return;
T* p = (&Front()) - 1;
{
unsigned i = size >> 1;
do
SortRefDown(p, i, size, compare, param);
while (--i != 0);
}
do
{
T temp = p[size];
p[size--] = p[1];
p[1] = temp;
SortRefDown(p, 1, size, compare, param);
}
while (size > 1);
}
static void SortRefDown2(T* p, unsigned k, unsigned size)
{
T temp = p[k];
for (;;)
{
unsigned s = (k << 1);
if (s > size)
break;
if (s < size && p[(size_t)s + 1].Compare(p[s]) > 0)
s++;
if (temp.Compare(p[s]) >= 0)
break;
p[k] = p[s];
k = s;
}
p[k] = temp;
}
void Sort2()
{
unsigned size = _size;
if (size <= 1)
return;
T* p = (&Front()) - 1;
{
unsigned i = size >> 1;
do
SortRefDown2(p, i, size);
while (--i != 0);
}
do
{
T temp = p[size];
p[size--] = p[1];
p[1] = temp;
SortRefDown2(p, 1, size);
}
while (size > 1);
}
};
typedef CRecordVector<int> CIntVector;
typedef CRecordVector<unsigned int> CUIntVector;
typedef CRecordVector<bool> CBoolVector;
typedef CRecordVector<unsigned char> CByteVector;
typedef CRecordVector<void *> CPointerVector;
template <class T>
class CObjectVector
{
CPointerVector _v;
public:
unsigned Size() const { return _v.Size(); }
bool IsEmpty() const { return _v.IsEmpty(); }
void ReserveDown() { _v.ReserveDown(); }
// void Reserve(unsigned newCapacity) { _v.Reserve(newCapacity); }
void ClearAndReserve(unsigned newCapacity) { Clear(); _v.ClearAndReserve(newCapacity); }
CObjectVector() {}
CObjectVector(const CObjectVector &v)
{
const unsigned size = v.Size();
_v.ConstructReserve(size);
for (unsigned i = 0; i < size; i++)
AddInReserved(v[i]);
}
CObjectVector& operator=(const CObjectVector &v)
{
if (&v == this)
return *this;
Clear();
const unsigned size = v.Size();
_v.Reserve(size);
for (unsigned i = 0; i < size; i++)
AddInReserved(v[i]);
return *this;
}
CObjectVector& operator+=(const CObjectVector &v)
{
const unsigned addSize = v.Size();
if (addSize != 0)
{
const unsigned size = Size();
if (size >= k_VectorSizeMax || addSize > k_VectorSizeMax - size)
throw 2021;
_v.Reserve(size + addSize);
for (unsigned i = 0; i < addSize; i++)
AddInReserved(v[i]);
}
return *this;
}
const T& operator[](unsigned index) const { return *((T *)_v[index]); }
T& operator[](unsigned index) { return *((T *)_v[index]); }
const T& operator[](int index) const { return *((T *)_v[(unsigned)index]); }
T& operator[](int index) { return *((T *)_v[(unsigned)index]); }
const T& Front() const { return operator[](0); }
T& Front() { return operator[](0); }
const T& Back() const { return *(T *)_v.Back(); }
T& Back() { return *(T *)_v.Back(); }
void MoveToFront(unsigned index) { _v.MoveToFront(index); }
unsigned Add(const T& item)
{
_v.ReserveOnePosition();
return AddInReserved(item);
}
unsigned AddInReserved(const T& item)
{
return _v.AddInReserved(new T(item));
}
void ReserveOnePosition()
{
_v.ReserveOnePosition();
}
unsigned AddInReserved_Ptr_of_new(T *ptr)
{
return _v.AddInReserved(ptr);
}
#define VECTOR_ADD_NEW_OBJECT(v, a) \
(v).ReserveOnePosition(); \
(v).AddInReserved_Ptr_of_new(new a);
T& AddNew()
{
_v.ReserveOnePosition();
T *p = new T;
_v.AddInReserved(p);
return *p;
}
T& AddNewInReserved()
{
T *p = new T;
_v.AddInReserved(p);
return *p;
}
void Insert(unsigned index, const T& item)
{
_v.ReserveOnePosition();
_v.InsertInReserved(index, new T(item));
}
T& InsertNew(unsigned index)
{
_v.ReserveOnePosition();
T *p = new T;
_v.InsertInReserved(index, p);
return *p;
}
~CObjectVector()
{
for (unsigned i = _v.Size(); i != 0;)
delete (T *)_v[--i];
}
void ClearAndFree()
{
Clear();
_v.ClearAndFree();
}
void Clear()
{
for (unsigned i = _v.Size(); i != 0;)
delete (T *)_v[--i];
_v.Clear();
}
void DeleteFrom(unsigned index)
{
const unsigned size = _v.Size();
for (unsigned i = index; i < size; i++)
delete (T *)_v[i];
_v.DeleteFrom(index);
}
void DeleteFrontal(unsigned num)
{
for (unsigned i = 0; i < num; i++)
delete (T *)_v[i];
_v.DeleteFrontal(num);
}
void DeleteBack()
{
delete (T *)_v.Back();
_v.DeleteBack();
}
void Delete(unsigned index)
{
delete (T *)_v[index];
_v.Delete(index);
}
// void Delete(int index) { Delete((unsigned)index); }
/*
void Delete(unsigned index, unsigned num)
{
for (unsigned i = 0; i < num; i++)
delete (T *)_v[index + i];
_v.Delete(index, num);
}
*/
/*
int Find(const T& item) const
{
unsigned size = Size();
for (unsigned i = 0; i < size; i++)
if (item == (*this)[i])
return i;
return -1;
}
*/
int FindInSorted(const T& item) const
{
unsigned left = 0, right = Size();
while (left != right)
{
// const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
const unsigned mid = (left + right) / 2;
const T& midVal = (*this)[mid];
const int comp = item.Compare(midVal);
if (comp == 0)
return (int)mid;
if (comp < 0)
right = mid;
else
left = mid + 1;
}
return -1;
}
unsigned AddToUniqueSorted(const T& item)
{
unsigned left = 0, right = Size();
while (left != right)
{
// const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
const unsigned mid = (left + right) / 2;
const T& midVal = (*this)[mid];
const int comp = item.Compare(midVal);
if (comp == 0)
return mid;
if (comp < 0)
right = mid;
else
left = mid + 1;
}
Insert(right, item);
return right;
}
/*
unsigned AddToSorted(const T& item)
{
unsigned left = 0, right = Size();
while (left != right)
{
// const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
const unsigned mid = (left + right) / 2;
const T& midVal = (*this)[mid];
const int comp = item.Compare(midVal);
if (comp == 0)
{
right = mid + 1;
break;
}
if (comp < 0)
right = mid;
else
left = mid + 1;
}
Insert(right, item);
return right;
}
*/
void Sort(int (*compare)(void *const *, void *const *, void *), void *param)
{ _v.Sort(compare, param); }
static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */)
{ return (*(*((const T *const *)a1))).Compare(*(*((const T *const *)a2))); }
void Sort() { _v.Sort(CompareObjectItems, NULL); }
};
#define FOR_VECTOR(_i_, _v_) for (unsigned _i_ = 0; _i_ < (_v_).Size(); _i_++)
#endif

View File

@ -4,68 +4,108 @@
#ifndef _WIN32
#include <stdlib.h>
#include <time.h>
#ifdef __GNUC__
#include <sys/time.h>
#endif
#include "MyWindows.h"
#include "Types.h"
#include <malloc.h>
static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); }
static inline void FreeForBSTR(void *pv) { ::free(pv);}
static UINT MyStringLen(const wchar_t *s)
{
UINT i;
for (i = 0; s[i] != '\0'; i++);
return i;
}
/* Win32 uses DWORD (32-bit) type to store size of string before (OLECHAR *) string.
We must select CBstrSizeType for another systems (not Win32):
BSTR SysAllocStringByteLen(LPCSTR psz, UINT len)
if (CBstrSizeType is UINT32),
then we support only strings smaller than 4 GB.
Win32 version always has that limitation.
if (CBstrSizeType is UINT),
(UINT can be 16/32/64-bit)
We can support strings larger than 4 GB (if UINT is 64-bit),
but sizeof(UINT) can be different in parts compiled by
different compilers/settings,
and we can't send such BSTR strings between such parts.
*/
typedef UINT32 CBstrSizeType;
// typedef UINT CBstrSizeType;
#define k_BstrSize_Max 0xFFFFFFFF
// #define k_BstrSize_Max UINT_MAX
// #define k_BstrSize_Max ((UINT)(INT)-1)
BSTR SysAllocStringByteLen(LPCSTR s, UINT len)
{
int realLen = len + sizeof(UINT) + sizeof(OLECHAR) + sizeof(OLECHAR);
void *p = AllocateForBSTR(realLen);
if (p == 0)
return 0;
*(UINT *)p = len;
BSTR bstr = (BSTR)((UINT *)p + 1);
memmove(bstr, psz, len);
Byte *pb = ((Byte *)bstr) + len;
for (int i = 0; i < sizeof(OLECHAR) * 2; i++)
pb[i] = 0;
/* Original SysAllocStringByteLen in Win32 maybe fills only unaligned null OLECHAR at the end.
We provide also aligned null OLECHAR at the end. */
if (len >= (k_BstrSize_Max - (UINT)sizeof(OLECHAR) - (UINT)sizeof(OLECHAR) - (UINT)sizeof(CBstrSizeType)))
return NULL;
UINT size = (len + (UINT)sizeof(OLECHAR) + (UINT)sizeof(OLECHAR) - 1) & ~((UINT)sizeof(OLECHAR) - 1);
void *p = AllocateForBSTR(size + (UINT)sizeof(CBstrSizeType));
if (!p)
return NULL;
*(CBstrSizeType *)p = (CBstrSizeType)len;
BSTR bstr = (BSTR)((CBstrSizeType *)p + 1);
if (s)
memcpy(bstr, s, len);
for (; len < size; len++)
((Byte *)bstr)[len] = 0;
return bstr;
}
BSTR SysAllocString(const OLECHAR *sz)
BSTR SysAllocStringLen(const OLECHAR *s, UINT len)
{
if (sz == 0)
return 0;
UINT strLen = MyStringLen(sz);
UINT len = (strLen + 1) * sizeof(OLECHAR);
void *p = AllocateForBSTR(len + sizeof(UINT));
if (p == 0)
return 0;
*(UINT *)p = strLen;
BSTR bstr = (BSTR)((UINT *)p + 1);
memmove(bstr, sz, len);
if (len >= (k_BstrSize_Max - (UINT)sizeof(OLECHAR) - (UINT)sizeof(CBstrSizeType)) / (UINT)sizeof(OLECHAR))
return NULL;
UINT size = len * (UINT)sizeof(OLECHAR);
void *p = AllocateForBSTR(size + (UINT)sizeof(CBstrSizeType) + (UINT)sizeof(OLECHAR));
if (!p)
return NULL;
*(CBstrSizeType *)p = (CBstrSizeType)size;
BSTR bstr = (BSTR)((CBstrSizeType *)p + 1);
if (s)
memcpy(bstr, s, size);
bstr[len] = 0;
return bstr;
}
BSTR SysAllocString(const OLECHAR *s)
{
if (!s)
return NULL;
const OLECHAR *s2 = s;
while (*s2 != 0)
s2++;
return SysAllocStringLen(s, (UINT)(s2 - s));
}
void SysFreeString(BSTR bstr)
{
if (bstr != 0)
FreeForBSTR((UINT *)bstr - 1);
if (bstr)
FreeForBSTR((CBstrSizeType *)bstr - 1);
}
UINT SysStringByteLen(BSTR bstr)
{
if (bstr == 0)
if (!bstr)
return 0;
return *((UINT *)bstr - 1);
return *((CBstrSizeType *)bstr - 1);
}
UINT SysStringLen(BSTR bstr)
{
return SysStringByteLen(bstr) / sizeof(OLECHAR);
if (!bstr)
return 0;
return *((CBstrSizeType *)bstr - 1) / (UINT)sizeof(OLECHAR);
}
HRESULT VariantClear(VARIANTARG *prop)
{
if (prop->vt == VT_BSTR)
@ -74,7 +114,7 @@ HRESULT VariantClear(VARIANTARG *prop)
return S_OK;
}
HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src)
HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src)
{
HRESULT res = ::VariantClear(dest);
if (res != S_OK)
@ -83,7 +123,7 @@ HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src)
{
dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal,
SysStringByteLen(src->bstrVal));
if (dest->bstrVal == 0)
if (!dest->bstrVal)
return E_OUTOFMEMORY;
dest->vt = VT_BSTR;
}
@ -103,7 +143,150 @@ LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2)
DWORD GetLastError()
{
return 0;
return (DWORD)errno;
}
void SetLastError(DWORD dw)
{
errno = (int)dw;
}
static LONG TIME_GetBias()
{
time_t utc = time(NULL);
struct tm *ptm = localtime(&utc);
int localdaylight = ptm->tm_isdst; /* daylight for local timezone */
ptm = gmtime(&utc);
ptm->tm_isdst = localdaylight; /* use local daylight, not that of Greenwich */
LONG bias = (int)(mktime(ptm)-utc);
return bias;
}
#define TICKS_PER_SEC 10000000
/*
#define SECS_PER_DAY (24 * 60 * 60)
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (UInt64)SECS_PER_DAY)
#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKS_PER_SEC)
*/
#define GET_TIME_64(pft) ((pft)->dwLowDateTime | ((UInt64)(pft)->dwHighDateTime << 32))
#define SET_FILETIME(ft, v64) \
(ft)->dwLowDateTime = (DWORD)v64; \
(ft)->dwHighDateTime = (DWORD)(v64 >> 32);
BOOL WINAPI FileTimeToLocalFileTime(const FILETIME *fileTime, FILETIME *localFileTime)
{
UInt64 v = GET_TIME_64(fileTime);
v = (UInt64)((Int64)v - (Int64)TIME_GetBias() * TICKS_PER_SEC);
SET_FILETIME(localFileTime, v)
return TRUE;
}
BOOL WINAPI LocalFileTimeToFileTime(const FILETIME *localFileTime, FILETIME *fileTime)
{
UInt64 v = GET_TIME_64(localFileTime);
v = (UInt64)((Int64)v + (Int64)TIME_GetBias() * TICKS_PER_SEC);
SET_FILETIME(fileTime, v)
return TRUE;
}
/*
VOID WINAPI GetSystemTimeAsFileTime(FILETIME *ft)
{
UInt64 t = 0;
timeval tv;
if (gettimeofday(&tv, NULL) == 0)
{
t = tv.tv_sec * (UInt64)TICKS_PER_SEC + TICKS_1601_TO_1970;
t += tv.tv_usec * 10;
}
SET_FILETIME(ft, t)
}
*/
DWORD WINAPI GetTickCount(VOID)
{
#ifndef _WIN32
// gettimeofday() doesn't work in some MINGWs by unknown reason
timeval tv;
if (gettimeofday(&tv, NULL) == 0)
{
// tv_sec and tv_usec are (long)
return (DWORD)((UInt64)(Int64)tv.tv_sec * (UInt64)1000 + (UInt64)(Int64)tv.tv_usec / 1000);
}
#endif
return (DWORD)time(NULL) * 1000;
}
#define PERIOD_4 (4 * 365 + 1)
#define PERIOD_100 (PERIOD_4 * 25 - 1)
#define PERIOD_400 (PERIOD_100 * 4 + 1)
BOOL WINAPI FileTimeToSystemTime(const FILETIME *ft, SYSTEMTIME *st)
{
UInt32 v;
UInt64 v64 = GET_TIME_64(ft);
v64 /= 10000;
st->wMilliseconds = (WORD)(v64 % 1000); v64 /= 1000;
st->wSecond = (WORD)(v64 % 60); v64 /= 60;
st->wMinute = (WORD)(v64 % 60); v64 /= 60;
v = (UInt32)v64;
st->wHour = (WORD)(v % 24); v /= 24;
// 1601-01-01 was Monday
st->wDayOfWeek = (WORD)((v + 1) % 7);
UInt32 leaps, year, day, mon;
leaps = (3 * ((4 * v + (365 - 31 - 28) * 4 + 3) / PERIOD_400) + 3) / 4;
v += 28188 + leaps;
// leaps - the number of exceptions from PERIOD_4 rules starting from 1600-03-01
// (1959 / 64) - converts day from 03-01 to month
year = (20 * v - 2442) / (5 * PERIOD_4);
day = v - (year * PERIOD_4) / 4;
mon = (64 * day) / 1959;
st->wDay = (WORD)(day - (1959 * mon) / 64);
mon -= 1;
year += 1524;
if (mon > 12)
{
mon -= 12;
year++;
}
st->wMonth = (WORD)mon;
st->wYear = (WORD)year;
/*
unsigned year, mon;
unsigned char ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
unsigned t;
year = (WORD)(1601 + v / PERIOD_400 * 400);
v %= PERIOD_400;
t = v / PERIOD_100; if (t == 4) t = 3; year += t * 100; v -= t * PERIOD_100;
t = v / PERIOD_4; if (t == 25) t = 24; year += t * 4; v -= t * PERIOD_4;
t = v / 365; if (t == 4) t = 3; year += t; v -= t * 365;
st->wYear = (WORD)year;
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
ms[1] = 29;
for (mon = 0;; mon++)
{
unsigned d = ms[mon];
if (v < d)
break;
v -= d;
}
st->wDay = (WORD)(v + 1);
st->wMonth = (WORD)(mon + 1);
*/
return TRUE;
}
#endif

View File

@ -1,19 +1,38 @@
// MyWindows.h
#ifndef __MYWINDOWS_H
#define __MYWINDOWS_H
#ifdef Z7_DEFINE_GUID
#undef Z7_DEFINE_GUID
#endif
#ifdef INITGUID
#define Z7_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
EXTERN_C const GUID name; \
EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
#else
#define Z7_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
EXTERN_C const GUID name
#endif
#ifndef ZIP7_INC_MY_WINDOWS_H
#define ZIP7_INC_MY_WINDOWS_H
#ifdef _WIN32
#include <windows.h>
#include "../../C/7zWindows.h"
#else
#else // _WIN32
#include <stddef.h> // for wchar_t
#include <string.h>
// #include <stdint.h> // for uintptr_t
#include "../../C/7zTypes.h"
#include "MyGuidDef.h"
// WINAPI is __stdcall in Windows-MSVC in windef.h
#define WINAPI
typedef char CHAR;
typedef unsigned char UCHAR;
@ -27,21 +46,28 @@ typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef short VARIANT_BOOL;
typedef int INT;
typedef Int32 INT32;
typedef unsigned int UINT;
typedef UInt32 UINT32;
typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit
typedef UINT32 ULONG;
#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xffff))
#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16))
#undef DWORD
typedef UINT32 DWORD;
// MS uses long for BOOL, but long is 32-bit in MS. So we use int.
// typedef long BOOL;
typedef int BOOL;
#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
// typedef size_t ULONG_PTR;
// typedef size_t DWORD_PTR;
// typedef uintptr_t UINT_PTR;
// typedef ptrdiff_t UINT_PTR;
typedef Int64 LONGLONG;
typedef UInt64 ULONGLONG;
typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;
typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;
typedef struct _LARGE_INTEGER { LONGLONG QuadPart; } LARGE_INTEGER;
typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart; } ULARGE_INTEGER;
typedef const CHAR *LPCSTR;
typedef CHAR TCHAR;
@ -57,13 +83,14 @@ typedef struct _FILETIME
{
DWORD dwLowDateTime;
DWORD dwHighDateTime;
}FILETIME;
} FILETIME;
#define HRESULT LONG
#define FAILED(Status) ((HRESULT)(Status)<0)
#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
#define FAILED(hr) ((HRESULT)(hr) < 0)
typedef ULONG PROPID;
typedef LONG SCODE;
#define S_OK ((HRESULT)0x00000000L)
#define S_FALSE ((HRESULT)0x00000001L)
#define E_NOTIMPL ((HRESULT)0x80004001L)
@ -71,41 +98,92 @@ typedef LONG SCODE;
#define E_ABORT ((HRESULT)0x80004004L)
#define E_FAIL ((HRESULT)0x80004005L)
#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L)
#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
#define E_INVALIDARG ((HRESULT)0x80070057L)
#define CLASS_E_CLASSNOTAVAILABLE ((HRESULT)0x80040111L)
#ifdef _MSC_VER
#define STDMETHODCALLTYPE __stdcall
#define STDAPICALLTYPE __stdcall
#else
// do we need __export here?
#define STDMETHODCALLTYPE
#define STDAPICALLTYPE
#endif
#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f
#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
#ifndef DECLSPEC_NOTHROW
#define DECLSPEC_NOTHROW Z7_DECLSPEC_NOTHROW
#endif
#ifndef DECLSPEC_NOVTABLE
#define DECLSPEC_NOVTABLE Z7_DECLSPEC_NOVTABLE
#endif
#ifndef COM_DECLSPEC_NOTHROW
#ifdef COM_STDMETHOD_CAN_THROW
#define COM_DECLSPEC_NOTHROW
#else
#define COM_DECLSPEC_NOTHROW DECLSPEC_NOTHROW
#endif
#endif
#define DECLARE_INTERFACE(iface) struct DECLSPEC_NOVTABLE iface
#define DECLARE_INTERFACE_(iface, baseiface) struct DECLSPEC_NOVTABLE iface : public baseiface
#define STDMETHOD_(t, f) virtual COM_DECLSPEC_NOTHROW t STDMETHODCALLTYPE f
#define STDMETHOD(f) STDMETHOD_(HRESULT, f)
#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
#define STDMETHODIMP_(t) COM_DECLSPEC_NOTHROW t STDMETHODCALLTYPE
#define STDMETHODIMP STDMETHODIMP_(HRESULT)
#define PURE = 0
#define MIDL_INTERFACE(x) struct
// #define MIDL_INTERFACE(x) struct
#ifdef __cplusplus
/*
p7zip and 7-Zip before v23 used virtual destructor in IUnknown,
if _WIN32 is not defined.
It used virtual destructor, because some compilers don't like virtual
interfaces without virtual destructor.
IUnknown in Windows (_WIN32) doesn't use virtual destructor in IUnknown.
We still can define Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN here,
if we want to be compatible with old plugin interface of p7zip and 7-Zip before v23.
v23:
In new 7-Zip v23 we try to be more compatible with original IUnknown from _WIN32.
So we do not define Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN here,
*/
// #define Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN
#ifdef Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif
#endif
Z7_PURE_INTERFACES_BEGIN
DEFINE_GUID(IID_IUnknown,
0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
struct IUnknown
{
STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE;
STDMETHOD_(ULONG, AddRef)() PURE;
STDMETHOD_(ULONG, Release)() PURE;
#ifndef _WIN32
STDMETHOD(QueryInterface) (REFIID iid, void **outObject) =0;
STDMETHOD_(ULONG, AddRef)() =0;
STDMETHOD_(ULONG, Release)() =0;
#ifdef Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN
virtual ~IUnknown() {}
#endif
};
typedef IUnknown *LPUNKNOWN;
#endif
Z7_PURE_INTERFACES_END
#endif // __cplusplus
#define VARIANT_TRUE ((VARIANT_BOOL)-1)
#define VARIANT_FALSE ((VARIANT_BOOL)0)
@ -127,6 +205,7 @@ enum VARENUM
VT_VARIANT = 12,
VT_UNKNOWN = 13,
VT_DECIMAL = 14,
VT_I1 = 16,
VT_UI1 = 17,
VT_UI2 = 18,
@ -145,8 +224,6 @@ typedef WORD PROPVAR_PAD1;
typedef WORD PROPVAR_PAD2;
typedef WORD PROPVAR_PAD3;
#ifdef __cplusplus
typedef struct tagPROPVARIANT
{
VARTYPE vt;
@ -176,22 +253,35 @@ typedef PROPVARIANT tagVARIANT;
typedef tagVARIANT VARIANT;
typedef VARIANT VARIANTARG;
MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src);
#endif
typedef struct tagSTATPROPSTG
{
LPOLESTR lpwstrName;
PROPID propid;
VARTYPE vt;
} STATPROPSTG;
MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
MY_EXTERN_C void SysFreeString(BSTR bstr);
MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
MY_EXTERN_C UINT SysStringLen(BSTR bstr);
EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
EXTERN_C BSTR SysAllocStringLen(const OLECHAR *sz, UINT len);
EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
EXTERN_C void SysFreeString(BSTR bstr);
EXTERN_C UINT SysStringByteLen(BSTR bstr);
EXTERN_C UINT SysStringLen(BSTR bstr);
MY_EXTERN_C DWORD GetLastError();
MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
EXTERN_C DWORD GetLastError();
EXTERN_C void SetLastError(DWORD dwCode);
EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
EXTERN_C DWORD GetCurrentThreadId();
EXTERN_C DWORD GetCurrentProcessId();
#define MAX_PATH 1024
#define CP_ACP 0
#define CP_OEMCP 1
#define CP_UTF8 65001
typedef enum tagSTREAM_SEEK
{
@ -200,5 +290,35 @@ typedef enum tagSTREAM_SEEK
STREAM_SEEK_END = 2
} STREAM_SEEK;
#endif
typedef struct _SYSTEMTIME
{
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME;
BOOL WINAPI FileTimeToLocalFileTime(const FILETIME *fileTime, FILETIME *localFileTime);
BOOL WINAPI LocalFileTimeToFileTime(const FILETIME *localFileTime, FILETIME *fileTime);
BOOL WINAPI FileTimeToSystemTime(const FILETIME *fileTime, SYSTEMTIME *systemTime);
// VOID WINAPI GetSystemTimeAsFileTime(FILETIME *systemTimeAsFileTime);
DWORD GetTickCount();
#define CREATE_NEW 1
#define CREATE_ALWAYS 2
#define OPEN_EXISTING 3
#define OPEN_ALWAYS 4
#define TRUNCATE_EXISTING 5
#endif // _WIN32
#endif

View File

@ -10,16 +10,57 @@
#ifndef DEBUG_MEMORY_LEAK
#ifdef _WIN32
#ifdef Z7_REDEFINE_OPERATOR_NEW
/*
void * my_new(size_t size)
{
// void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
if (size == 0)
size = 1;
void *p = ::malloc(size);
if (!p)
throw CNewException();
return p;
}
void my_delete(void *p) throw()
{
// if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p);
::free(p);
}
void * my_Realloc(void *p, size_t newSize, size_t oldSize)
{
void *newBuf = my_new(newSize);
if (oldSize != 0)
memcpy(newBuf, p, oldSize);
my_delete(p);
return newBuf;
}
*/
void *
#ifdef _MSC_VER
__cdecl
#endif
operator new(size_t size)
{
/* by C++ specification:
if (size == 0), operator new(size) returns non_NULL pointer.
If (operator new(0) returns NULL), it's out of specification.
but some calling code can work correctly even in this case too. */
// if (size == 0) return NULL; // for debug only. don't use it
/* malloc(0) returns non_NULL in main compilers, as we need here.
But specification also allows malloc(0) to return NULL.
So we change (size=0) to (size=1) here to get real non_NULL pointer */
if (size == 0)
size = 1;
// void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
// void *p = ::MyAlloc(size); // note: MyAlloc(0) returns NULL
void *p = ::malloc(size);
if (p == 0)
if (!p)
throw CNewException();
return p;
}
@ -30,41 +71,49 @@ __cdecl
#endif
operator delete(void *p) throw()
{
/*
if (p == 0)
return;
::HeapFree(::GetProcessHeap(), 0, p);
*/
// if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p);
// MyFree(p);
::free(p);
}
/*
void *
#ifdef _MSC_VER
__cdecl
#endif
operator new[](size_t size)
{
// void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
if (size == 0)
size = 1;
void *p = ::malloc(size);
if (!p)
throw CNewException();
return p;
}
void
#ifdef _MSC_VER
__cdecl
#endif
operator delete[](void *p) throw()
{
// if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p);
::free(p);
}
*/
#endif
#else
#pragma init_seg(lib)
#include <stdio.h>
// #pragma init_seg(lib)
/*
const int kDebugSize = 1000000;
static void *a[kDebugSize];
static int index = 0;
static int numAllocs = 0;
void * __cdecl operator new(size_t size)
{
numAllocs++;
void *p = HeapAlloc(GetProcessHeap(), 0, size);
if (index == 40)
{
int t = 1;
}
if (index < kDebugSize)
{
a[index] = p;
index++;
}
if (p == 0)
throw CNewException();
printf("Alloc %6d, size = %8d\n", numAllocs, size);
return p;
}
static int g_index = 0;
class CC
{
@ -76,27 +125,160 @@ public:
}
~CC()
{
printf("\nDestructor: %d\n", numAllocs);
for (int i = 0; i < kDebugSize; i++)
if (a[i] != 0)
return;
}
} g_CC;
*/
#ifdef _WIN32
static bool wasInit = false;
static CRITICAL_SECTION cs;
#endif
void __cdecl operator delete(void *p)
static int numAllocs = 0;
void *
#ifdef _MSC_VER
__cdecl
#endif
operator new(size_t size)
{
if (p == 0)
return;
#ifdef _WIN32
if (!wasInit)
{
InitializeCriticalSection(&cs);
wasInit = true;
}
EnterCriticalSection(&cs);
numAllocs++;
int loc = numAllocs;
void *p = HeapAlloc(GetProcessHeap(), 0, size);
/*
for (int i = 0; i < index; i++)
if (g_index < kDebugSize)
{
a[g_index] = p;
g_index++;
}
*/
printf("Alloc %6d, size = %8u\n", loc, (unsigned)size);
LeaveCriticalSection(&cs);
if (!p)
throw CNewException();
return p;
#else
numAllocs++;
int loc = numAllocs;
if (size == 0)
size = 1;
void *p = malloc(size);
/*
if (g_index < kDebugSize)
{
a[g_index] = p;
g_index++;
}
*/
printf("Alloc %6d, size = %8u\n", loc, (unsigned)size);
if (!p)
throw CNewException();
return p;
#endif
}
void
#ifdef _MSC_VER
__cdecl
#endif
operator delete(void *p) throw()
{
if (!p)
return;
#ifdef _WIN32
EnterCriticalSection(&cs);
/*
for (int i = 0; i < g_index; i++)
if (a[i] == p)
a[i] = 0;
*/
HeapFree(GetProcessHeap(), 0, p);
if (numAllocs == 0)
numAllocs = numAllocs; // ERROR
numAllocs--;
if (numAllocs == 0)
numAllocs = numAllocs; // OK: all objects were deleted
printf("Free %d\n", numAllocs);
LeaveCriticalSection(&cs);
#else
free(p);
numAllocs--;
printf("Free %d\n", numAllocs);
#endif
}
/*
void *
#ifdef _MSC_VER
__cdecl
#endif
operator new[](size_t size)
{
printf("operator_new[] : ");
return operator new(size);
}
void
#ifdef _MSC_VER
__cdecl
#endif
operator delete(void *p, size_t sz) throw();
void
#ifdef _MSC_VER
__cdecl
#endif
operator delete(void *p, size_t sz) throw()
{
if (!p)
return;
printf("operator_delete_size : size=%d : ", (unsigned)sz);
operator delete(p);
}
void
#ifdef _MSC_VER
__cdecl
#endif
operator delete[](void *p) throw()
{
if (!p)
return;
printf("operator_delete[] : ");
operator delete(p);
}
void
#ifdef _MSC_VER
__cdecl
#endif
operator delete[](void *p, size_t sz) throw();
void
#ifdef _MSC_VER
__cdecl
#endif
operator delete[](void *p, size_t sz) throw()
{
if (!p)
return;
printf("operator_delete_size[] : size=%d : ", (unsigned)sz);
operator delete(p);
}
*/
#endif
/*

View File

@ -1,16 +1,98 @@
// Common/NewHandler.h
#ifndef __COMMON_NEWHANDLER_H
#define __COMMON_NEWHANDLER_H
#ifndef ZIP7_INC_COMMON_NEW_HANDLER_H
#define ZIP7_INC_COMMON_NEW_HANDLER_H
/*
NewHandler.h and NewHandler.cpp allows to solve problem with compilers that
don't throw exception in operator new().
This file must be included before any code that uses operators new() or delete()
and you must compile and link "NewHandler.cpp", if you use some old MSVC compiler.
DOCs:
Since ISO C++98, operator new throws std::bad_alloc when memory allocation fails.
MSVC 6.0 returned a null pointer on an allocation failure.
Beginning in VS2002, operator new conforms to the standard and throws on failure.
By default, the compiler also generates defensive null checks to prevent
these older-style allocators from causing an immediate crash on failure.
The /Zc:throwingNew option tells the compiler to leave out these null checks,
on the assumption that all linked memory allocators conform to the standard.
The operator new() in some MSVC versions doesn't throw exception std::bad_alloc.
MSVC 6.0 (_MSC_VER == 1200) doesn't throw exception.
The code produced by some another MSVC compilers also can be linked
to library that doesn't throw exception.
We suppose that code compiled with VS2015+ (_MSC_VER >= 1900) throws exception std::bad_alloc.
For older _MSC_VER versions we redefine operator new() and operator delete().
Our version of operator new() throws CNewException() exception on failure.
It's still allowed to use redefined version of operator new() from "NewHandler.cpp"
with any compiler. 7-Zip's code can work with std::bad_alloc and CNewException() exceptions.
But if you use some additional code (outside of 7-Zip's code), you must check
that redefined version of operator new() is not problem for your code.
*/
#include <stddef.h>
#ifdef _WIN32
// We can compile my_new and my_delete with _fastcall
/*
void * my_new(size_t size);
void my_delete(void *p) throw();
// void * my_Realloc(void *p, size_t newSize, size_t oldSize);
*/
#endif
#if defined(_MSC_VER) && (_MSC_VER < 1600)
// If you want to use default operator new(), you can disable the following line
#define Z7_REDEFINE_OPERATOR_NEW
#endif
#ifdef Z7_REDEFINE_OPERATOR_NEW
// std::bad_alloc can require additional DLL dependency.
// So we don't define CNewException as std::bad_alloc here.
class CNewException {};
#ifdef _WIN32
void *
#ifdef _MSC_VER
__cdecl
#endif
operator new(size_t size);
void
#ifdef _MSC_VER
__cdecl
#endif
operator delete(void *p) throw();
#endif
#else
#include <new>
#define CNewException std::bad_alloc
#endif
/*
#ifdef _WIN32
void *
#ifdef _MSC_VER
__cdecl
#endif
operator new[](size_t size);
void
#ifdef _MSC_VER
__cdecl
#endif
operator delete[](void *p) throw();
#endif
*/
#endif

View File

@ -1,11 +0,0 @@
// Common/Types.h
#ifndef __COMMON_TYPES_H
#define __COMMON_TYPES_H
#include "../../C/Types.h"
typedef int HRes;
#endif

View File

@ -1,16 +1,16 @@
// Windows/Defs.h
#ifndef __WINDOWS_DEFS_H
#define __WINDOWS_DEFS_H
#ifndef ZIP7_INC_WINDOWS_DEFS_H
#define ZIP7_INC_WINDOWS_DEFS_H
#include "../Common/MyWindows.h"
#ifdef _WIN32
inline bool LRESULTToBool(LRESULT v) { return (v != FALSE); }
inline bool BOOLToBool(BOOL v) { return (v != FALSE); }
inline BOOL BoolToBOOL(bool v) { return (v ? TRUE: FALSE); }
#endif
inline bool BOOLToBool(BOOL v) { return (v != FALSE); }
inline VARIANT_BOOL BoolToVARIANT_BOOL(bool v) { return (v ? VARIANT_TRUE: VARIANT_FALSE); }
inline bool VARIANT_BOOLToBool(VARIANT_BOOL v) { return (v != VARIANT_FALSE); }

View File

@ -2,13 +2,53 @@
#include "StdAfx.h"
#include "PropVariant.h"
#include "../Common/Defs.h"
#include "PropVariant.h"
namespace NWindows {
namespace NCOM {
BSTR AllocBstrFromAscii(const char *s) throw()
{
if (!s)
return NULL;
UINT len = (UINT)strlen(s);
BSTR p = ::SysAllocStringLen(NULL, len);
if (p)
{
for (UINT i = 0; i <= len; i++)
p[i] = (Byte)s[i];
}
return p;
}
HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw()
{
p->bstrVal = ::SysAllocStringLen(NULL, numChars);
if (!p->bstrVal)
{
p->vt = VT_ERROR;
p->scode = E_OUTOFMEMORY;
return E_OUTOFMEMORY;
}
p->vt = VT_BSTR;
return S_OK;
}
HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw()
{
p->bstrVal = AllocBstrFromAscii(s);
if (p->bstrVal)
{
p->vt = VT_BSTR;
return S_OK;
}
p->vt = VT_ERROR;
p->scode = E_OUTOFMEMORY;
return E_OUTOFMEMORY;
}
CPropVariant::CPropVariant(const PROPVARIANT &varSrc)
{
vt = VT_EMPTY;
@ -38,6 +78,7 @@ CPropVariant& CPropVariant::operator=(const CPropVariant &varSrc)
InternalCopy(&varSrc);
return *this;
}
CPropVariant& CPropVariant::operator=(const PROPVARIANT &varSrc)
{
InternalCopy(&varSrc);
@ -50,7 +91,7 @@ CPropVariant& CPropVariant::operator=(BSTR bstrSrc)
return *this;
}
static const char *kMemException = "out of memory";
static const char * const kMemException = "out of memory";
CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
{
@ -58,7 +99,7 @@ CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
vt = VT_BSTR;
wReserved1 = 0;
bstrVal = ::SysAllocString(lpszSrc);
if (bstrVal == NULL && lpszSrc != NULL)
if (!bstrVal && lpszSrc)
{
throw kMemException;
// vt = VT_ERROR;
@ -67,29 +108,64 @@ CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
return *this;
}
CPropVariant& CPropVariant::operator=(const UString &s)
{
InternalClear();
vt = VT_BSTR;
wReserved1 = 0;
bstrVal = ::SysAllocStringLen(s, s.Len());
if (!bstrVal)
throw kMemException;
return *this;
}
CPropVariant& CPropVariant::operator=(const UString2 &s)
{
/*
if (s.IsEmpty())
*this = L"";
else
*/
{
InternalClear();
vt = VT_BSTR;
wReserved1 = 0;
bstrVal = ::SysAllocStringLen(s.GetRawPtr(), s.Len());
if (!bstrVal)
throw kMemException;
/* SysAllocStringLen probably appends a null-terminating character for NULL string.
But it doesn't specified in MSDN.
But we suppose that it works
if (!s.GetRawPtr())
{
*bstrVal = 0;
}
*/
/* MSDN: Windows CE: SysAllocStringLen() : Passing invalid (and under some circumstances NULL)
pointers to this function causes an unexpected termination of the application.
Is it safe? Maybe we must chamnge the code for that case ? */
}
return *this;
}
CPropVariant& CPropVariant::operator=(const char *s)
{
InternalClear();
vt = VT_BSTR;
wReserved1 = 0;
UINT len = (UINT)strlen(s);
bstrVal = ::SysAllocStringByteLen(0, (UINT)len * sizeof(OLECHAR));
if (bstrVal == NULL)
bstrVal = AllocBstrFromAscii(s);
if (!bstrVal)
{
throw kMemException;
// vt = VT_ERROR;
// scode = E_OUTOFMEMORY;
}
else
{
for (UINT i = 0; i <= len; i++)
bstrVal[i] = s[i];
}
return *this;
}
CPropVariant& CPropVariant::operator=(bool bSrc)
CPropVariant& CPropVariant::operator=(bool bSrc) throw()
{
if (vt != VT_BOOL)
{
@ -100,71 +176,124 @@ CPropVariant& CPropVariant::operator=(bool bSrc)
return *this;
}
BSTR CPropVariant::AllocBstr(unsigned numChars)
{
if (vt != VT_EMPTY)
InternalClear();
vt = VT_BSTR;
wReserved1 = 0;
bstrVal = ::SysAllocStringLen(NULL, numChars);
if (!bstrVal)
{
throw kMemException;
// vt = VT_ERROR;
// scode = E_OUTOFMEMORY;
}
return bstrVal;
}
#define SET_PROP_id_dest(id, dest) \
if (vt != id) { InternalClear(); vt = id; } dest = value; wReserved1 = 0;
void CPropVariant::Set_Int32(Int32 value) throw()
{
SET_PROP_id_dest(VT_I4, lVal)
}
void CPropVariant::Set_Int64(Int64 value) throw()
{
SET_PROP_id_dest(VT_I8, hVal.QuadPart)
}
#define SET_PROP_FUNC(type, id, dest) \
CPropVariant& CPropVariant::operator=(type value) \
{ if (vt != id) { InternalClear(); vt = id; } \
dest = value; return *this; }
CPropVariant& CPropVariant::operator=(type value) throw() \
{ SET_PROP_id_dest(id, dest) return *this; }
SET_PROP_FUNC(Byte, VT_UI1, bVal)
SET_PROP_FUNC(Int16, VT_I2, iVal)
SET_PROP_FUNC(Int32, VT_I4, lVal)
// SET_PROP_FUNC(Int16, VT_I2, iVal)
// SET_PROP_FUNC(Int32, VT_I4, lVal)
SET_PROP_FUNC(UInt32, VT_UI4, ulVal)
SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
// SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart)
SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
static HRESULT MyPropVariantClear(PROPVARIANT *prop)
#define CASE_SIMPLE_VT_VALUES \
case VT_EMPTY: \
case VT_BOOL: \
case VT_FILETIME: \
case VT_UI8: \
case VT_UI4: \
case VT_UI2: \
case VT_UI1: \
case VT_I8: \
case VT_I4: \
case VT_I2: \
case VT_I1: \
case VT_UINT: \
case VT_INT: \
case VT_NULL: \
case VT_ERROR: \
case VT_R4: \
case VT_R8: \
case VT_CY: \
case VT_DATE: \
/*
::VariantClear() and ::VariantCopy() don't work, if (vt == VT_FILETIME)
So we handle VT_FILETIME and another simple types directly
we call system functions for VT_BSTR and for unknown typed
*/
CPropVariant::~CPropVariant() throw()
{
switch(prop->vt)
switch ((unsigned)vt)
{
case VT_UI1:
case VT_I1:
case VT_I2:
case VT_UI2:
case VT_BOOL:
case VT_I4:
case VT_UI4:
case VT_R4:
case VT_INT:
case VT_UINT:
case VT_ERROR:
case VT_FILETIME:
case VT_UI8:
case VT_R8:
case VT_CY:
case VT_DATE:
CASE_SIMPLE_VT_VALUES
// vt = VT_EMPTY; // it's optional
return;
}
::VariantClear((tagVARIANT *)this);
}
HRESULT PropVariant_Clear(PROPVARIANT *prop) throw()
{
switch ((unsigned)prop->vt)
{
CASE_SIMPLE_VT_VALUES
prop->vt = VT_EMPTY;
break;
default:
{
const HRESULT res = ::VariantClear((VARIANTARG *)prop);
if (res != S_OK || prop->vt != VT_EMPTY)
return res;
break;
}
}
prop->wReserved1 = 0;
prop->wReserved2 = 0;
prop->wReserved3 = 0;
prop->uhVal.QuadPart = 0;
return S_OK;
}
HRESULT CPropVariant::Clear() throw()
{
if (vt == VT_EMPTY)
{
wReserved1 = 0;
return S_OK;
}
return ::VariantClear((VARIANTARG *)prop);
return PropVariant_Clear(this);
}
HRESULT CPropVariant::Clear()
HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
{
return MyPropVariantClear(this);
}
HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
{
::VariantClear((tagVARIANT *)this);
switch(pSrc->vt)
Clear();
switch ((unsigned)pSrc->vt)
{
case VT_UI1:
case VT_I1:
case VT_I2:
case VT_UI2:
case VT_BOOL:
case VT_I4:
case VT_UI4:
case VT_R4:
case VT_INT:
case VT_UINT:
case VT_ERROR:
case VT_FILETIME:
case VT_UI8:
case VT_R8:
case VT_CY:
case VT_DATE:
CASE_SIMPLE_VT_VALUES
memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
return S_OK;
}
@ -172,29 +301,41 @@ HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
}
HRESULT CPropVariant::Attach(PROPVARIANT *pSrc)
HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw()
{
HRESULT hr = Clear();
const HRESULT hr = Clear();
if (FAILED(hr))
return hr;
memcpy(this, pSrc, sizeof(PROPVARIANT));
// memcpy((PROPVARIANT *)this, pSrc, sizeof(PROPVARIANT));
*(PROPVARIANT *)this = *pSrc;
pSrc->vt = VT_EMPTY;
pSrc->wReserved1 = 0;
return S_OK;
}
HRESULT CPropVariant::Detach(PROPVARIANT *pDest)
HRESULT CPropVariant::Detach(PROPVARIANT *pDest) throw()
{
HRESULT hr = MyPropVariantClear(pDest);
if (pDest->vt != VT_EMPTY)
{
const HRESULT hr = PropVariant_Clear(pDest);
if (FAILED(hr))
return hr;
memcpy(pDest, this, sizeof(PROPVARIANT));
}
// memcpy(pDest, this, sizeof(PROPVARIANT));
*pDest = *(PROPVARIANT *)this;
vt = VT_EMPTY;
wReserved1 = 0;
return S_OK;
}
HRESULT CPropVariant::InternalClear()
HRESULT CPropVariant::InternalClear() throw()
{
HRESULT hr = Clear();
if (vt == VT_EMPTY)
{
wReserved1 = 0;
return S_OK;
}
const HRESULT hr = Clear();
if (FAILED(hr))
{
vt = VT_ERROR;
@ -205,7 +346,7 @@ HRESULT CPropVariant::InternalClear()
void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
{
HRESULT hr = Copy(pSrc);
const HRESULT hr = Copy(pSrc);
if (FAILED(hr))
{
if (hr == E_OUTOFMEMORY)
@ -215,11 +356,12 @@ void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
}
}
int CPropVariant::Compare(const CPropVariant &a)
int CPropVariant::Compare(const CPropVariant &a) throw()
{
if (vt != a.vt)
return MyCompare(vt, a.vt);
switch (vt)
switch ((unsigned)vt)
{
case VT_EMPTY: return 0;
// case VT_I1: return MyCompare(cVal, a.cVal);
@ -232,10 +374,16 @@ int CPropVariant::Compare(const CPropVariant &a)
case VT_I8: return MyCompare(hVal.QuadPart, a.hVal.QuadPart);
case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
case VT_BOOL: return -MyCompare(boolVal, a.boolVal);
case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime);
case VT_BSTR:
return 0; // Not implemented
// return MyCompare(aPropVarint.cVal);
case VT_FILETIME:
{
const int res = CompareFileTime(&filetime, &a.filetime);
if (res != 0)
return res;
const unsigned v1 = Get_Ns100();
const unsigned v2 = a.Get_Ns100();
return MyCompare(v1, v2);
}
case VT_BSTR: return 0; // Not implemented
default: return 0;
}
}

View File

@ -1,27 +1,130 @@
// Windows/PropVariant.h
#ifndef __WINDOWS_PROPVARIANT_H
#define __WINDOWS_PROPVARIANT_H
#ifndef ZIP7_INC_WINDOWS_PROP_VARIANT_H
#define ZIP7_INC_WINDOWS_PROP_VARIANT_H
#include "../Common/MyTypes.h"
#include "../Common/MyWindows.h"
#include "../Common/Types.h"
#include "../Common/MyString.h"
namespace NWindows {
namespace NCOM {
BSTR AllocBstrFromAscii(const char *s) throw();
HRESULT PropVariant_Clear(PROPVARIANT *p) throw();
HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw();
HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw();
inline void PropVarEm_Set_UInt32(PROPVARIANT *p, UInt32 v) throw()
{
p->vt = VT_UI4;
p->ulVal = v;
}
inline void PropVarEm_Set_UInt64(PROPVARIANT *p, UInt64 v) throw()
{
p->vt = VT_UI8;
p->uhVal.QuadPart = v;
}
inline void PropVarEm_Set_FileTime64_Prec(PROPVARIANT *p, UInt64 v, unsigned prec) throw()
{
p->vt = VT_FILETIME;
p->filetime.dwLowDateTime = (DWORD)v;
p->filetime.dwHighDateTime = (DWORD)(v >> 32);
p->wReserved1 = (WORD)prec;
p->wReserved2 = 0;
p->wReserved3 = 0;
}
inline void PropVarEm_Set_Bool(PROPVARIANT *p, bool b) throw()
{
p->vt = VT_BOOL;
p->boolVal = (b ? VARIANT_TRUE : VARIANT_FALSE);
}
class CPropVariant : public tagPROPVARIANT
{
// ---------- forbidden functions ----------
CPropVariant(const char *s);
// CPropVariant(const UString &s);
#ifdef DEBUG_FSTRING_INHERITS_ASTRING
CPropVariant(const FString &s);
CPropVariant& operator=(const FString &s);
#endif
public:
CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; }
~CPropVariant() { Clear(); }
CPropVariant()
{
vt = VT_EMPTY;
wReserved1 = 0;
// wReserved2 = 0;
// wReserved3 = 0;
// uhVal.QuadPart = 0;
bstrVal = NULL;
}
void Set_FtPrec(unsigned prec)
{
wReserved1 = (WORD)prec;
wReserved2 = 0;
wReserved3 = 0;
}
void SetAsTimeFrom_FT_Prec(const FILETIME &ft, unsigned prec)
{
operator=(ft);
Set_FtPrec(prec);
}
void SetAsTimeFrom_Ft64_Prec(UInt64 v, unsigned prec)
{
FILETIME ft;
ft.dwLowDateTime = (DWORD)(UInt32)v;
ft.dwHighDateTime = (DWORD)(UInt32)(v >> 32);
operator=(ft);
Set_FtPrec(prec);
}
void SetAsTimeFrom_FT_Prec_Ns100(const FILETIME &ft, unsigned prec, unsigned ns100)
{
operator=(ft);
wReserved1 = (WORD)prec;
wReserved2 = (WORD)ns100;
wReserved3 = 0;
}
unsigned Get_Ns100() const
{
const unsigned prec = wReserved1;
const unsigned ns100 = wReserved2;
if (prec == 0
&& prec <= k_PropVar_TimePrec_1ns
&& ns100 < 100
&& wReserved3 == 0)
return ns100;
return 0;
}
~CPropVariant() throw();
CPropVariant(const PROPVARIANT &varSrc);
CPropVariant(const CPropVariant &varSrc);
CPropVariant(BSTR bstrSrc);
CPropVariant(LPCOLESTR lpszSrc);
CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); };
CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); }
CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; }
CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; iVal = value; }
CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; }
private:
CPropVariant(UInt16 value); // { vt = VT_UI2; wReserved1 = 0; uiVal = value; }
CPropVariant(Int16 value); // { vt = VT_I2; wReserved1 = 0; iVal = value; }
CPropVariant(Int32 value); // { vt = VT_I4; wReserved1 = 0; lVal = value; }
CPropVariant(Int64 value); // { vt = VT_I8; wReserved1 = 0; hVal.QuadPart = value; }
public:
CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; }
CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal.QuadPart = value; }
CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; }
@ -30,25 +133,39 @@ public:
CPropVariant& operator=(const PROPVARIANT &varSrc);
CPropVariant& operator=(BSTR bstrSrc);
CPropVariant& operator=(LPCOLESTR lpszSrc);
CPropVariant& operator=(const UString &s);
CPropVariant& operator=(const UString2 &s);
CPropVariant& operator=(const char *s);
CPropVariant& operator=(bool bSrc);
CPropVariant& operator=(Byte value);
CPropVariant& operator=(Int16 value);
CPropVariant& operator=(Int32 value);
CPropVariant& operator=(UInt32 value);
CPropVariant& operator=(Int64 value);
CPropVariant& operator=(UInt64 value);
CPropVariant& operator=(const FILETIME &value);
CPropVariant& operator=(const AString &s)
{ return (*this)=(const char *)s; }
HRESULT Clear();
HRESULT Copy(const PROPVARIANT *pSrc);
HRESULT Attach(PROPVARIANT *pSrc);
HRESULT Detach(PROPVARIANT *pDest);
CPropVariant& operator=(bool bSrc) throw();
CPropVariant& operator=(Byte value) throw();
HRESULT InternalClear();
private:
CPropVariant& operator=(Int16 value) throw();
CPropVariant& operator=(UInt16 value) throw();
CPropVariant& operator=(Int32 value) throw();
CPropVariant& operator=(Int64 value) throw();
public:
CPropVariant& operator=(UInt32 value) throw();
CPropVariant& operator=(UInt64 value) throw();
CPropVariant& operator=(const FILETIME &value) throw();
void Set_Int32(Int32 value) throw();
void Set_Int64(Int64 value) throw();
BSTR AllocBstr(unsigned numChars);
HRESULT Clear() throw();
HRESULT Copy(const PROPVARIANT *pSrc) throw();
HRESULT Attach(PROPVARIANT *pSrc) throw();
HRESULT Detach(PROPVARIANT *pDest) throw();
HRESULT InternalClear() throw();
void InternalCopy(const PROPVARIANT *pSrc);
int Compare(const CPropVariant &a1);
int Compare(const CPropVariant &a) throw();
};
}}

View File

@ -1,9 +1,12 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#ifndef ZIP7_INC_STDAFX_H
#define ZIP7_INC_STDAFX_H
#include "../Common/MyWindows.h"
#include "../Common/NewHandler.h"
#if defined(_MSC_VER) && _MSC_VER >= 1800
#pragma warning(disable : 4464) // relative include path contains '..'
#endif
#include "../Common/Common.h"
#endif

View File

@ -82,7 +82,8 @@ int CArchive::Open()
// Open Archive
const UInt64 kMaxCheckStartPosition = 1 << 22; // 4MB
CMyComPtr<IArchiveOpenCallback> callback(new CArchiveOpener(this));
HRESULT Ret = InArchive->Open(new CArchiveIO(m_pDevice ? m_pDevice : new QFile(m_ArchivePath), QIODevice::ReadOnly, m_pDevice == NULL), &kMaxCheckStartPosition, callback);
CMyComPtr<IInStream> pStream = new CArchiveIO(m_pDevice ? m_pDevice : new QFile(m_ArchivePath), QIODevice::ReadOnly, m_pDevice == NULL);
HRESULT Ret = InArchive->Open(pStream, &kMaxCheckStartPosition, callback);
if(Ret != S_OK)
{
InArchive->Close();
@ -313,7 +314,8 @@ bool CArchive::Update(QMap<int, QIODevice*> *FileList, bool bDelete, int Level)
}
CMyComPtr<IArchiveUpdateCallback2> callback(new CArchiveUpdater(this, Files));
if(OutArchive->UpdateItems(new CArchiveIO(m_pDevice ? m_pDevice : pFile, QIODevice::WriteOnly, m_pDevice == NULL), FileCount(), callback) != S_OK)
CMyComPtr<ISequentialOutStream> pStream = new CArchiveIO(m_pDevice ? m_pDevice : pFile, QIODevice::WriteOnly, m_pDevice == NULL);
if(OutArchive->UpdateItems(pStream, FileCount(), callback) != S_OK)
{
LogError("Error(s) while updating Archive");
return false;

View File

@ -72,7 +72,7 @@ STDMETHODIMP CArchiveExtractor::SetOperationResult (Int32 operationResult)
case NArchive::NExtract::NOperationResult::kOK:
//TRACE(L"... Completed");
break;
case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
//TRACE(L"... Error (Un Supported Method)");
m_pArchive->LogError(QString("File Extraction Fails (Un Supported Method): %1").arg(m_pArchive->FileProperty(m_Index, "Path").toString()));
m_pArchive->FileProperty(m_Index, "Error", "Un Supported Method");

View File

@ -6,23 +6,23 @@
class CArchiveExtractor: public IArchiveExtractCallback, public ICryptoGetTextPassword, public CMyUnknownImp
{
Z7_COM_UNKNOWN_IMP_2(IArchiveExtractCallback, ICryptoGetTextPassword)
public:
MY_UNKNOWN_IMP2(IArchiveExtractCallback, ICryptoGetTextPassword)
CArchiveExtractor(CArchive* pArchive, const QMap<int,CArchiveIO*>& Files);
~CArchiveExtractor();
// IProgress
STDMETHOD(SetTotal)(UInt64 size);
STDMETHOD(SetCompleted)(const UInt64 *completeValue);
Z7_COM7F_IMF(SetTotal(UInt64 size));
Z7_COM7F_IMF(SetCompleted(const UInt64 *completeValue));
// IArchiveExtractCallback
STDMETHOD(PrepareOperation)(Int32 askExtractMode);
STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode);
STDMETHOD(SetOperationResult)(Int32 operationResult);
Z7_COM7F_IMF(PrepareOperation(Int32 askExtractMode));
Z7_COM7F_IMF(GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode));
Z7_COM7F_IMF(SetOperationResult(Int32 operationResult));
// ICryptoGetTextPassword
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
Z7_COM7F_IMF(CryptoGetTextPassword(BSTR *password));
protected:
CArchive* m_pArchive;

View File

@ -124,7 +124,7 @@ SPropertyNames::SPropertyNames()
Map.insert(kpidCreatorApp, "CreatorApp");
Map.insert(kpidSectorSize, "SectorSize");
Map.insert(kpidPosixAttrib, "PosixAttrib");
Map.insert(kpidLink, "Link");
Map.insert(kpidSymLink, "Link");
Map.insert(kpidError, "Error");
Map.insert(kpidTotalSize, "TotalSize");
@ -153,4 +153,10 @@ QString GetPropertyName(PROPID PropID)
#endif
#endif
#include "Archive.cpp"
#include "ArchiveExtractor.cpp"
#include "ArchiveInterface.cpp"
#include "ArchiveOpener.cpp"
#include "ArchiveUpdater.cpp"
#endif

View File

@ -6,8 +6,8 @@
class CArchiveIO: public IOutStream, public IInStream, public CMyUnknownImp
{
Z7_COM_UNKNOWN_IMP_2(IOutStream, IInStream)
public:
MY_UNKNOWN_IMP2(IOutStream, IInStream)
CArchiveIO(QIODevice* pFile, QIODevice::OpenMode Mode, bool bDelete = true)
{
@ -28,7 +28,7 @@ public:
return m_pFile->open(Mode);
}
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize)
Z7_COM7F_IMF(Read(void *data, UInt32 size, UInt32 *processedSize))
{
quint64 read = m_pFile->read((char*)data, size);
if(read == -1)
@ -38,7 +38,7 @@ public:
return S_OK;
}
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize)
Z7_COM7F_IMF(Write(const void *data, UInt32 size, UInt32 *processedSize))
{
quint64 written = m_pFile->write((const char*)data, size);
if(written == -1)
@ -48,7 +48,7 @@ public:
return S_OK;
}
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
Z7_COM7F_IMF(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
{
switch(seekOrigin)
{
@ -65,12 +65,12 @@ public:
return S_OK;
}
STDMETHOD(SetSize)(UInt64 newSize)
Z7_COM7F_IMF(SetSize(UInt64 newSize))
{
return S_OK;
}
STDMETHOD(GetSize)(UInt64 *size)
Z7_COM7F_IMF(GetSize(UInt64 *size))
{
*size = m_pFile->size();
return S_OK;

View File

@ -80,14 +80,14 @@ bool CArchiveInterface::Init()
{
CArcInfoEx info;
if(ReadStringProp(getProp, getProp2, i, NArchive::kName, info.Name) != S_OK)
if(ReadStringProp(getProp, getProp2, i, NArchive::NHandlerPropID::kName, info.Name) != S_OK)
{
//LogLine(LOG_ERROR | LOG_DEBUG, QObject::tr("7z: Failed to get Formats %1 Name!").arg(i));
return false;
}
NWindows::NCOM::CPropVariant prop;
if (ReadProp(getProp, getProp2, i, NArchive::kClassID, prop) != S_OK)
if (ReadProp(getProp, getProp2, i, NArchive::NHandlerPropID::kClassID, prop) != S_OK)
continue;
if (prop.vt != VT_BSTR)
continue;
@ -95,12 +95,12 @@ bool CArchiveInterface::Init()
prop.Clear();
QString ext, addExt;
if(ReadStringProp(getProp, getProp2, i, NArchive::kExtension, ext) != S_OK)
if(ReadStringProp(getProp, getProp2, i, NArchive::NHandlerPropID::kExtension, ext) != S_OK)
{
//LogLine(LOG_ERROR | LOG_DEBUG, QObject::tr("7z: Failed to get Formats %1 Property kExtension!").arg(i));
return false;
}
if(ReadStringProp(getProp, getProp2, i, NArchive::kAddExtension, addExt) != S_OK)
if(ReadStringProp(getProp, getProp2, i, NArchive::NHandlerPropID::kAddExtension, addExt) != S_OK)
{
//LogLine(LOG_ERROR | LOG_DEBUG, QObject::tr("7z: Failed to get Formats %1 Property kAddExtension!").arg(i));
return false;
@ -109,9 +109,9 @@ bool CArchiveInterface::Init()
//TRACE(L"Archive Format %S supported %S, %S", QS2CS(info.Name), QS2CS(ext), QS2CS(addExt));
ReadBoolProp(getProp, getProp2, i, NArchive::kUpdate, info.UpdateEnabled);
ReadBoolProp(getProp, getProp2, i, NArchive::NHandlerPropID::kUpdate, info.UpdateEnabled);
if (info.UpdateEnabled)
ReadBoolProp(getProp, getProp2, i, NArchive::kKeepName, info.KeepName);
ReadBoolProp(getProp, getProp2, i, NArchive::NHandlerPropID::kKeepName, info.KeepName);
#ifdef _SFX
if (ReadProp(getProp, getProp2, i, NArchive::kStartSignature, prop) == S_OK)

View File

@ -9,6 +9,12 @@ CArchiveOpener::CArchiveOpener(CArchive* pArchive)
m_pArchive = pArchive;
}
CArchiveOpener::~CArchiveOpener()
{
foreach(CArchiveIO* pFile, m_Files)
delete pFile;
}
STDMETHODIMP CArchiveOpener::GetProperty(PROPID propID, PROPVARIANT *value)
{
NWindows::NCOM::CPropVariant prop;
@ -35,7 +41,9 @@ STDMETHODIMP CArchiveOpener::GetStream(const wchar_t *name, IInStream **inStream
QString Path = m_pArchive->GetNextPart(QString::fromStdWString(name));
if(QFile::exists(Path))
{
CMyComPtr<IInStream> inStreamLoc(new CArchiveIO(new QFile(Path), QIODevice::ReadOnly));
CArchiveIO* pFile = new CArchiveIO(new QFile(Path), QIODevice::ReadOnly);
m_Files.append(pFile);
CMyComPtr<IInStream> inStreamLoc(pFile);
*inStream = inStreamLoc.Detach();
return S_OK;
}

View File

@ -6,24 +6,27 @@
class CArchiveOpener: public IArchiveOpenCallback, public IArchiveOpenVolumeCallback, public ICryptoGetTextPassword, public CMyUnknownImp
{
Z7_COM_UNKNOWN_IMP_3(IArchiveOpenCallback, IArchiveOpenVolumeCallback, ICryptoGetTextPassword)
public:
CArchiveOpener(CArchive* pArchive);
MY_UNKNOWN_IMP3(IArchiveOpenCallback, IArchiveOpenVolumeCallback, ICryptoGetTextPassword)
CArchiveOpener(CArchive* pArchive);
~CArchiveOpener();
// IArchiveOpenCallback
STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) {return S_OK;}
STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) {return S_OK;}
Z7_COM7F_IMF(SetTotal(const UInt64 *files, const UInt64 *bytes)) {return S_OK;}
Z7_COM7F_IMF(SetCompleted(const UInt64 *files, const UInt64 *bytes)) {return S_OK;}
// IArchiveOpenVolumeCallback
STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value);
STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream);
Z7_COM7F_IMF(GetProperty(PROPID propID, PROPVARIANT *value));
Z7_COM7F_IMF(GetStream(const wchar_t *name, IInStream **inStream));
// ICryptoGetTextPassword2
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
Z7_COM7F_IMF(CryptoGetTextPassword(BSTR *password));
protected:
CArchive* m_pArchive;
QList<CArchiveIO*> m_Files;
};
#endif

View File

@ -6,28 +6,28 @@
class CArchiveUpdater: public IArchiveUpdateCallback2, public ICryptoGetTextPassword2, public CMyUnknownImp
{
Z7_COM_UNKNOWN_IMP_2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)
public:
MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)
CArchiveUpdater(CArchive* pArchive, const QMap<int,CArchiveIO*>& Files);
~CArchiveUpdater();
// IProgress
STDMETHOD(SetTotal)(UInt64 size);
STDMETHOD(SetCompleted)(const UInt64 *completeValue);
Z7_COM7F_IMF(SetTotal(UInt64 size));
Z7_COM7F_IMF(SetCompleted(const UInt64 *completeValue));
// IArchiveUpdateCallback2
STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);
STDMETHOD(SetOperationResult)(Int32 operationResult) {return S_OK;}
Z7_COM7F_IMF(GetUpdateItemInfo(UInt32 index, Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive));
Z7_COM7F_IMF(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value));
Z7_COM7F_IMF(GetStream(UInt32 index, ISequentialInStream **inStream));
Z7_COM7F_IMF(SetOperationResult(Int32 operationResult)) {return S_OK;}
// deprecated
STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) {return S_FALSE;}
STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) {return S_FALSE;}
Z7_COM7F_IMF(GetVolumeSize(UInt32 index, UInt64 *size)) {return S_FALSE;}
Z7_COM7F_IMF(GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)){return S_FALSE;}
// ICryptoGetTextPassword2
STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
Z7_COM7F_IMF(CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password));
protected:
CArchive* m_pArchive;

View File

@ -2,7 +2,7 @@
#define VERSION_MJR 1
#define VERSION_MIN 11
#define VERSION_REV 2
#define VERSION_REV 3
#define VERSION_UPD 0
#ifndef STR