Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2015-11-03 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:16:57 +0300
commit7c8a265a15125b64808e695882acd2a0298ebce4 (patch)
tree81fc9fdedc6b70b979a3dfe3a3041457a6e9468d /CPP/7zip/Archive
parenta663a6deb7a150f935fac7efdbf4d53d27369594 (diff)
15.1015.10
Diffstat (limited to 'CPP/7zip/Archive')
-rw-r--r--CPP/7zip/Archive/7z/7z.dsp16
-rw-r--r--CPP/7zip/Archive/7z/7zExtract.cpp10
-rw-r--r--CPP/7zip/Archive/7z/7zFolderOutStream.cpp3
-rw-r--r--CPP/7zip/Archive/7z/7zFolderOutStream.h6
-rw-r--r--CPP/7zip/Archive/7z/7zHandler.cpp12
-rw-r--r--CPP/7zip/Archive/7z/7zHandler.h8
-rw-r--r--CPP/7zip/Archive/7z/makefile2
-rw-r--r--CPP/7zip/Archive/Common/CrossThreadProgress.cpp15
-rw-r--r--CPP/7zip/Archive/Common/CrossThreadProgress.h37
-rw-r--r--CPP/7zip/Archive/Common/HandlerOut.cpp4
-rw-r--r--CPP/7zip/Archive/Iso/IsoIn.cpp6
-rw-r--r--CPP/7zip/Archive/Rar/Rar5Handler.cpp28
-rw-r--r--CPP/7zip/Archive/Rar/Rar5Handler.h1
-rw-r--r--CPP/7zip/Archive/Rar/RarHandler.cpp32
-rw-r--r--CPP/7zip/Archive/Rar/RarHandler.h1
-rw-r--r--CPP/7zip/Archive/VhdHandler.cpp49
-rw-r--r--CPP/7zip/Archive/VmdkHandler.cpp32
-rw-r--r--CPP/7zip/Archive/Wim/WimHandler.cpp15
-rw-r--r--CPP/7zip/Archive/Wim/WimIn.cpp5
19 files changed, 158 insertions, 124 deletions
diff --git a/CPP/7zip/Archive/7z/7z.dsp b/CPP/7zip/Archive/7z/7z.dsp
index 7fd1ccdc..ffd28721 100644
--- a/CPP/7zip/Archive/7z/7z.dsp
+++ b/CPP/7zip/Archive/7z/7z.dsp
@@ -158,14 +158,6 @@ SOURCE=.\7zFolderInStream.h
# End Source File
# Begin Source File
-SOURCE=.\7zFolderOutStream.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\7zFolderOutStream.h
-# End Source File
-# Begin Source File
-
SOURCE=.\7zHandler.cpp
# End Source File
# Begin Source File
@@ -350,14 +342,6 @@ SOURCE=..\Common\CoderMixer2.h
# End Source File
# Begin Source File
-SOURCE=..\Common\CrossThreadProgress.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\Common\CrossThreadProgress.h
-# End Source File
-# Begin Source File
-
SOURCE=..\Common\HandlerOut.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp
index d21bafdb..83965164 100644
--- a/CPP/7zip/Archive/7z/7zExtract.cpp
+++ b/CPP/7zip/Archive/7z/7zExtract.cpp
@@ -254,8 +254,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
lps->Init(extractCallback, false);
CDecoder decoder(
- #ifndef USE_MIXER_ST
+ #if !defined(USE_MIXER_MT)
false
+ #elif !defined(USE_MIXER_ST)
+ true
+ #elif !defined(__7Z_SET_PROPERTIES)
+ #ifdef _7ZIP_ST
+ false
+ #else
+ true
+ #endif
#else
_useMultiThreadMixer
#endif
diff --git a/CPP/7zip/Archive/7z/7zFolderOutStream.cpp b/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
deleted file mode 100644
index e63ee925..00000000
--- a/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-// 7zFolderOutStream.cpp
-
-#include "StdAfx.h"
diff --git a/CPP/7zip/Archive/7z/7zFolderOutStream.h b/CPP/7zip/Archive/7z/7zFolderOutStream.h
deleted file mode 100644
index a32b22e0..00000000
--- a/CPP/7zip/Archive/7z/7zFolderOutStream.h
+++ /dev/null
@@ -1,6 +0,0 @@
-// 7zFolderOutStream.h
-
-#ifndef __7Z_FOLDER_OUT_STREAM_H
-#define __7Z_FOLDER_OUT_STREAM_H
-
-#endif
diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp
index d397e818..a95fc6a0 100644
--- a/CPP/7zip/Archive/7z/7zHandler.cpp
+++ b/CPP/7zip/Archive/7z/7zHandler.cpp
@@ -36,10 +36,14 @@ CHandler::CHandler()
#endif
#ifdef EXTRACT_ONLY
+
_crcSize = 4;
+
#ifdef __7Z_SET_PROPERTIES
_numThreads = NSystem::GetNumberOfProcessors();
+ _useMultiThreadMixer = true;
#endif
+
#endif
}
@@ -722,10 +726,14 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
UInt32 number;
- int index = ParseStringToUInt32(name, number);
+ unsigned index = ParseStringToUInt32(name, number);
if (index == 0)
{
- if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
+ if (name.IsEqualTo("mtf"))
+ {
+ RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer));
+ continue;
+ }
if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
RINOK(ParseMtProp(name.Ptr(2), value, numProcessors, _numThreads));
diff --git a/CPP/7zip/Archive/7z/7zHandler.h b/CPP/7zip/Archive/7z/7zHandler.h
index eb7791bc..d46401af 100644
--- a/CPP/7zip/Archive/7z/7zHandler.h
+++ b/CPP/7zip/Archive/7z/7zHandler.h
@@ -21,11 +21,11 @@ namespace N7z {
#ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
-#if !defined(_7ZIP_ST) && !defined(_SFX)
-#define __7Z_SET_PROPERTIES
-#endif
+ #if !defined(_7ZIP_ST) && !defined(_SFX)
+ #define __7Z_SET_PROPERTIES
+ #endif
#else
-#define __7Z_SET_PROPERTIES
+ #define __7Z_SET_PROPERTIES
#endif
#endif
diff --git a/CPP/7zip/Archive/7z/makefile b/CPP/7zip/Archive/7z/makefile
index 49818371..a3b077da 100644
--- a/CPP/7zip/Archive/7z/makefile
+++ b/CPP/7zip/Archive/7z/makefile
@@ -13,7 +13,6 @@ AR_OBJS = \
$O\7zEncode.obj \
$O\7zExtract.obj \
$O\7zFolderInStream.obj \
- $O\7zFolderOutStream.obj \
$O\7zHandler.obj \
$O\7zHandlerOut.obj \
$O\7zHeader.obj \
@@ -65,7 +64,6 @@ COMPRESS_OBJS = \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
- $O\CrossThreadProgress.obj \
$O\HandlerOut.obj \
$O\InStreamWithCRC.obj \
$O\ItemNameUtils.obj \
diff --git a/CPP/7zip/Archive/Common/CrossThreadProgress.cpp b/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
deleted file mode 100644
index a974b54c..00000000
--- a/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-// CrossThreadProgress.cpp
-
-#include "StdAfx.h"
-
-#include "CrossThreadProgress.h"
-
-STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
-{
- InSize = inSize;
- OutSize = outSize;
- ProgressEvent.Set();
- WaitEvent.Lock();
- return Result;
-}
-
diff --git a/CPP/7zip/Archive/Common/CrossThreadProgress.h b/CPP/7zip/Archive/Common/CrossThreadProgress.h
deleted file mode 100644
index 7e0b1053..00000000
--- a/CPP/7zip/Archive/Common/CrossThreadProgress.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// CrossThreadProgress.h
-
-#ifndef __CROSSTHREADPROGRESS_H
-#define __CROSSTHREADPROGRESS_H
-
-#include "../../ICoder.h"
-#include "../../../Windows/Synchronization.h"
-#include "../../../Common/MyCom.h"
-
-class CCrossThreadProgress:
- public ICompressProgressInfo,
- public CMyUnknownImp
-{
-public:
- const UInt64 *InSize;
- const UInt64 *OutSize;
- HRESULT Result;
- NWindows::NSynchronization::CAutoResetEvent ProgressEvent;
- NWindows::NSynchronization::CAutoResetEvent WaitEvent;
-
- HRes Create()
- {
- RINOK(ProgressEvent.CreateIfNotCreated());
- return WaitEvent.CreateIfNotCreated();
- }
- void Init()
- {
- ProgressEvent.Reset();
- WaitEvent.Reset();
- }
-
- MY_UNKNOWN_IMP
-
- STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
-};
-
-#endif
diff --git a/CPP/7zip/Archive/Common/HandlerOut.cpp b/CPP/7zip/Archive/Common/HandlerOut.cpp
index 9c11b31d..95381ea3 100644
--- a/CPP/7zip/Archive/Common/HandlerOut.cpp
+++ b/CPP/7zip/Archive/Common/HandlerOut.cpp
@@ -147,7 +147,9 @@ HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PR
#endif
}
else
- return ParseMethodFromPROPVARIANT(names[i], value);
+ {
+ RINOK(ParseMethodFromPROPVARIANT(names[i], value));
+ }
}
return S_OK;
}
diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp
index 1c7dd11e..1ebc15e8 100644
--- a/CPP/7zip/Archive/Iso/IsoIn.cpp
+++ b/CPP/7zip/Archive/Iso/IsoIn.cpp
@@ -294,7 +294,11 @@ void CInArchive::ReadVolumeDescriptor(CVolumeDescriptor &d)
d.FileStructureVersion = ReadByte(); // = 1
SkipZeros(1);
ReadBytes(d.ApplicationUse, sizeof(d.ApplicationUse));
- SkipZeros(653);
+
+ // Most ISO contains zeros in the following field (reserved for future standardization).
+ // But some ISO programs write some data to that area.
+ // So we disable check for zeros.
+ Skip(653); // SkipZeros(653);
}
static const Byte kSig_CD001[5] = { 'C', 'D', '0', '0', '1' };
diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.cpp b/CPP/7zip/Archive/Rar/Rar5Handler.cpp
index 2cfe805e..dff327f2 100644
--- a/CPP/7zip/Archive/Rar/Rar5Handler.cpp
+++ b/CPP/7zip/Archive/Rar/Rar5Handler.cpp
@@ -1292,6 +1292,18 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
break;
}
+ case kpidError:
+ {
+ if (/* &_missingVol || */ !_missingVolName.IsEmpty())
+ {
+ UString s;
+ s.SetFromAscii("Missing volume : ");
+ s += _missingVolName;
+ prop = s;
+ }
+ break;
+ }
+
case kpidErrorFlags:
{
UInt32 v = _errorFlags;
@@ -1840,13 +1852,18 @@ HRESULT CHandler::Open2(IInStream *stream,
break;
}
- HRESULT result = openVolumeCallback->GetStream(seqName.GetNextName(), &inStream);
- if (result == S_FALSE)
- break;
- if (result != S_OK)
+ const UString volName = seqName.GetNextName();
+
+ HRESULT result = openVolumeCallback->GetStream(volName, &inStream);
+
+ if (result != S_OK && result != S_FALSE)
return result;
- if (!inStream)
+
+ if (!inStream || result != S_OK)
+ {
+ _missingVolName = volName;
break;
+ }
}
UInt64 endPos = 0;
@@ -2120,6 +2137,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
STDMETHODIMP CHandler::Close()
{
COM_TRY_BEGIN
+ _missingVolName.Empty();
_errorFlags = 0;
// _warningFlags = 0;
_isArc = false;
diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.h b/CPP/7zip/Archive/Rar/Rar5Handler.h
index 5eaf0075..cf741c7c 100644
--- a/CPP/7zip/Archive/Rar/Rar5Handler.h
+++ b/CPP/7zip/Archive/Rar/Rar5Handler.h
@@ -381,6 +381,7 @@ private:
// UInt32 _warningFlags;
bool _isArc;
CByteBuffer _comment;
+ UString _missingVolName;
DECL_EXTERNAL_CODECS_VARS
diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp
index dde15958..31c06d96 100644
--- a/CPP/7zip/Archive/Rar/RarHandler.cpp
+++ b/CPP/7zip/Archive/Rar/RarHandler.cpp
@@ -855,8 +855,21 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
break;
}
- // case kpidError: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break;
+ case kpidError:
+ {
+ // if (!_errorMessage.IsEmpty()) prop = _errorMessage; break;
+
+ if (/* &_missingVol || */ !_missingVolName.IsEmpty())
+ {
+ UString s;
+ s.SetFromAscii("Missing volume : ");
+ s += _missingVolName;
+ prop = s;
+ }
+ break;
+ }
+
case kpidErrorFlags:
{
UInt32 v = _errorFlags;
@@ -1050,14 +1063,18 @@ HRESULT CHandler::Open2(IInStream *stream,
*/
}
- UString fullName = seqName.GetNextName();
- HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
- if (result == S_FALSE)
- break;
- if (result != S_OK)
+ const UString volName = seqName.GetNextName();
+
+ HRESULT result = openVolumeCallback->GetStream(volName, &inStream);
+
+ if (result != S_OK && result != S_FALSE)
return result;
- if (!inStream)
+
+ if (!inStream || result != S_OK)
+ {
+ _missingVolName = volName;
break;
+ }
}
else
inStream = stream;
@@ -1216,6 +1233,7 @@ STDMETHODIMP CHandler::Close()
{
COM_TRY_BEGIN
// _errorMessage.Empty();
+ _missingVolName.Empty();
_errorFlags = 0;
_warningFlags = 0;
_isArc = false;
diff --git a/CPP/7zip/Archive/Rar/RarHandler.h b/CPP/7zip/Archive/Rar/RarHandler.h
index dd3daa5d..9e6fb5cb 100644
--- a/CPP/7zip/Archive/Rar/RarHandler.h
+++ b/CPP/7zip/Archive/Rar/RarHandler.h
@@ -79,6 +79,7 @@ class CHandler:
UInt32 _errorFlags;
UInt32 _warningFlags;
bool _isArc;
+ UString _missingVolName;
DECL_EXTERNAL_CODECS_VARS
diff --git a/CPP/7zip/Archive/VhdHandler.cpp b/CPP/7zip/Archive/VhdHandler.cpp
index 0459571b..bddbf31b 100644
--- a/CPP/7zip/Archive/VhdHandler.cpp
+++ b/CPP/7zip/Archive/VhdHandler.cpp
@@ -682,9 +682,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
s += " -> ";
const CHandler *p = this;
- while (p != 0 && p->NeedParent())
+ while (p && p->NeedParent())
p = p->Parent;
- if (p == 0)
+ if (!p)
s += '?';
else
s += p->Footer.GetTypeString();
@@ -750,26 +750,24 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
COM_TRY_END
}
+
HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback *openArchiveCallback, unsigned level)
{
Close();
Stream = stream;
if (level > (1 << 12)) // Maybe we need to increase that limit
return S_FALSE;
+
RINOK(Open3());
+
if (child && memcmp(child->Dyn.ParentId, Footer.Id, 16) != 0)
return S_FALSE;
if (Footer.Type != kDiskType_Diff)
return S_OK;
- CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
- if (openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback) != S_OK)
- {
- // return S_FALSE;
- }
- CMyComPtr<IInStream> nextStream;
bool useRelative;
UString name;
+
if (!Dyn.RelativeParentNameFromLocator.IsEmpty())
{
useRelative = true;
@@ -780,11 +778,17 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
useRelative = false;
name = Dyn.ParentName;
}
+
Dyn.RelativeNameWasUsed = useRelative;
+ CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
+ openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback);
+
if (openVolumeCallback)
{
+ CMyComPtr<IInStream> nextStream;
HRESULT res = openVolumeCallback->GetStream(name, &nextStream);
+
if (res == S_FALSE)
{
if (useRelative && Dyn.ParentName != Dyn.RelativeParentNameFromLocator)
@@ -793,19 +797,35 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
if (res == S_OK)
Dyn.RelativeNameWasUsed = false;
}
- if (res == S_FALSE)
- return S_OK;
}
- RINOK(res);
+
+ if (res != S_OK && res != S_FALSE)
+ return res;
+
+ if (res == S_FALSE || !nextStream)
+ {
+ UString s;
+ s.SetFromAscii("Missing volume : ");
+ s += name;
+ AddErrorMessage(s);
+ return S_OK;
+ }
Parent = new CHandler;
ParentStream = Parent;
res = Parent->Open2(nextStream, this, openArchiveCallback, level + 1);
- if (res == S_FALSE)
+
+ if (res != S_OK)
{
Parent = NULL;
ParentStream.Release();
+ if (res == E_ABORT)
+ return res;
+ if (res != S_FALSE)
+ {
+ // we must show that error code
+ }
}
}
{
@@ -813,7 +833,7 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
while (p->NeedParent())
{
p = p->Parent;
- if (p == 0)
+ if (!p)
{
AddErrorMessage(L"Can't open parent VHD file:");
AddErrorMessage(Dyn.ParentName);
@@ -824,12 +844,13 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
return S_OK;
}
+
void CHandler::CloseAtError()
{
_phySize = 0;
Bat.Clear();
NumUsedBlocks = 0;
- Parent = 0;
+ Parent = NULL;
Stream.Release();
ParentStream.Release();
Dyn.Clear();
diff --git a/CPP/7zip/Archive/VmdkHandler.cpp b/CPP/7zip/Archive/VmdkHandler.cpp
index 83e38d02..359691e3 100644
--- a/CPP/7zip/Archive/VmdkHandler.cpp
+++ b/CPP/7zip/Archive/VmdkHandler.cpp
@@ -450,6 +450,8 @@ class CHandler: public CHandlerImg
CByteBuffer _descriptorBuf;
CDescriptor _descriptor;
+
+ UString _missingVolName;
void InitAndSeekMain()
{
@@ -882,6 +884,19 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidNumVolumes: if (_isMultiVol) prop = (UInt32)_extents.Size(); break;
+ case kpidError:
+ {
+ if (_missingVol || !_missingVolName.IsEmpty())
+ {
+ UString s;
+ s.SetFromAscii("Missing volume : ");
+ if (!_missingVolName.IsEmpty())
+ s += _missingVolName;
+ prop = s;
+ }
+ break;
+ }
+
case kpidErrorFlags:
{
UInt32 v = 0;
@@ -889,7 +904,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod;
if (_unsupportedSome) v |= kpv_ErrorFlags_UnsupportedMethod;
if (_headerError) v |= kpv_ErrorFlags_HeadersError;
- if (_missingVol) v |= kpv_ErrorFlags_UnexpectedEnd;
+ // if (_missingVol) v |= kpv_ErrorFlags_UnexpectedEnd;
if (v != 0)
prop = v;
break;
@@ -1081,15 +1096,14 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
}
HRESULT result = volumeCallback->GetStream(u, &nextStream);
- if (result == S_FALSE)
- {
- _missingVol = true;
- continue;
- }
- if (result != S_OK)
+
+ if (result != S_OK && result != S_FALSE)
return result;
- if (!nextStream)
+
+ if (!nextStream || result != S_OK)
{
+ if (_missingVolName.IsEmpty())
+ _missingVolName = u;
_missingVol = true;
continue;
}
@@ -1431,6 +1445,8 @@ STDMETHODIMP CHandler::Close()
_isMultiVol = false;
_needDeflate = false;
+ _missingVolName.Empty();
+
_descriptorBuf.Free();
_descriptor.Clear();
diff --git a/CPP/7zip/Archive/Wim/WimHandler.cpp b/CPP/7zip/Archive/Wim/WimHandler.cpp
index 6c07f37c..910de06d 100644
--- a/CPP/7zip/Archive/Wim/WimHandler.cpp
+++ b/CPP/7zip/Archive/Wim/WimHandler.cpp
@@ -1028,6 +1028,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCal
COM_TRY_END
}
+
STDMETHODIMP CHandler::Close()
{
_firstVolumeIndex = -1;
@@ -1093,7 +1094,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
- for (i = 0; i < numItems;
+ for (i = 0;; i++,
currentTotalUnPacked += currentItemUnPacked)
{
currentItemUnPacked = 0;
@@ -1102,14 +1103,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
lps->OutSize = currentTotalUnPacked;
RINOK(lps->SetCur());
+
+ if (i >= numItems)
+ break;
+
UInt32 index = allFilesMode ? i : indices[i];
- i++;
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
CMyComPtr<ISequentialOutStream> realOutStream;
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+
if (index >= _db.SortedItems.Size())
{
if (!testMode && !realOutStream)
@@ -1153,13 +1158,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
continue;
RINOK(extractCallback->PrepareOperation(askMode));
Int32 opRes = NExtract::NOperationResult::kOK;
+
if (streamIndex != prevSuccessStreamIndex || realOutStream)
{
Byte digest[kHashSize];
const CVolume &vol = _volumes[si.PartNumber];
bool needDigest = !si.IsEmptyHash();
+
HRESULT res = unpacker.Unpack(vol.Stream, si.Resource, vol.Header, &_db,
realOutStream, progress, needDigest ? digest : NULL);
+
if (res == S_OK)
{
if (!needDigest || memcmp(digest, si.Hash, kHashSize) == 0)
@@ -1174,13 +1182,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
else
return res;
}
+
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(opRes));
}
+
return S_OK;
COM_TRY_END
}
+
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _db.SortedItems.Size() +
diff --git a/CPP/7zip/Archive/Wim/WimIn.cpp b/CPP/7zip/Archive/Wim/WimIn.cpp
index 1da6ca98..b1bed3c6 100644
--- a/CPP/7zip/Archive/Wim/WimIn.cpp
+++ b/CPP/7zip/Archive/Wim/WimIn.cpp
@@ -255,7 +255,12 @@ HRESULT CUnpacker::Unpack2(
_solidIndex = resource.SolidIndex;
_unpackedChunkIndex = chunkIndex;
+
+ if (cur < offsetInChunk)
+ return E_FAIL;
+ cur -= offsetInChunk;
+
if (cur > rem)
cur = (size_t)rem;