// ArchiveExports.cpp | |
#include "StdAfx.h" | |
#include "../../../C/7zVersion.h" | |
#include "../../Common/ComTry.h" | |
#include "../../Windows/PropVariant.h" | |
#include "../Common/RegisterArc.h" | |
static const unsigned kNumArcsMax = 64; | |
static unsigned g_NumArcs = 0; | |
static unsigned g_DefaultArcIndex = 0; | |
static const CArcInfo *g_Arcs[kNumArcsMax]; | |
void RegisterArc(const CArcInfo *arcInfo) throw() | |
{ | |
if (g_NumArcs < kNumArcsMax) | |
{ | |
const char *p = arcInfo->Name; | |
if (p[0] == '7' && p[1] == 'z' && p[2] == 0) | |
g_DefaultArcIndex = g_NumArcs; | |
g_Arcs[g_NumArcs] = arcInfo; | |
g_NumArcs++; | |
} | |
} | |
DEFINE_GUID(CLSID_CArchiveHandler, | |
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); | |
#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5]) | |
static inline HRESULT SetPropString(const char *s, unsigned size, PROPVARIANT *value) | |
{ | |
if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0) | |
value->vt = VT_BSTR; | |
return S_OK; | |
} | |
static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) | |
{ | |
return SetPropString((const char *)&guid, sizeof(GUID), value); | |
} | |
int FindFormatCalssId(const GUID *clsID) | |
{ | |
GUID cls = *clsID; | |
CLS_ARC_ID_ITEM(cls) = 0; | |
if (cls != CLSID_CArchiveHandler) | |
return -1; | |
Byte id = CLS_ARC_ID_ITEM(*clsID); | |
for (unsigned i = 0; i < g_NumArcs; i++) | |
if (g_Arcs[i]->ClassId == id) | |
return (int)i; | |
return -1; | |
} | |
STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject) | |
{ | |
COM_TRY_BEGIN | |
{ | |
int needIn = (*iid == IID_IInArchive); | |
int needOut = (*iid == IID_IOutArchive); | |
if (!needIn && !needOut) | |
return E_NOINTERFACE; | |
int formatIndex = FindFormatCalssId(clsid); | |
if (formatIndex < 0) | |
return CLASS_E_CLASSNOTAVAILABLE; | |
const CArcInfo &arc = *g_Arcs[formatIndex]; | |
if (needIn) | |
{ | |
*outObject = arc.CreateInArchive(); | |
((IInArchive *)*outObject)->AddRef(); | |
} | |
else | |
{ | |
if (!arc.CreateOutArchive) | |
return CLASS_E_CLASSNOTAVAILABLE; | |
*outObject = arc.CreateOutArchive(); | |
((IOutArchive *)*outObject)->AddRef(); | |
} | |
} | |
COM_TRY_END | |
return S_OK; | |
} | |
STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value) | |
{ | |
COM_TRY_BEGIN | |
NWindows::NCOM::PropVariant_Clear(value); | |
if (formatIndex >= g_NumArcs) | |
return E_INVALIDARG; | |
const CArcInfo &arc = *g_Arcs[formatIndex]; | |
NWindows::NCOM::CPropVariant prop; | |
switch (propID) | |
{ | |
case NArchive::NHandlerPropID::kName: prop = arc.Name; break; | |
case NArchive::NHandlerPropID::kClassID: | |
{ | |
GUID clsId = CLSID_CArchiveHandler; | |
CLS_ARC_ID_ITEM(clsId) = arc.ClassId; | |
return SetPropGUID(clsId, value); | |
} | |
case NArchive::NHandlerPropID::kExtension: if (arc.Ext) prop = arc.Ext; break; | |
case NArchive::NHandlerPropID::kAddExtension: if (arc.AddExt) prop = arc.AddExt; break; | |
case NArchive::NHandlerPropID::kUpdate: prop = (bool)(arc.CreateOutArchive != NULL); break; | |
case NArchive::NHandlerPropID::kKeepName: prop = ((arc.Flags & NArcInfoFlags::kKeepName) != 0); break; | |
case NArchive::NHandlerPropID::kAltStreams: prop = ((arc.Flags & NArcInfoFlags::kAltStreams) != 0); break; | |
case NArchive::NHandlerPropID::kNtSecure: prop = ((arc.Flags & NArcInfoFlags::kNtSecure) != 0); break; | |
case NArchive::NHandlerPropID::kFlags: prop = (UInt32)arc.Flags; break; | |
case NArchive::NHandlerPropID::kSignatureOffset: prop = (UInt32)arc.SignatureOffset; break; | |
// case NArchive::NHandlerPropID::kVersion: prop = (UInt32)MY_VER_MIX; break; | |
case NArchive::NHandlerPropID::kSignature: | |
if (!arc.IsMultiSignature()) | |
return SetPropString((const char *)arc.Signature, arc.SignatureSize, value); | |
break; | |
case NArchive::NHandlerPropID::kMultiSignature: | |
if (arc.IsMultiSignature()) | |
return SetPropString((const char *)arc.Signature, arc.SignatureSize, value); | |
break; | |
} | |
prop.Detach(value); | |
return S_OK; | |
COM_TRY_END | |
} | |
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) | |
{ | |
return GetHandlerProperty2(g_DefaultArcIndex, propID, value); | |
} | |
STDAPI GetNumberOfFormats(UINT32 *numFormats) | |
{ | |
*numFormats = g_NumArcs; | |
return S_OK; | |
} | |
STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc) | |
{ | |
*isArc = NULL; | |
if (formatIndex >= g_NumArcs) | |
return E_INVALIDARG; | |
*isArc = g_Arcs[formatIndex]->IsArc; | |
return S_OK; | |
} |