Home | History | Annotate | Download | only in Archive
      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