updated 7zip to 23.01
This commit is contained in:
parent
555cb59a69
commit
4ee146430f
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*/
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
// Common/MyVector.cpp
|
||||
|
||||
#include "StdAfx.h"
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
// Common/Types.h
|
||||
|
||||
#ifndef __COMMON_TYPES_H
|
||||
#define __COMMON_TYPES_H
|
||||
|
||||
#include "../../C/Types.h"
|
||||
|
||||
typedef int HRes;
|
||||
|
||||
#endif
|
||||
|
|
@ -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); }
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
}}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue