mirror of
https://github.com/holub/mame
synced 2025-07-07 19:03:29 +03:00
705 lines
22 KiB
C++
705 lines
22 KiB
C++
// IArchive.h
|
|
|
|
#ifndef ZIP7_INC_IARCHIVE_H
|
|
#define ZIP7_INC_IARCHIVE_H
|
|
|
|
#include "../IProgress.h"
|
|
#include "../IStream.h"
|
|
#include "../PropID.h"
|
|
|
|
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
|
|
{
|
|
kNotDefined = -1,
|
|
kWindows = 0,
|
|
kUnix,
|
|
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, // 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
|
|
{
|
|
namespace NAskMode
|
|
{
|
|
enum
|
|
{
|
|
kExtract = 0,
|
|
kTest,
|
|
kSkip,
|
|
kReadExternal
|
|
};
|
|
}
|
|
|
|
namespace NOperationResult
|
|
{
|
|
enum
|
|
{
|
|
kOK = 0,
|
|
kUnsupportedMethod,
|
|
kDataError,
|
|
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 = 1,
|
|
// kError_FileChanged
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
#define Z7_IFACEM_IArchiveOpenCallback(x) \
|
|
x(SetTotal(const UInt64 *files, const UInt64 *bytes)) \
|
|
x(SetCompleted(const UInt64 *files, const UInt64 *bytes)) \
|
|
|
|
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)
|
|
{
|
|
IProgress::SetCompleted(completeValue) uses
|
|
packSize - for some stream formats (xz, gz, bz2, lzma, z, ppmd).
|
|
unpackSize - for another formats.
|
|
}
|
|
else
|
|
{
|
|
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.
|
|
|
|
Int32 opRes (NExtract::NOperationResult)
|
|
*/
|
|
|
|
// INTERFACE_IProgress(x)
|
|
|
|
#define Z7_IFACEM_IArchiveExtractCallback(x) \
|
|
x(GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)) \
|
|
x(PrepareOperation(Int32 askExtractMode)) \
|
|
x(SetOperationResult(Int32 opRes)) \
|
|
|
|
Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallback, IProgress, 0x20)
|
|
|
|
|
|
|
|
/*
|
|
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 = (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.
|
|
*/
|
|
|
|
#if defined(_MSC_VER) && !defined(__clang__)
|
|
#define MY_NO_THROW_DECL_ONLY Z7_COM7F_E
|
|
#else
|
|
#define MY_NO_THROW_DECL_ONLY
|
|
#endif
|
|
|
|
#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
|
|
{
|
|
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;
|
|
};
|
|
|
|
namespace NWindows {
|
|
namespace NCOM {
|
|
// PropVariant.cpp
|
|
BSTR AllocBstrFromAscii(const char *s) throw();
|
|
}}
|
|
|
|
|
|
#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; \
|
|
|
|
#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; } \
|
|
|
|
|
|
#define IMP_IInArchive_Props \
|
|
IMP_IInArchive_GetProp_NO_NAME(GetNumberOfProperties, GetPropertyInfo, kProps)
|
|
|
|
#define IMP_IInArchive_Props_WITH_NAME \
|
|
IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfProperties, GetPropertyInfo, kProps)
|
|
|
|
#define IMP_IInArchive_ArcProps \
|
|
IMP_IInArchive_GetProp_NO_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps)
|
|
|
|
#define IMP_IInArchive_ArcProps_WITH_NAME \
|
|
IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps)
|
|
|
|
#define IMP_IInArchive_ArcProps_NO_Table \
|
|
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 \
|
|
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
|