mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-07 18:06:55 -06:00
23.01
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
#ifndef ZIP7_INC_STDAFX_H
|
||||
#define ZIP7_INC_STDAFX_H
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1800
|
||||
#pragma warning(disable : 4464) // relative include path contains '..'
|
||||
#endif
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,31 +30,22 @@ namespace NZip {
|
||||
using namespace NFileHeader;
|
||||
|
||||
|
||||
static const UInt32 kLzmaPropsSize = 5;
|
||||
static const UInt32 kLzmaHeaderSize = 4 + kLzmaPropsSize;
|
||||
static const unsigned kLzmaPropsSize = 5;
|
||||
static const unsigned kLzmaHeaderSize = 4 + kLzmaPropsSize;
|
||||
|
||||
class CLzmaEncoder:
|
||||
public ICompressCoder,
|
||||
public ICompressSetCoderProperties,
|
||||
public ICompressSetCoderPropertiesOpt,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
Z7_CLASS_IMP_NOQIB_3(
|
||||
CLzmaEncoder
|
||||
, ICompressCoder
|
||||
, ICompressSetCoderProperties
|
||||
, ICompressSetCoderPropertiesOpt
|
||||
)
|
||||
public:
|
||||
NCompress::NLzma::CEncoder *EncoderSpec;
|
||||
CMyComPtr<ICompressCoder> Encoder;
|
||||
Byte Header[kLzmaHeaderSize];
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
|
||||
STDMETHOD(SetCoderPropertiesOpt)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
|
||||
|
||||
MY_UNKNOWN_IMP2(
|
||||
ICompressSetCoderProperties,
|
||||
ICompressSetCoderPropertiesOpt)
|
||||
};
|
||||
|
||||
STDMETHODIMP CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
|
||||
Z7_COM7F_IMF(CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps))
|
||||
{
|
||||
if (!Encoder)
|
||||
{
|
||||
@@ -64,8 +55,8 @@ STDMETHODIMP CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPV
|
||||
CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
outStreamSpec->Init(Header + 4, kLzmaPropsSize);
|
||||
RINOK(EncoderSpec->SetCoderProperties(propIDs, props, numProps));
|
||||
RINOK(EncoderSpec->WriteCoderProperties(outStream));
|
||||
RINOK(EncoderSpec->SetCoderProperties(propIDs, props, numProps))
|
||||
RINOK(EncoderSpec->WriteCoderProperties(outStream))
|
||||
if (outStreamSpec->GetPos() != kLzmaPropsSize)
|
||||
return E_FAIL;
|
||||
Header[0] = MY_VER_MAJOR;
|
||||
@@ -75,15 +66,15 @@ STDMETHODIMP CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPV
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CLzmaEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
|
||||
Z7_COM7F_IMF(CLzmaEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps))
|
||||
{
|
||||
return EncoderSpec->SetCoderPropertiesOpt(propIDs, props, numProps);
|
||||
}
|
||||
|
||||
STDMETHODIMP CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
|
||||
Z7_COM7F_IMF(CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress))
|
||||
{
|
||||
RINOK(WriteStream(outStream, Header, kLzmaHeaderSize));
|
||||
RINOK(WriteStream(outStream, Header, kLzmaHeaderSize))
|
||||
return Encoder->Code(inStream, outStream, inSize, outSize, progress);
|
||||
}
|
||||
|
||||
@@ -120,7 +111,7 @@ HRESULT CAddCommon::CalcStreamCRC(ISequentialInStream *inStream, UInt32 &resultC
|
||||
for (;;)
|
||||
{
|
||||
UInt32 processed;
|
||||
RINOK(inStream->Read(_buf, kBufSize, &processed));
|
||||
RINOK(inStream->Read(_buf, kBufSize, &processed))
|
||||
if (processed == 0)
|
||||
{
|
||||
resultCRC = CRC_GET_DIGEST(crc);
|
||||
@@ -148,9 +139,9 @@ HRESULT CAddCommon::Set_Pre_CompressionResult(bool inSeqMode, bool outSeqMode, U
|
||||
if (opRes.PackSize < unpackSize)
|
||||
opRes.PackSize = unpackSize;
|
||||
|
||||
Byte method = _options.MethodSequence[0];
|
||||
const Byte method = _options.MethodSequence[0];
|
||||
|
||||
if (method == NCompressionMethod::kStore && !_options.PasswordIsDefined)
|
||||
if (method == NCompressionMethod::kStore && !_options.Password_Defined)
|
||||
opRes.PackSize = unpackSize;
|
||||
|
||||
opRes.CRC = 0;
|
||||
@@ -160,7 +151,7 @@ HRESULT CAddCommon::Set_Pre_CompressionResult(bool inSeqMode, bool outSeqMode, U
|
||||
opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default;
|
||||
opRes.DescriptorMode = outSeqMode;
|
||||
|
||||
if (_options.PasswordIsDefined)
|
||||
if (_options.Password_Defined)
|
||||
{
|
||||
opRes.ExtractVersion = NCompressionMethod::kExtractVersion_ZipCrypto;
|
||||
if (_options.IsAesMode)
|
||||
@@ -202,10 +193,11 @@ HRESULT CAddCommon::Compress(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
ISequentialInStream *inStream, IOutStream *outStream,
|
||||
bool inSeqMode, bool outSeqMode,
|
||||
UInt32 fileTime, UInt64 expectedDataSize,
|
||||
UInt32 fileTime,
|
||||
UInt64 expectedDataSize, bool expectedDataSize_IsConfirmed,
|
||||
ICompressProgressInfo *progress, CCompressingResult &opRes)
|
||||
{
|
||||
opRes.LzmaEos = false;
|
||||
// opRes.LzmaEos = false;
|
||||
|
||||
if (!inStream)
|
||||
{
|
||||
@@ -229,9 +221,11 @@ HRESULT CAddCommon::Compress(
|
||||
}
|
||||
|
||||
inSecCrcStreamSpec->SetStream(inStream);
|
||||
inSecCrcStreamSpec->Init();
|
||||
inSecCrcStreamSpec->SetFullSize(expectedDataSize_IsConfirmed ? expectedDataSize : (UInt64)(Int64)-1);
|
||||
// inSecCrcStreamSpec->Init();
|
||||
|
||||
unsigned numTestMethods = _options.MethodSequence.Size();
|
||||
// numTestMethods != 0
|
||||
|
||||
bool descriptorMode = outSeqMode;
|
||||
|
||||
@@ -240,7 +234,7 @@ HRESULT CAddCommon::Compress(
|
||||
// The descriptor allows to use ZipCrypto check field without CRC (InfoZip's modification).
|
||||
|
||||
if (!outSeqMode)
|
||||
if (inSeqMode && _options.PasswordIsDefined && !_options.IsAesMode)
|
||||
if (inSeqMode && _options.Password_Defined && !_options.IsAesMode)
|
||||
descriptorMode = true;
|
||||
opRes.DescriptorMode = descriptorMode;
|
||||
|
||||
@@ -251,28 +245,27 @@ HRESULT CAddCommon::Compress(
|
||||
UInt32 crc = 0;
|
||||
bool crc_IsCalculated = false;
|
||||
|
||||
Byte method = 0;
|
||||
CFilterCoder::C_OutStream_Releaser outStreamReleaser;
|
||||
opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default;
|
||||
// opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default;
|
||||
|
||||
for (unsigned i = 0; i < numTestMethods; i++)
|
||||
{
|
||||
opRes.LzmaEos = false;
|
||||
opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default;
|
||||
|
||||
inSecCrcStreamSpec->Init();
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
if (inStream2)
|
||||
// if (inStream2)
|
||||
{
|
||||
inSecCrcStreamSpec->Init();
|
||||
RINOK(inStream2->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
RINOK(InStream_SeekToBegin(inStream2))
|
||||
}
|
||||
|
||||
RINOK(outStream->SetSize(0));
|
||||
RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL))
|
||||
RINOK(outStream->SetSize(0))
|
||||
}
|
||||
|
||||
method = _options.MethodSequence[i];
|
||||
opRes.LzmaEos = false;
|
||||
opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default;
|
||||
|
||||
const Byte method = _options.MethodSequence[i];
|
||||
if (method == NCompressionMethod::kStore && descriptorMode)
|
||||
{
|
||||
// we still can create descriptor_mode archives with "Store" method, but they are not good for 100%
|
||||
@@ -281,7 +274,7 @@ HRESULT CAddCommon::Compress(
|
||||
|
||||
bool needCode = true;
|
||||
|
||||
if (_options.PasswordIsDefined)
|
||||
if (_options.Password_Defined)
|
||||
{
|
||||
opRes.ExtractVersion = NCompressionMethod::kExtractVersion_ZipCrypto;
|
||||
|
||||
@@ -298,9 +291,9 @@ HRESULT CAddCommon::Compress(
|
||||
{
|
||||
_cryptoStreamSpec->Filter = _filterAesSpec = new NCrypto::NWzAes::CEncoder;
|
||||
_filterAesSpec->SetKeyMode(_options.AesKeyMode);
|
||||
RINOK(_filterAesSpec->CryptoSetPassword((const Byte *)(const char *)_options.Password, _options.Password.Len()));
|
||||
RINOK(_filterAesSpec->CryptoSetPassword((const Byte *)(const char *)_options.Password, _options.Password.Len()))
|
||||
}
|
||||
RINOK(_filterAesSpec->WriteHeader(outStream));
|
||||
RINOK(_filterAesSpec->WriteHeader(outStream))
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -321,26 +314,26 @@ HRESULT CAddCommon::Compress(
|
||||
{
|
||||
if (!crc_IsCalculated)
|
||||
{
|
||||
RINOK(CalcStreamCRC(inStream, crc));
|
||||
RINOK(CalcStreamCRC(inStream, crc))
|
||||
crc_IsCalculated = true;
|
||||
RINOK(inStream2->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
RINOK(InStream_SeekToBegin(inStream2))
|
||||
inSecCrcStreamSpec->Init();
|
||||
}
|
||||
check = (crc >> 16);
|
||||
}
|
||||
|
||||
RINOK(_filterSpec->WriteHeader_Check16(outStream, (UInt16)check));
|
||||
RINOK(_filterSpec->WriteHeader_Check16(outStream, (UInt16)check))
|
||||
}
|
||||
|
||||
if (method == NCompressionMethod::kStore)
|
||||
{
|
||||
needCode = false;
|
||||
RINOK(_cryptoStreamSpec->Code(inCrcStream, outStream, NULL, NULL, progress));
|
||||
RINOK(_cryptoStreamSpec->Code(inCrcStream, outStream, NULL, NULL, progress))
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(_cryptoStreamSpec->SetOutStream(outStream));
|
||||
RINOK(_cryptoStreamSpec->InitEncoder());
|
||||
RINOK(_cryptoStreamSpec->SetOutStream(outStream))
|
||||
RINOK(_cryptoStreamSpec->InitEncoder())
|
||||
outStreamReleaser.FilterCoder = _cryptoStreamSpec;
|
||||
}
|
||||
}
|
||||
@@ -357,11 +350,11 @@ HRESULT CAddCommon::Compress(
|
||||
_copyCoder = _copyCoderSpec;
|
||||
}
|
||||
CMyComPtr<ISequentialOutStream> outStreamNew;
|
||||
if (_options.PasswordIsDefined)
|
||||
if (_options.Password_Defined)
|
||||
outStreamNew = _cryptoStream;
|
||||
else
|
||||
outStreamNew = outStream;
|
||||
RINOK(_copyCoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress));
|
||||
RINOK(_copyCoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -406,7 +399,7 @@ HRESULT CAddCommon::Compress(
|
||||
}
|
||||
RINOK(CreateCoder_Id(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
methodId, true, _compressEncoder));
|
||||
methodId, true, _compressEncoder))
|
||||
if (!_compressEncoder)
|
||||
return E_NOTIMPL;
|
||||
|
||||
@@ -428,7 +421,7 @@ HRESULT CAddCommon::Compress(
|
||||
COneMethodInfo *oneMethodMain = &_options._methods[0];
|
||||
|
||||
RINOK(oneMethodMain->SetCoderProps(setCoderProps,
|
||||
_options._dataSizeReduceDefined ? &_options._dataSizeReduce : NULL));
|
||||
_options.DataSizeReduce_Defined ? &_options.DataSizeReduce : NULL))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -440,7 +433,7 @@ HRESULT CAddCommon::Compress(
|
||||
opRes.LzmaEos = _isLzmaEos;
|
||||
|
||||
CMyComPtr<ISequentialOutStream> outStreamNew;
|
||||
if (_options.PasswordIsDefined)
|
||||
if (_options.Password_Defined)
|
||||
outStreamNew = _cryptoStream;
|
||||
else
|
||||
outStreamNew = outStream;
|
||||
@@ -452,41 +445,45 @@ HRESULT CAddCommon::Compress(
|
||||
_compressEncoder->QueryInterface(IID_ICompressSetCoderPropertiesOpt, (void **)&optProps);
|
||||
if (optProps)
|
||||
{
|
||||
PROPID propID = NCoderPropID::kExpectedDataSize;
|
||||
const PROPID propID = NCoderPropID::kExpectedDataSize;
|
||||
NWindows::NCOM::CPropVariant prop = (UInt64)expectedDataSize;
|
||||
RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1));
|
||||
RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1))
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
RINOK(_compressEncoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress));
|
||||
RINOK(_compressEncoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress))
|
||||
} catch (...) { return E_FAIL; }
|
||||
break;
|
||||
}
|
||||
} // switch end
|
||||
|
||||
if (_options.PasswordIsDefined)
|
||||
if (_options.Password_Defined)
|
||||
{
|
||||
RINOK(_cryptoStreamSpec->OutStreamFinish());
|
||||
RINOK(_cryptoStreamSpec->OutStreamFinish())
|
||||
}
|
||||
}
|
||||
|
||||
if (_options.PasswordIsDefined)
|
||||
if (_options.Password_Defined)
|
||||
{
|
||||
if (_options.IsAesMode)
|
||||
{
|
||||
RINOK(_filterAesSpec->WriteFooter(outStream));
|
||||
RINOK(_filterAesSpec->WriteFooter(outStream))
|
||||
}
|
||||
}
|
||||
|
||||
RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &opRes.PackSize));
|
||||
RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &opRes.PackSize))
|
||||
|
||||
{
|
||||
opRes.CRC = inSecCrcStreamSpec->GetCRC();
|
||||
opRes.UnpackSize = inSecCrcStreamSpec->GetSize();
|
||||
opRes.Method = method;
|
||||
}
|
||||
|
||||
if (_options.PasswordIsDefined)
|
||||
if (!inSecCrcStreamSpec->WasFinished())
|
||||
return E_FAIL;
|
||||
|
||||
if (_options.Password_Defined)
|
||||
{
|
||||
if (opRes.PackSize < opRes.UnpackSize +
|
||||
(_options.IsAesMode ? _filterAesSpec->GetAddPackSize() : NCrypto::NZip::kHeaderSize))
|
||||
@@ -496,8 +493,6 @@ HRESULT CAddCommon::Compress(
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
opRes.Method = method;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// ZipAddCommon.h
|
||||
|
||||
#ifndef __ZIP_ADD_COMMON_H
|
||||
#define __ZIP_ADD_COMMON_H
|
||||
#ifndef ZIP7_INC_ZIP_ADD_COMMON_H
|
||||
#define ZIP7_INC_ZIP_ADD_COMMON_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../IProgress.h"
|
||||
@@ -68,7 +68,8 @@ public:
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
ISequentialInStream *inStream, IOutStream *outStream,
|
||||
bool inSeqMode, bool outSeqMode,
|
||||
UInt32 fileTime, UInt64 expectedDataSize,
|
||||
UInt32 fileTime,
|
||||
UInt64 expectedDataSize, bool expectedDataSize_IsConfirmed,
|
||||
ICompressProgressInfo *progress, CCompressingResult &opRes);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// CompressionMode.h
|
||||
|
||||
#ifndef __ZIP_COMPRESSION_MODE_H
|
||||
#define __ZIP_COMPRESSION_MODE_H
|
||||
#ifndef ZIP7_INC_ZIP_COMPRESSION_MODE_H
|
||||
#define ZIP7_INC_ZIP_COMPRESSION_MODE_H
|
||||
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
#ifndef Z7_ST
|
||||
#include "../../../Windows/System.h"
|
||||
#endif
|
||||
|
||||
@@ -34,20 +34,26 @@ struct CBaseProps: public CMultiMethodProps
|
||||
struct CCompressionMethodMode: public CBaseProps
|
||||
{
|
||||
CRecordVector<Byte> MethodSequence;
|
||||
bool PasswordIsDefined;
|
||||
AString Password; // _Wipe
|
||||
bool Password_Defined;
|
||||
bool Force_SeqOutMode;
|
||||
bool DataSizeReduce_Defined;
|
||||
UInt64 DataSizeReduce;
|
||||
|
||||
UInt64 _dataSizeReduce;
|
||||
bool _dataSizeReduceDefined;
|
||||
|
||||
bool IsRealAesMode() const { return PasswordIsDefined && IsAesMode; }
|
||||
bool IsRealAesMode() const { return Password_Defined && IsAesMode; }
|
||||
|
||||
CCompressionMethodMode(): PasswordIsDefined(false)
|
||||
CCompressionMethodMode()
|
||||
{
|
||||
_dataSizeReduceDefined = false;
|
||||
_dataSizeReduce = 0;
|
||||
Password_Defined = false;
|
||||
Force_SeqOutMode = false;
|
||||
DataSizeReduce_Defined = false;
|
||||
DataSizeReduce = 0;
|
||||
}
|
||||
|
||||
#ifdef Z7_CPP_IS_SUPPORTED_default
|
||||
CCompressionMethodMode(const CCompressionMethodMode &) = default;
|
||||
CCompressionMethodMode& operator =(const CCompressionMethodMode &) = default;
|
||||
#endif
|
||||
~CCompressionMethodMode() { Password.Wipe_and_Empty(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "../../Compress/CopyCoder.h"
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
#ifdef Z7_EXTERNAL_CODECS
|
||||
#ifndef SUPPORT_LZFSE
|
||||
#define SUPPORT_LZFSE
|
||||
#endif
|
||||
@@ -92,18 +92,20 @@ const char * const kMethodNames1[kNumMethodNames1] =
|
||||
, "BZip2"
|
||||
, NULL
|
||||
, "LZMA"
|
||||
/*
|
||||
, NULL
|
||||
, NULL
|
||||
, NULL
|
||||
, NULL
|
||||
, NULL
|
||||
, "zstd-pk"
|
||||
, "zstd-pk" // deprecated
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
const char * const kMethodNames2[kNumMethodNames2] =
|
||||
{
|
||||
"zstd-wz"
|
||||
"zstd"
|
||||
, "MP3"
|
||||
, "xz"
|
||||
, "Jpeg"
|
||||
@@ -129,6 +131,7 @@ static const CUInt32PCharPair g_HeaderCharacts[] =
|
||||
{
|
||||
{ 0, "Encrypt" },
|
||||
{ 3, "Descriptor" },
|
||||
// { 4, "Enhanced" },
|
||||
// { 5, "Patched" },
|
||||
{ 6, kMethod_StrongCrypto },
|
||||
{ 11, "UTF8" },
|
||||
@@ -221,7 +224,7 @@ static AString BytesToString(const CByteBuffer &data)
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
@@ -343,7 +346,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
|
||||
{
|
||||
*numItems = m_Items.Size();
|
||||
return S_OK;
|
||||
@@ -377,7 +380,7 @@ static bool NtfsUnixTimeToProp(bool fromCentral,
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
@@ -521,7 +524,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
if (extra.GetWzAes(aesField))
|
||||
{
|
||||
m += kMethod_AES;
|
||||
m += '-';
|
||||
m.Add_Minus();
|
||||
m.Add_UInt32(((unsigned)aesField.Strength + 1) * 64);
|
||||
id = aesField.Method;
|
||||
isWzAes = true;
|
||||
@@ -537,7 +540,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
f.AlgId = 0;
|
||||
if (extra.GetStrongCrypto(f))
|
||||
{
|
||||
const char *s = FindNameForId(k_StrongCryptoPairs, ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId);
|
||||
const char *s = FindNameForId(k_StrongCryptoPairs, Z7_ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId);
|
||||
if (s)
|
||||
m += s;
|
||||
else
|
||||
@@ -629,7 +632,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
|
||||
if (flags != 0)
|
||||
{
|
||||
AString s2 = FlagsToString(g_HeaderCharacts, ARRAY_SIZE(g_HeaderCharacts), flags);
|
||||
const AString s2 = FlagsToString(g_HeaderCharacts, Z7_ARRAY_SIZE(g_HeaderCharacts), flags);
|
||||
if (!s2.IsEmpty())
|
||||
{
|
||||
if (!s.IsEmpty())
|
||||
@@ -690,13 +693,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
|
||||
|
||||
/*
|
||||
STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps)
|
||||
Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)
|
||||
{
|
||||
*numProps = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)
|
||||
Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)
|
||||
{
|
||||
UNUSED_VAR(index);
|
||||
*propID = 0;
|
||||
@@ -704,7 +707,7 @@ STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)
|
||||
Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)
|
||||
{
|
||||
*parentType = NParentType::kDir;
|
||||
*parent = (UInt32)(Int32)-1;
|
||||
@@ -720,7 +723,7 @@ STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentTyp
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
|
||||
Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
|
||||
{
|
||||
UNUSED_VAR(index);
|
||||
UNUSED_VAR(propID);
|
||||
@@ -767,13 +770,16 @@ void CHandler::MarkAltStreams(CObjectVector<CItemEx> &items)
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
|
||||
Z7_COM7F_IMF(CHandler::Open(IInStream *inStream,
|
||||
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback))
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
try
|
||||
{
|
||||
Close();
|
||||
m_Archive.Force_ReadLocals_Mode = _force_OpenSeq;
|
||||
// m_Archive.Disable_VolsRead = _force_OpenSeq;
|
||||
// m_Archive.Disable_FindMarker = _force_OpenSeq;
|
||||
HRESULT res = m_Archive.Open(inStream, maxCheckStartPosition, callback, m_Items);
|
||||
if (res != S_OK)
|
||||
{
|
||||
@@ -787,7 +793,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
Z7_COM7F_IMF(CHandler::Close())
|
||||
{
|
||||
m_Items.Clear();
|
||||
m_Archive.Close();
|
||||
@@ -795,25 +801,16 @@ STDMETHODIMP CHandler::Close()
|
||||
}
|
||||
|
||||
|
||||
class CLzmaDecoder:
|
||||
public ICompressCoder,
|
||||
public ICompressSetFinishMode,
|
||||
public ICompressGetInStreamProcessedSize,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
Z7_CLASS_IMP_NOQIB_3(
|
||||
CLzmaDecoder
|
||||
, ICompressCoder
|
||||
, ICompressSetFinishMode
|
||||
, ICompressGetInStreamProcessedSize
|
||||
)
|
||||
public:
|
||||
NCompress::NLzma::CDecoder *DecoderSpec;
|
||||
CMyComPtr<ICompressCoder> Decoder;
|
||||
|
||||
MY_UNKNOWN_IMP2(
|
||||
ICompressSetFinishMode,
|
||||
ICompressGetInStreamProcessedSize)
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
|
||||
STDMETHOD(SetFinishMode)(UInt32 finishMode);
|
||||
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
|
||||
|
||||
CLzmaDecoder();
|
||||
};
|
||||
|
||||
@@ -825,14 +822,14 @@ CLzmaDecoder::CLzmaDecoder()
|
||||
|
||||
static const unsigned kZipLzmaPropsSize = 4 + LZMA_PROPS_SIZE;
|
||||
|
||||
HRESULT CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
|
||||
Z7_COM7F_IMF(CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress))
|
||||
{
|
||||
Byte buf[kZipLzmaPropsSize];
|
||||
RINOK(ReadStream_FALSE(inStream, buf, kZipLzmaPropsSize));
|
||||
RINOK(ReadStream_FALSE(inStream, buf, kZipLzmaPropsSize))
|
||||
if (buf[2] != LZMA_PROPS_SIZE || buf[3] != 0)
|
||||
return E_NOTIMPL;
|
||||
RINOK(DecoderSpec->SetDecoderProperties2(buf + 4, LZMA_PROPS_SIZE));
|
||||
RINOK(DecoderSpec->SetDecoderProperties2(buf + 4, LZMA_PROPS_SIZE))
|
||||
UInt64 inSize2 = 0;
|
||||
if (inSize)
|
||||
{
|
||||
@@ -844,13 +841,13 @@ HRESULT CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *
|
||||
return Decoder->Code(inStream, outStream, inSize ? &inSize2 : NULL, outSize, progress);
|
||||
}
|
||||
|
||||
STDMETHODIMP CLzmaDecoder::SetFinishMode(UInt32 finishMode)
|
||||
Z7_COM7F_IMF(CLzmaDecoder::SetFinishMode(UInt32 finishMode))
|
||||
{
|
||||
DecoderSpec->FinishStream = (finishMode != 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CLzmaDecoder::GetInStreamProcessedSize(UInt64 *value)
|
||||
Z7_COM7F_IMF(CLzmaDecoder::GetInStreamProcessedSize(UInt64 *value))
|
||||
{
|
||||
*value = DecoderSpec->GetInputProcessedSize() + kZipLzmaPropsSize;
|
||||
return S_OK;
|
||||
@@ -888,11 +885,11 @@ class CZipDecoder
|
||||
CLzmaDecoder *lzmaDecoderSpec;
|
||||
public:
|
||||
CZipDecoder():
|
||||
_zipCryptoDecoderSpec(0),
|
||||
_pkAesDecoderSpec(0),
|
||||
_wzAesDecoderSpec(0),
|
||||
filterStreamSpec(0),
|
||||
lzmaDecoderSpec(0)
|
||||
_zipCryptoDecoderSpec(NULL),
|
||||
_pkAesDecoderSpec(NULL),
|
||||
_wzAesDecoderSpec(NULL),
|
||||
filterStreamSpec(NULL),
|
||||
lzmaDecoderSpec(NULL)
|
||||
{}
|
||||
|
||||
HRESULT Decode(
|
||||
@@ -901,7 +898,7 @@ public:
|
||||
ISequentialOutStream *realOutStream,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
ICompressProgressInfo *compressProgress,
|
||||
#ifndef _7ZIP_ST
|
||||
#ifndef Z7_ST
|
||||
UInt32 numThreads, UInt64 memUsage,
|
||||
#endif
|
||||
Int32 &res);
|
||||
@@ -919,7 +916,7 @@ static HRESULT SkipStreamData(ISequentialInStream *stream,
|
||||
for (;;)
|
||||
{
|
||||
size_t size = kBufSize;
|
||||
RINOK(ReadStream(stream, buf, &size));
|
||||
RINOK(ReadStream(stream, buf, &size))
|
||||
if (size == 0)
|
||||
return S_OK;
|
||||
thereAreData = true;
|
||||
@@ -927,25 +924,23 @@ static HRESULT SkipStreamData(ISequentialInStream *stream,
|
||||
if ((packSize - prev) >= (1 << 22))
|
||||
{
|
||||
prev = packSize;
|
||||
RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
|
||||
RINOK(progress->SetRatioInfo(&packSize, &unpackSize))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class COutStreamWithPadPKCS7:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
Z7_CLASS_IMP_NOQIB_1(
|
||||
COutStreamWithPadPKCS7
|
||||
, ISequentialOutStream
|
||||
)
|
||||
CMyComPtr<ISequentialOutStream> _stream;
|
||||
UInt64 _size;
|
||||
UInt64 _padPos;
|
||||
UInt32 _padSize;
|
||||
bool _padFailure;
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
|
||||
void ReleaseStream() { _stream.Release(); }
|
||||
|
||||
@@ -962,7 +957,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
STDMETHODIMP COutStreamWithPadPKCS7::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
Z7_COM7F_IMF(COutStreamWithPadPKCS7::Write(const void *data, UInt32 size, UInt32 *processedSize))
|
||||
{
|
||||
UInt32 written = 0;
|
||||
HRESULT result = S_OK;
|
||||
@@ -1003,7 +998,7 @@ HRESULT CZipDecoder::Decode(
|
||||
ISequentialOutStream *realOutStream,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
ICompressProgressInfo *compressProgress,
|
||||
#ifndef _7ZIP_ST
|
||||
#ifndef Z7_ST
|
||||
UInt32 numThreads, UInt64 memUsage,
|
||||
#endif
|
||||
Int32 &res)
|
||||
@@ -1074,7 +1069,7 @@ HRESULT CZipDecoder::Decode(
|
||||
return S_OK;
|
||||
packSize -= NCrypto::NWzAes::kMacSize;
|
||||
}
|
||||
RINOK(archive.GetItemStream(item, true, packStream));
|
||||
RINOK(archive.GetItemStream(item, true, packStream))
|
||||
if (!packStream)
|
||||
{
|
||||
res = NExtract::NOperationResult::kUnavailable;
|
||||
@@ -1126,7 +1121,7 @@ HRESULT CZipDecoder::Decode(
|
||||
}
|
||||
|
||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||
RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword));
|
||||
RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword))
|
||||
if (!cryptoSetPassword)
|
||||
return E_FAIL;
|
||||
|
||||
@@ -1136,12 +1131,12 @@ HRESULT CZipDecoder::Decode(
|
||||
if (getTextPassword)
|
||||
{
|
||||
CMyComBSTR_Wipe password;
|
||||
RINOK(getTextPassword->CryptoGetTextPassword(&password));
|
||||
RINOK(getTextPassword->CryptoGetTextPassword(&password))
|
||||
AString_Wipe charPassword;
|
||||
if (password)
|
||||
{
|
||||
/*
|
||||
// 22.00: do we need UTF-8 passwords here ?
|
||||
// 22.00: do we need UTF-8 passwords here ?
|
||||
if (item.IsUtf8()) // 22.00
|
||||
{
|
||||
// throw 1;
|
||||
@@ -1226,7 +1221,7 @@ HRESULT CZipDecoder::Decode(
|
||||
szMethodID = kMethodId_ZipBase + (Byte)id;
|
||||
}
|
||||
|
||||
RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS szMethodID, false, mi.Coder));
|
||||
RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS szMethodID, false, mi.Coder))
|
||||
|
||||
if (!mi.Coder)
|
||||
{
|
||||
@@ -1241,13 +1236,13 @@ HRESULT CZipDecoder::Decode(
|
||||
ICompressCoder *coder = mi.Coder;
|
||||
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
#ifndef Z7_ST
|
||||
{
|
||||
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
||||
coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
|
||||
if (setCoderMt)
|
||||
{
|
||||
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
|
||||
RINOK(setCoderMt->SetNumberOfThreads(numThreads))
|
||||
}
|
||||
}
|
||||
// if (memUsage != 0)
|
||||
@@ -1256,7 +1251,7 @@ HRESULT CZipDecoder::Decode(
|
||||
coder->QueryInterface(IID_ICompressSetMemLimit, (void **)&setMemLimit);
|
||||
if (setMemLimit)
|
||||
{
|
||||
RINOK(setMemLimit->SetMemLimit(memUsage));
|
||||
RINOK(setMemLimit->SetMemLimit(memUsage))
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1267,7 +1262,7 @@ HRESULT CZipDecoder::Decode(
|
||||
if (setDecoderProperties)
|
||||
{
|
||||
Byte properties = (Byte)item.Flags;
|
||||
RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1));
|
||||
RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1363,7 +1358,7 @@ HRESULT CZipDecoder::Decode(
|
||||
coder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
|
||||
if (setFinishMode)
|
||||
{
|
||||
RINOK(setFinishMode->SetFinishMode(BoolToUInt(true)));
|
||||
RINOK(setFinishMode->SetFinishMode(BoolToUInt(true)))
|
||||
}
|
||||
|
||||
const UInt64 coderPackSize = limitedStreamSpec->GetRem();
|
||||
@@ -1421,12 +1416,12 @@ HRESULT CZipDecoder::Decode(
|
||||
{
|
||||
readFromFilter = true;
|
||||
inStreamReleaser.FilterCoder = filterStreamSpec;
|
||||
RINOK(filterStreamSpec->SetInStream(inStream));
|
||||
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->Init_NoSubFilterInit())
|
||||
// RINOK(filterStreamSpec->SetOutStreamSize(NULL));
|
||||
}
|
||||
|
||||
@@ -1448,7 +1443,7 @@ HRESULT CZipDecoder::Decode(
|
||||
if (getInStreamProcessedSize && setFinishMode)
|
||||
{
|
||||
UInt64 processed;
|
||||
RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed));
|
||||
RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed))
|
||||
if (processed != (UInt64)(Int64)-1)
|
||||
{
|
||||
if (pkAesMode)
|
||||
@@ -1474,7 +1469,7 @@ HRESULT CZipDecoder::Decode(
|
||||
UInt32 processedSize = 0;
|
||||
if (readInStream)
|
||||
{
|
||||
RINOK(readInStream->ReadUnusedFromInBuf(buf, kBufSize, &processedSize));
|
||||
RINOK(readInStream->ReadUnusedFromInBuf(buf, kBufSize, &processedSize))
|
||||
}
|
||||
if (processedSize > padSize)
|
||||
dataAfterEnd = true;
|
||||
@@ -1532,7 +1527,7 @@ HRESULT CZipDecoder::Decode(
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
RINOK(result);
|
||||
RINOK(result)
|
||||
}
|
||||
|
||||
bool crcOK = true;
|
||||
@@ -1600,66 +1595,59 @@ HRESULT CZipDecoder::Decode(
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback))
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
CZipDecoder myDecoder;
|
||||
UInt64 totalUnPacked = 0, totalPacked = 0;
|
||||
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
||||
const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = m_Items.Size();
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
UInt64 total = 0; // , totalPacked = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
const CItemEx &item = m_Items[allFilesMode ? i : indices[i]];
|
||||
totalUnPacked += item.Size;
|
||||
totalPacked += item.PackSize;
|
||||
total += item.Size;
|
||||
// totalPacked += item.PackSize;
|
||||
}
|
||||
RINOK(extractCallback->SetTotal(totalUnPacked));
|
||||
RINOK(extractCallback->SetTotal(total))
|
||||
|
||||
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
||||
UInt64 currentItemUnPacked, currentItemPacked;
|
||||
CZipDecoder myDecoder;
|
||||
UInt64 cur_Unpacked, cur_Packed;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
for (i = 0; i < numItems; i++,
|
||||
currentTotalUnPacked += currentItemUnPacked,
|
||||
currentTotalPacked += currentItemPacked)
|
||||
for (i = 0;; i++,
|
||||
lps->OutSize += cur_Unpacked,
|
||||
lps->InSize += cur_Packed)
|
||||
{
|
||||
currentItemUnPacked = 0;
|
||||
currentItemPacked = 0;
|
||||
RINOK(lps->SetCur())
|
||||
if (i >= numItems)
|
||||
return S_OK;
|
||||
const UInt32 index = allFilesMode ? i : indices[i];
|
||||
CItemEx item = m_Items[index];
|
||||
cur_Unpacked = item.Size;
|
||||
cur_Packed = item.PackSize;
|
||||
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = currentTotalUnPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
const bool isLocalOffsetOK = m_Archive.IsLocalOffsetOK(item);
|
||||
const bool skip = !isLocalOffsetOK && !item.IsDir();
|
||||
const Int32 askMode = skip ?
|
||||
NExtract::NAskMode::kSkip : testMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
UInt32 index = allFilesMode ? i : indices[i];
|
||||
|
||||
CItemEx item = m_Items[index];
|
||||
bool isLocalOffsetOK = m_Archive.IsLocalOffsetOK(item);
|
||||
bool skip = !isLocalOffsetOK && !item.IsDir();
|
||||
if (skip)
|
||||
askMode = NExtract::NAskMode::kSkip;
|
||||
|
||||
currentItemUnPacked = item.Size;
|
||||
currentItemPacked = item.PackSize;
|
||||
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode))
|
||||
|
||||
if (!isLocalOffsetOK)
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->PrepareOperation(askMode))
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable))
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1668,30 +1656,30 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
if (!item.FromLocal)
|
||||
{
|
||||
bool isAvail = true;
|
||||
HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item, isAvail, headersError);
|
||||
if (res == S_FALSE)
|
||||
const HRESULT hres = m_Archive.Read_LocalItem_After_CdItem(item, isAvail, headersError);
|
||||
if (hres == S_FALSE)
|
||||
{
|
||||
if (item.IsDir() || realOutStream || testMode)
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->PrepareOperation(askMode))
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
isAvail ?
|
||||
NExtract::NOperationResult::kHeadersError :
|
||||
NExtract::NOperationResult::kUnavailable));
|
||||
NExtract::NOperationResult::kUnavailable))
|
||||
}
|
||||
continue;
|
||||
}
|
||||
RINOK(res);
|
||||
RINOK(hres)
|
||||
}
|
||||
|
||||
if (item.IsDir())
|
||||
{
|
||||
// if (!testMode)
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->PrepareOperation(askMode))
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK))
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -1699,19 +1687,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->PrepareOperation(askMode))
|
||||
|
||||
Int32 res;
|
||||
HRESULT hres = myDecoder.Decode(
|
||||
const HRESULT hres = myDecoder.Decode(
|
||||
EXTERNAL_CODECS_VARS
|
||||
m_Archive, item, realOutStream, extractCallback,
|
||||
progress,
|
||||
#ifndef _7ZIP_ST
|
||||
#ifndef Z7_ST
|
||||
_props._numThreads, _props._memUsage_Decompress,
|
||||
#endif
|
||||
res);
|
||||
|
||||
RINOK(hres);
|
||||
RINOK(hres)
|
||||
realOutStream.Release();
|
||||
|
||||
if (res == NExtract::NOperationResult::kOK && headersError)
|
||||
@@ -1720,9 +1708,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
RINOK(extractCallback->SetOperationResult(res))
|
||||
}
|
||||
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = currentTotalUnPacked;
|
||||
return lps->SetCur();
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Zip/Handler.h
|
||||
|
||||
#ifndef __ZIP_HANDLER_H
|
||||
#define __ZIP_HANDLER_H
|
||||
#ifndef ZIP7_INC_ZIP_HANDLER_H
|
||||
#define ZIP7_INC_ZIP_HANDLER_H
|
||||
|
||||
#include "../../../Common/DynamicBuffer.h"
|
||||
#include "../../ICoder.h"
|
||||
@@ -23,46 +23,43 @@ extern const char * const kMethodNames1[kNumMethodNames1];
|
||||
extern const char * const kMethodNames2[kNumMethodNames2];
|
||||
|
||||
|
||||
class CHandler:
|
||||
class CHandler Z7_final:
|
||||
public IInArchive,
|
||||
// public IArchiveGetRawProps,
|
||||
public IOutArchive,
|
||||
public ISetProperties,
|
||||
PUBLIC_ISetCompressCodecsInfo
|
||||
Z7_PUBLIC_ISetCompressCodecsInfo_IFEC
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_QUERYINTERFACE_BEGIN2(IInArchive)
|
||||
// MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
|
||||
MY_QUERYINTERFACE_ENTRY(IOutArchive)
|
||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
||||
QUERY_ENTRY_ISetCompressCodecsInfo
|
||||
MY_QUERYINTERFACE_END
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
INTERFACE_IInArchive(;)
|
||||
// INTERFACE_IArchiveGetRawProps(;)
|
||||
INTERFACE_IOutArchive(;)
|
||||
|
||||
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
|
||||
Z7_COM_QI_BEGIN2(IInArchive)
|
||||
// Z7_COM_QI_ENTRY(IArchiveGetRawProps)
|
||||
Z7_COM_QI_ENTRY(IOutArchive)
|
||||
Z7_COM_QI_ENTRY(ISetProperties)
|
||||
Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC
|
||||
Z7_COM_QI_END
|
||||
Z7_COM_ADDREF_RELEASE
|
||||
|
||||
Z7_IFACE_COM7_IMP(IInArchive)
|
||||
// Z7_IFACE_COM7_IMP(IArchiveGetRawProps)
|
||||
Z7_IFACE_COM7_IMP(IOutArchive)
|
||||
Z7_IFACE_COM7_IMP(ISetProperties)
|
||||
DECL_ISetCompressCodecsInfo
|
||||
|
||||
CHandler();
|
||||
private:
|
||||
CObjectVector<CItemEx> m_Items;
|
||||
CInArchive m_Archive;
|
||||
|
||||
CBaseProps _props;
|
||||
CHandlerTimeOptions TimeOptions;
|
||||
|
||||
int m_MainMethod;
|
||||
bool m_ForceAesMode;
|
||||
|
||||
CHandlerTimeOptions TimeOptions;
|
||||
|
||||
|
||||
bool _removeSfxBlock;
|
||||
bool m_ForceLocal;
|
||||
bool m_ForceUtf8;
|
||||
bool _force_SeqOutMode; // for creation
|
||||
bool _force_OpenSeq;
|
||||
bool _forceCodePage;
|
||||
UInt32 _specifiedCodePage;
|
||||
|
||||
@@ -71,13 +68,15 @@ private:
|
||||
void InitMethodProps()
|
||||
{
|
||||
_props.Init();
|
||||
m_MainMethod = -1;
|
||||
m_ForceAesMode = false;
|
||||
TimeOptions.Init();
|
||||
TimeOptions.Prec = k_PropVar_TimePrec_0;
|
||||
m_MainMethod = -1;
|
||||
m_ForceAesMode = false;
|
||||
_removeSfxBlock = false;
|
||||
m_ForceLocal = false;
|
||||
m_ForceUtf8 = false;
|
||||
_force_SeqOutMode = false;
|
||||
_force_OpenSeq = false;
|
||||
_forceCodePage = false;
|
||||
_specifiedCodePage = CP_OEMCP;
|
||||
}
|
||||
@@ -85,6 +84,9 @@ private:
|
||||
// void MarkAltStreams(CObjectVector<CItemEx> &items);
|
||||
|
||||
HRESULT GetOutProperty(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, PROPVARIANT *value);
|
||||
|
||||
public:
|
||||
CHandler();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -28,7 +28,7 @@ using namespace NTime;
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
|
||||
Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType))
|
||||
{
|
||||
*timeType = TimeOptions.Prec;
|
||||
return S_OK;
|
||||
@@ -79,7 +79,7 @@ static HRESULT GetTime(IArchiveUpdateCallback *callback, unsigned index, PROPID
|
||||
{
|
||||
filetime.dwHighDateTime = filetime.dwLowDateTime = 0;
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(callback->GetProperty(index, propID, &prop));
|
||||
RINOK(callback->GetProperty(index, propID, &prop))
|
||||
if (prop.vt == VT_FILETIME)
|
||||
filetime = prop.filetime;
|
||||
else if (prop.vt != VT_EMPTY)
|
||||
@@ -88,8 +88,8 @@ static HRESULT GetTime(IArchiveUpdateCallback *callback, unsigned index, PROPID
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
|
||||
IArchiveUpdateCallback *callback)
|
||||
Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
|
||||
IArchiveUpdateCallback *callback))
|
||||
{
|
||||
COM_TRY_BEGIN2
|
||||
|
||||
@@ -122,7 +122,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
if (!callback)
|
||||
return E_FAIL;
|
||||
|
||||
RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc));
|
||||
RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc))
|
||||
|
||||
name.Empty();
|
||||
ui.Clear();
|
||||
@@ -147,7 +147,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
{
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(callback->GetProperty(i, kpidAttrib, &prop));
|
||||
RINOK(callback->GetProperty(i, kpidAttrib, &prop))
|
||||
if (prop.vt == VT_EMPTY)
|
||||
ui.Attrib = 0;
|
||||
else if (prop.vt != VT_UI4)
|
||||
@@ -158,7 +158,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(callback->GetProperty(i, kpidPath, &prop));
|
||||
RINOK(callback->GetProperty(i, kpidPath, &prop))
|
||||
if (prop.vt == VT_EMPTY)
|
||||
{
|
||||
// name.Empty();
|
||||
@@ -171,7 +171,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(callback->GetProperty(i, kpidIsDir, &prop));
|
||||
RINOK(callback->GetProperty(i, kpidIsDir, &prop))
|
||||
if (prop.vt == VT_EMPTY)
|
||||
ui.IsDir = false;
|
||||
else if (prop.vt != VT_BOOL)
|
||||
@@ -219,9 +219,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
}
|
||||
*/
|
||||
|
||||
if (TimeOptions.Write_MTime.Val) RINOK (GetTime (callback, i, kpidMTime, ui.Ntfs_MTime));
|
||||
if (TimeOptions.Write_ATime.Val) RINOK (GetTime (callback, i, kpidATime, ui.Ntfs_ATime));
|
||||
if (TimeOptions.Write_CTime.Val) RINOK (GetTime (callback, i, kpidCTime, ui.Ntfs_CTime));
|
||||
if (TimeOptions.Write_MTime.Val) RINOK (GetTime (callback, i, kpidMTime, ui.Ntfs_MTime))
|
||||
if (TimeOptions.Write_ATime.Val) RINOK (GetTime (callback, i, kpidATime, ui.Ntfs_ATime))
|
||||
if (TimeOptions.Write_CTime.Val) RINOK (GetTime (callback, i, kpidCTime, ui.Ntfs_CTime))
|
||||
|
||||
if (TimeOptions.Prec != k_PropVar_TimePrec_DOS)
|
||||
{
|
||||
@@ -325,7 +325,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(callback->GetProperty(i, kpidComment, &prop));
|
||||
RINOK(callback->GetProperty(i, kpidComment, &prop))
|
||||
if (prop.vt == VT_EMPTY)
|
||||
{
|
||||
// ui.Comment.Free();
|
||||
@@ -374,7 +374,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
if (!ui.IsDir)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(callback->GetProperty(i, kpidSize, &prop));
|
||||
RINOK(callback->GetProperty(i, kpidSize, &prop))
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = prop.uhVal.QuadPart;
|
||||
@@ -396,18 +396,18 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
}
|
||||
CCompressionMethodMode options;
|
||||
(CBaseProps &)options = _props;
|
||||
options._dataSizeReduce = largestSize;
|
||||
options._dataSizeReduceDefined = largestSizeDefined;
|
||||
options.DataSizeReduce = largestSize;
|
||||
options.DataSizeReduce_Defined = largestSizeDefined;
|
||||
|
||||
options.PasswordIsDefined = false;
|
||||
options.Password_Defined = false;
|
||||
options.Password.Wipe_and_Empty();
|
||||
if (getTextPassword)
|
||||
{
|
||||
CMyComBSTR_Wipe password;
|
||||
Int32 passwordIsDefined;
|
||||
RINOK(getTextPassword->CryptoGetTextPassword2(&passwordIsDefined, &password));
|
||||
options.PasswordIsDefined = IntToBool(passwordIsDefined);
|
||||
if (options.PasswordIsDefined)
|
||||
RINOK(getTextPassword->CryptoGetTextPassword2(&passwordIsDefined, &password))
|
||||
options.Password_Defined = IntToBool(passwordIsDefined);
|
||||
if (options.Password_Defined)
|
||||
{
|
||||
if (!m_ForceAesMode)
|
||||
options.IsAesMode = thereAreAesUpdates;
|
||||
@@ -439,8 +439,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
{
|
||||
CMethodId methodId;
|
||||
UInt32 numStreams;
|
||||
bool isFilter;
|
||||
if (FindMethod_Index(EXTERNAL_CODECS_VARS methodName, true,
|
||||
methodId, numStreams) < 0)
|
||||
methodId, numStreams, isFilter) < 0)
|
||||
return E_NOTIMPL;
|
||||
if (numStreams != 1)
|
||||
return E_NOTIMPL;
|
||||
@@ -472,6 +473,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
if (mainMethod != NFileHeader::NCompressionMethod::kStore)
|
||||
options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStore);
|
||||
|
||||
options.Force_SeqOutMode = _force_SeqOutMode;
|
||||
|
||||
CUpdateOptions uo;
|
||||
uo.Write_MTime = TimeOptions.Write_MTime.Val;
|
||||
uo.Write_ATime = TimeOptions.Write_ATime.Val;
|
||||
@@ -493,7 +496,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
|
||||
Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
|
||||
{
|
||||
InitMethodProps();
|
||||
|
||||
@@ -540,26 +543,34 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
|
||||
|
||||
else if (name.IsEqualTo("cl"))
|
||||
{
|
||||
RINOK(PROPVARIANT_to_bool(prop, m_ForceLocal));
|
||||
RINOK(PROPVARIANT_to_bool(prop, m_ForceLocal))
|
||||
if (m_ForceLocal)
|
||||
m_ForceUtf8 = false;
|
||||
}
|
||||
else if (name.IsEqualTo("cu"))
|
||||
{
|
||||
RINOK(PROPVARIANT_to_bool(prop, m_ForceUtf8));
|
||||
RINOK(PROPVARIANT_to_bool(prop, m_ForceUtf8))
|
||||
if (m_ForceUtf8)
|
||||
m_ForceLocal = false;
|
||||
}
|
||||
else if (name.IsEqualTo("cp"))
|
||||
{
|
||||
UInt32 cp = CP_OEMCP;
|
||||
RINOK(ParsePropToUInt32(L"", prop, cp));
|
||||
RINOK(ParsePropToUInt32(L"", prop, cp))
|
||||
_forceCodePage = true;
|
||||
_specifiedCodePage = cp;
|
||||
}
|
||||
else if (name.IsEqualTo("rsfx"))
|
||||
{
|
||||
RINOK(PROPVARIANT_to_bool(prop, _removeSfxBlock));
|
||||
RINOK(PROPVARIANT_to_bool(prop, _removeSfxBlock))
|
||||
}
|
||||
else if (name.IsEqualTo("rws"))
|
||||
{
|
||||
RINOK(PROPVARIANT_to_bool(prop, _force_SeqOutMode))
|
||||
}
|
||||
else if (name.IsEqualTo("ros"))
|
||||
{
|
||||
RINOK(PROPVARIANT_to_bool(prop, _force_OpenSeq))
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -573,10 +584,10 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
|
||||
else
|
||||
{
|
||||
bool processed = false;
|
||||
RINOK(TimeOptions.Parse(name, prop, processed));
|
||||
RINOK(TimeOptions.Parse(name, prop, processed))
|
||||
if (!processed)
|
||||
{
|
||||
RINOK(_props.SetProperty(name, prop));
|
||||
RINOK(_props.SetProperty(name, prop))
|
||||
}
|
||||
}
|
||||
// RINOK(_props.MethodInfo.ParseParamsFromPROPVARIANT(name, prop));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// ZipHeader.h
|
||||
|
||||
#ifndef __ARCHIVE_ZIP_HEADER_H
|
||||
#define __ARCHIVE_ZIP_HEADER_H
|
||||
#ifndef ZIP7_INC_ARCHIVE_ZIP_HEADER_H
|
||||
#define ZIP7_INC_ARCHIVE_ZIP_HEADER_H
|
||||
|
||||
#include "../../../Common/MyTypes.h"
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
#include "../IArchive.h"
|
||||
|
||||
#include "ZipIn.h"
|
||||
@@ -28,9 +26,38 @@
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
// (kBufferSize >= kDataDescriptorSize64 + 4)
|
||||
/* we try to use same size of Buffer (1 << 17) for all tasks.
|
||||
it allow to avoid reallocations and cache clearing. */
|
||||
|
||||
static const size_t kSeqBufferSize = (size_t)1 << 14;
|
||||
static const size_t kSeqBufferSize = (size_t)1 << 17;
|
||||
|
||||
/*
|
||||
Open()
|
||||
{
|
||||
_inBufMode = false;
|
||||
ReadVols()
|
||||
FindCd();
|
||||
TryEcd64()
|
||||
SeekToVol()
|
||||
FindMarker()
|
||||
_inBufMode = true;
|
||||
ReadHeaders()
|
||||
_inBufMode = false;
|
||||
ReadCd()
|
||||
FindCd()
|
||||
TryEcd64()
|
||||
TryReadCd()
|
||||
{
|
||||
SeekToVol();
|
||||
_inBufMode = true;
|
||||
}
|
||||
_inBufMode = true;
|
||||
ReadLocals()
|
||||
ReadCdItem()
|
||||
....
|
||||
}
|
||||
FindCd() writes to Buffer without touching (_inBufMode)
|
||||
*/
|
||||
|
||||
/*
|
||||
if (not defined ZIP_SELF_CHECK) : it reads CD and if error in first pass CD reading, it reads LOCALS-CD-MODE
|
||||
@@ -187,11 +214,14 @@ HRESULT CInArchive::Seek_SavePos(UInt64 offset)
|
||||
return Stream->Seek((Int64)offset, STREAM_SEEK_SET, &_streamPos);
|
||||
}
|
||||
|
||||
|
||||
/* SeekToVol() will keep the cached mode, if new volIndex is
|
||||
same Vols.StreamIndex volume, and offset doesn't go out of cached region */
|
||||
|
||||
HRESULT CInArchive::SeekToVol(int volIndex, UInt64 offset)
|
||||
{
|
||||
if (volIndex != Vols.StreamIndex)
|
||||
{
|
||||
InitBuf();
|
||||
if (IsMultiVol && volIndex >= 0)
|
||||
{
|
||||
if ((unsigned)volIndex >= Vols.Streams.Size())
|
||||
@@ -221,12 +251,29 @@ HRESULT CInArchive::SeekToVol(int volIndex, UInt64 offset)
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
InitBuf();
|
||||
}
|
||||
InitBuf();
|
||||
return Seek_SavePos(offset);
|
||||
}
|
||||
|
||||
|
||||
HRESULT CInArchive::AllocateBuffer(size_t size)
|
||||
{
|
||||
if (size <= Buffer.Size())
|
||||
return S_OK;
|
||||
/* in cached mode virtual_pos is not equal to phy_pos (_streamPos)
|
||||
so we change _streamPos and do Seek() to virtual_pos before cache clearing */
|
||||
if (_bufPos != _bufCached)
|
||||
{
|
||||
RINOK(Seek_SavePos(GetVirtStreamPos()))
|
||||
}
|
||||
InitBuf();
|
||||
Buffer.AllocAtLeast(size);
|
||||
if (!Buffer.IsAllocated())
|
||||
return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// ---------- ReadFromCache ----------
|
||||
// reads from cache and from Stream
|
||||
// move to next volume can be allowed if (CanStartNewVol) and only before first byte reading
|
||||
@@ -465,7 +512,7 @@ API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size)
|
||||
{
|
||||
if (extraSize < 4)
|
||||
{
|
||||
// 7-Zip before 9.31 created incorrect WsAES Extra in folder's local headers.
|
||||
// 7-Zip before 9.31 created incorrect WzAES Extra in folder's local headers.
|
||||
// so we return k_IsArc_Res_YES to support such archives.
|
||||
// return k_IsArc_Res_NO; // do we need to support such extra ?
|
||||
return k_IsArc_Res_YES;
|
||||
@@ -508,20 +555,46 @@ static UInt32 IsArc_Zip_2(const Byte *p, size_t size, bool isFinal)
|
||||
|
||||
|
||||
|
||||
MY_NO_INLINE
|
||||
static const Byte *FindPK(const Byte *p, const Byte *limit)
|
||||
/* FindPK_4() is allowed to access data up to and including &limit[3].
|
||||
limit[4] access is not allowed.
|
||||
return:
|
||||
(return_ptr < limit) : "PK" was found at (return_ptr)
|
||||
(return_ptr >= limit) : limit was reached or crossed. So no "PK" found before limit
|
||||
*/
|
||||
Z7_NO_INLINE
|
||||
static const Byte *FindPK_4(const Byte *p, const Byte *limit)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
Byte b0;
|
||||
b0 = p[0]; if (p >= limit) return p; p++; if (b0 == 0x50) break;
|
||||
b0 = p[0]; if (p >= limit) return p; p++; if (b0 == 0x50) break;
|
||||
if (p >= limit)
|
||||
return limit;
|
||||
Byte b = p[1];
|
||||
if (b == 0x4B) { if (p[0] == 0x50) { return p; } p += 1; break; }
|
||||
if (b == 0x50) { if (p[2] == 0x4B) { return p + 1; } p += 2; break; }
|
||||
b = p[3];
|
||||
p += 4;
|
||||
if (b == 0x4B) { if (p[-2]== 0x50) { return p - 2; } p -= 1; break; }
|
||||
if (b == 0x50) { if (p[0] == 0x4B) { return p - 1; } break; }
|
||||
}
|
||||
if (p[0] == 0x4B)
|
||||
}
|
||||
/*
|
||||
for (;;)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (p >= limit)
|
||||
return limit;
|
||||
if (*p++ == 0x50) break;
|
||||
if (*p++ == 0x50) break;
|
||||
if (*p++ == 0x50) break;
|
||||
if (*p++ == 0x50) break;
|
||||
}
|
||||
if (*p == 0x4B)
|
||||
return p - 1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -554,7 +627,7 @@ HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
|
||||
if (searchLimit && *searchLimit == 0)
|
||||
{
|
||||
Byte startBuf[kMarkerSize];
|
||||
RINOK(ReadFromCache_FALSE(startBuf, kMarkerSize));
|
||||
RINOK(ReadFromCache_FALSE(startBuf, kMarkerSize))
|
||||
|
||||
UInt32 marker = Get32(startBuf);
|
||||
_signature = marker;
|
||||
@@ -562,7 +635,7 @@ HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
|
||||
if ( marker == NSignature::kNoSpan
|
||||
|| marker == NSignature::kSpan)
|
||||
{
|
||||
RINOK(ReadFromCache_FALSE(startBuf, kMarkerSize));
|
||||
RINOK(ReadFromCache_FALSE(startBuf, kMarkerSize))
|
||||
_signature = Get32(startBuf);
|
||||
}
|
||||
|
||||
@@ -579,16 +652,12 @@ HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
const size_t kCheckSize = (size_t)1 << 16; // must be smaller than kBufSize
|
||||
const size_t kBufSize = (size_t)1 << 17; // must be larger than kCheckSize
|
||||
// zip specification: (_zip_header_size < (1 << 16))
|
||||
// so we need such size to check header
|
||||
const size_t kCheckSize = (size_t)1 << 16;
|
||||
const size_t kBufSize = (size_t)1 << 17; // (kBufSize must be > kCheckSize)
|
||||
|
||||
if (Buffer.Size() < kBufSize)
|
||||
{
|
||||
InitBuf();
|
||||
Buffer.AllocAtLeast(kBufSize);
|
||||
if (!Buffer.IsAllocated())
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
RINOK(AllocateBuffer(kBufSize))
|
||||
|
||||
_inBufMode = true;
|
||||
|
||||
@@ -596,12 +665,13 @@ HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
RINOK(LookAhead(kBufSize));
|
||||
RINOK(LookAhead(kBufSize))
|
||||
|
||||
const size_t avail = GetAvail();
|
||||
|
||||
size_t limitPos;
|
||||
const bool isFinished = (avail != kBufSize);
|
||||
// (avail > kBufSize) is possible, if (Buffer.Size() > kBufSize)
|
||||
const bool isFinished = (avail < kBufSize);
|
||||
if (isFinished)
|
||||
{
|
||||
const unsigned kMinAllowed = 4;
|
||||
@@ -618,7 +688,7 @@ HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
|
||||
if (!s.Stream)
|
||||
break;
|
||||
|
||||
RINOK(s.SeekToStart());
|
||||
RINOK(s.SeekToStart())
|
||||
|
||||
InitBuf();
|
||||
Vols.StreamIndex++;
|
||||
@@ -651,11 +721,15 @@ HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
|
||||
|
||||
for (;; p++)
|
||||
{
|
||||
p = FindPK(p, limit);
|
||||
p = FindPK_4(p, limit);
|
||||
if (p >= limit)
|
||||
break;
|
||||
const size_t rem = (size_t)(pStart + avail - p);
|
||||
UInt32 res = IsArc_Zip_2(p, rem, isFinished);
|
||||
size_t rem = (size_t)(pStart + avail - p);
|
||||
/* 22.02 : we limit check size with kCheckSize to be consistent for
|
||||
any different combination of _bufPos in Buffer and size of Buffer. */
|
||||
if (rem > kCheckSize)
|
||||
rem = kCheckSize;
|
||||
const UInt32 res = IsArc_Zip_2(p, rem, isFinished);
|
||||
if (res != k_IsArc_Res_NO)
|
||||
{
|
||||
if (rem < kMarkerSize)
|
||||
@@ -689,7 +763,7 @@ HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
|
||||
{
|
||||
progressPrev = _cnt;
|
||||
// const UInt64 numFiles64 = 0;
|
||||
RINOK(Callback->SetCompleted(NULL, &_cnt));
|
||||
RINOK(Callback->SetCompleted(NULL, &_cnt))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -734,6 +808,8 @@ HRESULT CInArchive::IncreaseRealPosition(UInt64 offset, bool &isFinished)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// cache is empty
|
||||
|
||||
if (!IsMultiVol)
|
||||
{
|
||||
_cnt += offset;
|
||||
@@ -767,7 +843,7 @@ HRESULT CInArchive::IncreaseRealPosition(UInt64 offset, bool &isFinished)
|
||||
_cnt += offset;
|
||||
return Stream->Seek((Int64)offset, STREAM_SEEK_CUR, &_streamPos);
|
||||
}
|
||||
RINOK(Seek_SavePos(s.Size));
|
||||
RINOK(Seek_SavePos(s.Size))
|
||||
offset -= rem;
|
||||
_cnt += rem;
|
||||
}
|
||||
@@ -787,7 +863,7 @@ HRESULT CInArchive::IncreaseRealPosition(UInt64 offset, bool &isFinished)
|
||||
return S_OK;
|
||||
}
|
||||
Stream = s2.Stream;
|
||||
RINOK(Seek_SavePos(0));
|
||||
RINOK(Seek_SavePos(0))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -847,7 +923,7 @@ HRESULT CInArchive::LookAhead(size_t minRequired)
|
||||
if (!s.Stream)
|
||||
return S_OK;
|
||||
|
||||
RINOK(s.SeekToStart());
|
||||
RINOK(s.SeekToStart())
|
||||
|
||||
Vols.StreamIndex++;
|
||||
_streamPos = 0;
|
||||
@@ -957,7 +1033,7 @@ HRESULT CInArchive::Skip64(UInt64 num, unsigned numFiles)
|
||||
if (Callback)
|
||||
{
|
||||
const UInt64 numFiles64 = numFiles;
|
||||
RINOK(Callback->SetCompleted(&numFiles64, &_cnt));
|
||||
RINOK(Callback->SetCompleted(&numFiles64, &_cnt))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1000,6 +1076,7 @@ bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlo
|
||||
const UInt32 pair = ReadUInt32();
|
||||
subBlock.ID = (pair & 0xFFFF);
|
||||
unsigned size = (unsigned)(pair >> 16);
|
||||
// const unsigned origSize = size;
|
||||
|
||||
extraSize -= 4;
|
||||
|
||||
@@ -1068,13 +1145,15 @@ bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlo
|
||||
}
|
||||
}
|
||||
|
||||
// we can ignore errors, when some zip archiver still write all fields to zip64 extra in local header
|
||||
// if (&& (cdItem || !isOK || origSize != 8 * 3 + 4 || size != 8 * 1 + 4))
|
||||
if (!isOK || size != 0)
|
||||
{
|
||||
HeadersWarning = true;
|
||||
extra.Error = true;
|
||||
extra.IsZip64_Error = true;
|
||||
Skip(size);
|
||||
}
|
||||
Skip(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1092,7 +1171,7 @@ bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlo
|
||||
{
|
||||
ExtraMinorError = true;
|
||||
extra.MinorError = true;
|
||||
// 7-Zip before 9.31 created incorrect WsAES Extra in folder's local headers.
|
||||
// 7-Zip before 9.31 created incorrect WzAES Extra in folder's local headers.
|
||||
// so we don't return false, but just set warning flag
|
||||
// return false;
|
||||
Skip(extraSize);
|
||||
@@ -1184,9 +1263,10 @@ static bool FlagsAreSame(const CItem &i1, const CItem &i2_cd)
|
||||
mask &= 0x7FFF;
|
||||
}
|
||||
|
||||
// we can ignore utf8 flag, if name is ascii
|
||||
// we can ignore utf8 flag, if name is ascii, or if only cdItem has utf8 flag
|
||||
if (mask & NFileHeader::NFlags::kUtf8)
|
||||
if (i1.Name.IsAscii() && i2_cd.Name.IsAscii())
|
||||
if ((i1.Name.IsAscii() && i2_cd.Name.IsAscii())
|
||||
|| (i2_cd.Flags & NFileHeader::NFlags::kUtf8))
|
||||
mask &= ~NFileHeader::NFlags::kUtf8;
|
||||
|
||||
// some bad archive in rare case can use descriptor without descriptor flag in Central Dir
|
||||
@@ -1270,11 +1350,8 @@ static bool AreItemsEqual(const CItemEx &localItem, const CItemEx &cdItem)
|
||||
}
|
||||
|
||||
|
||||
HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail, bool &headersError)
|
||||
HRESULT CInArchive::Read_LocalItem_After_CdItem(CItemEx &item, bool &isAvail, bool &headersError)
|
||||
{
|
||||
InitBuf();
|
||||
_inBufMode = false;
|
||||
|
||||
isAvail = true;
|
||||
headersError = false;
|
||||
if (item.FromLocal)
|
||||
@@ -1315,13 +1392,16 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail, bool
|
||||
}
|
||||
}
|
||||
|
||||
RINOK(Seek_SavePos(offset));
|
||||
|
||||
/*
|
||||
// we can check buf mode
|
||||
_inBufMode = false;
|
||||
RINOK(Seek_SavePos(offset))
|
||||
InitBuf();
|
||||
/*
|
||||
// we can use buf mode with small buffer to reduce
|
||||
// the number of Read() calls in ReadLocalItem()
|
||||
_inBufMode = true;
|
||||
Buffer.AllocAtLeast(1 << 10);
|
||||
Buffer.Alloc(1 << 10);
|
||||
if (!Buffer.IsAllocated())
|
||||
return E_OUTOFMEMORY;
|
||||
*/
|
||||
|
||||
CItemEx localItem;
|
||||
@@ -1405,7 +1485,7 @@ HRESULT CInArchive::FindDescriptor(CItemEx &item, unsigned numFiles)
|
||||
|
||||
// size_t processedSize;
|
||||
CanStartNewVol = true;
|
||||
RINOK(LookAhead(descriptorSize4));
|
||||
RINOK(LookAhead(descriptorSize4))
|
||||
const size_t avail = GetAvail();
|
||||
|
||||
if (avail < descriptorSize4)
|
||||
@@ -1429,7 +1509,7 @@ HRESULT CInArchive::FindDescriptor(CItemEx &item, unsigned numFiles)
|
||||
// descriptor signature field is Info-ZIP's extension to pkware Zip specification.
|
||||
// New ZIP specification also allows descriptorSignature.
|
||||
|
||||
p = FindPK(p, limit + 1);
|
||||
p = FindPK_4(p, limit + 1);
|
||||
if (p > limit)
|
||||
break;
|
||||
|
||||
@@ -1487,7 +1567,7 @@ HRESULT CInArchive::FindDescriptor(CItemEx &item, unsigned numFiles)
|
||||
{
|
||||
progressPrev = _cnt;
|
||||
const UInt64 numFiles64 = numFiles;
|
||||
RINOK(Callback->SetCompleted(&numFiles64, &_cnt));
|
||||
RINOK(Callback->SetCompleted(&numFiles64, &_cnt))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1501,7 +1581,7 @@ HRESULT CInArchive::CheckDescriptor(const CItemEx &item)
|
||||
// pkzip's version without descriptor signature is not supported
|
||||
|
||||
bool isFinished = false;
|
||||
RINOK(IncreaseRealPosition(item.PackSize, isFinished));
|
||||
RINOK(IncreaseRealPosition(item.PackSize, isFinished))
|
||||
if (isFinished)
|
||||
return S_FALSE;
|
||||
|
||||
@@ -1548,7 +1628,7 @@ HRESULT CInArchive::CheckDescriptor(const CItemEx &item)
|
||||
}
|
||||
|
||||
|
||||
HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item)
|
||||
HRESULT CInArchive::Read_LocalItem_After_CdItem_Full(CItemEx &item)
|
||||
{
|
||||
if (item.FromLocal)
|
||||
return S_OK;
|
||||
@@ -1556,7 +1636,7 @@ HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item)
|
||||
{
|
||||
bool isAvail = true;
|
||||
bool headersError = false;
|
||||
RINOK(ReadLocalItemAfterCdItem(item, isAvail, headersError));
|
||||
RINOK(Read_LocalItem_After_CdItem(item, isAvail, headersError))
|
||||
if (headersError)
|
||||
return S_FALSE;
|
||||
if (item.HasDescriptor())
|
||||
@@ -1606,14 +1686,22 @@ HRESULT CInArchive::ReadCdItem(CItemEx &item)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
TryEcd64()
|
||||
(_inBufMode == false) is expected here
|
||||
so TryEcd64() can't change the Buffer.
|
||||
if (Ecd64 is not covered by cached region),
|
||||
TryEcd64() can change cached region ranges (_bufCached, _bufPos) and _streamPos.
|
||||
*/
|
||||
|
||||
HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo)
|
||||
{
|
||||
if (offset >= ((UInt64)1 << 63))
|
||||
return S_FALSE;
|
||||
Byte buf[kEcd64_FullSize];
|
||||
|
||||
RINOK(SeekToVol(Vols.StreamIndex, offset));
|
||||
RINOK(ReadFromCache_FALSE(buf, kEcd64_FullSize));
|
||||
RINOK(SeekToVol(Vols.StreamIndex, offset))
|
||||
RINOK(ReadFromCache_FALSE(buf, kEcd64_FullSize))
|
||||
|
||||
if (Get32(buf) != NSignature::kEcd64)
|
||||
return S_FALSE;
|
||||
@@ -1625,6 +1713,9 @@ HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo)
|
||||
}
|
||||
|
||||
|
||||
/* FindCd() doesn't use previous cached region,
|
||||
but it uses Buffer. So it sets new cached region */
|
||||
|
||||
HRESULT CInArchive::FindCd(bool checkOffsetMode)
|
||||
{
|
||||
CCdInfo &cdInfo = Vols.ecd;
|
||||
@@ -1635,7 +1726,7 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode)
|
||||
// So here we don't use cache data from previous operations .
|
||||
|
||||
InitBuf();
|
||||
RINOK(Stream->Seek(0, STREAM_SEEK_END, &endPos));
|
||||
RINOK(InStream_GetSize_SeekToEnd(Stream, endPos))
|
||||
_streamPos = endPos;
|
||||
|
||||
// const UInt32 kBufSizeMax2 = ((UInt32)1 << 16) + kEcdSize + kEcd64Locator_Size + kEcd64_FullSize;
|
||||
@@ -1646,15 +1737,9 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode)
|
||||
return S_FALSE;
|
||||
// CByteArr byteBuffer(bufSize);
|
||||
|
||||
if (Buffer.Size() < kBufSizeMax)
|
||||
{
|
||||
// InitBuf();
|
||||
Buffer.AllocAtLeast(kBufSizeMax);
|
||||
if (!Buffer.IsAllocated())
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
RINOK(AllocateBuffer(kBufSizeMax))
|
||||
|
||||
RINOK(Seek_SavePos(endPos - bufSize));
|
||||
RINOK(Seek_SavePos(endPos - bufSize))
|
||||
|
||||
size_t processed = bufSize;
|
||||
HRESULT res = ReadStream(Stream, Buffer, &processed);
|
||||
@@ -1799,14 +1884,14 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdIn
|
||||
// _startLocalFromCd_Disk = (UInt32)(Int32)-1;
|
||||
// _startLocalFromCd_Offset = (UInt64)(Int64)-1;
|
||||
|
||||
RINOK(SeekToVol(IsMultiVol ? (int)cdInfo.CdDisk : -1, cdOffset));
|
||||
RINOK(SeekToVol(IsMultiVol ? (int)cdInfo.CdDisk : -1, cdOffset))
|
||||
|
||||
_inBufMode = true;
|
||||
_cnt = 0;
|
||||
|
||||
if (Callback)
|
||||
{
|
||||
RINOK(Callback->SetTotal(&cdInfo.NumEntries, IsMultiVol ? &Vols.TotalBytesSize : NULL));
|
||||
RINOK(Callback->SetTotal(&cdInfo.NumEntries, IsMultiVol ? &Vols.TotalBytesSize : NULL))
|
||||
}
|
||||
UInt64 numFileExpected = cdInfo.NumEntries;
|
||||
const UInt64 *totalFilesPtr = &numFileExpected;
|
||||
@@ -1820,7 +1905,7 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdIn
|
||||
CanStartNewVol = false;
|
||||
{
|
||||
CItemEx cdItem;
|
||||
RINOK(ReadCdItem(cdItem));
|
||||
RINOK(ReadCdItem(cdItem))
|
||||
|
||||
/*
|
||||
if (cdItem.Disk < _startLocalFromCd_Disk ||
|
||||
@@ -1854,10 +1939,10 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdIn
|
||||
else
|
||||
while (numFiles > numFileExpected)
|
||||
numFileExpected += (UInt32)1 << 16;
|
||||
RINOK(Callback->SetTotal(totalFilesPtr, NULL));
|
||||
RINOK(Callback->SetTotal(totalFilesPtr, NULL))
|
||||
}
|
||||
|
||||
RINOK(Callback->SetCompleted(&numFiles, &_cnt));
|
||||
RINOK(Callback->SetCompleted(&numFiles, &_cnt))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1900,7 +1985,7 @@ HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt32 &cdDisk, UInt64
|
||||
|
||||
if (!Vols.ecd_wasRead)
|
||||
{
|
||||
RINOK(FindCd(checkOffsetMode));
|
||||
RINOK(FindCd(checkOffsetMode))
|
||||
}
|
||||
|
||||
CCdInfo &cdInfo = Vols.ecd;
|
||||
@@ -2004,7 +2089,7 @@ HRESULT CInArchive::ReadLocals(CObjectVector<CItemEx> &items)
|
||||
|
||||
if (Callback)
|
||||
{
|
||||
RINOK(Callback->SetTotal(NULL, IsMultiVol ? &Vols.TotalBytesSize : NULL));
|
||||
RINOK(Callback->SetTotal(NULL, IsMultiVol ? &Vols.TotalBytesSize : NULL))
|
||||
}
|
||||
|
||||
while (_signature == NSignature::kLocalFileHeader)
|
||||
@@ -2023,14 +2108,14 @@ HRESULT CInArchive::ReadLocals(CObjectVector<CItemEx> &items)
|
||||
|
||||
if (item.HasDescriptor())
|
||||
{
|
||||
RINOK(FindDescriptor(item, items.Size()));
|
||||
RINOK(FindDescriptor(item, items.Size()))
|
||||
isFinished = !item.DescriptorWasRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item.PackSize >= ((UInt64)1 << 62))
|
||||
throw CUnexpectEnd();
|
||||
RINOK(IncreaseRealPosition(item.PackSize, isFinished));
|
||||
RINOK(IncreaseRealPosition(item.PackSize, isFinished))
|
||||
}
|
||||
|
||||
items.Add(item);
|
||||
@@ -2054,7 +2139,7 @@ HRESULT CInArchive::ReadLocals(CObjectVector<CItemEx> &items)
|
||||
{
|
||||
progressPrev = _cnt;
|
||||
const UInt64 numFiles = items.Size();
|
||||
RINOK(Callback->SetCompleted(&numFiles, &_cnt));
|
||||
RINOK(Callback->SetCompleted(&numFiles, &_cnt))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2072,7 +2157,7 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
|
||||
UString name;
|
||||
{
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
RINOK(volCallback->GetProperty(kpidName, &prop));
|
||||
RINOK(volCallback->GetProperty(kpidName, &prop))
|
||||
if (prop.vt != VT_BSTR)
|
||||
return S_OK;
|
||||
name = prop.bstrVal;
|
||||
@@ -2235,11 +2320,8 @@ HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback,
|
||||
}
|
||||
}
|
||||
|
||||
UInt64 size;
|
||||
UInt64 pos;
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &pos));
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_END, &size));
|
||||
RINOK(stream->Seek((Int64)pos, STREAM_SEEK_SET, NULL));
|
||||
UInt64 pos, size;
|
||||
RINOK(InStream_GetPos_GetSize(stream, pos, size))
|
||||
|
||||
while (i >= Vols.Streams.Size())
|
||||
Vols.Streams.AddNew();
|
||||
@@ -2270,7 +2352,7 @@ HRESULT CInArchive::ReadVols()
|
||||
if (!volCallback)
|
||||
return S_OK;
|
||||
|
||||
RINOK(Vols.ParseArcName(volCallback));
|
||||
RINOK(Vols.ParseArcName(volCallback))
|
||||
|
||||
// const int startZIndex = Vols.StartVolIndex;
|
||||
|
||||
@@ -2324,7 +2406,7 @@ HRESULT CInArchive::ReadVols()
|
||||
if (cdDisk != zipDisk)
|
||||
{
|
||||
// get volumes required for cd.
|
||||
RINOK(ReadVols2(volCallback, (unsigned)cdDisk, zipDisk, zipDisk, 0, numMissingVols));
|
||||
RINOK(ReadVols2(volCallback, (unsigned)cdDisk, zipDisk, zipDisk, 0, numMissingVols))
|
||||
if (numMissingVols != 0)
|
||||
{
|
||||
// cdOK = false;
|
||||
@@ -2352,7 +2434,7 @@ HRESULT CInArchive::ReadVols()
|
||||
{
|
||||
// get volumes that were no requested still
|
||||
const unsigned kNumMissingVolsMax = 1 << 12;
|
||||
RINOK(ReadVols2(volCallback, 0, cdDisk < 0 ? -1 : cdDisk, zipDisk, kNumMissingVolsMax, numMissingVols));
|
||||
RINOK(ReadVols2(volCallback, 0, cdDisk < 0 ? -1 : cdDisk, zipDisk, kNumMissingVolsMax, numMissingVols))
|
||||
}
|
||||
|
||||
// if (Vols.StartVolIndex >= 0)
|
||||
@@ -2364,7 +2446,7 @@ HRESULT CInArchive::ReadVols()
|
||||
|| !Vols.Streams[(unsigned)Vols.StartVolIndex].Stream)
|
||||
{
|
||||
// we get volumes starting from StartVolIndex, if they we not requested before know the volume index (if FindCd() was ok)
|
||||
RINOK(ReadVols2(volCallback, (unsigned)Vols.StartVolIndex, zipDisk, zipDisk, 0, numMissingVols));
|
||||
RINOK(ReadVols2(volCallback, (unsigned)Vols.StartVolIndex, zipDisk, zipDisk, 0, numMissingVols))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2377,7 +2459,7 @@ HRESULT CInArchive::ReadVols()
|
||||
if (zipDisk >= 0)
|
||||
{
|
||||
// we create item in Streams for ZipStream, if we know the volume index (if FindCd() was ok)
|
||||
RINOK(ReadVols2(volCallback, (unsigned)zipDisk, zipDisk + 1, zipDisk, 0, numMissingVols));
|
||||
RINOK(ReadVols2(volCallback, (unsigned)zipDisk, zipDisk + 1, zipDisk, 0, numMissingVols))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2428,7 +2510,7 @@ HRESULT CVols::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
return S_FALSE;
|
||||
if (NeedSeek)
|
||||
{
|
||||
RINOK(s.SeekToStart());
|
||||
RINOK(s.SeekToStart())
|
||||
NeedSeek = false;
|
||||
}
|
||||
UInt32 realProcessedSize = 0;
|
||||
@@ -2444,7 +2526,7 @@ HRESULT CVols::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CVolStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
Z7_COM7F_IMF(CVolStream::Read(void *data, UInt32 size, UInt32 *processedSize))
|
||||
{
|
||||
return Vols->Read(data, size, processedSize);
|
||||
}
|
||||
@@ -2458,14 +2540,10 @@ STDMETHODIMP CVolStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
|
||||
HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
{
|
||||
if (Buffer.Size() < kSeqBufferSize)
|
||||
{
|
||||
InitBuf();
|
||||
Buffer.AllocAtLeast(kSeqBufferSize);
|
||||
if (!Buffer.IsAllocated())
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
// buffer that can be used for cd reading
|
||||
RINOK(AllocateBuffer(kSeqBufferSize))
|
||||
|
||||
// here we can read small records. So we switch off _inBufMode.
|
||||
_inBufMode = false;
|
||||
|
||||
HRESULT res = S_OK;
|
||||
@@ -2488,6 +2566,13 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
|
||||
UInt64 cdAbsOffset = 0; // absolute cd offset, for LOCALS-CD-MODE only.
|
||||
|
||||
if (Force_ReadLocals_Mode)
|
||||
{
|
||||
IsArc = true;
|
||||
res = S_FALSE; // we will use LOCALS-CD-MODE mode
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!MarkerIsFound || !MarkerIsSafe)
|
||||
{
|
||||
IsArc = true;
|
||||
@@ -2497,7 +2582,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
else if (res != S_FALSE)
|
||||
return res;
|
||||
}
|
||||
else
|
||||
else // (MarkerIsFound && MarkerIsSafe)
|
||||
{
|
||||
|
||||
// _signature must be kLocalFileHeader or kEcd or kEcd64
|
||||
@@ -2528,7 +2613,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
RINOK(Skip64(recordSize - kEcd64_MainSize, 0));
|
||||
RINOK(Skip64(recordSize - kEcd64_MainSize, 0))
|
||||
}
|
||||
|
||||
ReadSignature();
|
||||
@@ -2568,7 +2653,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
ArcInfo.Base = (Int64)ArcInfo.MarkerPos;
|
||||
IsArc = true; // check it: we need more tests?
|
||||
|
||||
RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2));
|
||||
RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2))
|
||||
ReadSignature();
|
||||
}
|
||||
else
|
||||
@@ -2650,8 +2735,9 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // (MarkerIsFound && MarkerIsSafe)
|
||||
|
||||
} // (!onlyLocalsMode)
|
||||
|
||||
|
||||
CObjectVector<CItemEx> cdItems;
|
||||
@@ -2676,17 +2762,20 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
HeadersWarning = false;
|
||||
ExtraMinorError = false;
|
||||
|
||||
// we can use any mode: with buffer and without buffer
|
||||
// without buffer : skips packed data : fast for big files : slow for small files
|
||||
// with buffer : reads packed data : slow for big files : fast for small files
|
||||
|
||||
_inBufMode = false;
|
||||
// _inBufMode = true;
|
||||
|
||||
InitBuf();
|
||||
/* we can use any mode: with buffer and without buffer
|
||||
without buffer : skips packed data : fast for big files : slow for small files
|
||||
with buffer : reads packed data : slow for big files : fast for small files
|
||||
Buffer mode is more effective. */
|
||||
// _inBufMode = false;
|
||||
_inBufMode = true;
|
||||
// we could change the buffer size here, if we want smaller Buffer.
|
||||
// RINOK(ReAllocateBuffer(kSeqBufferSize));
|
||||
// InitBuf()
|
||||
|
||||
ArcInfo.Base = 0;
|
||||
|
||||
if (!Disable_FindMarker)
|
||||
{
|
||||
if (!MarkerIsFound)
|
||||
{
|
||||
if (!IsMultiVol)
|
||||
@@ -2695,7 +2784,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
return S_FALSE;
|
||||
// if (StartParsingVol == 0) and we didn't find marker, we use default zero marker.
|
||||
// so we suppose that there is no sfx stub
|
||||
RINOK(SeekToVol(0, ArcInfo.MarkerPos2));
|
||||
RINOK(SeekToVol(0, ArcInfo.MarkerPos2))
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2710,17 +2799,16 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
*/
|
||||
ArcInfo.Base = (Int64)ArcInfo.MarkerPos2;
|
||||
}
|
||||
|
||||
RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2));
|
||||
RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2))
|
||||
}
|
||||
|
||||
}
|
||||
_cnt = 0;
|
||||
|
||||
ReadSignature();
|
||||
|
||||
LocalsWereRead = true;
|
||||
|
||||
RINOK(ReadLocals(items));
|
||||
RINOK(ReadLocals(items))
|
||||
|
||||
if (_signature != NSignature::kCentralFileHeader)
|
||||
{
|
||||
@@ -2775,14 +2863,14 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
{
|
||||
CItemEx cdItem;
|
||||
|
||||
RINOK(ReadCdItem(cdItem));
|
||||
RINOK(ReadCdItem(cdItem))
|
||||
|
||||
cdItems.Add(cdItem);
|
||||
if (Callback && (cdItems.Size() & 0xFFF) == 0)
|
||||
{
|
||||
const UInt64 numFiles = items.Size();
|
||||
const UInt64 numBytes = _cnt;
|
||||
RINOK(Callback->SetCompleted(&numFiles, &numBytes));
|
||||
RINOK(Callback->SetCompleted(&numFiles, &numBytes))
|
||||
}
|
||||
ReadSignature();
|
||||
if (_signature != NSignature::kCentralFileHeader)
|
||||
@@ -2842,7 +2930,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
cdInfo.ParseEcd64e(buf);
|
||||
}
|
||||
|
||||
RINOK(Skip64(recordSize - kEcd64_MainSize, items.Size()));
|
||||
RINOK(Skip64(recordSize - kEcd64_MainSize, items.Size()))
|
||||
}
|
||||
|
||||
|
||||
@@ -2886,12 +2974,12 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
ecd.Parse(buf);
|
||||
}
|
||||
|
||||
COPY_ECD_ITEM_16(ThisDisk);
|
||||
COPY_ECD_ITEM_16(CdDisk);
|
||||
COPY_ECD_ITEM_16(NumEntries_in_ThisDisk);
|
||||
COPY_ECD_ITEM_16(NumEntries);
|
||||
COPY_ECD_ITEM_32(Size);
|
||||
COPY_ECD_ITEM_32(Offset);
|
||||
COPY_ECD_ITEM_16(ThisDisk)
|
||||
COPY_ECD_ITEM_16(CdDisk)
|
||||
COPY_ECD_ITEM_16(NumEntries_in_ThisDisk)
|
||||
COPY_ECD_ITEM_16(NumEntries)
|
||||
COPY_ECD_ITEM_32(Size)
|
||||
COPY_ECD_ITEM_32(Offset)
|
||||
|
||||
bool cdOK = true;
|
||||
|
||||
@@ -3040,7 +3128,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
if ((i & 0x3FFF) == 0)
|
||||
{
|
||||
const UInt64 numFiles64 = items.Size() + items2.Size();
|
||||
RINOK(Callback->SetCompleted(&numFiles64, &_cnt));
|
||||
RINOK(Callback->SetCompleted(&numFiles64, &_cnt))
|
||||
}
|
||||
|
||||
const CItemEx &cdItem = cdItems[i];
|
||||
@@ -3093,6 +3181,9 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
|
||||
item.ExternalAttrib = cdItem.ExternalAttrib;
|
||||
item.Comment = cdItem.Comment;
|
||||
item.FromCentral = cdItem.FromCentral;
|
||||
// 22.02: we force utf8 flag, if central header has utf8 flag
|
||||
if (cdItem.Flags & NFileHeader::NFlags::kUtf8)
|
||||
item.Flags |= NFileHeader::NFlags::kUtf8;
|
||||
}
|
||||
|
||||
FOR_VECTOR (k, items2)
|
||||
@@ -3175,8 +3266,8 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
|
||||
Close();
|
||||
|
||||
UInt64 startPos;
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &startPos));
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_END, &ArcInfo.FileEndPos));
|
||||
RINOK(InStream_GetPos(stream, startPos))
|
||||
RINOK(InStream_GetSize_SeekToEnd(stream, ArcInfo.FileEndPos))
|
||||
_streamPos = ArcInfo.FileEndPos;
|
||||
|
||||
StartStream = stream;
|
||||
@@ -3187,18 +3278,30 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
|
||||
|
||||
bool volWasRequested = false;
|
||||
|
||||
if (!Disable_VolsRead)
|
||||
if (callback
|
||||
&& (startPos == 0 || !searchLimit || *searchLimit != 0))
|
||||
{
|
||||
// we try to read volumes only if it's first call (offset == 0) or scan is allowed.
|
||||
volWasRequested = true;
|
||||
RINOK(ReadVols());
|
||||
RINOK(ReadVols())
|
||||
}
|
||||
|
||||
if (Disable_FindMarker)
|
||||
{
|
||||
RINOK(SeekToVol(-1, startPos))
|
||||
StreamRef = stream;
|
||||
Stream = stream;
|
||||
MarkerIsFound = true;
|
||||
MarkerIsSafe = true;
|
||||
ArcInfo.MarkerPos = startPos;
|
||||
ArcInfo.MarkerPos2 = startPos;
|
||||
}
|
||||
else
|
||||
if (IsMultiVol && Vols.StartParsingVol == 0 && (unsigned)Vols.StartParsingVol < Vols.Streams.Size())
|
||||
{
|
||||
// only StartParsingVol = 0 is safe search.
|
||||
RINOK(SeekToVol(0, 0));
|
||||
RINOK(SeekToVol(0, 0))
|
||||
// if (Stream)
|
||||
{
|
||||
// UInt64 limit = 1 << 22; // for sfx
|
||||
@@ -3222,11 +3325,11 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
|
||||
&& (unsigned)Vols.StartParsingVol < Vols.Streams.Size()
|
||||
&& Vols.Streams[(unsigned)Vols.StartParsingVol].Stream)
|
||||
{
|
||||
RINOK(SeekToVol(Vols.StartParsingVol, Vols.StreamIndex == Vols.StartVolIndex ? startPos : 0));
|
||||
RINOK(SeekToVol(Vols.StartParsingVol, Vols.StreamIndex == Vols.StartVolIndex ? startPos : 0))
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(SeekToVol(-1, startPos));
|
||||
RINOK(SeekToVol(-1, startPos))
|
||||
}
|
||||
|
||||
// UInt64 limit = 1 << 22;
|
||||
@@ -3242,8 +3345,8 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
|
||||
else if (!IsMultiVol)
|
||||
{
|
||||
/*
|
||||
// if (startPos != 0), probably CD copuld be already tested with another call with (startPos == 0).
|
||||
// so we don't want to try to open CD again in that ase.
|
||||
// if (startPos != 0), probably CD could be already tested with another call with (startPos == 0).
|
||||
// so we don't want to try to open CD again in that case.
|
||||
if (startPos != 0)
|
||||
return res;
|
||||
// we can try to open CD, if there is no Marker and (startPos == 0).
|
||||
@@ -3254,7 +3357,7 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
|
||||
|
||||
if (ArcInfo.IsSpanMode && !volWasRequested)
|
||||
{
|
||||
RINOK(ReadVols());
|
||||
RINOK(ReadVols())
|
||||
if (IsMultiVol && MarkerIsFound && ArcInfo.MarkerVolIndex < 0)
|
||||
ArcInfo.MarkerVolIndex = Vols.StartVolIndex;
|
||||
}
|
||||
@@ -3271,7 +3374,7 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
|
||||
Stream = Vols.Streams[(unsigned)Vols.StartVolIndex].Stream;
|
||||
if (Stream)
|
||||
{
|
||||
RINOK(Seek_SavePos(curPos));
|
||||
RINOK(Seek_SavePos(curPos))
|
||||
}
|
||||
else
|
||||
IsMultiVol = false;
|
||||
@@ -3287,7 +3390,7 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
|
||||
Stream = StartStream;
|
||||
Vols.StreamIndex = -1;
|
||||
InitBuf();
|
||||
RINOK(Seek_SavePos(curPos));
|
||||
RINOK(Seek_SavePos(curPos))
|
||||
}
|
||||
|
||||
ArcInfo.MarkerVolIndex = -1;
|
||||
@@ -3356,7 +3459,7 @@ HRESULT CInArchive::GetItemStream(const CItemEx &item, bool seekPackData, CMyCom
|
||||
if (UseDisk_in_SingleVol && item.Disk != EcdVolIndex)
|
||||
return S_OK;
|
||||
pos = (UInt64)((Int64)pos + ArcInfo.Base);
|
||||
RINOK(StreamRef->Seek((Int64)pos, STREAM_SEEK_SET, NULL));
|
||||
RINOK(InStream_SeekSet(StreamRef, pos))
|
||||
stream = StreamRef;
|
||||
return S_OK;
|
||||
}
|
||||
@@ -3367,7 +3470,7 @@ HRESULT CInArchive::GetItemStream(const CItemEx &item, bool seekPackData, CMyCom
|
||||
IInStream *str2 = Vols.Streams[item.Disk].Stream;
|
||||
if (!str2)
|
||||
return S_OK;
|
||||
RINOK(str2->Seek((Int64)pos, STREAM_SEEK_SET, NULL));
|
||||
RINOK(InStream_SeekSet(str2, pos))
|
||||
|
||||
Vols.NeedSeek = false;
|
||||
Vols.StreamIndex = (int)item.Disk;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// Archive/ZipIn.h
|
||||
|
||||
#ifndef __ZIP_IN_H
|
||||
#define __ZIP_IN_H
|
||||
#ifndef ZIP7_INC_ZIP_IN_H
|
||||
#define ZIP7_INC_ZIP_IN_H
|
||||
|
||||
#include "../../../Common/MyBuffer2.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../Common/StreamUtils.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
#include "ZipHeader.h"
|
||||
@@ -154,7 +155,7 @@ struct CVols
|
||||
CMyComPtr<IInStream> Stream;
|
||||
UInt64 Size;
|
||||
|
||||
HRESULT SeekToStart() const { return Stream->Seek(0, STREAM_SEEK_SET, NULL); }
|
||||
HRESULT SeekToStart() const { return InStream_SeekToBegin(Stream); }
|
||||
|
||||
CSubStreamInfo(): Size(0) {}
|
||||
};
|
||||
@@ -233,16 +234,12 @@ struct CVols
|
||||
};
|
||||
|
||||
|
||||
class CVolStream:
|
||||
public ISequentialInStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
Z7_CLASS_IMP_COM_1(
|
||||
CVolStream
|
||||
, ISequentialInStream
|
||||
)
|
||||
public:
|
||||
CVols *Vols;
|
||||
|
||||
MY_UNKNOWN_IMP1(ISequentialInStream)
|
||||
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
|
||||
@@ -269,6 +266,8 @@ class CInArchive
|
||||
_cnt += skip;
|
||||
}
|
||||
|
||||
HRESULT AllocateBuffer(size_t size);
|
||||
|
||||
UInt64 GetVirtStreamPos() { return _streamPos - _bufCached + _bufPos; }
|
||||
|
||||
bool _inBufMode;
|
||||
@@ -353,12 +352,19 @@ public:
|
||||
UInt32 EcdVolIndex;
|
||||
|
||||
CVols Vols;
|
||||
|
||||
bool Force_ReadLocals_Mode;
|
||||
bool Disable_VolsRead;
|
||||
bool Disable_FindMarker;
|
||||
|
||||
CInArchive():
|
||||
IsArcOpen(false),
|
||||
Stream(NULL),
|
||||
StartStream(NULL),
|
||||
Callback(NULL)
|
||||
Callback(NULL),
|
||||
Force_ReadLocals_Mode(false),
|
||||
Disable_VolsRead(false),
|
||||
Disable_FindMarker(false)
|
||||
{}
|
||||
|
||||
UInt64 GetPhySize() const
|
||||
@@ -412,8 +418,8 @@ public:
|
||||
|
||||
|
||||
HRESULT CheckDescriptor(const CItemEx &item);
|
||||
HRESULT ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail, bool &headersError);
|
||||
HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item);
|
||||
HRESULT Read_LocalItem_After_CdItem(CItemEx &item, bool &isAvail, bool &headersError);
|
||||
HRESULT Read_LocalItem_After_CdItem_Full(CItemEx &item);
|
||||
|
||||
HRESULT GetItemStream(const CItemEx &item, bool seekPackData, CMyComPtr<ISequentialInStream> &stream);
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ static const CUInt32PCharPair g_ExtraTypes[] =
|
||||
|
||||
void CExtraSubBlock::PrintInfo(AString &s) const
|
||||
{
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(g_ExtraTypes); i++)
|
||||
for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExtraTypes); i++)
|
||||
{
|
||||
const CUInt32PCharPair &pair = g_ExtraTypes[i];
|
||||
if (pair.Value == ID)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Archive/ZipItem.h
|
||||
|
||||
#ifndef __ARCHIVE_ZIP_ITEM_H
|
||||
#define __ARCHIVE_ZIP_ITEM_H
|
||||
#ifndef ZIP7_INC_ARCHIVE_ZIP_ITEM_H
|
||||
#define ZIP7_INC_ARCHIVE_ZIP_ITEM_H
|
||||
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
|
||||
@@ -12,6 +12,20 @@
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
HRESULT COutArchive::ClearRestriction()
|
||||
{
|
||||
if (SetRestriction)
|
||||
return SetRestriction->SetRestriction(0, 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT COutArchive::SetRestrictionFromCurrent()
|
||||
{
|
||||
if (SetRestriction)
|
||||
return SetRestriction->SetRestriction(m_Base + m_CurPos, (UInt64)(Int64)-1);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT COutArchive::Create(IOutStream *outStream)
|
||||
{
|
||||
m_CurPos = 0;
|
||||
@@ -97,7 +111,7 @@ void COutArchive::WriteCommonItemInfo(const CLocalItem &item, bool isZip64)
|
||||
}
|
||||
|
||||
|
||||
#define WRITE_32_VAL_SPEC(__v, __isZip64) Write32((__isZip64) ? 0xFFFFFFFF : (UInt32)(__v));
|
||||
#define WRITE_32_VAL_SPEC(_v_, _isZip64_) Write32((_isZip64_) ? 0xFFFFFFFF : (UInt32)(_v_));
|
||||
|
||||
|
||||
void COutArchive::WriteUtfName(const CItemOut &item)
|
||||
@@ -192,8 +206,8 @@ void COutArchive::WriteLocalHeader(CItemOut &item, bool needCheck)
|
||||
size = 0;
|
||||
}
|
||||
|
||||
WRITE_32_VAL_SPEC(packSize, isZip64);
|
||||
WRITE_32_VAL_SPEC(size, isZip64);
|
||||
WRITE_32_VAL_SPEC(packSize, isZip64)
|
||||
WRITE_32_VAL_SPEC(size, isZip64)
|
||||
|
||||
Write16((UInt16)item.Name.Len());
|
||||
|
||||
@@ -249,19 +263,19 @@ void COutArchive::WriteLocalHeader_Replace(CItemOut &item)
|
||||
void COutArchive::WriteDescriptor(const CItemOut &item)
|
||||
{
|
||||
Byte buf[kDataDescriptorSize64];
|
||||
SetUi32(buf, NSignature::kDataDescriptor);
|
||||
SetUi32(buf + 4, item.Crc);
|
||||
SetUi32(buf, NSignature::kDataDescriptor)
|
||||
SetUi32(buf + 4, item.Crc)
|
||||
unsigned descriptorSize;
|
||||
if (m_IsZip64)
|
||||
{
|
||||
SetUi64(buf + 8, item.PackSize);
|
||||
SetUi64(buf + 16, item.Size);
|
||||
SetUi64(buf + 8, item.PackSize)
|
||||
SetUi64(buf + 16, item.Size)
|
||||
descriptorSize = kDataDescriptorSize64;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetUi32(buf + 8, (UInt32)item.PackSize);
|
||||
SetUi32(buf + 12, (UInt32)item.Size);
|
||||
SetUi32(buf + 8, (UInt32)item.PackSize)
|
||||
SetUi32(buf + 12, (UInt32)item.Size)
|
||||
descriptorSize = kDataDescriptorSize32;
|
||||
}
|
||||
WriteBytes(buf, descriptorSize);
|
||||
@@ -283,8 +297,8 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
|
||||
WriteCommonItemInfo(item, isZip64);
|
||||
Write32(item.Crc);
|
||||
|
||||
WRITE_32_VAL_SPEC(item.PackSize, isPack64);
|
||||
WRITE_32_VAL_SPEC(item.Size, isUnPack64);
|
||||
WRITE_32_VAL_SPEC(item.PackSize, isPack64)
|
||||
WRITE_32_VAL_SPEC(item.Size, isUnPack64)
|
||||
|
||||
Write16((UInt16)item.Name.Len());
|
||||
|
||||
@@ -306,10 +320,10 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
|
||||
const UInt16 commentSize = (UInt16)item.Comment.Size();
|
||||
|
||||
Write16(commentSize);
|
||||
Write16(0); // DiskNumberStart;
|
||||
Write16(0); // DiskNumberStart
|
||||
Write16(item.InternalAttrib);
|
||||
Write32(item.ExternalAttrib);
|
||||
WRITE_32_VAL_SPEC(item.LocalHeaderPos, isPosition64);
|
||||
WRITE_32_VAL_SPEC(item.LocalHeaderPos, isPosition64)
|
||||
WriteBytes((const char *)item.Name, item.Name.Len());
|
||||
|
||||
if (isZip64)
|
||||
@@ -332,8 +346,10 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
|
||||
WriteBytes(item.Comment, commentSize);
|
||||
}
|
||||
|
||||
void COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const CByteBuffer *comment)
|
||||
HRESULT COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const CByteBuffer *comment)
|
||||
{
|
||||
RINOK(ClearRestriction())
|
||||
|
||||
const UInt64 cdOffset = GetCurPos();
|
||||
FOR_VECTOR (i, items)
|
||||
WriteCentralHeader(items[i]);
|
||||
@@ -357,8 +373,8 @@ void COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const CB
|
||||
|
||||
Write16(45); // made by version
|
||||
Write16(45); // extract version
|
||||
Write32(0); // ThisDiskNumber = 0;
|
||||
Write32(0); // StartCentralDirectoryDiskNumber;;
|
||||
Write32(0); // ThisDiskNumber
|
||||
Write32(0); // StartCentralDirectoryDiskNumber
|
||||
Write64((UInt64)items.Size());
|
||||
Write64((UInt64)items.Size());
|
||||
Write64((UInt64)cdSize);
|
||||
@@ -373,19 +389,20 @@ void COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const CB
|
||||
}
|
||||
|
||||
Write32(NSignature::kEcd);
|
||||
Write16(0); // ThisDiskNumber = 0;
|
||||
Write16(0); // StartCentralDirectoryDiskNumber;
|
||||
Write16(0); // ThisDiskNumber
|
||||
Write16(0); // StartCentralDirectoryDiskNumber
|
||||
Write16((UInt16)(items64 ? 0xFFFF: items.Size()));
|
||||
Write16((UInt16)(items64 ? 0xFFFF: items.Size()));
|
||||
|
||||
WRITE_32_VAL_SPEC(cdSize, cdSize64);
|
||||
WRITE_32_VAL_SPEC(cdOffset, cdOffset64);
|
||||
WRITE_32_VAL_SPEC(cdSize, cdSize64)
|
||||
WRITE_32_VAL_SPEC(cdOffset, cdOffset64)
|
||||
|
||||
const UInt16 commentSize = (UInt16)(comment ? comment->Size() : 0);
|
||||
Write16((UInt16)commentSize);
|
||||
if (commentSize != 0)
|
||||
WriteBytes((const Byte *)*comment, commentSize);
|
||||
m_OutBuffer.FlushWithCheck();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void COutArchive::CreateStreamForCompressing(CMyComPtr<IOutStream> &outStream)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// ZipOut.h
|
||||
|
||||
#ifndef __ZIP_OUT_H
|
||||
#define __ZIP_OUT_H
|
||||
#ifndef ZIP7_INC_ZIP_OUT_H
|
||||
#define ZIP7_INC_ZIP_OUT_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
@@ -74,6 +74,10 @@ class COutArchive
|
||||
|
||||
void SeekToCurPos();
|
||||
public:
|
||||
CMyComPtr<IStreamSetRestriction> SetRestriction;
|
||||
|
||||
HRESULT ClearRestriction();
|
||||
HRESULT SetRestrictionFromCurrent();
|
||||
HRESULT Create(IOutStream *outStream);
|
||||
|
||||
UInt64 GetCurPos() const { return m_CurPos; }
|
||||
@@ -88,7 +92,7 @@ public:
|
||||
|
||||
void WriteDescriptor(const CItemOut &item);
|
||||
|
||||
void WriteCentralDir(const CObjectVector<CItemOut> &items, const CByteBuffer *comment);
|
||||
HRESULT WriteCentralDir(const CObjectVector<CItemOut> &items, const CByteBuffer *comment);
|
||||
|
||||
void CreateStreamForCompressing(CMyComPtr<IOutStream> &outStream);
|
||||
void CreateStreamForCopying(CMyComPtr<ISequentialOutStream> &outStream);
|
||||
|
||||
@@ -17,7 +17,7 @@ static const Byte k_Signature[] = {
|
||||
6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B }; // NoSpan
|
||||
|
||||
REGISTER_ARC_IO(
|
||||
"zip", "zip z01 zipx jar xpi odt ods docx xlsx epub ipa apk appx", 0, 1,
|
||||
"zip", "zip z01 zipx jar xpi odt ods docx xlsx epub ipa apk appx", NULL, 1,
|
||||
k_Signature,
|
||||
0,
|
||||
NArcInfoFlags::kFindSignature
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
// ZipUpdate.h
|
||||
|
||||
#ifndef __ZIP_UPDATE_H
|
||||
#define __ZIP_UPDATE_H
|
||||
#ifndef ZIP7_INC_ZIP_UPDATE_H
|
||||
#define ZIP7_INC_ZIP_UPDATE_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../IArchive.h"
|
||||
@@ -20,8 +20,8 @@ struct CUpdateRange
|
||||
UInt64 Position;
|
||||
UInt64 Size;
|
||||
|
||||
// CUpdateRange() {};
|
||||
CUpdateRange(UInt64 position, UInt64 size): Position(position), Size(size) {};
|
||||
// CUpdateRange() {}
|
||||
CUpdateRange(UInt64 position, UInt64 size): Position(position), Size(size) {}
|
||||
};
|
||||
*/
|
||||
|
||||
@@ -34,6 +34,7 @@ struct CUpdateItem
|
||||
bool Write_UnixTime;
|
||||
// bool Write_UnixTime_ATime;
|
||||
bool IsUtf8;
|
||||
bool Size_WasSetFromStream;
|
||||
// bool IsAltStream;
|
||||
int IndexInArc;
|
||||
unsigned IndexInClient;
|
||||
@@ -57,6 +58,7 @@ struct CUpdateItem
|
||||
Write_UnixTime = false;
|
||||
|
||||
IsUtf8 = false;
|
||||
Size_WasSetFromStream = false;
|
||||
// IsAltStream = false;
|
||||
Time = 0;
|
||||
Size = 0;
|
||||
@@ -74,6 +76,7 @@ struct CUpdateItem
|
||||
Write_NtfsTime(false),
|
||||
Write_UnixTime(false),
|
||||
IsUtf8(false),
|
||||
Size_WasSetFromStream(false),
|
||||
// IsAltStream(false),
|
||||
Time(0),
|
||||
Size(0)
|
||||
|
||||
Reference in New Issue
Block a user