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