xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/IArchive.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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 namespace NRequestMemoryUseFlags
569 {
570   const UInt32 k_AllowedSize_WasForced    = 1 << 0;  // (*allowedSize) was forced by -mmemx or -smemx
571   const UInt32 k_DefaultLimit_Exceeded    = 1 << 1;  // default limit of archive format was exceeded
572   const UInt32 k_MLimit_Exceeded          = 1 << 2;  // -mmemx value was exceeded
573   const UInt32 k_SLimit_Exceeded          = 1 << 3;  // -smemx value was exceeded
574 
575   const UInt32 k_NoErrorMessage           = 1 << 10; // do not show error message, and show only request
576   const UInt32 k_IsReport                 = 1 << 11; // only report is required, without user request
577 
578   const UInt32 k_SkipArc_IsExpected       = 1 << 12; // NRequestMemoryAnswerFlags::k_SkipArc flag answer is expected
579   const UInt32 k_Report_SkipArc           = 1 << 13; // report about SkipArc operation
580 
581   // const UInt32 k_SkipBigFile_IsExpected   = 1 << 14; // NRequestMemoryAnswerFlags::k_SkipBigFiles flag answer is expected (unused)
582   // const UInt32 k_Report_SkipBigFile       = 1 << 15; // report about SkipFile operation (unused)
583 
584   // const UInt32 k_SkipBigFiles_IsExpected  = 1 << 16; // NRequestMemoryAnswerFlags::k_SkipBigFiles flag answer is expected (unused)
585   // const UInt32 k_Report_SkipBigFiles      = 1 << 17; // report that all big files will be skipped (unused)
586 }
587 
588 namespace NRequestMemoryAnswerFlags
589 {
590   const UInt32 k_Allow          = 1 << 0;  // allow further archive extraction
591   const UInt32 k_Stop           = 1 << 1;  // for exit (and return_code == E_ABORT is used)
592   const UInt32 k_SkipArc        = 1 << 2;  // skip current archive extraction
593   // const UInt32 k_SkipBigFile    = 1 << 4;  // skip extracting of files that exceed limit (unused)
594   // const UInt32 k_SkipBigFiles   = 1 << 5;  // skip extracting of files that exceed limit (unused)
595   const UInt32 k_Limit_Exceeded  = 1 << 10;  // limit was exceeded
596 }
597 
598 /*
599   *allowedSize is in/out:
600     in  : default allowed memory usage size or forced size, if it was changed by switch -mmemx.
601     out : value specified by user or unchanged value.
602 
603   *answerFlags is in/out:
604     *answerFlags must be set by caller before calling for default action,
605 
606   indexType : must be set with NEventIndexType::* constant
607           (indexType == kNoIndex), if request for whole archive.
608   index : must be set for some (indexType) types (if
609           fileIndex , if (indexType == NEventIndexType::kInArcIndex)
610           0, if       if (indexType == kNoIndex)
611   path : NULL can be used for any indexType.
612 */
613 #define Z7_IFACEM_IArchiveRequestMemoryUseCallback(x) \
614   x(RequestMemoryUse(UInt32 flags, UInt32 indexType, UInt32 index, const wchar_t *path, \
615     UInt64 requiredSize, UInt64 *allowedSize, UInt32 *answerFlags))
616 Z7_IFACE_CONSTR_ARCHIVE(IArchiveRequestMemoryUseCallback, 0x09)
617 
618 
619 struct CStatProp
620 {
621   const char *Name;
622   UInt32 PropID;
623   VARTYPE vt;
624 };
625 
626 namespace NWindows {
627 namespace NCOM {
628 // PropVariant.cpp
629 BSTR AllocBstrFromAscii(const char *s) throw();
630 }}
631 
632 
633 #define IMP_IInArchive_GetProp_Base(fn, f, k) \
634   Z7_COM7F_IMF(CHandler::fn(UInt32 *numProps)) \
635     { *numProps = Z7_ARRAY_SIZE(k); return S_OK; } \
636   Z7_COM7F_IMF(CHandler::f(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \
637     { if (index >= Z7_ARRAY_SIZE(k)) return E_INVALIDARG; \
638 
639 #define IMP_IInArchive_GetProp_NO_NAME(fn, f, k) \
640   IMP_IInArchive_GetProp_Base(fn, f, k) \
641     *propID = k[index]; \
642     *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; \
643     *name = NULL; return S_OK; } \
644 
645 #define IMP_IInArchive_GetProp_WITH_NAME(fn, f, k) \
646   IMP_IInArchive_GetProp_Base(fn, f, k) \
647     const CStatProp &prop = k[index]; \
648     *propID = (PROPID)prop.PropID; \
649     *varType = prop.vt; \
650     *name = NWindows::NCOM::AllocBstrFromAscii(prop.Name); return S_OK; } \
651 
652 
653 #define IMP_IInArchive_Props \
654   IMP_IInArchive_GetProp_NO_NAME(GetNumberOfProperties, GetPropertyInfo, kProps)
655 
656 #define IMP_IInArchive_Props_WITH_NAME \
657   IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfProperties, GetPropertyInfo, kProps)
658 
659 #define IMP_IInArchive_ArcProps \
660   IMP_IInArchive_GetProp_NO_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps)
661 
662 #define IMP_IInArchive_ArcProps_WITH_NAME \
663   IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps)
664 
665 #define IMP_IInArchive_ArcProps_NO_Table \
666   Z7_COM7F_IMF(CHandler::GetNumberOfArchiveProperties(UInt32 *numProps)) \
667     { *numProps = 0; return S_OK; } \
668   Z7_COM7F_IMF(CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *)) \
669     { return E_NOTIMPL; } \
670 
671 #define IMP_IInArchive_ArcProps_NO \
672   IMP_IInArchive_ArcProps_NO_Table \
673   Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value)) \
674     { value->vt = VT_EMPTY; return S_OK; }
675 
676 
677 #define Z7_class_CHandler_final \
678         Z7_class_final(CHandler)
679 
680 
681 #define Z7_CLASS_IMP_CHandler_IInArchive_0 \
682   Z7_CLASS_IMP_COM_1(CHandler, IInArchive)
683 #define Z7_CLASS_IMP_CHandler_IInArchive_1(i1) \
684   Z7_CLASS_IMP_COM_2(CHandler, IInArchive, i1)
685 #define Z7_CLASS_IMP_CHandler_IInArchive_2(i1, i2) \
686   Z7_CLASS_IMP_COM_3(CHandler, IInArchive, i1, i2)
687 #define Z7_CLASS_IMP_CHandler_IInArchive_3(i1, i2, i3) \
688   Z7_CLASS_IMP_COM_4(CHandler, IInArchive, i1, i2, i3)
689 #define Z7_CLASS_IMP_CHandler_IInArchive_4(i1, i2, i3, i4) \
690   Z7_CLASS_IMP_COM_5(CHandler, IInArchive, i1, i2, i3, i4)
691 #define Z7_CLASS_IMP_CHandler_IInArchive_5(i1, i2, i3, i4, i5) \
692   Z7_CLASS_IMP_COM_6(CHandler, IInArchive, i1, i2, i3, i4, i5)
693 
694 
695 
696 #define k_IsArc_Res_NO   0
697 #define k_IsArc_Res_YES  1
698 #define k_IsArc_Res_NEED_MORE 2
699 // #define k_IsArc_Res_YES_LOW_PROB 3
700 
701 #define API_FUNC_IsArc EXTERN_C UInt32 WINAPI
702 #define API_FUNC_static_IsArc extern "C" { static UInt32 WINAPI
703 
704 extern "C"
705 {
706   typedef HRESULT (WINAPI *Func_CreateObject)(const GUID *clsID, const GUID *iid, void **outObject);
707 
708   typedef UInt32 (WINAPI *Func_IsArc)(const Byte *p, size_t size);
709   typedef HRESULT (WINAPI *Func_GetIsArc)(UInt32 formatIndex, Func_IsArc *isArc);
710 
711   typedef HRESULT (WINAPI *Func_GetNumberOfFormats)(UInt32 *numFormats);
712   typedef HRESULT (WINAPI *Func_GetHandlerProperty)(PROPID propID, PROPVARIANT *value);
713   typedef HRESULT (WINAPI *Func_GetHandlerProperty2)(UInt32 index, PROPID propID, PROPVARIANT *value);
714 
715   typedef HRESULT (WINAPI *Func_SetCaseSensitive)(Int32 caseSensitive);
716   typedef HRESULT (WINAPI *Func_SetLargePageMode)();
717   // typedef HRESULT (WINAPI *Func_SetClientVersion)(UInt32 version);
718 
719   typedef IOutArchive * (*Func_CreateOutArchive)();
720   typedef IInArchive * (*Func_CreateInArchive)();
721 }
722 
723 
724 /*
725   if there is no time in archive, external MTime of archive
726   will be used instead of _item.Time from archive.
727   For 7-zip before 22.00 we need to return some supported value.
728   But (kpidTimeType > kDOS) is not allowed in 7-Zip before 22.00.
729   So we return highest precision value supported by old 7-Zip.
730   new 7-Zip 22.00 doesn't use that value in usual cases.
731 */
732 
733 
734 #define DECLARE_AND_SET_CLIENT_VERSION_VAR
735 #define GET_FileTimeType_NotDefined_for_GetFileTimeType \
736       NFileTimeType::kWindows
737 
738 /*
739 extern UInt32 g_ClientVersion;
740 
741 #define GET_CLIENT_VERSION(major, minor)  \
742   ((UInt32)(((UInt32)(major) << 16) | (UInt32)(minor)))
743 
744 #define DECLARE_AND_SET_CLIENT_VERSION_VAR \
745   UInt32 g_ClientVersion = GET_CLIENT_VERSION(MY_VER_MAJOR, MY_VER_MINOR);
746 
747 #define GET_FileTimeType_NotDefined_for_GetFileTimeType \
748       ((UInt32)(g_ClientVersion >= GET_CLIENT_VERSION(22, 0) ? \
749         (UInt32)(Int32)NFileTimeType::kNotDefined : \
750         NFileTimeType::kWindows))
751 */
752 
753 Z7_PURE_INTERFACES_END
754 #endif
755