mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-12 14:11:33 -06:00
23.01
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user