mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 06:07:07 -06:00
9.34
This commit is contained in:
committed by
Kornel Lesiński
parent
83f8ddcc5b
commit
f08f4dcc3c
327
CPP/7zip/Archive/IArchive.h
Executable file → Normal file
327
CPP/7zip/Archive/IArchive.h
Executable file → Normal file
@@ -20,20 +20,43 @@ namespace NFileTimeType
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
namespace NArchive
|
||||
{
|
||||
enum
|
||||
namespace NHandlerPropID
|
||||
{
|
||||
kName = 0,
|
||||
kClassID,
|
||||
kExtension,
|
||||
kAddExtension,
|
||||
kUpdate,
|
||||
kKeepName,
|
||||
kStartSignature,
|
||||
kFinishSignature,
|
||||
kAssociate
|
||||
};
|
||||
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
|
||||
// kVersion // VT_UI4 ((VER_MAJOR << 8) | VER_MINOR)
|
||||
};
|
||||
}
|
||||
|
||||
namespace NExtract
|
||||
{
|
||||
@@ -46,25 +69,32 @@ namespace NArchive
|
||||
kSkip
|
||||
};
|
||||
}
|
||||
|
||||
namespace NOperationResult
|
||||
{
|
||||
enum
|
||||
{
|
||||
kOK = 0,
|
||||
kUnSupportedMethod,
|
||||
kUnsupportedMethod,
|
||||
kDataError,
|
||||
kCRCError
|
||||
kCRCError,
|
||||
kUnavailable,
|
||||
kUnexpectedEnd,
|
||||
kDataAfterEnd,
|
||||
kIsNotArc,
|
||||
kHeadersError
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace NUpdate
|
||||
{
|
||||
namespace NOperationResult
|
||||
{
|
||||
enum
|
||||
{
|
||||
kOK = 0,
|
||||
kError
|
||||
kOK = 0
|
||||
, // kError
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -79,10 +109,16 @@ ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)
|
||||
INTERFACE_IArchiveOpenCallback(PURE);
|
||||
};
|
||||
|
||||
/*
|
||||
IArchiveExtractCallback::GetStream
|
||||
Result:
|
||||
(*inStream == NULL) - for directories
|
||||
(*inStream == NULL) - if link (hard link or symbolic link) was created
|
||||
*/
|
||||
|
||||
#define INTERFACE_IArchiveExtractCallback(x) \
|
||||
INTERFACE_IProgress(x) \
|
||||
STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \
|
||||
STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \
|
||||
STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \
|
||||
STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) x; \
|
||||
|
||||
@@ -115,41 +151,175 @@ ARCHIVE_INTERFACE(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;
|
||||
STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) throw() x; \
|
||||
STDMETHOD(Close)() throw() x; \
|
||||
STDMETHOD(GetNumberOfItems)(UInt32 *numItems) throw() x; \
|
||||
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) throw() x; \
|
||||
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) throw() x; \
|
||||
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) throw() x; \
|
||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) throw() x; \
|
||||
STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) throw() x; \
|
||||
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) throw() x; \
|
||||
STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) throw() x;
|
||||
|
||||
ARCHIVE_INTERFACE(IInArchive, 0x60)
|
||||
{
|
||||
INTERFACE_IInArchive(PURE)
|
||||
};
|
||||
|
||||
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 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 INTERFACE_IArchiveGetRawProps(x) \
|
||||
STDMETHOD(GetParent)(UInt32 index, UInt32 *parent, UInt32 *parentType) x; \
|
||||
STDMETHOD(GetRawProp)(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \
|
||||
STDMETHOD(GetNumRawProps)(UInt32 *numProps) x; \
|
||||
STDMETHOD(GetRawPropInfo)(UInt32 index, BSTR *name, PROPID *propID) x;
|
||||
|
||||
ARCHIVE_INTERFACE(IArchiveGetRawProps, 0x70)
|
||||
{
|
||||
INTERFACE_IArchiveGetRawProps(PURE)
|
||||
};
|
||||
|
||||
#define INTERFACE_IArchiveGetRootProps(x) \
|
||||
STDMETHOD(GetRootProp)(PROPID propID, PROPVARIANT *value) x; \
|
||||
STDMETHOD(GetRootRawProp)(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \
|
||||
|
||||
ARCHIVE_INTERFACE(IArchiveGetRootProps, 0x71)
|
||||
{
|
||||
INTERFACE_IArchiveGetRootProps(PURE)
|
||||
};
|
||||
|
||||
ARCHIVE_INTERFACE(IArchiveOpenSeq, 0x61)
|
||||
{
|
||||
STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE;
|
||||
};
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
ARCHIVE_INTERFACE(IArchiveOpen2, 0x62)
|
||||
{
|
||||
STDMETHOD(ArcOpen2)(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback) PURE;
|
||||
};
|
||||
*/
|
||||
|
||||
// ---------- 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)
|
||||
|
||||
*/
|
||||
|
||||
#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(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive) x; \
|
||||
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
|
||||
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \
|
||||
STDMETHOD(SetOperationResult)(Int32 operationResult) x; \
|
||||
@@ -169,6 +339,27 @@ ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
|
||||
INTERFACE_IArchiveUpdateCallback2(PURE);
|
||||
};
|
||||
|
||||
/*
|
||||
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 INTERFACE_IOutArchive(x) \
|
||||
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \
|
||||
@@ -182,47 +373,61 @@ ARCHIVE_INTERFACE(IOutArchive, 0xA0)
|
||||
|
||||
ARCHIVE_INTERFACE(ISetProperties, 0x03)
|
||||
{
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE;
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps) PURE;
|
||||
};
|
||||
|
||||
ARCHIVE_INTERFACE(IArchiveKeepModeForNextOpen, 0x04)
|
||||
{
|
||||
STDMETHOD(KeepModeForNextOpen)() PURE;
|
||||
};
|
||||
|
||||
/* 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 */
|
||||
|
||||
ARCHIVE_INTERFACE(IArchiveAllowTail, 0x05)
|
||||
{
|
||||
STDMETHOD(AllowTail)(Int32 allowTail) 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; } \
|
||||
{ if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \
|
||||
*propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; *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; \
|
||||
{ if (index >= ARRAY_SIZE(k)) 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::GetNumberOfProperties(UInt32 *numProps) \
|
||||
{ *numProps = ARRAY_SIZE(kProps); return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps)
|
||||
|
||||
#define IMP_IInArchive_Props_WITH_NAME \
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
|
||||
{ *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \
|
||||
{ *numProps = ARRAY_SIZE(kProps); return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps)
|
||||
|
||||
|
||||
#define IMP_IInArchive_ArcProps \
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
|
||||
{ *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
|
||||
{ *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps)
|
||||
|
||||
#define IMP_IInArchive_ArcProps_WITH_NAME \
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
|
||||
{ *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
|
||||
{ *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps)
|
||||
|
||||
#define IMP_IInArchive_ArcProps_NO_Table \
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
|
||||
{ *numProperties = 0; return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
|
||||
{ *numProps = 0; return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \
|
||||
{ return E_NOTIMPL; } \
|
||||
|
||||
@@ -231,4 +436,32 @@ ARCHIVE_INTERFACE(ISetProperties, 0x03)
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \
|
||||
{ value->vt = VT_EMPTY; return S_OK; }
|
||||
|
||||
|
||||
|
||||
#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 IOutArchive * (*Func_CreateOutArchive)();
|
||||
typedef IInArchive * (*Func_CreateInArchive)();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user