diff options
Diffstat (limited to 'CPP/7zip/Archive/ComHandler.cpp')
| -rw-r--r-- | CPP/7zip/Archive/ComHandler.cpp | 144 |
1 files changed, 80 insertions, 64 deletions
diff --git a/CPP/7zip/Archive/ComHandler.cpp b/CPP/7zip/Archive/ComHandler.cpp index a1f643b..7aabd65 100644 --- a/CPP/7zip/Archive/ComHandler.cpp +++ b/CPP/7zip/Archive/ComHandler.cpp | |||
| @@ -26,8 +26,8 @@ | |||
| 26 | namespace NArchive { | 26 | namespace NArchive { |
| 27 | namespace NCom { | 27 | namespace NCom { |
| 28 | 28 | ||
| 29 | #define SIGNATURE { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 } | 29 | static const Byte kSignature[] = |
| 30 | static const Byte kSignature[] = SIGNATURE; | 30 | { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }; |
| 31 | 31 | ||
| 32 | enum EType | 32 | enum EType |
| 33 | { | 33 | { |
| @@ -120,6 +120,7 @@ public: | |||
| 120 | Int32 MainSubfile; | 120 | Int32 MainSubfile; |
| 121 | 121 | ||
| 122 | UInt64 PhySize; | 122 | UInt64 PhySize; |
| 123 | UInt64 PhySize_Aligned; | ||
| 123 | EType Type; | 124 | EType Type; |
| 124 | 125 | ||
| 125 | bool IsNotArcType() const | 126 | bool IsNotArcType() const |
| @@ -129,10 +130,12 @@ public: | |||
| 129 | Type != k_Type_Msp; | 130 | Type != k_Type_Msp; |
| 130 | } | 131 | } |
| 131 | 132 | ||
| 132 | void UpdatePhySize(UInt64 val) | 133 | void UpdatePhySize(UInt64 val, UInt64 val_Aligned) |
| 133 | { | 134 | { |
| 134 | if (PhySize < val) | 135 | if (PhySize < val) |
| 135 | PhySize = val; | 136 | PhySize = val; |
| 137 | if (PhySize_Aligned < val_Aligned) | ||
| 138 | PhySize_Aligned = val_Aligned; | ||
| 136 | } | 139 | } |
| 137 | HRESULT ReadSector(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid); | 140 | HRESULT ReadSector(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid); |
| 138 | HRESULT ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest); | 141 | HRESULT ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest); |
| @@ -165,14 +168,15 @@ public: | |||
| 165 | 168 | ||
| 166 | HRESULT CDatabase::ReadSector(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid) | 169 | HRESULT CDatabase::ReadSector(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid) |
| 167 | { | 170 | { |
| 168 | UpdatePhySize(((UInt64)sid + 2) << sectorSizeBits); | 171 | const UInt64 end = ((UInt64)sid + 2) << sectorSizeBits; |
| 169 | RINOK(inStream->Seek((((UInt64)sid + 1) << sectorSizeBits), STREAM_SEEK_SET, NULL)); | 172 | UpdatePhySize(end, end); |
| 173 | RINOK(InStream_SeekSet(inStream, (((UInt64)sid + 1) << sectorSizeBits))) | ||
| 170 | return ReadStream_FALSE(inStream, buf, (size_t)1 << sectorSizeBits); | 174 | return ReadStream_FALSE(inStream, buf, (size_t)1 << sectorSizeBits); |
| 171 | } | 175 | } |
| 172 | 176 | ||
| 173 | HRESULT CDatabase::ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest) | 177 | HRESULT CDatabase::ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest) |
| 174 | { | 178 | { |
| 175 | RINOK(ReadSector(inStream, buf, sectorSizeBits, sid)); | 179 | RINOK(ReadSector(inStream, buf, sectorSizeBits, sid)) |
| 176 | UInt32 sectorSize = (UInt32)1 << sectorSizeBits; | 180 | UInt32 sectorSize = (UInt32)1 << sectorSizeBits; |
| 177 | for (UInt32 t = 0; t < sectorSize; t += 4) | 181 | for (UInt32 t = 0; t < sectorSize; t += 4) |
| 178 | *dest++ = Get32(buf + t); | 182 | *dest++ = Get32(buf + t); |
| @@ -205,6 +209,7 @@ void CItem::Parse(const Byte *p, bool mode64bit) | |||
| 205 | void CDatabase::Clear() | 209 | void CDatabase::Clear() |
| 206 | { | 210 | { |
| 207 | PhySize = 0; | 211 | PhySize = 0; |
| 212 | PhySize_Aligned = 0; | ||
| 208 | 213 | ||
| 209 | Fat.Free(); | 214 | Fat.Free(); |
| 210 | MiniSids.Free(); | 215 | MiniSids.Free(); |
| @@ -227,14 +232,14 @@ HRESULT CDatabase::AddNode(int parent, UInt32 did) | |||
| 227 | CRef ref; | 232 | CRef ref; |
| 228 | ref.Parent = parent; | 233 | ref.Parent = parent; |
| 229 | ref.Did = did; | 234 | ref.Did = did; |
| 230 | int index = Refs.Add(ref); | 235 | const unsigned index = Refs.Add(ref); |
| 231 | if (Refs.Size() > Items.Size()) | 236 | if (Refs.Size() > Items.Size()) |
| 232 | return S_FALSE; | 237 | return S_FALSE; |
| 233 | RINOK(AddNode(parent, item.LeftDid)); | 238 | RINOK(AddNode(parent, item.LeftDid)) |
| 234 | RINOK(AddNode(parent, item.RightDid)); | 239 | RINOK(AddNode(parent, item.RightDid)) |
| 235 | if (item.IsDir()) | 240 | if (item.IsDir()) |
| 236 | { | 241 | { |
| 237 | RINOK(AddNode(index, item.SonDid)); | 242 | RINOK(AddNode((int)index, item.SonDid)) |
| 238 | } | 243 | } |
| 239 | return S_OK; | 244 | return S_OK; |
| 240 | } | 245 | } |
| @@ -244,11 +249,11 @@ static UString CompoundNameToFileName(const UString &s) | |||
| 244 | UString res; | 249 | UString res; |
| 245 | for (unsigned i = 0; i < s.Len(); i++) | 250 | for (unsigned i = 0; i < s.Len(); i++) |
| 246 | { | 251 | { |
| 247 | wchar_t c = s[i]; | 252 | const wchar_t c = s[i]; |
| 248 | if (c < 0x20) | 253 | if ((unsigned)(int)c < 0x20) |
| 249 | { | 254 | { |
| 250 | res += '['; | 255 | res += '['; |
| 251 | res.Add_UInt32(c); | 256 | res.Add_UInt32((UInt32)(unsigned)(int)c); |
| 252 | res += ']'; | 257 | res += ']'; |
| 253 | } | 258 | } |
| 254 | else | 259 | else |
| @@ -360,7 +365,7 @@ UString CDatabase::GetItemPath(UInt32 index) const | |||
| 360 | if (!s.IsEmpty()) | 365 | if (!s.IsEmpty()) |
| 361 | s.InsertAtFront(WCHAR_PATH_SEPARATOR); | 366 | s.InsertAtFront(WCHAR_PATH_SEPARATOR); |
| 362 | s.Insert(0, ConvertName(item.Name)); | 367 | s.Insert(0, ConvertName(item.Name)); |
| 363 | index = ref.Parent; | 368 | index = (unsigned)ref.Parent; |
| 364 | } | 369 | } |
| 365 | return s; | 370 | return s; |
| 366 | } | 371 | } |
| @@ -371,11 +376,11 @@ HRESULT CDatabase::Update_PhySize_WithItem(unsigned index) | |||
| 371 | bool isLargeStream = (index == 0 || IsLargeStream(item.Size)); | 376 | bool isLargeStream = (index == 0 || IsLargeStream(item.Size)); |
| 372 | if (!isLargeStream) | 377 | if (!isLargeStream) |
| 373 | return S_OK; | 378 | return S_OK; |
| 374 | unsigned bsLog = isLargeStream ? SectorSizeBits : MiniSectorSizeBits; | 379 | const unsigned bsLog = isLargeStream ? SectorSizeBits : MiniSectorSizeBits; |
| 375 | // streamSpec->Size = item.Size; | 380 | // streamSpec->Size = item.Size; |
| 376 | 381 | ||
| 377 | UInt32 clusterSize = (UInt32)1 << bsLog; | 382 | const UInt32 clusterSize = (UInt32)1 << bsLog; |
| 378 | UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog; | 383 | const UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog; |
| 379 | if (numClusters64 >= ((UInt32)1 << 31)) | 384 | if (numClusters64 >= ((UInt32)1 << 31)) |
| 380 | return S_FALSE; | 385 | return S_FALSE; |
| 381 | UInt32 sid = item.Sid; | 386 | UInt32 sid = item.Sid; |
| @@ -389,7 +394,13 @@ HRESULT CDatabase::Update_PhySize_WithItem(unsigned index) | |||
| 389 | { | 394 | { |
| 390 | if (sid >= FatSize) | 395 | if (sid >= FatSize) |
| 391 | return S_FALSE; | 396 | return S_FALSE; |
| 392 | UpdatePhySize(((UInt64)sid + 2) << bsLog); | 397 | UInt64 end = ((UInt64)sid + 1) << bsLog; |
| 398 | const UInt64 end_Aligned = end + clusterSize; | ||
| 399 | if (size < clusterSize) | ||
| 400 | end += size; | ||
| 401 | else | ||
| 402 | end = end_Aligned; | ||
| 403 | UpdatePhySize(end, end_Aligned); | ||
| 393 | sid = Fat[sid]; | 404 | sid = Fat[sid]; |
| 394 | } | 405 | } |
| 395 | if (size <= clusterSize) | 406 | if (size <= clusterSize) |
| @@ -415,8 +426,8 @@ HRESULT CDatabase::Open(IInStream *inStream) | |||
| 415 | const UInt32 kHeaderSize = 512; | 426 | const UInt32 kHeaderSize = 512; |
| 416 | Byte p[kHeaderSize]; | 427 | Byte p[kHeaderSize]; |
| 417 | PhySize = kHeaderSize; | 428 | PhySize = kHeaderSize; |
| 418 | RINOK(ReadStream_FALSE(inStream, p, kHeaderSize)); | 429 | RINOK(ReadStream_FALSE(inStream, p, kHeaderSize)) |
| 419 | if (memcmp(p, kSignature, ARRAY_SIZE(kSignature)) != 0) | 430 | if (memcmp(p, kSignature, Z7_ARRAY_SIZE(kSignature)) != 0) |
| 420 | return S_FALSE; | 431 | return S_FALSE; |
| 421 | if (Get16(p + 0x1A) > 4) // majorVer | 432 | if (Get16(p + 0x1A) > 4) // majorVer |
| 422 | return S_FALSE; | 433 | return S_FALSE; |
| @@ -461,7 +472,7 @@ HRESULT CDatabase::Open(IInStream *inStream) | |||
| 461 | UInt32 sid = Get32(p + 0x44); | 472 | UInt32 sid = Get32(p + 0x44); |
| 462 | for (UInt32 s = 0; s < numSectorsForBat; s++) | 473 | for (UInt32 s = 0; s < numSectorsForBat; s++) |
| 463 | { | 474 | { |
| 464 | RINOK(ReadIDs(inStream, sect, sectorSizeBits, sid, bat + i)); | 475 | RINOK(ReadIDs(inStream, sect, sectorSizeBits, sid, bat + i)) |
| 465 | i += numSidsInSec - 1; | 476 | i += numSidsInSec - 1; |
| 466 | sid = bat[i]; | 477 | sid = bat[i]; |
| 467 | } | 478 | } |
| @@ -474,7 +485,7 @@ HRESULT CDatabase::Open(IInStream *inStream) | |||
| 474 | { | 485 | { |
| 475 | if (j >= numBatItems) | 486 | if (j >= numBatItems) |
| 476 | return S_FALSE; | 487 | return S_FALSE; |
| 477 | RINOK(ReadIDs(inStream, sect, sectorSizeBits, bat[j], Fat + i)); | 488 | RINOK(ReadIDs(inStream, sect, sectorSizeBits, bat[j], Fat + i)) |
| 478 | } | 489 | } |
| 479 | FatSize = numFatItems = i; | 490 | FatSize = numFatItems = i; |
| 480 | } | 491 | } |
| @@ -490,7 +501,7 @@ HRESULT CDatabase::Open(IInStream *inStream) | |||
| 490 | UInt32 sid = Get32(p + 0x3C); // short-sector table SID | 501 | UInt32 sid = Get32(p + 0x3C); // short-sector table SID |
| 491 | for (i = 0; i < numMatItems; i += numSidsInSec) | 502 | for (i = 0; i < numMatItems; i += numSidsInSec) |
| 492 | { | 503 | { |
| 493 | RINOK(ReadIDs(inStream, sect, sectorSizeBits, sid, Mat + i)); | 504 | RINOK(ReadIDs(inStream, sect, sectorSizeBits, sid, Mat + i)) |
| 494 | if (sid >= numFatItems) | 505 | if (sid >= numFatItems) |
| 495 | return S_FALSE; | 506 | return S_FALSE; |
| 496 | sid = Fat[sid]; | 507 | sid = Fat[sid]; |
| @@ -511,7 +522,7 @@ HRESULT CDatabase::Open(IInStream *inStream) | |||
| 511 | if (used[sid]) | 522 | if (used[sid]) |
| 512 | return S_FALSE; | 523 | return S_FALSE; |
| 513 | used[sid] = 1; | 524 | used[sid] = 1; |
| 514 | RINOK(ReadSector(inStream, sect, sectorSizeBits, sid)); | 525 | RINOK(ReadSector(inStream, sect, sectorSizeBits, sid)) |
| 515 | for (UInt32 i = 0; i < sectSize; i += 128) | 526 | for (UInt32 i = 0; i < sectSize; i += 128) |
| 516 | { | 527 | { |
| 517 | CItem item; | 528 | CItem item; |
| @@ -563,7 +574,7 @@ HRESULT CDatabase::Open(IInStream *inStream) | |||
| 563 | } | 574 | } |
| 564 | } | 575 | } |
| 565 | 576 | ||
| 566 | RINOK(AddNode(-1, root.SonDid)); | 577 | RINOK(AddNode(-1, root.SonDid)) |
| 567 | 578 | ||
| 568 | unsigned numCabs = 0; | 579 | unsigned numCabs = 0; |
| 569 | 580 | ||
| @@ -584,7 +595,7 @@ HRESULT CDatabase::Open(IInStream *inStream) | |||
| 584 | ) | 595 | ) |
| 585 | { | 596 | { |
| 586 | numCabs++; | 597 | numCabs++; |
| 587 | MainSubfile = i; | 598 | MainSubfile = (int)i; |
| 588 | } | 599 | } |
| 589 | } | 600 | } |
| 590 | } | 601 | } |
| @@ -599,6 +610,17 @@ HRESULT CDatabase::Open(IInStream *inStream) | |||
| 599 | } | 610 | } |
| 600 | } | 611 | } |
| 601 | { | 612 | { |
| 613 | if (PhySize != PhySize_Aligned) | ||
| 614 | { | ||
| 615 | /* some msi (in rare cases) have unaligned size of archive, | ||
| 616 | where there is no padding data after payload data in last cluster of archive */ | ||
| 617 | UInt64 fileSize; | ||
| 618 | RINOK(InStream_GetSize_SeekToEnd(inStream, fileSize)) | ||
| 619 | if (PhySize != fileSize) | ||
| 620 | PhySize = PhySize_Aligned; | ||
| 621 | } | ||
| 622 | } | ||
| 623 | { | ||
| 602 | FOR_VECTOR (t, Items) | 624 | FOR_VECTOR (t, Items) |
| 603 | { | 625 | { |
| 604 | const CItem &item = Items[t]; | 626 | const CItem &item = Items[t]; |
| @@ -634,17 +656,11 @@ HRESULT CDatabase::Open(IInStream *inStream) | |||
| 634 | return S_OK; | 656 | return S_OK; |
| 635 | } | 657 | } |
| 636 | 658 | ||
| 637 | class CHandler: | 659 | Z7_CLASS_IMP_CHandler_IInArchive_1( |
| 638 | public IInArchive, | 660 | IInArchiveGetStream |
| 639 | public IInArchiveGetStream, | 661 | ) |
| 640 | public CMyUnknownImp | ||
| 641 | { | ||
| 642 | CMyComPtr<IInStream> _stream; | 662 | CMyComPtr<IInStream> _stream; |
| 643 | CDatabase _db; | 663 | CDatabase _db; |
| 644 | public: | ||
| 645 | MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) | ||
| 646 | INTERFACE_IInArchive(;) | ||
| 647 | STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); | ||
| 648 | }; | 664 | }; |
| 649 | 665 | ||
| 650 | static const Byte kProps[] = | 666 | static const Byte kProps[] = |
| @@ -666,7 +682,7 @@ static const Byte kArcProps[] = | |||
| 666 | IMP_IInArchive_Props | 682 | IMP_IInArchive_Props |
| 667 | IMP_IInArchive_ArcProps | 683 | IMP_IInArchive_ArcProps |
| 668 | 684 | ||
| 669 | STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) | 685 | Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) |
| 670 | { | 686 | { |
| 671 | COM_TRY_BEGIN | 687 | COM_TRY_BEGIN |
| 672 | NWindows::NCOM::CPropVariant prop; | 688 | NWindows::NCOM::CPropVariant prop; |
| @@ -684,7 +700,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) | |||
| 684 | COM_TRY_END | 700 | COM_TRY_END |
| 685 | } | 701 | } |
| 686 | 702 | ||
| 687 | STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) | 703 | Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) |
| 688 | { | 704 | { |
| 689 | COM_TRY_BEGIN | 705 | COM_TRY_BEGIN |
| 690 | NWindows::NCOM::CPropVariant prop; | 706 | NWindows::NCOM::CPropVariant prop; |
| @@ -705,9 +721,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val | |||
| 705 | COM_TRY_END | 721 | COM_TRY_END |
| 706 | } | 722 | } |
| 707 | 723 | ||
| 708 | STDMETHODIMP CHandler::Open(IInStream *inStream, | 724 | Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, |
| 709 | const UInt64 * /* maxCheckStartPosition */, | 725 | const UInt64 * /* maxCheckStartPosition */, |
| 710 | IArchiveOpenCallback * /* openArchiveCallback */) | 726 | IArchiveOpenCallback * /* openArchiveCallback */)) |
| 711 | { | 727 | { |
| 712 | COM_TRY_BEGIN | 728 | COM_TRY_BEGIN |
| 713 | Close(); | 729 | Close(); |
| @@ -722,18 +738,18 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, | |||
| 722 | COM_TRY_END | 738 | COM_TRY_END |
| 723 | } | 739 | } |
| 724 | 740 | ||
| 725 | STDMETHODIMP CHandler::Close() | 741 | Z7_COM7F_IMF(CHandler::Close()) |
| 726 | { | 742 | { |
| 727 | _db.Clear(); | 743 | _db.Clear(); |
| 728 | _stream.Release(); | 744 | _stream.Release(); |
| 729 | return S_OK; | 745 | return S_OK; |
| 730 | } | 746 | } |
| 731 | 747 | ||
| 732 | STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, | 748 | Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, |
| 733 | Int32 testMode, IArchiveExtractCallback *extractCallback) | 749 | Int32 testMode, IArchiveExtractCallback *extractCallback)) |
| 734 | { | 750 | { |
| 735 | COM_TRY_BEGIN | 751 | COM_TRY_BEGIN |
| 736 | bool allFilesMode = (numItems == (UInt32)(Int32)-1); | 752 | const bool allFilesMode = (numItems == (UInt32)(Int32)-1); |
| 737 | if (allFilesMode) | 753 | if (allFilesMode) |
| 738 | numItems = _db.Refs.Size(); | 754 | numItems = _db.Refs.Size(); |
| 739 | if (numItems == 0) | 755 | if (numItems == 0) |
| @@ -746,7 +762,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, | |||
| 746 | if (!item.IsDir()) | 762 | if (!item.IsDir()) |
| 747 | totalSize += item.Size; | 763 | totalSize += item.Size; |
| 748 | } | 764 | } |
| 749 | RINOK(extractCallback->SetTotal(totalSize)); | 765 | RINOK(extractCallback->SetTotal(totalSize)) |
| 750 | 766 | ||
| 751 | UInt64 totalPackSize; | 767 | UInt64 totalPackSize; |
| 752 | totalSize = totalPackSize = 0; | 768 | totalSize = totalPackSize = 0; |
| @@ -762,20 +778,20 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, | |||
| 762 | { | 778 | { |
| 763 | lps->InSize = totalPackSize; | 779 | lps->InSize = totalPackSize; |
| 764 | lps->OutSize = totalSize; | 780 | lps->OutSize = totalSize; |
| 765 | RINOK(lps->SetCur()); | 781 | RINOK(lps->SetCur()) |
| 766 | Int32 index = allFilesMode ? i : indices[i]; | 782 | const UInt32 index = allFilesMode ? i : indices[i]; |
| 767 | const CItem &item = _db.Items[_db.Refs[index].Did]; | 783 | const CItem &item = _db.Items[_db.Refs[index].Did]; |
| 768 | 784 | ||
| 769 | CMyComPtr<ISequentialOutStream> outStream; | 785 | CMyComPtr<ISequentialOutStream> outStream; |
| 770 | Int32 askMode = testMode ? | 786 | const Int32 askMode = testMode ? |
| 771 | NExtract::NAskMode::kTest : | 787 | NExtract::NAskMode::kTest : |
| 772 | NExtract::NAskMode::kExtract; | 788 | NExtract::NAskMode::kExtract; |
| 773 | RINOK(extractCallback->GetStream(index, &outStream, askMode)); | 789 | RINOK(extractCallback->GetStream(index, &outStream, askMode)) |
| 774 | 790 | ||
| 775 | if (item.IsDir()) | 791 | if (item.IsDir()) |
| 776 | { | 792 | { |
| 777 | RINOK(extractCallback->PrepareOperation(askMode)); | 793 | RINOK(extractCallback->PrepareOperation(askMode)) |
| 778 | RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); | 794 | RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) |
| 779 | continue; | 795 | continue; |
| 780 | } | 796 | } |
| 781 | 797 | ||
| @@ -784,7 +800,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, | |||
| 784 | 800 | ||
| 785 | if (!testMode && !outStream) | 801 | if (!testMode && !outStream) |
| 786 | continue; | 802 | continue; |
| 787 | RINOK(extractCallback->PrepareOperation(askMode)); | 803 | RINOK(extractCallback->PrepareOperation(askMode)) |
| 788 | Int32 res = NExtract::NOperationResult::kDataError; | 804 | Int32 res = NExtract::NOperationResult::kDataError; |
| 789 | CMyComPtr<ISequentialInStream> inStream; | 805 | CMyComPtr<ISequentialInStream> inStream; |
| 790 | HRESULT hres = GetStream(index, &inStream); | 806 | HRESULT hres = GetStream(index, &inStream); |
| @@ -794,45 +810,45 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, | |||
| 794 | res = NExtract::NOperationResult::kUnsupportedMethod; | 810 | res = NExtract::NOperationResult::kUnsupportedMethod; |
| 795 | else | 811 | else |
| 796 | { | 812 | { |
| 797 | RINOK(hres); | 813 | RINOK(hres) |
| 798 | if (inStream) | 814 | if (inStream) |
| 799 | { | 815 | { |
| 800 | RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); | 816 | RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)) |
| 801 | if (copyCoderSpec->TotalSize == item.Size) | 817 | if (copyCoderSpec->TotalSize == item.Size) |
| 802 | res = NExtract::NOperationResult::kOK; | 818 | res = NExtract::NOperationResult::kOK; |
| 803 | } | 819 | } |
| 804 | } | 820 | } |
| 805 | outStream.Release(); | 821 | outStream.Release(); |
| 806 | RINOK(extractCallback->SetOperationResult(res)); | 822 | RINOK(extractCallback->SetOperationResult(res)) |
| 807 | } | 823 | } |
| 808 | return S_OK; | 824 | return S_OK; |
| 809 | COM_TRY_END | 825 | COM_TRY_END |
| 810 | } | 826 | } |
| 811 | 827 | ||
| 812 | STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) | 828 | Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) |
| 813 | { | 829 | { |
| 814 | *numItems = _db.Refs.Size(); | 830 | *numItems = _db.Refs.Size(); |
| 815 | return S_OK; | 831 | return S_OK; |
| 816 | } | 832 | } |
| 817 | 833 | ||
| 818 | STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) | 834 | Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) |
| 819 | { | 835 | { |
| 820 | COM_TRY_BEGIN | 836 | COM_TRY_BEGIN |
| 821 | *stream = 0; | 837 | *stream = NULL; |
| 822 | UInt32 itemIndex = _db.Refs[index].Did; | 838 | const UInt32 itemIndex = _db.Refs[index].Did; |
| 823 | const CItem &item = _db.Items[itemIndex]; | 839 | const CItem &item = _db.Items[itemIndex]; |
| 824 | CClusterInStream *streamSpec = new CClusterInStream; | 840 | CClusterInStream *streamSpec = new CClusterInStream; |
| 825 | CMyComPtr<ISequentialInStream> streamTemp = streamSpec; | 841 | CMyComPtr<ISequentialInStream> streamTemp = streamSpec; |
| 826 | streamSpec->Stream = _stream; | 842 | streamSpec->Stream = _stream; |
| 827 | streamSpec->StartOffset = 0; | 843 | streamSpec->StartOffset = 0; |
| 828 | 844 | ||
| 829 | bool isLargeStream = (itemIndex == 0 || _db.IsLargeStream(item.Size)); | 845 | const bool isLargeStream = (itemIndex == 0 || _db.IsLargeStream(item.Size)); |
| 830 | int bsLog = isLargeStream ? _db.SectorSizeBits : _db.MiniSectorSizeBits; | 846 | const unsigned bsLog = isLargeStream ? _db.SectorSizeBits : _db.MiniSectorSizeBits; |
| 831 | streamSpec->BlockSizeLog = bsLog; | 847 | streamSpec->BlockSizeLog = bsLog; |
| 832 | streamSpec->Size = item.Size; | 848 | streamSpec->Size = item.Size; |
| 833 | 849 | ||
| 834 | UInt32 clusterSize = (UInt32)1 << bsLog; | 850 | const UInt32 clusterSize = (UInt32)1 << bsLog; |
| 835 | UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog; | 851 | const UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog; |
| 836 | if (numClusters64 >= ((UInt32)1 << 31)) | 852 | if (numClusters64 >= ((UInt32)1 << 31)) |
| 837 | return E_NOTIMPL; | 853 | return E_NOTIMPL; |
| 838 | streamSpec->Vector.ClearAndReserve((unsigned)numClusters64); | 854 | streamSpec->Vector.ClearAndReserve((unsigned)numClusters64); |
| @@ -864,14 +880,14 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) | |||
| 864 | } | 880 | } |
| 865 | if (sid != NFatID::kEndOfChain) | 881 | if (sid != NFatID::kEndOfChain) |
| 866 | return S_FALSE; | 882 | return S_FALSE; |
| 867 | RINOK(streamSpec->InitAndSeek()); | 883 | RINOK(streamSpec->InitAndSeek()) |
| 868 | *stream = streamTemp.Detach(); | 884 | *stream = streamTemp.Detach(); |
| 869 | return S_OK; | 885 | return S_OK; |
| 870 | COM_TRY_END | 886 | COM_TRY_END |
| 871 | } | 887 | } |
| 872 | 888 | ||
| 873 | REGISTER_ARC_I( | 889 | REGISTER_ARC_I( |
| 874 | "Compound", "msi msp doc xls ppt", 0, 0xE5, | 890 | "Compound", "msi msp doc xls ppt", NULL, 0xE5, |
| 875 | kSignature, | 891 | kSignature, |
| 876 | 0, | 892 | 0, |
| 877 | 0, | 893 | 0, |
