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-06-15 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:16:54 +0300
commit54490d51d5c6b0d794dcbad2d634d4c95fc25b6c (patch)
treec3c413656432c0ef87b2841c80e42b55ad17d4e8 /CPP/7zip/Archive/Zip
parent0713a3ab803e57401f18432148b4139e5fe6e5dd (diff)
15.0515.05
Diffstat (limited to 'CPP/7zip/Archive/Zip')
-rw-r--r--CPP/7zip/Archive/Zip/ZipAddCommon.cpp116
-rw-r--r--CPP/7zip/Archive/Zip/ZipAddCommon.h6
-rw-r--r--CPP/7zip/Archive/Zip/ZipHandler.cpp180
-rw-r--r--CPP/7zip/Archive/Zip/ZipHandler.h2
-rw-r--r--CPP/7zip/Archive/Zip/ZipHandlerOut.cpp24
-rw-r--r--CPP/7zip/Archive/Zip/ZipHeader.h2
-rw-r--r--CPP/7zip/Archive/Zip/ZipIn.cpp23
-rw-r--r--CPP/7zip/Archive/Zip/ZipIn.h4
-rw-r--r--CPP/7zip/Archive/Zip/ZipItem.cpp7
-rw-r--r--CPP/7zip/Archive/Zip/ZipItem.h16
-rw-r--r--CPP/7zip/Archive/Zip/ZipOut.h2
-rw-r--r--CPP/7zip/Archive/Zip/ZipRegister.cpp21
-rw-r--r--CPP/7zip/Archive/Zip/ZipUpdate.cpp80
13 files changed, 336 insertions, 147 deletions
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
index 9a0d7515..c9c290aa 100644
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
@@ -3,6 +3,7 @@
#include "StdAfx.h"
#include "../../../../C/7zCrc.h"
+#include "../../../../C/Alloc.h"
#include "../../../Windows/PropVariant.h"
@@ -77,32 +78,46 @@ STDMETHODIMP CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStr
CAddCommon::CAddCommon(const CCompressionMethodMode &options):
- _options(options),
- _copyCoderSpec(NULL),
- _cryptoStreamSpec(0)
- {}
+ _options(options),
+ _copyCoderSpec(NULL),
+ _cryptoStreamSpec(NULL),
+ _buf(NULL)
+ {}
-static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC)
+CAddCommon::~CAddCommon()
{
+ MidFree(_buf);
+}
+
+static const UInt32 kBufSize = ((UInt32)1 << 16);
+
+HRESULT CAddCommon::CalcStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC)
+{
+ if (!_buf)
+ {
+ _buf = (Byte *)MidAlloc(kBufSize);
+ if (!_buf)
+ return E_OUTOFMEMORY;
+ }
+
UInt32 crc = CRC_INIT_VAL;
- const UInt32 kBufSize = (1 << 14);
- Byte buf[kBufSize];
for (;;)
{
UInt32 processed;
- RINOK(inStream->Read(buf, kBufSize, &processed));
+ RINOK(inStream->Read(_buf, kBufSize, &processed));
if (processed == 0)
{
resultCRC = CRC_GET_DIGEST(crc);
return S_OK;
}
- crc = CrcUpdate(crc, buf, (size_t)processed);
+ crc = CrcUpdate(crc, _buf, (size_t)processed);
}
}
HRESULT CAddCommon::Compress(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream, IOutStream *outStream,
+ UInt32 /* fileTime */,
ICompressProgressInfo *progress, CCompressingResult &opRes)
{
if (!inStream)
@@ -111,13 +126,14 @@ HRESULT CAddCommon::Compress(
return E_INVALIDARG;
}
- CSequentialInStreamWithCRC *inSecCrcStreamSpec = NULL;
+ // CSequentialInStreamWithCRC *inSecCrcStreamSpec = NULL;
CInStreamWithCRC *inCrcStreamSpec = NULL;
CMyComPtr<ISequentialInStream> inCrcStream;
{
CMyComPtr<IInStream> inStream2;
- // we don't support stdin, since stream from stdin can require 64-bit size header
- RINOK(inStream->QueryInterface(IID_IInStream, (void **)&inStream2));
+
+ inStream->QueryInterface(IID_IInStream, (void **)&inStream2);
+
if (inStream2)
{
inCrcStreamSpec = new CInStreamWithCRC;
@@ -127,28 +143,29 @@ HRESULT CAddCommon::Compress(
}
else
{
+ // we don't support stdin, since stream from stdin can require 64-bit size header
+ return E_NOTIMPL;
+ /*
inSecCrcStreamSpec = new CSequentialInStreamWithCRC;
inCrcStream = inSecCrcStreamSpec;
inSecCrcStreamSpec->SetStream(inStream);
inSecCrcStreamSpec->Init();
+ */
}
}
unsigned numTestMethods = _options.MethodSequence.Size();
- if (numTestMethods > 1 || _options.PasswordIsDefined)
- {
- if (!inCrcStreamSpec)
- {
- if (_options.PasswordIsDefined)
- return E_NOTIMPL;
- numTestMethods = 1;
- }
- }
+ if (numTestMethods > 1 && !inCrcStreamSpec)
+ numTestMethods = 1;
+
+ UInt32 crc = 0;
+ bool crc_IsCalculated = false;
Byte method = 0;
- COutStreamReleaser outStreamReleaser;
+ CFilterCoder::C_OutStream_Releaser outStreamReleaser;
opRes.ExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_Default;
+ opRes.FileTimeWasUsed = false;
for (unsigned i = 0; i < numTestMethods; i++)
{
@@ -164,7 +181,7 @@ HRESULT CAddCommon::Compress(
if (!_cryptoStream)
{
- _cryptoStreamSpec = new CFilterCoder;
+ _cryptoStreamSpec = new CFilterCoder(true);
_cryptoStream = _cryptoStreamSpec;
}
@@ -186,13 +203,32 @@ HRESULT CAddCommon::Compress(
_cryptoStreamSpec->Filter = _filterSpec = new NCrypto::NZip::CEncoder;
_filterSpec->CryptoSetPassword((const Byte *)(const char *)_options.Password, _options.Password.Len());
}
- UInt32 crc = 0;
- RINOK(GetStreamCRC(inStream, crc));
- RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL));
- RINOK(_filterSpec->WriteHeader(outStream, crc));
+
+ UInt32 check;
+
+ // if (inCrcStreamSpec)
+ {
+ if (!crc_IsCalculated)
+ {
+ RINOK(CalcStreamCRC(inStream, crc));
+ crc_IsCalculated = true;
+ RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL));
+ }
+ check = (crc >> 16);
+ }
+ /*
+ else
+ {
+ opRes.FileTimeWasUsed = true;
+ check = (fileTime & 0xFFFF);
+ }
+ */
+
+ RINOK(_filterSpec->WriteHeader_Check16(outStream, (UInt16)check));
}
RINOK(_cryptoStreamSpec->SetOutStream(outStream));
+ RINOK(_cryptoStreamSpec->InitEncoder());
outStreamReleaser.FilterCoder = _cryptoStreamSpec;
}
@@ -250,7 +286,7 @@ HRESULT CAddCommon::Compress(
}
RINOK(CreateCoder(
EXTERNAL_CODECS_LOC_VARS
- methodId, _compressEncoder, true));
+ methodId, true, _compressEncoder));
if (!_compressEncoder)
return E_NOTIMPL;
@@ -284,34 +320,42 @@ HRESULT CAddCommon::Compress(
}
}
+ if (_options.PasswordIsDefined)
+ {
+ RINOK(_cryptoStreamSpec->OutStreamFinish());
+
+ if (_options.IsAesMode)
+ {
+ RINOK(_filterAesSpec->WriteFooter(outStream));
+ }
+ }
+
RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &opRes.PackSize));
- if (inCrcStreamSpec)
+ // if (inCrcStreamSpec)
{
opRes.CRC = inCrcStreamSpec->GetCRC();
opRes.UnpackSize = inCrcStreamSpec->GetSize();
}
+ /*
else
{
opRes.CRC = inSecCrcStreamSpec->GetCRC();
opRes.UnpackSize = inSecCrcStreamSpec->GetSize();
}
+ */
if (_options.PasswordIsDefined)
{
if (opRes.PackSize < opRes.UnpackSize +
- (_options.IsAesMode ? _filterAesSpec->GetHeaderSize() : NCrypto::NZip::kHeaderSize))
+ (_options.IsAesMode ? _filterAesSpec->GetAddPackSize() : NCrypto::NZip::kHeaderSize))
break;
}
else if (opRes.PackSize < opRes.UnpackSize)
break;
}
-
- if (_options.PasswordIsDefined && _options.IsAesMode)
- {
- RINOK(_filterAesSpec->WriteFooter(outStream));
- RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &opRes.PackSize));
- }
+
+
opRes.Method = method;
return S_OK;
}
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.h b/CPP/7zip/Archive/Zip/ZipAddCommon.h
index e4c02db3..1e0c3bfa 100644
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.h
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.h
@@ -26,6 +26,7 @@ struct CCompressingResult
UInt32 CRC;
UInt16 Method;
Byte ExtractVersion;
+ bool FileTimeWasUsed;
};
class CAddCommon
@@ -43,11 +44,16 @@ class CAddCommon
NCrypto::NZip::CEncoder *_filterSpec;
NCrypto::NWzAes::CEncoder *_filterAesSpec;
+ Byte *_buf;
+
+ HRESULT CalcStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC);
public:
CAddCommon(const CCompressionMethodMode &options);
+ ~CAddCommon();
HRESULT Compress(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream, IOutStream *outStream,
+ UInt32 fileTime,
ICompressProgressInfo *progress, CCompressingResult &operationResult);
};
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp
index f556068c..3e29a880 100644
--- a/CPP/7zip/Archive/Zip/ZipHandler.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp
@@ -28,6 +28,8 @@
#include "../Common/ItemNameUtils.h"
#include "../Common/OutStreamWithCRC.h"
+#include "../XzHandler.h"
+
#include "ZipHandler.h"
using namespace NWindows;
@@ -38,7 +40,7 @@ namespace NZip {
static const CMethodId kMethodId_ZipBase = 0x040100;
static const CMethodId kMethodId_BZip2 = 0x040202;
-static const char *kHostOS[] =
+static const char * const kHostOS[] =
{
"FAT"
, "AMIGA"
@@ -62,7 +64,7 @@ static const char *kHostOS[] =
, "OS/X"
};
-static const char *kMethods[] =
+static const char * const kMethods[] =
{
"Store"
, "Shrink"
@@ -91,6 +93,7 @@ static const CIdToNamePair k_MethodIdNamePairs[] =
{
{ NFileHeader::NCompressionMethod::kBZip2, "BZip2" },
{ NFileHeader::NCompressionMethod::kLZMA, "LZMA" },
+ { NFileHeader::NCompressionMethod::kXz, "xz" },
{ NFileHeader::NCompressionMethod::kJpeg, "Jpeg" },
{ NFileHeader::NCompressionMethod::kWavPack, "WavPack" },
{ NFileHeader::NCompressionMethod::kPPMd, "PPMd" }
@@ -156,14 +159,7 @@ CHandler::CHandler()
static AString BytesToString(const CByteBuffer &data)
{
AString s;
- unsigned size = (unsigned)data.Size();
- if (size > 0)
- {
- char *p = s.GetBuffer(size);
- memcpy(p, (const Byte *)data, size);
- p[size] = 0;
- s.ReleaseBuffer();
- }
+ s.SetFrom_CalcLen((const char *)(const Byte *)data, (unsigned)data.Size());
return s;
}
@@ -220,6 +216,14 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = v;
break;
}
+
+ case kpidReadOnly:
+ {
+ if (m_Archive.IsOpen())
+ if (!m_Archive.CanUpdate())
+ prop = true;
+ break;
+ }
}
prop.Detach(value);
COM_TRY_END
@@ -334,12 +338,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidMethod:
{
- UInt16 methodId = item.Method;
+ unsigned id = item.Method;
AString m;
if (item.IsEncrypted())
{
- if (methodId == NFileHeader::NCompressionMethod::kWzAES)
+ if (id == NFileHeader::NCompressionMethod::kWzAES)
{
m += kMethod_AES;
CWzAesExtra aesField;
@@ -349,7 +353,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
s[0] = '-';
ConvertUInt32ToString(((unsigned)aesField.Strength + 1) * 64 , s + 1);
m += s;
- methodId = aesField.Method;
+ id = aesField.Method;
}
}
else if (item.IsStrongEncrypted())
@@ -381,19 +385,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
char temp[16];
const char *s = NULL;
- if (methodId < ARRAY_SIZE(kMethods))
- s = kMethods[methodId];
+ if (id < ARRAY_SIZE(kMethods))
+ s = kMethods[id];
else
{
- s = FindNameForId(k_MethodIdNamePairs, ARRAY_SIZE(k_MethodIdNamePairs), methodId);
+ s = FindNameForId(k_MethodIdNamePairs, ARRAY_SIZE(k_MethodIdNamePairs), id);
if (!s)
{
- ConvertUInt32ToString(methodId, temp);
+ ConvertUInt32ToString(id, temp);
s = temp;
}
}
m += s;
- if (methodId == NFileHeader::NCompressionMethod::kLZMA && item.IsLzmaEOS())
+ if (id == NFileHeader::NCompressionMethod::kLZMA && item.IsLzmaEOS())
m += ":EOS";
}
@@ -507,9 +511,36 @@ HRESULT CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *
return Decoder->Code(inStream, outStream, NULL, outSize, progress);
}
+
+class CXzDecoder:
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ NArchive::NXz::CDecoder _decoder;
+public:
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+
+ MY_UNKNOWN_IMP
+};
+
+HRESULT CXzDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
+{
+ RINOK(_decoder.Decode(inStream, outStream, progress));
+ Int32 opRes = _decoder.Get_Extract_OperationResult();
+ if (opRes == NExtract::NOperationResult::kUnsupportedMethod)
+ return E_NOTIMPL;
+ if (opRes != NExtract::NOperationResult::kOK)
+ return S_FALSE;
+ return S_OK;
+}
+
+
struct CMethodItem
{
- UInt16 ZipMethod;
+ unsigned ZipMethod;
CMyComPtr<ICompressCoder> Coder;
};
@@ -559,12 +590,13 @@ HRESULT CZipDecoder::Decode(
Int32 &res)
{
res = NExtract::NOperationResult::kDataError;
- CInStreamReleaser inStreamReleaser;
+ CFilterCoder::C_InStream_Releaser inStreamReleaser;
bool needCRC = true;
bool wzAesMode = false;
bool pkAesMode = false;
- UInt16 methodId = item.Method;
+ unsigned id = item.Method;
+
if (item.IsEncrypted())
{
if (item.IsStrongEncrypted())
@@ -580,7 +612,7 @@ HRESULT CZipDecoder::Decode(
return S_OK;
}
}
- if (!pkAesMode && methodId == NFileHeader::NCompressionMethod::kWzAES)
+ if (!pkAesMode && id == NFileHeader::NCompressionMethod::kWzAES)
{
CWzAesExtra aesField;
if (item.CentralExtra.GetWzAes(aesField))
@@ -613,6 +645,7 @@ HRESULT CZipDecoder::Decode(
}
CMyComPtr<ICompressFilter> cryptoFilter;
+
if (item.IsEncrypted())
{
if (wzAesMode)
@@ -620,15 +653,18 @@ HRESULT CZipDecoder::Decode(
CWzAesExtra aesField;
if (!item.CentralExtra.GetWzAes(aesField))
return S_OK;
- methodId = aesField.Method;
+ id = aesField.Method;
if (!_wzAesDecoder)
{
_wzAesDecoderSpec = new NCrypto::NWzAes::CDecoder;
_wzAesDecoder = _wzAesDecoderSpec;
}
cryptoFilter = _wzAesDecoder;
- Byte properties = aesField.Strength;
- RINOK(_wzAesDecoderSpec->SetDecoderProperties2(&properties, 1));
+ if (!_wzAesDecoderSpec->SetKeyMode(aesField.Strength))
+ {
+ res = NExtract::NOperationResult::kUnsupportedMethod;
+ return S_OK;
+ }
}
else if (pkAesMode)
{
@@ -648,6 +684,7 @@ HRESULT CZipDecoder::Decode(
}
cryptoFilter = _zipCryptoDecoder;
}
+
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword));
@@ -699,39 +736,41 @@ HRESULT CZipDecoder::Decode(
unsigned m;
for (m = 0; m < methodItems.Size(); m++)
- if (methodItems[m].ZipMethod == methodId)
+ if (methodItems[m].ZipMethod == id)
break;
if (m == methodItems.Size())
{
CMethodItem mi;
- mi.ZipMethod = methodId;
- if (methodId == NFileHeader::NCompressionMethod::kStored)
+ mi.ZipMethod = id;
+ if (id == NFileHeader::NCompressionMethod::kStored)
mi.Coder = new NCompress::CCopyCoder;
- else if (methodId == NFileHeader::NCompressionMethod::kShrunk)
+ else if (id == NFileHeader::NCompressionMethod::kShrunk)
mi.Coder = new NCompress::NShrink::CDecoder;
- else if (methodId == NFileHeader::NCompressionMethod::kImploded)
+ else if (id == NFileHeader::NCompressionMethod::kImploded)
mi.Coder = new NCompress::NImplode::NDecoder::CCoder;
- else if (methodId == NFileHeader::NCompressionMethod::kLZMA)
+ else if (id == NFileHeader::NCompressionMethod::kLZMA)
mi.Coder = new CLzmaDecoder;
- else if (methodId == NFileHeader::NCompressionMethod::kPPMd)
+ else if (id == NFileHeader::NCompressionMethod::kXz)
+ mi.Coder = new CXzDecoder;
+ else if (id == NFileHeader::NCompressionMethod::kPPMd)
mi.Coder = new NCompress::NPpmdZip::CDecoder(true);
else
{
CMethodId szMethodID;
- if (methodId == NFileHeader::NCompressionMethod::kBZip2)
+ if (id == NFileHeader::NCompressionMethod::kBZip2)
szMethodID = kMethodId_BZip2;
else
{
- if (methodId > 0xFF)
+ if (id > 0xFF)
{
res = NExtract::NOperationResult::kUnsupportedMethod;
return S_OK;
}
- szMethodID = kMethodId_ZipBase + (Byte)methodId;
+ szMethodID = kMethodId_ZipBase + (Byte)id;
}
- RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS szMethodID, mi.Coder, false));
+ RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS szMethodID, false, mi.Coder));
if (mi.Coder == 0)
{
@@ -741,6 +780,7 @@ HRESULT CZipDecoder::Decode(
}
m = methodItems.Add(mi);
}
+
ICompressCoder *coder = methodItems[m].Coder;
{
@@ -771,13 +811,23 @@ HRESULT CZipDecoder::Decode(
{
if (!filterStream)
{
- filterStreamSpec = new CFilterCoder;
+ filterStreamSpec = new CFilterCoder(false);
filterStream = filterStreamSpec;
}
+
filterStreamSpec->Filter = cryptoFilter;
+
if (wzAesMode)
{
result = _wzAesDecoderSpec->ReadHeader(inStream);
+ if (result == S_OK)
+ {
+ if (!_wzAesDecoderSpec->Init_and_CheckPassword())
+ {
+ res = NExtract::NOperationResult::kWrongPassword;
+ return S_OK;
+ }
+ }
}
else if (pkAesMode)
{
@@ -785,43 +835,64 @@ HRESULT CZipDecoder::Decode(
if (result == S_OK)
{
bool passwOK;
- result = _pkAesDecoderSpec->CheckPassword(passwOK);
+ result = _pkAesDecoderSpec->Init_and_CheckPassword(passwOK);
if (result == S_OK && !passwOK)
- result = S_FALSE;
+ {
+ res = NExtract::NOperationResult::kWrongPassword;
+ return S_OK;
+ }
}
}
else
{
result = _zipCryptoDecoderSpec->ReadHeader(inStream);
+ if (result == S_OK)
+ {
+ _zipCryptoDecoderSpec->Init_BeforeDecode();
+
+ /* Info-ZIP modification to ZipCrypto format:
+ if bit 3 of the general purpose bit flag is set,
+ it uses high byte of 16-bit File Time.
+ Info-ZIP code probably writes 2 bytes of File Time.
+ We check only 1 byte. */
+
+ // UInt32 v1 = GetUi16(_zipCryptoDecoderSpec->_header + NCrypto::NZip::kHeaderSize - 2);
+ // UInt32 v2 = (item.HasDescriptor() ? (item.Time & 0xFFFF) : (item.Crc >> 16));
+
+ Byte v1 = _zipCryptoDecoderSpec->_header[NCrypto::NZip::kHeaderSize - 1];
+ Byte v2 = (Byte)(item.HasDescriptor() ? (item.Time >> 8) : (item.Crc >> 24));
+
+ if (v1 != v2)
+ {
+ res = NExtract::NOperationResult::kWrongPassword;
+ return S_OK;
+ }
+ }
}
if (result == S_OK)
{
- if (pkAesMode)
- {
- /* 9.31: The BUG in 9.24-9.30 was fixed. pkAes archives didn't work.
- We don't need to call CAesCbcCoder::Init() to reset IV for data. */
- filterStreamSpec->SetInStream_NoSubFilterInit(inStream);
- }
- else
- {
- RINOK(filterStreamSpec->SetInStream(inStream));
- }
inStreamReleaser.FilterCoder = filterStreamSpec;
+ RINOK(filterStreamSpec->SetInStream(inStream));
+
+ /* IFilter::Init() does nothing in all zip crypto filters.
+ So we can call any Initialize function in CFilterCoder. */
+
+ RINOK(filterStreamSpec->Init_NoSubFilterInit());
+ // RINOK(filterStreamSpec->SetOutStreamSize(NULL));
+
inStreamNew = filterStream;
- if (wzAesMode)
- {
- if (!_wzAesDecoderSpec->CheckPasswordVerifyCode())
- result = S_FALSE;
- }
}
}
else
inStreamNew = inStream;
+
if (result == S_OK)
result = coder->Code(inStreamNew, outStream, NULL, &item.Size, compressProgress);
+
if (result == S_FALSE)
return S_OK;
+
if (result == E_NOTIMPL)
{
res = NExtract::NOperationResult::kUnsupportedMethod;
@@ -830,6 +901,7 @@ HRESULT CZipDecoder::Decode(
RINOK(result);
}
+
bool crcOK = true;
bool authOk = true;
if (needCRC)
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h
index 7f1d2eba..c2a362a7 100644
--- a/CPP/7zip/Archive/Zip/ZipHandler.h
+++ b/CPP/7zip/Archive/Zip/ZipHandler.h
@@ -33,7 +33,7 @@ public:
INTERFACE_IInArchive(;)
INTERFACE_IOutArchive(;)
- STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps);
+ STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
DECL_ISetCompressCodecsInfo
diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
index ae58cbe2..f1c8b227 100644
--- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
@@ -34,15 +34,16 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
return S_OK;
}
-static bool IsAsciiString(const UString &s)
+static bool IsSimpleAsciiString(const wchar_t *s)
{
- for (unsigned i = 0; i < s.Len(); i++)
+ for (;;)
{
- wchar_t c = s[i];
+ wchar_t c = *s++;
+ if (c == 0)
+ return true;
if (c < 0x20 || c > 0x7F)
return false;
}
- return true;
}
#define COM_TRY_BEGIN2 try {
@@ -180,11 +181,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (tryUtf8)
{
- unsigned i;
- for (i = 0; i < name.Len() && (unsigned)name[i] < 0x80; i++);
- ui.IsUtf8 = (i != name.Len());
- if (!ConvertUnicodeToUTF8(name, ui.Name))
- return E_INVALIDARG;
+ ui.IsUtf8 = !name.IsAscii();
+ ConvertUnicodeToUTF8(name, ui.Name);
}
if (ui.Name.Len() >= (1 << 16))
@@ -249,10 +247,10 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (!m_ForceAesMode)
options.IsAesMode = thereAreAesUpdates;
- if (!IsAsciiString((BSTR)password))
+ if (!IsSimpleAsciiString(password))
return E_INVALIDARG;
if (password)
- options.Password = UnicodeStringToMultiByte((BSTR)password, CP_OEMCP);
+ options.Password = UnicodeStringToMultiByte((LPCOLESTR)password, CP_OEMCP);
if (options.IsAesMode)
{
if (options.Password.Len() > NCrypto::NWzAes::kPasswordSizeMax)
@@ -297,7 +295,7 @@ static const CMethodIndexToName k_SupportedMethods[] =
{ NFileHeader::NCompressionMethod::kPPMd, "ppmd" }
};
-STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps)
+STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
InitMethodProps();
#ifndef _7ZIP_ST
@@ -318,7 +316,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
UInt32 level = 9;
RINOK(ParsePropToUInt32(name.Ptr(1), prop, level));
_props.Level = level;
- _props.MethodInfo.AddLevelProp(level);
+ _props.MethodInfo.AddProp_Level(level);
}
else if (name == L"m")
{
diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h
index 1391cdf4..c109992c 100644
--- a/CPP/7zip/Archive/Zip/ZipHeader.h
+++ b/CPP/7zip/Archive/Zip/ZipHeader.h
@@ -54,6 +54,8 @@ namespace NFileHeader
kLZMA = 14,
kTerse = 18,
kLz77 = 19,
+
+ kXz = 0x5F,
kJpeg = 0x60,
kWavPack = 0x61,
kPPMd = 0x62,
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
index 345fbf56..6f495305 100644
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -348,7 +348,7 @@ HRESULT CInArchive::FindAndReadMarker(IInStream *stream, const UInt64 *searchLim
return S_FALSE;
}
-HRESULT CInArchive::IncreaseRealPosition(UInt64 addValue)
+HRESULT CInArchive::IncreaseRealPosition(Int64 addValue)
{
return Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position);
}
@@ -439,10 +439,9 @@ void CInArchive::ReadFileName(unsigned size, AString &s)
s.Empty();
return;
}
- char *p = s.GetBuffer(size);
+ char *p = s.GetBuf(size);
SafeReadBytes(p, size);
- p[size] = 0;
- s.ReleaseBuffer();
+ s.ReleaseBuf_CalcLen(size);
}
bool CInArchive::ReadExtra(unsigned extraSize, CExtraBlock &extraBlock,
@@ -556,7 +555,12 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
UInt32 diskStartNumber = 0;
if (!ReadExtra(extraSize, item.LocalExtra, item.Size, item.PackSize,
localHeaderOffset, diskStartNumber))
- return false;
+ {
+ /* Most of archives are OK for Extra. But there are some rare cases
+ that have error. And if error in first item, it can't open archive.
+ So we ignore that error */
+ // return false;
+ }
}
if (!CheckDosTime(item.Time))
{
@@ -650,6 +654,7 @@ HRESULT CInArchive::ReadLocalItemDescriptor(CItemEx &item)
numBytesInBuffer += processedSize;
if (numBytesInBuffer < kDataDescriptorSize)
return S_FALSE;
+
UInt32 i;
for (i = 0; i <= numBytesInBuffer - kDataDescriptorSize; i++)
{
@@ -666,10 +671,11 @@ HRESULT CInArchive::ReadLocalItemDescriptor(CItemEx &item)
item.Crc = Get32(buf + i + 4);
item.PackSize = descriptorPackSize;
item.Size = Get32(buf + i + 12);
- return IncreaseRealPosition(Int64(Int32(0 - (numBytesInBuffer - i - kDataDescriptorSize))));
+ return IncreaseRealPosition((Int64)(Int32)(0 - (numBytesInBuffer - i - kDataDescriptorSize)));
}
}
}
+
packedSize += i;
unsigned j;
for (j = 0; i < numBytesInBuffer; i++, j++)
@@ -1262,7 +1268,10 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *p
(UInt32)ecd64.cdSize != (UInt32)cdSize ||
((UInt32)(ecd64.cdStartOffset) != (UInt32)cdRelatOffset &&
(!items.IsEmpty())))
- return S_FALSE;
+ {
+ // return S_FALSE;
+ HeadersError = true;
+ }
// printf("\nOpen OK");
return S_OK;
diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h
index f6b349b1..734d3bcb 100644
--- a/CPP/7zip/Archive/Zip/ZipIn.h
+++ b/CPP/7zip/Archive/Zip/ZipIn.h
@@ -25,7 +25,7 @@ public:
UInt64 GetLocalFullSize() const
{ return LocalFullHeaderSize + PackSize + (HasDescriptor() ? kDataDescriptorSize : 0); }
UInt64 GetDataPosition() const
- { return LocalHeaderPos + LocalFullHeaderSize; };
+ { return LocalHeaderPos + LocalFullHeaderSize; }
};
struct CInArchiveInfo
@@ -107,7 +107,7 @@ class CInArchive
HRESULT Seek(UInt64 offset);
HRESULT FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
- HRESULT IncreaseRealPosition(UInt64 addValue);
+ HRESULT IncreaseRealPosition(Int64 addValue);
HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize);
void SafeReadBytes(void *data, unsigned size);
diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp
index ae88944d..f2ccc814 100644
--- a/CPP/7zip/Archive/Zip/ZipItem.cpp
+++ b/CPP/7zip/Archive/Zip/ZipItem.cpp
@@ -114,7 +114,7 @@ bool CItem::IsDir() const
case NHostOS::kMVS:
return false; // change it throw kUnknownAttributes;
case NHostOS::kUnix:
- return (highAttrib & NUnixAttrib::kIFDIR) != 0;
+ return ((highAttrib & NUnixAttrib::kIFMT) == NUnixAttrib::kIFDIR);
default:
return false;
}
@@ -130,6 +130,11 @@ UInt32 CItem::GetWinAttrib() const
if (FromCentral)
winAttrib = ExternalAttrib;
break;
+ case NHostOS::kUnix:
+ // do we need to clear 16 low bits in this case?
+ if (FromCentral)
+ winAttrib = ExternalAttrib & 0xFFFF0000;
+ break;
}
if (IsDir()) // test it;
winAttrib |= FILE_ATTRIBUTE_DIRECTORY;
diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h
index d50c3ae9..98afdf1d 100644
--- a/CPP/7zip/Archive/Zip/ZipItem.h
+++ b/CPP/7zip/Archive/Zip/ZipItem.h
@@ -179,9 +179,12 @@ struct CExtraBlock
void RemoveUnknownSubBlocks()
{
- for (int i = SubBlocks.Size() - 1; i >= 0; i--)
+ for (unsigned i = SubBlocks.Size(); i != 0;)
+ {
+ i--;
if (SubBlocks[i].ID != NFileHeader::NExtraID::kWzAES)
SubBlocks.Delete(i);
+ }
}
};
@@ -204,8 +207,8 @@ public:
bool IsUtf8() const { return (Flags & NFileHeader::NFlags::kUtf8) != 0; }
bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kEncrypted) != 0; }
- bool IsStrongEncrypted() const { return IsEncrypted() && (Flags & NFileHeader::NFlags::kStrongEncrypted) != 0; };
- bool IsAesEncrypted() const { return IsEncrypted() && (IsStrongEncrypted() || Method == NFileHeader::NCompressionMethod::kWzAES); };
+ bool IsStrongEncrypted() const { return IsEncrypted() && (Flags & NFileHeader::NFlags::kStrongEncrypted) != 0; }
+ bool IsAesEncrypted() const { return IsEncrypted() && (IsStrongEncrypted() || Method == NFileHeader::NCompressionMethod::kWzAES); }
bool IsLzmaEOS() const { return (Flags & NFileHeader::NFlags::kLzmaEOS) != 0; }
bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; }
@@ -237,6 +240,7 @@ public:
void ClearFlags() { Flags = 0; }
void SetEncrypted(bool encrypted) { SetFlag(NFileHeader::NFlags::kEncrypted, encrypted); }
void SetUtf8(bool isUtf8) { SetFlag(NFileHeader::NFlags::kUtf8, isUtf8); }
+ void SetDescriptorMode(bool useDescriptor) { SetFlag(NFileHeader::NFlags::kDescriptorUsedMask, useDescriptor); }
UINT GetCodePage() const { return CP_OEMCP; }
};
@@ -277,6 +281,7 @@ public:
void GetUnicodeString(const AString &s, UString &res, bool useSpecifiedCodePage, UINT codePage) const
{
bool isUtf8 = IsUtf8();
+ bool ignore_Utf8_Errors = true;
#ifdef _WIN32
if (!isUtf8)
@@ -287,14 +292,15 @@ public:
{
/* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header.
We try to get name as UTF-8.
- Do we need to do it in POSIX version also? */
+ Do we need to do it in POSIX version also? */
isUtf8 = true;
+ ignore_Utf8_Errors = false;
}
}
#endif
if (isUtf8)
- if (ConvertUTF8ToUnicode(s, res))
+ if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors)
return;
MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
}
diff --git a/CPP/7zip/Archive/Zip/ZipOut.h b/CPP/7zip/Archive/Zip/ZipOut.h
index eaaa0320..056d0d09 100644
--- a/CPP/7zip/Archive/Zip/ZipOut.h
+++ b/CPP/7zip/Archive/Zip/ZipOut.h
@@ -63,7 +63,7 @@ public:
HRESULT Create(IOutStream *outStream);
void MoveCurPos(UInt64 distanceToMove);
- UInt64 GetCurPos() const { return m_CurPos; };
+ UInt64 GetCurPos() const { return m_CurPos; }
void SeekToCurPos();
diff --git a/CPP/7zip/Archive/Zip/ZipRegister.cpp b/CPP/7zip/Archive/Zip/ZipRegister.cpp
index 545e76c6..2be783e6 100644
--- a/CPP/7zip/Archive/Zip/ZipRegister.cpp
+++ b/CPP/7zip/Archive/Zip/ZipRegister.cpp
@@ -9,23 +9,18 @@
namespace NArchive {
namespace NZip {
-IMP_CreateArcIn
-IMP_CreateArcOut
-
-static CArcInfo g_ArcInfo =
- { "zip", "zip zipx jar xpi odt ods docx xlsx epub", 0, 1,
- 3 + 4 + 4 + 6,
- {
+static const Byte k_Signature[] = {
4, 0x50, 0x4B, 0x03, 0x04,
4, 0x50, 0x4B, 0x05, 0x06,
- 6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B,
- },
+ 6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B };
+
+REGISTER_ARC_IO(
+ "zip", "zip zipx jar xpi odt ods docx xlsx epub", 0, 1,
+ k_Signature,
0,
NArcInfoFlags::kFindSignature |
NArcInfoFlags::kMultiSignature |
NArcInfoFlags::kUseGlobalOffset,
- REF_CreateArc_Pair, IsArc_Zip };
-
-REGISTER_ARC(Zip)
-
+ IsArc_Zip)
+
}}
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
index 97cce5ac..9a9526cc 100644
--- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
@@ -65,6 +65,7 @@ static void SetFileHeader(
COutArchive &archive,
const CCompressionMethodMode &options,
const CUpdateItem &ui,
+ // bool isSeqMode,
CItemOut &item)
{
item.Size = ui.Size;
@@ -95,6 +96,8 @@ static void SetFileHeader(
item.InternalAttrib = 0; // test it
item.SetEncrypted(!isDir && options.PasswordIsDefined);
+ // item.SetDescriptorMode(isSeqMode);
+
if (isDir)
{
item.ExtractVersion.Version = NFileHeader::NCompressionMethod::kExtractVersion_Dir;
@@ -156,12 +159,14 @@ struct CThreadInfo
bool IsFree;
UInt32 UpdateIndex;
+ UInt32 FileTime;
CThreadInfo(const CCompressionMethodMode &options):
ExitThread(false),
ProgressSpec(0),
OutStreamSpec(0),
- Coder(options)
+ Coder(options),
+ FileTime(0)
{}
HRESULT CreateEvents()
@@ -192,9 +197,11 @@ void CThreadInfo::WaitAndCode()
CompressEvent.Lock();
if (ExitThread)
return;
+
Result = Coder.Compress(
EXTERNAL_CODECS_LOC_VARS
- InStream, OutStream, Progress, CompressingResult);
+ InStream, OutStream, FileTime, Progress, CompressingResult);
+
if (Result == S_OK && Progress)
Result = Progress->SetRatioInfo(&CompressingResult.UnpackSize, &CompressingResult.PackSize);
CompressionCompletedEvent.Set();
@@ -254,7 +261,7 @@ public:
MY_UNKNOWN_IMP
void Create(IProgress *progress, bool inSizeIsMain);
void SetProgressOffset(UInt64 progressOffset);
- HRESULT SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize);
+ HRESULT SetRatioInfo(unsigned index, const UInt64 *inSize, const UInt64 *outSize);
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
@@ -274,16 +281,16 @@ void CMtProgressMixer2::SetProgressOffset(UInt64 progressOffset)
CriticalSection.Leave();
}
-HRESULT CMtProgressMixer2::SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize)
+HRESULT CMtProgressMixer2::SetRatioInfo(unsigned index, const UInt64 *inSize, const UInt64 *outSize)
{
NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
if (index == 0 && RatioProgress)
{
RINOK(RatioProgress->SetRatioInfo(inSize, outSize));
}
- if (inSize != 0)
+ if (inSize)
InSizes[index] = *inSize;
- if (outSize != 0)
+ if (outSize)
OutSizes[index] = *outSize;
UInt64 v = ProgressOffset + (_inSizeIsMain ?
(InSizes[0] + InSizes[1]) :
@@ -332,8 +339,16 @@ static HRESULT UpdateItemOldData(
CItemOut &item,
/* bool izZip64, */
ICompressProgressInfo *progress,
+ IArchiveUpdateCallbackFile *opCallback,
UInt64 &complexity)
{
+ if (opCallback)
+ {
+ RINOK(opCallback->ReportOperation(
+ NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArc,
+ NUpdateNotifyOp::kReplicate))
+ }
+
if (ui.NewProps)
{
if (item.HasDescriptor())
@@ -396,7 +411,8 @@ static HRESULT Update2St(
const CObjectVector<CUpdateItem> &updateItems,
const CCompressionMethodMode *options,
const CByteBuffer *comment,
- IArchiveUpdateCallback *updateCallback)
+ IArchiveUpdateCallback *updateCallback,
+ IArchiveUpdateCallbackFile *opCallback)
{
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
@@ -445,15 +461,37 @@ static HRESULT Update2St(
if (!fileInStream)
return E_INVALIDARG;
+ // bool isSeqMode = false;
+ /*
+ {
+ CMyComPtr<IInStream> inStream2;
+ fileInStream->QueryInterface(IID_IInStream, (void **)&inStream2);
+ isSeqMode = (inStream2 == NULL);
+ }
+ */
+
// file Size can be 64-bit !!!
SetFileHeader(archive, *options, ui, item);
archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, options->IsRealAesMode());
CCompressingResult compressingResult;
CMyComPtr<IOutStream> outStream;
archive.CreateStreamForCompressing(&outStream);
+
RINOK(compressor.Compress(
EXTERNAL_CODECS_LOC_VARS
- fileInStream, outStream, progress, compressingResult));
+ fileInStream, outStream,
+ ui.Time,
+ progress, compressingResult));
+
+ if (compressingResult.FileTimeWasUsed)
+ {
+ /*
+ if (!item.HasDescriptor())
+ return E_FAIL;
+ */
+ item.SetDescriptorMode(true);
+ }
+
SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item);
archive.WriteLocalHeader_And_SeekToNextFile(item);
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
@@ -465,13 +503,14 @@ static HRESULT Update2St(
{
UInt64 complexity = 0;
lps->SendRatio = false;
- RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, complexity));
+ RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity));
lps->SendRatio = true;
lps->ProgressOffset += complexity;
}
items.Add(item);
lps->ProgressOffset += kLocalHeaderSize;
}
+
lps->InSize = unpackSizeTotal;
lps->OutSize = packSizeTotal;
RINOK(lps->SetCur());
@@ -489,6 +528,9 @@ static HRESULT Update2(
const CByteBuffer *comment,
IArchiveUpdateCallback *updateCallback)
{
+ CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
+ updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
+
UInt64 complexity = 0;
UInt64 numFilesToCompress = 0;
UInt64 numBytesToCompress = 0;
@@ -542,6 +584,7 @@ static HRESULT Update2(
numThreads = MAXIMUM_WAIT_OBJECTS;
if (numThreads < 1)
numThreads = 1;
+
const size_t kMemPerThread = (1 << 25);
const size_t kBlockSize = 1 << 16;
@@ -558,7 +601,7 @@ static HRESULT Update2(
{
// fixed for 9.31. bzip2 default is just one thread.
if (options2.NumThreadsWasChanged || method == NFileHeader::NCompressionMethod::kBZip2)
- options2.MethodInfo.AddNumThreadsProp(numThreads);
+ options2.MethodInfo.AddProp_NumThreads(numThreads);
}
}
else
@@ -577,7 +620,7 @@ static HRESULT Update2(
numBZip2Threads = 32;
if (averageNumberOfBlocks < numBZip2Threads)
numBZip2Threads = (UInt32)averageNumberOfBlocks;
- options2.MethodInfo.AddNumThreadsProp(numBZip2Threads);
+ options2.MethodInfo.AddProp_NumThreads(numBZip2Threads);
}
numThreads /= numBZip2Threads;
}
@@ -599,7 +642,7 @@ static HRESULT Update2(
return Update2St(
EXTERNAL_CODECS_LOC_VARS
archive, inArchive,
- inputItems, updateItems, &options2, comment, updateCallback);
+ inputItems, updateItems, &options2, comment, updateCallback, opCallback);
#ifndef _7ZIP_ST
@@ -643,6 +686,7 @@ static HRESULT Update2(
threadInfo.ProgressSpec = new CMtCompressProgress();
threadInfo.Progress = threadInfo.ProgressSpec;
threadInfo.ProgressSpec->Init(&mtCompressProgressMixer, (int)i);
+ threadInfo.FileTime = 0; // fix it !
RINOK(threadInfo.CreateThread());
}
}
@@ -784,7 +828,15 @@ static HRESULT Update2(
DWORD result = ::WaitForMultipleObjects(compressingCompletedEvents.Size(),
&compressingCompletedEvents.Front(), FALSE, INFINITE);
- int t = (int)(result - WAIT_OBJECT_0);
+ if (result == WAIT_FAILED)
+ {
+ DWORD lastError = GetLastError();
+ return lastError != 0 ? lastError : E_FAIL;
+ }
+ unsigned t = (unsigned)(result - WAIT_OBJECT_0);
+ if (t >= compressingCompletedEvents.Size())
+ return E_FAIL;
+
CThreadInfo &threadInfo = threads.Threads[threadIndices[t]];
threadInfo.InStream.Release();
threadInfo.IsFree = true;
@@ -813,7 +865,7 @@ static HRESULT Update2(
}
else
{
- RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, complexity));
+ RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity));
}
items.Add(item);
complexity += kLocalHeaderSize;