ArchiveExports.cpp 3.1 KB

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