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