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 609