misc/libphysfs/lzma/CPP/7zip/Archive/ArchiveExports.cpp
changeset 13904 99b265e0d1d0
parent 13903 5f819b90d479
child 13905 b172a5d40eee
equal deleted inserted replaced
13903:5f819b90d479 13904:99b265e0d1d0
     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 }