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, |