1// ArchiveExports.cpp 2 3#include "StdAfx.h" 4 5#include "../../../C/7zVersion.h" 6 7#include "../../Common/ComTry.h" 8 9#include "../../Windows/PropVariant.h" 10 11#include "../Common/RegisterArc.h" 12 13static const unsigned kNumArcsMax = 72; 14static unsigned g_NumArcs = 0; 15static unsigned g_DefaultArcIndex = 0; 16static const CArcInfo *g_Arcs[kNumArcsMax]; 17 18void RegisterArc(const CArcInfo *arcInfo) throw() 19{ 20 if (g_NumArcs < kNumArcsMax) 21 { 22 const char *p = arcInfo->Name; 23 if (p[0] == '7' && p[1] == 'z' && p[2] == 0) 24 g_DefaultArcIndex = g_NumArcs; 25 g_Arcs[g_NumArcs++] = arcInfo; 26 } 27 // else throw 1; 28} 29 30Z7_DEFINE_GUID(CLSID_CArchiveHandler, 31 k_7zip_GUID_Data1, 32 k_7zip_GUID_Data2, 33 k_7zip_GUID_Data3_Common, 34 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); 35 36#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5]) 37 38static inline HRESULT SetPropStrFromBin(const char *s, unsigned size, PROPVARIANT *value) 39{ 40 if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != NULL) 41 value->vt = VT_BSTR; 42 return S_OK; 43} 44 45static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) 46{ 47 return SetPropStrFromBin((const char *)&guid, sizeof(guid), value); 48} 49 50static int FindFormatCalssId(const GUID *clsid) 51{ 52 GUID cls = *clsid; 53 CLS_ARC_ID_ITEM(cls) = 0; 54 if (cls != CLSID_CArchiveHandler) 55 return -1; 56 const Byte id = CLS_ARC_ID_ITEM(*clsid); 57 for (unsigned i = 0; i < g_NumArcs; i++) 58 if (g_Arcs[i]->Id == id) 59 return (int)i; 60 return -1; 61} 62 63STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject); 64STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject) 65{ 66 COM_TRY_BEGIN 67 { 68 const int needIn = (*iid == IID_IInArchive); 69 const int needOut = (*iid == IID_IOutArchive); 70 if (!needIn && !needOut) 71 return E_NOINTERFACE; 72 const int formatIndex = FindFormatCalssId(clsid); 73 if (formatIndex < 0) 74 return CLASS_E_CLASSNOTAVAILABLE; 75 76 const CArcInfo &arc = *g_Arcs[formatIndex]; 77 if (needIn) 78 { 79 *outObject = arc.CreateInArchive(); 80 ((IInArchive *)*outObject)->AddRef(); 81 } 82 else 83 { 84 if (!arc.CreateOutArchive) 85 return CLASS_E_CLASSNOTAVAILABLE; 86 *outObject = arc.CreateOutArchive(); 87 ((IOutArchive *)*outObject)->AddRef(); 88 } 89 } 90 COM_TRY_END 91 return S_OK; 92} 93 94STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value); 95STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value) 96{ 97 COM_TRY_BEGIN 98 NWindows::NCOM::PropVariant_Clear(value); 99 if (formatIndex >= g_NumArcs) 100 return E_INVALIDARG; 101 const CArcInfo &arc = *g_Arcs[formatIndex]; 102 NWindows::NCOM::CPropVariant prop; 103 switch (propID) 104 { 105 case NArchive::NHandlerPropID::kName: prop = arc.Name; break; 106 case NArchive::NHandlerPropID::kClassID: 107 { 108 GUID clsId = CLSID_CArchiveHandler; 109 CLS_ARC_ID_ITEM(clsId) = arc.Id; 110 return SetPropGUID(clsId, value); 111 } 112 case NArchive::NHandlerPropID::kExtension: if (arc.Ext) prop = arc.Ext; break; 113 case NArchive::NHandlerPropID::kAddExtension: if (arc.AddExt) prop = arc.AddExt; break; 114 case NArchive::NHandlerPropID::kUpdate: prop = (bool)(arc.CreateOutArchive != NULL); break; 115 case NArchive::NHandlerPropID::kKeepName: prop = ((arc.Flags & NArcInfoFlags::kKeepName) != 0); break; 116 case NArchive::NHandlerPropID::kAltStreams: prop = ((arc.Flags & NArcInfoFlags::kAltStreams) != 0); break; 117 case NArchive::NHandlerPropID::kNtSecure: prop = ((arc.Flags & NArcInfoFlags::kNtSecure) != 0); break; 118 case NArchive::NHandlerPropID::kFlags: prop = (UInt32)arc.Flags; break; 119 case NArchive::NHandlerPropID::kTimeFlags: prop = (UInt32)arc.TimeFlags; break; 120 case NArchive::NHandlerPropID::kSignatureOffset: prop = (UInt32)arc.SignatureOffset; break; 121 // case NArchive::NHandlerPropID::kVersion: prop = (UInt32)MY_VER_MIX; break; 122 123 case NArchive::NHandlerPropID::kSignature: 124 if (arc.SignatureSize != 0 && !arc.IsMultiSignature()) 125 return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value); 126 break; 127 case NArchive::NHandlerPropID::kMultiSignature: 128 if (arc.SignatureSize != 0 && arc.IsMultiSignature()) 129 return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value); 130 break; 131 } 132 prop.Detach(value); 133 return S_OK; 134 COM_TRY_END 135} 136 137STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value); 138STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) 139{ 140 return GetHandlerProperty2(g_DefaultArcIndex, propID, value); 141} 142 143STDAPI GetNumberOfFormats(UINT32 *numFormats); 144STDAPI GetNumberOfFormats(UINT32 *numFormats) 145{ 146 *numFormats = g_NumArcs; 147 return S_OK; 148} 149 150STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc); 151STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc) 152{ 153 *isArc = NULL; 154 if (formatIndex >= g_NumArcs) 155 return E_INVALIDARG; 156 *isArc = g_Arcs[formatIndex]->IsArc; 157 return S_OK; 158} 159