tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

IArchive.h (19010B)


      1 // IArchive.h
      2 
      3 #ifndef __IARCHIVE_H
      4 #define __IARCHIVE_H
      5 
      6 #include "../IProgress.h"
      7 #include "../IStream.h"
      8 #include "../PropID.h"
      9 
     10 #define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x)
     11 #define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x)
     12 
     13 namespace NFileTimeType
     14 {
     15  enum EEnum
     16  {
     17    kWindows,
     18    kUnix,
     19    kDOS
     20  };
     21 }
     22 
     23 namespace NArcInfoFlags
     24 {
     25  const UInt32 kKeepName        = 1 << 0;  // keep name of file in archive name
     26  const UInt32 kAltStreams      = 1 << 1;  // the handler supports alt streams
     27  const UInt32 kNtSecure        = 1 << 2;  // the handler supports NT security
     28  const UInt32 kFindSignature   = 1 << 3;  // the handler can find start of archive
     29  const UInt32 kMultiSignature  = 1 << 4;  // there are several signatures
     30  const UInt32 kUseGlobalOffset = 1 << 5;  // the seek position of stream must be set as global offset
     31  const UInt32 kStartOpen       = 1 << 6;  // call handler for each start position
     32  const UInt32 kPureStartOpen   = 1 << 7;  // call handler only for start of file
     33  const UInt32 kBackwardOpen    = 1 << 8;  // archive can be open backward
     34  const UInt32 kPreArc          = 1 << 9;  // such archive can be stored before real archive (like SFX stub)
     35  const UInt32 kSymLinks        = 1 << 10; // the handler supports symbolic links
     36  const UInt32 kHardLinks       = 1 << 11; // the handler supports hard links
     37 }
     38 
     39 namespace NArchive
     40 {
     41  namespace NHandlerPropID
     42  {
     43    enum
     44    {
     45      kName = 0,        // VT_BSTR
     46      kClassID,         // binary GUID in VT_BSTR
     47      kExtension,       // VT_BSTR
     48      kAddExtension,    // VT_BSTR
     49      kUpdate,          // VT_BOOL
     50      kKeepName,        // VT_BOOL
     51      kSignature,       // binary in VT_BSTR
     52      kMultiSignature,  // binary in VT_BSTR
     53      kSignatureOffset, // VT_UI4
     54      kAltStreams,      // VT_BOOL
     55      kNtSecure,        // VT_BOOL
     56      kFlags            // VT_UI4
     57      // kVersion          // VT_UI4 ((VER_MAJOR << 8) | VER_MINOR)
     58    };
     59  }
     60 
     61  namespace NExtract
     62  {
     63    namespace NAskMode
     64    {
     65      enum
     66      {
     67        kExtract = 0,
     68        kTest,
     69        kSkip
     70      };
     71    }
     72  
     73    namespace NOperationResult
     74    {
     75      enum
     76      {
     77        kOK = 0,
     78        kUnsupportedMethod,
     79        kDataError,
     80        kCRCError,
     81        kUnavailable,
     82        kUnexpectedEnd,
     83        kDataAfterEnd,
     84        kIsNotArc,
     85        kHeadersError,
     86        kWrongPassword
     87      };
     88    }
     89  }
     90 
     91  namespace NEventIndexType
     92  {
     93    enum
     94    {
     95      kNoIndex = 0,
     96      kInArcIndex,
     97      kBlockIndex,
     98      kOutArcIndex
     99    };
    100  }
    101  
    102  namespace NUpdate
    103  {
    104    namespace NOperationResult
    105    {
    106      enum
    107      {
    108        kOK = 0
    109        , // kError
    110      };
    111    }
    112  }
    113 }
    114 
    115 #define INTERFACE_IArchiveOpenCallback(x) \
    116  STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \
    117  STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \
    118 
    119 ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)
    120 {
    121  INTERFACE_IArchiveOpenCallback(PURE);
    122 };
    123 
    124 /*
    125 IArchiveExtractCallback::
    126 
    127 7-Zip doesn't call IArchiveExtractCallback functions
    128  GetStream()
    129  PrepareOperation()
    130  SetOperationResult()
    131 from different threads simultaneously.
    132 But 7-Zip can call functions for IProgress or ICompressProgressInfo functions
    133 from another threads simultaneously with calls for IArchiveExtractCallback interface.
    134 
    135 IArchiveExtractCallback::GetStream()
    136  UInt32 index - index of item in Archive
    137  Int32 askExtractMode  (Extract::NAskMode)
    138    if (askMode != NExtract::NAskMode::kExtract)
    139    {
    140      then the callee can not real stream: (*inStream == NULL)
    141    }
    142  
    143  Out:
    144      (*inStream == NULL) - for directories
    145      (*inStream == NULL) - if link (hard link or symbolic link) was created
    146      if (*inStream == NULL && askMode == NExtract::NAskMode::kExtract)
    147      {
    148        then the caller must skip extracting of that file.
    149      }
    150 
    151  returns:
    152    S_OK     : OK
    153    S_FALSE  : data error (for decoders)
    154 
    155 if (IProgress::SetTotal() was called)
    156 {
    157  IProgress::SetCompleted(completeValue) uses
    158    packSize   - for some stream formats (xz, gz, bz2, lzma, z, ppmd).
    159    unpackSize - for another formats.
    160 }
    161 else
    162 {
    163  IProgress::SetCompleted(completeValue) uses packSize.
    164 }
    165 
    166 SetOperationResult()
    167  7-Zip calls SetOperationResult at the end of extracting,
    168  so the callee can close the file, set attributes, timestamps and security information.
    169 
    170  Int32 opRes (NExtract::NOperationResult)
    171 */
    172 
    173 #define INTERFACE_IArchiveExtractCallback(x) \
    174  INTERFACE_IProgress(x) \
    175  STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \
    176  STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \
    177  STDMETHOD(SetOperationResult)(Int32 opRes) x; \
    178 
    179 ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20)
    180 {
    181  INTERFACE_IArchiveExtractCallback(PURE)
    182 };
    183 
    184 
    185 
    186 /*
    187 IArchiveExtractCallbackMessage can be requested from IArchiveExtractCallback object
    188  by Extract() or UpdateItems() functions to report about extracting errors
    189 ReportExtractResult()
    190  UInt32 indexType (NEventIndexType)
    191  UInt32 index
    192  Int32 opRes (NExtract::NOperationResult)
    193 */
    194 
    195 #define INTERFACE_IArchiveExtractCallbackMessage(x) \
    196  STDMETHOD(ReportExtractResult)(UInt32 indexType, UInt32 index, Int32 opRes) x; \
    197 
    198 ARCHIVE_INTERFACE_SUB(IArchiveExtractCallbackMessage, IProgress, 0x21)
    199 {
    200  INTERFACE_IArchiveExtractCallbackMessage(PURE)
    201 };
    202 
    203 
    204 #define INTERFACE_IArchiveOpenVolumeCallback(x) \
    205  STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \
    206  STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \
    207 
    208 ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30)
    209 {
    210  INTERFACE_IArchiveOpenVolumeCallback(PURE);
    211 };
    212 
    213 
    214 ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40)
    215 {
    216  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE;
    217 };
    218 
    219 
    220 ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50)
    221 {
    222  STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE;
    223 };
    224 
    225 
    226 /*
    227 IInArchive::Open
    228    stream
    229      if (kUseGlobalOffset), stream current position can be non 0.
    230      if (!kUseGlobalOffset), stream current position is 0.
    231    if (maxCheckStartPosition == NULL), the handler can try to search archive start in stream
    232    if (*maxCheckStartPosition == 0), the handler must check only current position as archive start
    233 
    234 IInArchive::Extract:
    235  indices must be sorted
    236  numItems = (UInt32)(Int32)-1 = 0xFFFFFFFF means "all files"
    237  testMode != 0 means "test files without writing to outStream"
    238 
    239 IInArchive::GetArchiveProperty:
    240  kpidOffset  - start offset of archive.
    241      VT_EMPTY : means offset = 0.
    242      VT_UI4, VT_UI8, VT_I8 : result offset; negative values is allowed
    243  kpidPhySize - size of archive. VT_EMPTY means unknown size.
    244    kpidPhySize is allowed to be larger than file size. In that case it must show
    245    supposed size.
    246 
    247  kpidIsDeleted:
    248  kpidIsAltStream:
    249  kpidIsAux:
    250  kpidINode:
    251    must return VARIANT_TRUE (VT_BOOL), if archive can support that property in GetProperty.
    252 
    253 
    254 Notes:
    255  Don't call IInArchive functions for same IInArchive object from different threads simultaneously.
    256  Some IInArchive handlers will work incorrectly in that case.
    257 */
    258 
    259 #ifdef _MSC_VER
    260  #define MY_NO_THROW_DECL_ONLY throw()
    261 #else
    262  #define MY_NO_THROW_DECL_ONLY
    263 #endif
    264 
    265 #define INTERFACE_IInArchive(x) \
    266  STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; \
    267  STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \
    268  STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; \
    269  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
    270  STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; \
    271  STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \
    272  STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
    273  STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
    274  STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \
    275  STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \
    276 
    277 ARCHIVE_INTERFACE(IInArchive, 0x60)
    278 {
    279  INTERFACE_IInArchive(PURE)
    280 };
    281 
    282 namespace NParentType
    283 {
    284  enum
    285  {
    286    kDir = 0,
    287    kAltStream
    288  };
    289 };
    290 
    291 namespace NPropDataType
    292 {
    293  const UInt32 kMask_ZeroEnd   = 1 << 4;
    294  // const UInt32 kMask_BigEndian = 1 << 5;
    295  const UInt32 kMask_Utf       = 1 << 6;
    296  const UInt32 kMask_Utf8  = kMask_Utf | 0;
    297  const UInt32 kMask_Utf16 = kMask_Utf | 1;
    298  // const UInt32 kMask_Utf32 = kMask_Utf | 2;
    299 
    300  const UInt32 kNotDefined = 0;
    301  const UInt32 kRaw = 1;
    302 
    303  const UInt32 kUtf8z  = kMask_Utf8  | kMask_ZeroEnd;
    304  const UInt32 kUtf16z = kMask_Utf16 | kMask_ZeroEnd;
    305 };
    306 
    307 // UTF string (pointer to wchar_t) with zero end and little-endian.
    308 #define PROP_DATA_TYPE_wchar_t_PTR_Z_LE ((NPropDataType::kMask_Utf | NPropDataType::kMask_ZeroEnd) + (sizeof(wchar_t) >> 1))
    309 
    310 /*
    311 GetRawProp:
    312  Result:
    313    S_OK - even if property is not set
    314 */
    315 
    316 #define INTERFACE_IArchiveGetRawProps(x) \
    317  STDMETHOD(GetParent)(UInt32 index, UInt32 *parent, UInt32 *parentType) x; \
    318  STDMETHOD(GetRawProp)(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \
    319  STDMETHOD(GetNumRawProps)(UInt32 *numProps) x; \
    320  STDMETHOD(GetRawPropInfo)(UInt32 index, BSTR *name, PROPID *propID) x;
    321 
    322 ARCHIVE_INTERFACE(IArchiveGetRawProps, 0x70)
    323 {
    324  INTERFACE_IArchiveGetRawProps(PURE)
    325 };
    326 
    327 #define INTERFACE_IArchiveGetRootProps(x) \
    328  STDMETHOD(GetRootProp)(PROPID propID, PROPVARIANT *value) x; \
    329  STDMETHOD(GetRootRawProp)(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \
    330 
    331 ARCHIVE_INTERFACE(IArchiveGetRootProps, 0x71)
    332 {
    333  INTERFACE_IArchiveGetRootProps(PURE)
    334 };
    335 
    336 ARCHIVE_INTERFACE(IArchiveOpenSeq, 0x61)
    337 {
    338  STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE;
    339 };
    340 
    341 /*
    342  OpenForSize
    343  Result:
    344    S_FALSE - is not archive
    345    ? - DATA error
    346 */
    347    
    348 /*
    349 const UInt32 kOpenFlags_RealPhySize = 1 << 0;
    350 const UInt32 kOpenFlags_NoSeek = 1 << 1;
    351 // const UInt32 kOpenFlags_BeforeExtract = 1 << 2;
    352 */
    353 
    354 /*
    355 Flags:
    356   0 - opens archive with IInStream, if IInStream interface is supported
    357     - if phySize is not available, it doesn't try to make full parse to get phySize
    358   kOpenFlags_NoSeek -  ArcOpen2 function doesn't use IInStream interface, even if it's available
    359   kOpenFlags_RealPhySize - the handler will try to get PhySize, even if it requires full decompression for file
    360   
    361  if handler is not allowed to use IInStream and the flag kOpenFlags_RealPhySize is not specified,
    362  the handler can return S_OK, but it doesn't check even Signature.
    363  So next Extract can be called for that sequential stream.
    364 */
    365 
    366 /*
    367 ARCHIVE_INTERFACE(IArchiveOpen2, 0x62)
    368 {
    369  STDMETHOD(ArcOpen2)(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback) PURE;
    370 };
    371 */
    372 
    373 // ---------- UPDATE ----------
    374 
    375 /*
    376 GetUpdateItemInfo outs:
    377 *newData  *newProps
    378   0        0      - Copy data and properties from archive
    379   0        1      - Copy data from archive, request new properties
    380   1        0      - that combination is unused now
    381   1        1      - Request new data and new properties. It can be used even for folders
    382 
    383  indexInArchive = -1 if there is no item in archive, or if it doesn't matter.
    384 
    385 
    386 GetStream out:
    387  Result:
    388    S_OK:
    389      (*inStream == NULL) - only for directories
    390                          - the bug was fixed in 9.33: (*Stream == NULL) was in case of anti-file
    391      (*inStream != NULL) - for any file, even for empty file or anti-file
    392    S_FALSE - skip that file (don't add item to archive) - (client code can't open stream of that file by some reason)
    393      (*inStream == NULL)
    394 
    395 The order of calling for hard links:
    396  - GetStream()
    397  - GetProperty(kpidHardLink)
    398 
    399 SetOperationResult()
    400  Int32 opRes (NExtract::NOperationResult::kOK)
    401 */
    402 
    403 #define INTERFACE_IArchiveUpdateCallback(x) \
    404  INTERFACE_IProgress(x); \
    405  STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive) x; \
    406  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
    407  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \
    408  STDMETHOD(SetOperationResult)(Int32 operationResult) x; \
    409 
    410 ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80)
    411 {
    412  INTERFACE_IArchiveUpdateCallback(PURE);
    413 };
    414 
    415 #define INTERFACE_IArchiveUpdateCallback2(x) \
    416  INTERFACE_IArchiveUpdateCallback(x) \
    417  STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \
    418  STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \
    419 
    420 ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
    421 {
    422  INTERFACE_IArchiveUpdateCallback2(PURE);
    423 };
    424 
    425 namespace NUpdateNotifyOp
    426 {
    427  enum
    428  {
    429    kAdd = 0,
    430    kUpdate,
    431    kAnalyze,
    432    kReplicate,
    433    kRepack,
    434    kSkip,
    435    kDelete,
    436    kHeader
    437 
    438    // kNumDefined
    439  };
    440 };
    441 
    442 /*
    443 IArchiveUpdateCallbackFile::ReportOperation
    444  UInt32 indexType (NEventIndexType)
    445  UInt32 index
    446  UInt32 notifyOp (NUpdateNotifyOp)
    447 */
    448 
    449 #define INTERFACE_IArchiveUpdateCallbackFile(x) \
    450  STDMETHOD(GetStream2)(UInt32 index, ISequentialInStream **inStream, UInt32 notifyOp) x; \
    451  STDMETHOD(ReportOperation)(UInt32 indexType, UInt32 index, UInt32 notifyOp) x; \
    452 
    453 ARCHIVE_INTERFACE(IArchiveUpdateCallbackFile, 0x83)
    454 {
    455  INTERFACE_IArchiveUpdateCallbackFile(PURE);
    456 };
    457 
    458 
    459 /*
    460 UpdateItems()
    461 -------------
    462 
    463  outStream: output stream. (the handler) MUST support the case when
    464    Seek position in outStream is not ZERO.
    465    but the caller calls with empty outStream and seek position is ZERO??
    466 
    467  archives with stub:
    468 
    469  If archive is open and the handler and (Offset > 0), then the handler
    470  knows about stub size.
    471  UpdateItems():
    472  1) the handler MUST copy that stub to outStream
    473  2) the caller MUST NOT copy the stub to outStream, if
    474     "rsfx" property is set with SetProperties
    475 
    476  the handler must support the case where
    477    ISequentialOutStream *outStream
    478 */
    479 
    480 
    481 #define INTERFACE_IOutArchive(x) \
    482  STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \
    483  STDMETHOD(GetFileTimeType)(UInt32 *type) x;
    484 
    485 ARCHIVE_INTERFACE(IOutArchive, 0xA0)
    486 {
    487  INTERFACE_IOutArchive(PURE)
    488 };
    489 
    490 
    491 /*
    492 ISetProperties::SetProperties()
    493  PROPVARIANT values[i].vt:
    494    VT_EMPTY
    495    VT_BOOL
    496    VT_UI4   - if 32-bit number
    497    VT_UI8   - if 64-bit number
    498    VT_BSTR
    499 */
    500 
    501 ARCHIVE_INTERFACE(ISetProperties, 0x03)
    502 {
    503  STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) PURE;
    504 };
    505 
    506 ARCHIVE_INTERFACE(IArchiveKeepModeForNextOpen, 0x04)
    507 {
    508  STDMETHOD(KeepModeForNextOpen)() PURE;
    509 };
    510 
    511 /* Exe handler: the handler for executable format (PE, ELF, Mach-O).
    512   SFX archive: executable stub + some tail data.
    513     before 9.31: exe handler didn't parse SFX archives as executable format.
    514     for 9.31+: exe handler parses SFX archives as executable format, only if AllowTail(1) was called */
    515 
    516 ARCHIVE_INTERFACE(IArchiveAllowTail, 0x05)
    517 {
    518  STDMETHOD(AllowTail)(Int32 allowTail) PURE;
    519 };
    520 
    521 
    522 #define IMP_IInArchive_GetProp(k) \
    523  (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
    524    { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \
    525    *propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID];  *name = 0; return S_OK; } \
    526 
    527 
    528 struct CStatProp
    529 {
    530  const char *Name;
    531  UInt32 PropID;
    532  VARTYPE vt;
    533 };
    534 
    535 namespace NWindows {
    536 namespace NCOM {
    537 // PropVariant.cpp
    538 BSTR AllocBstrFromAscii(const char *s) throw();
    539 }}
    540 
    541 #define IMP_IInArchive_GetProp_WITH_NAME(k) \
    542  (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
    543    { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \
    544    const CStatProp &prop = k[index]; \
    545    *propID = (PROPID)prop.PropID; *varType = prop.vt; \
    546    *name = NWindows::NCOM::AllocBstrFromAscii(prop.Name); return S_OK; } \
    547 
    548 #define IMP_IInArchive_Props \
    549  STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \
    550    { *numProps = ARRAY_SIZE(kProps); return S_OK; } \
    551  STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps)
    552 
    553 #define IMP_IInArchive_Props_WITH_NAME \
    554  STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \
    555    { *numProps = ARRAY_SIZE(kProps); return S_OK; } \
    556  STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps)
    557 
    558 
    559 #define IMP_IInArchive_ArcProps \
    560  STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
    561    { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \
    562  STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps)
    563 
    564 #define IMP_IInArchive_ArcProps_WITH_NAME \
    565  STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
    566    { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \
    567  STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps)
    568 
    569 #define IMP_IInArchive_ArcProps_NO_Table \
    570  STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \
    571    { *numProps = 0; return S_OK; } \
    572  STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \
    573    { return E_NOTIMPL; } \
    574 
    575 #define IMP_IInArchive_ArcProps_NO \
    576  IMP_IInArchive_ArcProps_NO_Table \
    577  STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \
    578    { value->vt = VT_EMPTY; return S_OK; }
    579 
    580 
    581 
    582 #define k_IsArc_Res_NO   0
    583 #define k_IsArc_Res_YES  1
    584 #define k_IsArc_Res_NEED_MORE 2
    585 // #define k_IsArc_Res_YES_LOW_PROB 3
    586 
    587 #define API_FUNC_IsArc EXTERN_C UInt32 WINAPI
    588 #define API_FUNC_static_IsArc extern "C" { static UInt32 WINAPI
    589 
    590 extern "C"
    591 {
    592  typedef HRESULT (WINAPI *Func_CreateObject)(const GUID *clsID, const GUID *iid, void **outObject);
    593 
    594  typedef UInt32 (WINAPI *Func_IsArc)(const Byte *p, size_t size);
    595  typedef HRESULT (WINAPI *Func_GetIsArc)(UInt32 formatIndex, Func_IsArc *isArc);
    596 
    597  typedef HRESULT (WINAPI *Func_GetNumberOfFormats)(UInt32 *numFormats);
    598  typedef HRESULT (WINAPI *Func_GetHandlerProperty)(PROPID propID, PROPVARIANT *value);
    599  typedef HRESULT (WINAPI *Func_GetHandlerProperty2)(UInt32 index, PROPID propID, PROPVARIANT *value);
    600 
    601  typedef HRESULT (WINAPI *Func_SetCaseSensitive)(Int32 caseSensitive);
    602  typedef HRESULT (WINAPI *Func_SetLargePageMode)();
    603 
    604  typedef IOutArchive * (*Func_CreateOutArchive)();
    605  typedef IInArchive * (*Func_CreateInArchive)();
    606 }
    607 
    608 #endif