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