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