• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
10 Z7_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 /*
21 How the function in 7-Zip returns object for output parameter via pointer
22 
23 1) 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 
29 2) 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 
34 3) The callee writes new value to variable for output parameter and
35   returns execution to caller.
36 
37 4) 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 
44 namespace NFileTimeType
45 {
46   enum EEnum
47   {
48     kNotDefined = -1,
49     kWindows = 0,
50     kUnix,
51     kDOS,
52     k1ns
53   };
54 }
55 
56 namespace 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 
82 namespace 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 
97 namespace 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 
181 Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenCallback, 0x10)
182 
183 /*
184 IArchiveExtractCallback::
185 
186 7-Zip doesn't call IArchiveExtractCallback functions
187   GetStream()
188   PrepareOperation()
189   SetOperationResult()
190 from different threads simultaneously.
191 But 7-Zip can call functions for IProgress or ICompressProgressInfo functions
192 from another threads simultaneously with calls for IArchiveExtractCallback interface.
193 
194 IArchiveExtractCallback::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 
214 if (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 }
220 else
221 {
222   IProgress::SetCompleted(completeValue) uses packSize.
223 }
224 
225 SetOperationResult()
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 
239 Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallback, IProgress, 0x20)
240 
241 
242 
243 /*
244 v23:
245 IArchiveExtractCallbackMessage2 can be requested from IArchiveExtractCallback object
246   by Extract() or UpdateItems() functions to report about extracting errors
247 ReportExtractResult()
248   UInt32 indexType (NEventIndexType)
249   UInt32 index
250   Int32 opRes (NExtract::NOperationResult)
251 */
252 /*
253 before v23:
254 #define Z7_IFACEM_IArchiveExtractCallbackMessage(x) \
255   x(ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes))
256 Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallbackMessage, IProgress, 0x21)
257 */
258 #define Z7_IFACEM_IArchiveExtractCallbackMessage2(x) \
259   x(ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes))
260 Z7_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))
265 Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenVolumeCallback, 0x30)
266 
267 
268 #define Z7_IFACEM_IInArchiveGetStream(x) \
269   x(GetStream(UInt32 index, ISequentialInStream **stream))
270 Z7_IFACE_CONSTR_ARCHIVE(IInArchiveGetStream, 0x40)
271 
272 #define Z7_IFACEM_IArchiveOpenSetSubArchiveName(x) \
273   x(SetSubArchiveName(const wchar_t *name))
274 Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenSetSubArchiveName, 0x50)
275 
276 
277 /*
278 IInArchive::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 
285 IInArchive::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 
290 IInArchive::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 
305 Notes:
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 
328 Z7_IFACE_CONSTR_ARCHIVE(IInArchive, 0x60)
329 
330 namespace NParentType
331 {
332   enum
333   {
334     kDir = 0,
335     kAltStream
336   };
337 }
338 
339 namespace 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 /*
360 GetRawProp:
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 
371 Z7_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 
377 Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetRootProps, 0x71)
378 
379 #define Z7_IFACEM_IArchiveOpenSeq(x) \
380   x(OpenSeq(ISequentialInStream *stream)) \
381 
382 Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenSeq, 0x61)
383 
384 /*
385   OpenForSize
386   Result:
387     S_FALSE - is not archive
388     ? - DATA error
389 */
390 
391 /*
392 const UInt32 kOpenFlags_RealPhySize = 1 << 0;
393 const UInt32 kOpenFlags_NoSeek = 1 << 1;
394 // const UInt32 kOpenFlags_BeforeExtract = 1 << 2;
395 */
396 
397 /*
398 Flags:
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))
411 Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpen2, 0x62)
412 */
413 
414 // ---------- UPDATE ----------
415 
416 /*
417 GetUpdateItemInfo 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 
427 GetStream 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 
436 The order of calling for hard links:
437   - GetStream()
438   - GetProperty(kpidHardLink)
439 
440 SetOperationResult()
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 
451 Z7_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 
458 Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
459 
460 namespace 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 /*
480 IArchiveUpdateCallbackFile::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 
490 Z7_IFACE_CONSTR_ARCHIVE(IArchiveUpdateCallbackFile, 0x83)
491 
492 
493 #define Z7_IFACEM_IArchiveGetDiskProperty(x) \
494   x(GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \
495 
496 Z7_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 
505 Z7_IFACE_CONSTR_ARCHIVE(IArchiveUpdateCallbackArcProp, 0x85)
506 */
507 
508 /*
509 UpdateItems()
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 
534 Z7_IFACE_CONSTR_ARCHIVE(IOutArchive, 0xA0)
535 
536 
537 /*
538 ISetProperties::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 
550 Z7_IFACE_CONSTR_ARCHIVE(ISetProperties, 0x03)
551 
552 #define Z7_IFACEM_IArchiveKeepModeForNextOpen(x) \
553   x(KeepModeForNextOpen()) \
554 
555 Z7_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 
565 Z7_IFACE_CONSTR_ARCHIVE(IArchiveAllowTail, 0x05)
566 
567 
568 
569 struct CStatProp
570 {
571   const char *Name;
572   UInt32 PropID;
573   VARTYPE vt;
574 };
575 
576 namespace NWindows {
577 namespace NCOM {
578 // PropVariant.cpp
579 BSTR 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 
654 extern "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 /*
689 extern 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 
703 Z7_PURE_INTERFACES_END
704 #endif
705