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];
RegisterArc(const CArcInfo * arcInfo)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
SetPropString(const char * s,unsigned int size,PROPVARIANT * value)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
SetPropGUID(const GUID & guid,PROPVARIANT * value)38 static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
39 {
40 return SetPropString((const char *)&guid, sizeof(GUID), value);
41 }
42
FindFormatCalssId(const GUID * clsID)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
CreateArchiver(const GUID * clsid,const GUID * iid,void ** outObject)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
GetHandlerProperty2(UInt32 formatIndex,PROPID propID,PROPVARIANT * value)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
GetHandlerProperty(PROPID propID,PROPVARIANT * value)126 STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
127 {
128 return GetHandlerProperty2(g_DefaultArcIndex, propID, value);
129 }
130
GetNumberOfFormats(UINT32 * numFormats)131 STDAPI GetNumberOfFormats(UINT32 *numFormats)
132 {
133 *numFormats = g_NumArcs;
134 return S_OK;
135 }
136