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