Source code

Revision control

Copy as Markdown

Other Tools

// 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;↩
}↩
}↩
DEFINE_GUID(CLSID_CArchiveHandler,↩
k_7zip_GUID_Data1,↩
k_7zip_GUID_Data2,↩
k_7zip_GUID_Data3_Common,↩
0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);↩
#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])↩
static inline HRESULT SetPropStrFromBin(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 SetPropStrFromBin((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]->Id == 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.Id;↩
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.SignatureSize != 0 && !arc.IsMultiSignature())↩
return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value);↩
break;↩
case NArchive::NHandlerPropID::kMultiSignature:↩
if (arc.SignatureSize != 0 && arc.IsMultiSignature())↩
return SetPropStrFromBin((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;↩
}↩