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