This commit is contained in:
Igor Pavlov
2023-12-22 17:17:05 +00:00
committed by Kornel
parent ec44a8a070
commit a36c48cece
954 changed files with 42199 additions and 25482 deletions

View File

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

View File

@@ -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;
}

View File

@@ -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);
};

View File

@@ -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(); }
};

View File

@@ -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
}

View File

@@ -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();
};
}}

View File

@@ -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));

View File

@@ -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"

View File

@@ -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;

View File

@@ -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);

View File

@@ -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)

View File

@@ -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"

View File

@@ -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)

View File

@@ -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);

View File

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

View File

File diff suppressed because it is too large Load Diff

View File

@@ -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)