aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/Archive/ComHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Archive/ComHandler.cpp')
-rw-r--r--CPP/7zip/Archive/ComHandler.cpp144
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 @@
26namespace NArchive { 26namespace NArchive {
27namespace NCom { 27namespace NCom {
28 28
29#define SIGNATURE { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 } 29static const Byte kSignature[] =
30static const Byte kSignature[] = SIGNATURE; 30 { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 };
31 31
32enum EType 32enum 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
166HRESULT CDatabase::ReadSector(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid) 169HRESULT 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
173HRESULT CDatabase::ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest) 177HRESULT 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)
205void CDatabase::Clear() 209void 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
637class CHandler: 659Z7_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;
644public:
645 MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
646 INTERFACE_IInArchive(;)
647 STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
648}; 664};
649 665
650static const Byte kProps[] = 666static const Byte kProps[] =
@@ -666,7 +682,7 @@ static const Byte kArcProps[] =
666IMP_IInArchive_Props 682IMP_IInArchive_Props
667IMP_IInArchive_ArcProps 683IMP_IInArchive_ArcProps
668 684
669STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) 685Z7_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
687STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) 703Z7_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
708STDMETHODIMP CHandler::Open(IInStream *inStream, 724Z7_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
725STDMETHODIMP CHandler::Close() 741Z7_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
732STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, 748Z7_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
812STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) 828Z7_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
818STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) 834Z7_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
873REGISTER_ARC_I( 889REGISTER_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,