mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 12:07:03 -06:00
9.21
This commit is contained in:
committed by
Kornel Lesiński
parent
de4f8c22fe
commit
35596517f2
@@ -33,6 +33,7 @@ static const UInt32 kLzmaHeaderSize = 4 + kLzmaPropsSize;
|
||||
|
||||
class CLzmaEncoder:
|
||||
public ICompressCoder,
|
||||
public ICompressSetCoderProperties,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
NCompress::NLzma::CEncoder *EncoderSpec;
|
||||
@@ -41,12 +42,12 @@ class CLzmaEncoder:
|
||||
public:
|
||||
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
|
||||
HRESULT SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
|
||||
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
|
||||
};
|
||||
|
||||
HRESULT CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
|
||||
STDMETHODIMP CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
|
||||
{
|
||||
if (!Encoder)
|
||||
{
|
||||
@@ -67,7 +68,7 @@ HRESULT CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIAN
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
STDMETHODIMP CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
|
||||
{
|
||||
RINOK(WriteStream(outStream, Header, kLzmaHeaderSize));
|
||||
@@ -210,52 +211,12 @@ HRESULT CAddCommon::Compress(
|
||||
_compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_LZMA;
|
||||
CLzmaEncoder *_lzmaEncoder = new CLzmaEncoder();
|
||||
_compressEncoder = _lzmaEncoder;
|
||||
NWindows::NCOM::CPropVariant props[] =
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
_options.NumThreads,
|
||||
#endif
|
||||
_options.Algo,
|
||||
_options.DicSize,
|
||||
_options.NumFastBytes,
|
||||
const_cast<BSTR>((const wchar_t *)_options.MatchFinder),
|
||||
_options.NumMatchFinderCycles
|
||||
};
|
||||
PROPID propIDs[] =
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
NCoderPropID::kNumThreads,
|
||||
#endif
|
||||
NCoderPropID::kAlgorithm,
|
||||
NCoderPropID::kDictionarySize,
|
||||
NCoderPropID::kNumFastBytes,
|
||||
NCoderPropID::kMatchFinder,
|
||||
NCoderPropID::kMatchFinderCycles
|
||||
};
|
||||
int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
|
||||
if (!_options.NumMatchFinderCyclesDefined)
|
||||
numProps--;
|
||||
RINOK(_lzmaEncoder->SetCoderProperties(propIDs, props, numProps));
|
||||
}
|
||||
else if (method == NFileHeader::NCompressionMethod::kPPMd)
|
||||
{
|
||||
_compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_PPMd;
|
||||
NCompress::NPpmdZip::CEncoder *encoder = new NCompress::NPpmdZip::CEncoder();
|
||||
_compressEncoder = encoder;
|
||||
NWindows::NCOM::CPropVariant props[] =
|
||||
{
|
||||
_options.Algo,
|
||||
_options.MemSize,
|
||||
_options.Order
|
||||
|
||||
};
|
||||
PROPID propIDs[] =
|
||||
{
|
||||
NCoderPropID::kAlgorithm,
|
||||
NCoderPropID::kUsedMemorySize,
|
||||
NCoderPropID::kOrder
|
||||
};
|
||||
RINOK(encoder->SetCoderProperties(propIDs, props, sizeof(propIDs) / sizeof(propIDs[0])));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -282,56 +243,20 @@ HRESULT CAddCommon::Compress(
|
||||
if (method == NFileHeader::NCompressionMethod::kDeflated ||
|
||||
method == NFileHeader::NCompressionMethod::kDeflated64)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant props[] =
|
||||
{
|
||||
_options.Algo,
|
||||
_options.NumPasses,
|
||||
_options.NumFastBytes,
|
||||
_options.NumMatchFinderCycles
|
||||
};
|
||||
PROPID propIDs[] =
|
||||
{
|
||||
NCoderPropID::kAlgorithm,
|
||||
NCoderPropID::kNumPasses,
|
||||
NCoderPropID::kNumFastBytes,
|
||||
NCoderPropID::kMatchFinderCycles
|
||||
};
|
||||
int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
|
||||
if (!_options.NumMatchFinderCyclesDefined)
|
||||
numProps--;
|
||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||
_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
|
||||
if (setCoderProperties)
|
||||
{
|
||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, props, numProps));
|
||||
}
|
||||
}
|
||||
else if (method == NFileHeader::NCompressionMethod::kBZip2)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant props[] =
|
||||
{
|
||||
_options.DicSize,
|
||||
_options.NumPasses
|
||||
#ifndef _7ZIP_ST
|
||||
, _options.NumThreads
|
||||
#endif
|
||||
};
|
||||
PROPID propIDs[] =
|
||||
{
|
||||
NCoderPropID::kDictionarySize,
|
||||
NCoderPropID::kNumPasses
|
||||
#ifndef _7ZIP_ST
|
||||
, NCoderPropID::kNumThreads
|
||||
#endif
|
||||
};
|
||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||
_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
|
||||
if (setCoderProperties)
|
||||
{
|
||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, props, sizeof(propIDs) / sizeof(propIDs[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
CMyComPtr<ICompressSetCoderProperties> setCoderProps;
|
||||
_compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProps);
|
||||
if (setCoderProps)
|
||||
{
|
||||
RINOK(_options.MethodInfo.SetCoderProps(setCoderProps,
|
||||
_options._dataSizeReduceDefined ? &_options._dataSizeReduce : NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
CMyComPtr<ISequentialOutStream> outStreamNew;
|
||||
if (_options.PasswordIsDefined)
|
||||
|
||||
@@ -5,36 +5,54 @@
|
||||
|
||||
#include "Common/MyString.h"
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
#include "../../../Windows/System.h"
|
||||
#endif
|
||||
|
||||
#include "../Common/HandlerOut.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
struct CCompressionMethodMode
|
||||
struct CBaseProps
|
||||
{
|
||||
CRecordVector<Byte> MethodSequence;
|
||||
UString MatchFinder;
|
||||
UInt32 Algo;
|
||||
UInt32 NumPasses;
|
||||
UInt32 NumFastBytes;
|
||||
bool NumMatchFinderCyclesDefined;
|
||||
UInt32 NumMatchFinderCycles;
|
||||
UInt32 DicSize;
|
||||
UInt32 MemSize;
|
||||
UInt32 Order;
|
||||
CMethodProps MethodInfo;
|
||||
Int32 Level;
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
UInt32 NumThreads;
|
||||
bool NumThreadsWasChanged;
|
||||
#endif
|
||||
bool PasswordIsDefined;
|
||||
AString Password;
|
||||
bool IsAesMode;
|
||||
Byte AesKeyMode;
|
||||
|
||||
void Init()
|
||||
{
|
||||
MethodInfo.Clear();
|
||||
Level = -1;
|
||||
#ifndef _7ZIP_ST
|
||||
NumThreads = NWindows::NSystem::GetNumberOfProcessors();;
|
||||
NumThreadsWasChanged = false;
|
||||
#endif
|
||||
IsAesMode = false;
|
||||
AesKeyMode = 3;
|
||||
}
|
||||
};
|
||||
|
||||
struct CCompressionMethodMode: public CBaseProps
|
||||
{
|
||||
CRecordVector<Byte> MethodSequence;
|
||||
bool PasswordIsDefined;
|
||||
AString Password;
|
||||
|
||||
UInt64 _dataSizeReduce;
|
||||
bool _dataSizeReduceDefined;
|
||||
|
||||
CCompressionMethodMode():
|
||||
NumMatchFinderCyclesDefined(false),
|
||||
PasswordIsDefined(false),
|
||||
IsAesMode(false),
|
||||
AesKeyMode(3)
|
||||
{}
|
||||
CCompressionMethodMode(): PasswordIsDefined(false)
|
||||
{
|
||||
_dataSizeReduceDefined = false;
|
||||
_dataSizeReduce = 0;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -107,7 +107,7 @@ static struct CStrongCryptoPair
|
||||
{ NStrongCryptoFlags::kRC4, "RC4" }
|
||||
};
|
||||
|
||||
static STATPROPSTG kProps[] =
|
||||
static const STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsDir, VT_BOOL},
|
||||
@@ -117,6 +117,7 @@ static STATPROPSTG kProps[] =
|
||||
{ NULL, kpidCTime, VT_FILETIME},
|
||||
{ NULL, kpidATime, VT_FILETIME},
|
||||
{ NULL, kpidAttrib, VT_UI4},
|
||||
// { NULL, kpidPosixAttrib, VT_UI4},
|
||||
{ NULL, kpidEncrypted, VT_BOOL},
|
||||
{ NULL, kpidComment, VT_BSTR},
|
||||
{ NULL, kpidCRC, VT_UI4},
|
||||
@@ -125,7 +126,7 @@ static STATPROPSTG kProps[] =
|
||||
{ NULL, kpidUnpackVer, VT_UI4}
|
||||
};
|
||||
|
||||
static STATPROPSTG kArcProps[] =
|
||||
static const STATPROPSTG kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidBit64, VT_BOOL},
|
||||
{ NULL, kpidComment, VT_BSTR},
|
||||
@@ -135,7 +136,7 @@ static STATPROPSTG kArcProps[] =
|
||||
|
||||
CHandler::CHandler()
|
||||
{
|
||||
InitMethodProperties();
|
||||
InitMethodProps();
|
||||
}
|
||||
|
||||
static AString BytesToString(const CByteBuffer &data)
|
||||
@@ -165,6 +166,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
case kpidComment: prop = MultiByteToUnicodeString(BytesToString(m_Archive.ArcInfo.Comment), CP_ACP); break;
|
||||
case kpidPhySize: prop = m_Archive.ArcInfo.GetPhySize(); break;
|
||||
case kpidOffset: if (m_Archive.ArcInfo.StartPosition != 0) prop = m_Archive.ArcInfo.StartPosition; break;
|
||||
case kpidError: if (!m_Archive.IsOkHeaders) prop = "Incorrect headers"; break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
COM_TRY_END
|
||||
@@ -194,7 +196,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
UInt32 unixTime;
|
||||
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
|
||||
prop = (UInt32)NFileTimeType::kWindows;
|
||||
else if (item.CentralExtra.GetUnixTime(NFileHeader::NUnixTime::kMTime, unixTime))
|
||||
else if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
|
||||
prop = (UInt32)NFileTimeType::kUnix;
|
||||
else
|
||||
prop = (UInt32)NFileTimeType::kDOS;
|
||||
@@ -220,7 +222,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
|
||||
{
|
||||
UInt32 unixTime;
|
||||
if (item.CentralExtra.GetUnixTime(NFileHeader::NUnixTime::kMTime, unixTime))
|
||||
if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
|
||||
NTime::UnixTimeToFileTime(unixTime, utc);
|
||||
else
|
||||
{
|
||||
@@ -233,7 +235,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
prop = utc;
|
||||
break;
|
||||
}
|
||||
case kpidAttrib: prop = item.GetWinAttributes(); break;
|
||||
case kpidAttrib: prop = item.GetWinAttrib(); break;
|
||||
case kpidPosixAttrib:
|
||||
{
|
||||
UInt32 attrib;
|
||||
if (item.GetPosixAttrib(attrib))
|
||||
prop = attrib;
|
||||
break;
|
||||
}
|
||||
case kpidEncrypted: prop = item.IsEncrypted(); break;
|
||||
case kpidComment: prop = item.GetUnicodeString(BytesToString(item.Comment)); break;
|
||||
case kpidCRC: if (item.IsThereCrc()) prop = item.FileCRC; break;
|
||||
@@ -435,7 +444,10 @@ public:
|
||||
ISequentialOutStream *realOutStream,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
ICompressProgressInfo *compressProgress,
|
||||
UInt32 numThreads, Int32 &res);
|
||||
#ifndef _7ZIP_ST
|
||||
UInt32 numThreads,
|
||||
#endif
|
||||
Int32 &res);
|
||||
};
|
||||
|
||||
HRESULT CZipDecoder::Decode(
|
||||
@@ -444,7 +456,10 @@ HRESULT CZipDecoder::Decode(
|
||||
ISequentialOutStream *realOutStream,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
ICompressProgressInfo *compressProgress,
|
||||
UInt32 numThreads, Int32 &res)
|
||||
#ifndef _7ZIP_ST
|
||||
UInt32 numThreads,
|
||||
#endif
|
||||
Int32 &res)
|
||||
{
|
||||
res = NExtract::NOperationResult::kDataError;
|
||||
CInStreamReleaser inStreamReleaser;
|
||||
@@ -805,15 +820,22 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
|
||||
Int32 res;
|
||||
RINOK(myDecoder.Decode(
|
||||
HRESULT hres = myDecoder.Decode(
|
||||
EXTERNAL_CODECS_VARS
|
||||
m_Archive, item, realOutStream, extractCallback,
|
||||
progress, _numThreads, res));
|
||||
progress,
|
||||
#ifndef _7ZIP_ST
|
||||
_props.NumThreads,
|
||||
#endif
|
||||
res);
|
||||
RINOK(hres);
|
||||
realOutStream.Release();
|
||||
|
||||
RINOK(extractCallback->SetOperationResult(res))
|
||||
}
|
||||
return S_OK;
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = currentTotalUnPacked;
|
||||
return lps->SetCur();
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,6 @@
|
||||
#include "ZipIn.h"
|
||||
#include "ZipCompressionMode.h"
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
#include "../../../Windows/System.h"
|
||||
#endif
|
||||
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
@@ -46,53 +42,24 @@ private:
|
||||
CObjectVector<CItemEx> m_Items;
|
||||
CInArchive m_Archive;
|
||||
|
||||
int m_Level;
|
||||
CBaseProps _props;
|
||||
|
||||
int m_MainMethod;
|
||||
UInt32 m_DicSize;
|
||||
UInt32 m_Algo;
|
||||
UInt32 m_NumPasses;
|
||||
UInt32 m_NumFastBytes;
|
||||
UInt32 m_NumMatchFinderCycles;
|
||||
UInt32 m_MemSize;
|
||||
UInt32 m_Order;
|
||||
|
||||
bool m_NumMatchFinderCyclesDefined;
|
||||
|
||||
bool m_ForceAesMode;
|
||||
bool m_IsAesMode;
|
||||
Byte m_AesKeyMode;
|
||||
|
||||
bool m_WriteNtfsTimeExtra;
|
||||
bool m_ForceLocal;
|
||||
bool m_ForceUtf8;
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
UInt32 _numThreads;
|
||||
#endif
|
||||
|
||||
DECL_EXTERNAL_CODECS_VARS
|
||||
|
||||
void InitMethodProperties()
|
||||
void InitMethodProps()
|
||||
{
|
||||
m_Level = -1;
|
||||
_props.Init();
|
||||
m_MainMethod = -1;
|
||||
m_Algo =
|
||||
m_DicSize =
|
||||
m_NumPasses =
|
||||
m_NumFastBytes =
|
||||
m_Order =
|
||||
m_MemSize =
|
||||
m_NumMatchFinderCycles = 0xFFFFFFFF;
|
||||
m_NumMatchFinderCyclesDefined = false;
|
||||
m_ForceAesMode = false;
|
||||
m_IsAesMode = false;
|
||||
m_AesKeyMode = 3; // aes-256
|
||||
m_WriteNtfsTimeExtra = true;
|
||||
m_ForceLocal = false;
|
||||
m_ForceUtf8 = false;
|
||||
#ifndef _7ZIP_ST
|
||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -28,37 +28,6 @@ using namespace NTime;
|
||||
namespace NArchive {
|
||||
namespace NZip {
|
||||
|
||||
static const UInt32 kLzAlgoX1 = 0;
|
||||
static const UInt32 kLzAlgoX5 = 1;
|
||||
|
||||
static const UInt32 kDeflateNumPassesX1 = 1;
|
||||
static const UInt32 kDeflateNumPassesX7 = 3;
|
||||
static const UInt32 kDeflateNumPassesX9 = 10;
|
||||
|
||||
static const UInt32 kDeflateNumFastBytesX1 = 32;
|
||||
static const UInt32 kDeflateNumFastBytesX7 = 64;
|
||||
static const UInt32 kDeflateNumFastBytesX9 = 128;
|
||||
|
||||
static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
|
||||
static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
|
||||
|
||||
static const UInt32 kLzmaNumFastBytesX1 = 32;
|
||||
static const UInt32 kLzmaNumFastBytesX7 = 64;
|
||||
|
||||
static const UInt32 kLzmaDicSizeX1 = 1 << 16;
|
||||
static const UInt32 kLzmaDicSizeX3 = 1 << 20;
|
||||
static const UInt32 kLzmaDicSizeX5 = 1 << 24;
|
||||
static const UInt32 kLzmaDicSizeX7 = 1 << 25;
|
||||
static const UInt32 kLzmaDicSizeX9 = 1 << 26;
|
||||
|
||||
static const UInt32 kBZip2NumPassesX1 = 1;
|
||||
static const UInt32 kBZip2NumPassesX7 = 2;
|
||||
static const UInt32 kBZip2NumPassesX9 = 7;
|
||||
|
||||
static const UInt32 kBZip2DicSizeX1 = 100000;
|
||||
static const UInt32 kBZip2DicSizeX3 = 500000;
|
||||
static const UInt32 kBZip2DicSizeX5 = 900000;
|
||||
|
||||
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
|
||||
{
|
||||
*timeType = NFileTimeType::kDOS;
|
||||
@@ -99,6 +68,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
COM_TRY_BEGIN2
|
||||
CObjectVector<CUpdateItem> updateItems;
|
||||
bool thereAreAesUpdates = false;
|
||||
UInt64 largestSize = 0;
|
||||
bool largestSizeDefined = false;
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
CUpdateItem ui;
|
||||
@@ -178,7 +149,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
const wchar_t kSlash = L'/';
|
||||
if (!name.IsEmpty())
|
||||
{
|
||||
if (name[name.Length() - 1] == kSlash)
|
||||
if (name.Back() == kSlash)
|
||||
{
|
||||
if (!ui.IsDir)
|
||||
return E_INVALIDARG;
|
||||
@@ -235,6 +206,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = prop.uhVal.QuadPart;
|
||||
if (largestSize < size)
|
||||
largestSize = size;
|
||||
largestSizeDefined = true;
|
||||
}
|
||||
ui.Size = size;
|
||||
}
|
||||
@@ -247,6 +221,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
|
||||
}
|
||||
CCompressionMethodMode options;
|
||||
(CBaseProps &)options = _props;
|
||||
options._dataSizeReduce = largestSize;
|
||||
options._dataSizeReduceDefined = largestSizeDefined;
|
||||
|
||||
if (getTextPassword)
|
||||
{
|
||||
@@ -256,8 +233,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
options.PasswordIsDefined = IntToBool(passwordIsDefined);
|
||||
if (options.PasswordIsDefined)
|
||||
{
|
||||
options.IsAesMode = (m_ForceAesMode ? m_IsAesMode : thereAreAesUpdates);
|
||||
options.AesKeyMode = m_AesKeyMode;
|
||||
if (!m_ForceAesMode)
|
||||
options.IsAesMode = thereAreAesUpdates;
|
||||
|
||||
if (!IsAsciiString((const wchar_t *)password))
|
||||
return E_INVALIDARG;
|
||||
@@ -272,13 +249,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
else
|
||||
options.PasswordIsDefined = false;
|
||||
|
||||
int level = m_Level;
|
||||
if (level < 0)
|
||||
level = 5;
|
||||
|
||||
Byte mainMethod;
|
||||
if (m_MainMethod < 0)
|
||||
mainMethod = (Byte)(((level == 0) ?
|
||||
mainMethod = (Byte)(((_props.Level == 0) ?
|
||||
NFileHeader::NCompressionMethod::kStored :
|
||||
NFileHeader::NCompressionMethod::kDeflated));
|
||||
else
|
||||
@@ -286,83 +259,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
options.MethodSequence.Add(mainMethod);
|
||||
if (mainMethod != NFileHeader::NCompressionMethod::kStored)
|
||||
options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored);
|
||||
bool isDeflate = (mainMethod == NFileHeader::NCompressionMethod::kDeflated) ||
|
||||
(mainMethod == NFileHeader::NCompressionMethod::kDeflated64);
|
||||
bool isLZMA = (mainMethod == NFileHeader::NCompressionMethod::kLZMA);
|
||||
bool isLz = (isLZMA || isDeflate);
|
||||
options.NumPasses = m_NumPasses;
|
||||
options.DicSize = m_DicSize;
|
||||
options.NumFastBytes = m_NumFastBytes;
|
||||
options.NumMatchFinderCycles = m_NumMatchFinderCycles;
|
||||
options.NumMatchFinderCyclesDefined = m_NumMatchFinderCyclesDefined;
|
||||
options.Algo = m_Algo;
|
||||
options.MemSize = m_MemSize;
|
||||
options.Order = m_Order;
|
||||
#ifndef _7ZIP_ST
|
||||
options.NumThreads = _numThreads;
|
||||
#endif
|
||||
if (isLz)
|
||||
{
|
||||
if (isDeflate)
|
||||
{
|
||||
if (options.NumPasses == 0xFFFFFFFF)
|
||||
options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 :
|
||||
(level >= 7 ? kDeflateNumPassesX7 :
|
||||
kDeflateNumPassesX1));
|
||||
if (options.NumFastBytes == 0xFFFFFFFF)
|
||||
options.NumFastBytes = (level >= 9 ? kDeflateNumFastBytesX9 :
|
||||
(level >= 7 ? kDeflateNumFastBytesX7 :
|
||||
kDeflateNumFastBytesX1));
|
||||
}
|
||||
else if (isLZMA)
|
||||
{
|
||||
if (options.DicSize == 0xFFFFFFFF)
|
||||
options.DicSize =
|
||||
(level >= 9 ? kLzmaDicSizeX9 :
|
||||
(level >= 7 ? kLzmaDicSizeX7 :
|
||||
(level >= 5 ? kLzmaDicSizeX5 :
|
||||
(level >= 3 ? kLzmaDicSizeX3 :
|
||||
kLzmaDicSizeX1))));
|
||||
|
||||
if (options.NumFastBytes == 0xFFFFFFFF)
|
||||
options.NumFastBytes = (level >= 7 ? kLzmaNumFastBytesX7 :
|
||||
kLzmaNumFastBytesX1);
|
||||
|
||||
options.MatchFinder =
|
||||
(level >= 5 ? kLzmaMatchFinderX5 :
|
||||
kLzmaMatchFinderX1);
|
||||
}
|
||||
|
||||
if (options.Algo == 0xFFFFFFFF)
|
||||
options.Algo = (level >= 5 ? kLzAlgoX5 :
|
||||
kLzAlgoX1);
|
||||
}
|
||||
if (mainMethod == NFileHeader::NCompressionMethod::kBZip2)
|
||||
{
|
||||
if (options.NumPasses == 0xFFFFFFFF)
|
||||
options.NumPasses = (level >= 9 ? kBZip2NumPassesX9 :
|
||||
(level >= 7 ? kBZip2NumPassesX7 :
|
||||
kBZip2NumPassesX1));
|
||||
if (options.DicSize == 0xFFFFFFFF)
|
||||
options.DicSize = (level >= 5 ? kBZip2DicSizeX5 :
|
||||
(level >= 3 ? kBZip2DicSizeX3 :
|
||||
kBZip2DicSizeX1));
|
||||
}
|
||||
if (mainMethod == NFileHeader::NCompressionMethod::kPPMd)
|
||||
{
|
||||
int level2 = level;
|
||||
if (level2 < 1) level2 = 1;
|
||||
if (level2 > 9) level2 = 9;
|
||||
|
||||
if (options.MemSize == 0xFFFFFFFF)
|
||||
options.MemSize = (1 << (19 + (level2 > 8 ? 8 : level2)));
|
||||
|
||||
if (options.Order == 0xFFFFFFFF)
|
||||
options.Order = 3 + level2;
|
||||
|
||||
if (options.Algo == 0xFFFFFFFF)
|
||||
options.Algo = (level2 >= 7 ? 1 : 0);
|
||||
}
|
||||
|
||||
return Update(
|
||||
EXTERNAL_CODECS_VARS
|
||||
@@ -371,16 +267,34 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
COM_TRY_END2
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
||||
struct CMethodIndexToName
|
||||
{
|
||||
unsigned Method;
|
||||
const wchar_t *Name;
|
||||
};
|
||||
|
||||
static const CMethodIndexToName k_SupportedMethods[] =
|
||||
{
|
||||
{ NFileHeader::NCompressionMethod::kStored, L"COPY" },
|
||||
{ NFileHeader::NCompressionMethod::kDeflated, L"DEFLATE" },
|
||||
{ NFileHeader::NCompressionMethod::kDeflated64, L"DEFLATE64" },
|
||||
{ NFileHeader::NCompressionMethod::kBZip2, L"BZIP2" },
|
||||
{ NFileHeader::NCompressionMethod::kLZMA, L"LZMA" },
|
||||
{ NFileHeader::NCompressionMethod::kPPMd, L"PPMD" }
|
||||
};
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
|
||||
{
|
||||
InitMethodProps();
|
||||
#ifndef _7ZIP_ST
|
||||
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
|
||||
_numThreads = numProcessors;
|
||||
const UInt32 numProcessors = _props.NumThreads;
|
||||
#endif
|
||||
InitMethodProperties();
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
|
||||
for (int i = 0; i < numProps; i++)
|
||||
{
|
||||
UString name = UString(names[i]);
|
||||
UString name = names[i];
|
||||
name.MakeUpper();
|
||||
if (name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
@@ -390,140 +304,112 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
||||
if (name[0] == L'X')
|
||||
{
|
||||
UInt32 level = 9;
|
||||
RINOK(ParsePropValue(name.Mid(1), prop, level));
|
||||
m_Level = level;
|
||||
continue;
|
||||
RINOK(ParsePropToUInt32(name.Mid(1), prop, level));
|
||||
_props.Level = level;
|
||||
_props.MethodInfo.AddLevelProp(level);
|
||||
}
|
||||
else if (name == L"M")
|
||||
{
|
||||
if (prop.vt == VT_BSTR)
|
||||
{
|
||||
UString m = prop.bstrVal;
|
||||
UString m = prop.bstrVal, m2;
|
||||
m.MakeUpper();
|
||||
if (m == L"COPY") m_MainMethod = NFileHeader::NCompressionMethod::kStored;
|
||||
else if (m == L"DEFLATE") m_MainMethod = NFileHeader::NCompressionMethod::kDeflated;
|
||||
else if (m == L"DEFLATE64") m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64;
|
||||
else if (m == L"BZIP2") m_MainMethod = NFileHeader::NCompressionMethod::kBZip2;
|
||||
else if (m == L"LZMA") m_MainMethod = NFileHeader::NCompressionMethod::kLZMA;
|
||||
else if (m == L"PPMD") m_MainMethod = NFileHeader::NCompressionMethod::kPPMd;
|
||||
else return E_INVALIDARG;
|
||||
int colonPos = m.Find(L':');
|
||||
if (colonPos >= 0)
|
||||
{
|
||||
m2 = m.Mid(colonPos + 1);
|
||||
m = m.Left(colonPos);
|
||||
}
|
||||
int k;
|
||||
for (k = 0; k < ARRAY_SIZE(k_SupportedMethods); k++)
|
||||
{
|
||||
const CMethodIndexToName &pair = k_SupportedMethods[k];
|
||||
if (m == pair.Name)
|
||||
{
|
||||
if (!m2.IsEmpty())
|
||||
{
|
||||
RINOK(_props.MethodInfo.ParseParamsFromString(m2));
|
||||
}
|
||||
m_MainMethod = pair.Method;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k == ARRAY_SIZE(k_SupportedMethods))
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else if (prop.vt == VT_UI4)
|
||||
{
|
||||
switch(prop.ulVal)
|
||||
int k;
|
||||
for (k = 0; k < ARRAY_SIZE(k_SupportedMethods); k++)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kStored:
|
||||
case NFileHeader::NCompressionMethod::kDeflated:
|
||||
case NFileHeader::NCompressionMethod::kDeflated64:
|
||||
case NFileHeader::NCompressionMethod::kBZip2:
|
||||
case NFileHeader::NCompressionMethod::kLZMA:
|
||||
m_MainMethod = (Byte)prop.ulVal;
|
||||
unsigned method = k_SupportedMethods[k].Method;
|
||||
if (prop.ulVal == method)
|
||||
{
|
||||
m_MainMethod = method;
|
||||
break;
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
if (k == ARRAY_SIZE(k_SupportedMethods))
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else if (name.Left(2) == L"EM")
|
||||
{
|
||||
if (prop.vt == VT_BSTR)
|
||||
if (prop.vt != VT_BSTR)
|
||||
return E_INVALIDARG;
|
||||
{
|
||||
UString valueString = prop.bstrVal;
|
||||
valueString.MakeUpper();
|
||||
if (valueString.Left(3) == L"AES")
|
||||
UString m = prop.bstrVal;
|
||||
m.MakeUpper();
|
||||
if (m.Left(3) == L"AES")
|
||||
{
|
||||
valueString = valueString.Mid(3);
|
||||
if (valueString == L"128")
|
||||
m_AesKeyMode = 1;
|
||||
else if (valueString == L"192")
|
||||
m_AesKeyMode = 2;
|
||||
else if (valueString == L"256" || valueString.IsEmpty())
|
||||
m_AesKeyMode = 3;
|
||||
m = m.Mid(3);
|
||||
if (m == L"128")
|
||||
_props.AesKeyMode = 1;
|
||||
else if (m == L"192")
|
||||
_props.AesKeyMode = 2;
|
||||
else if (m == L"256" || m.IsEmpty())
|
||||
_props.AesKeyMode = 3;
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
m_IsAesMode = true;
|
||||
_props.IsAesMode = true;
|
||||
m_ForceAesMode = true;
|
||||
}
|
||||
else if (valueString == L"ZIPCRYPTO")
|
||||
else if (m == L"ZIPCRYPTO")
|
||||
{
|
||||
m_IsAesMode = false;
|
||||
_props.IsAesMode = false;
|
||||
m_ForceAesMode = true;
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else if (name[0] == L'D')
|
||||
{
|
||||
UInt32 dicSize = kBZip2DicSizeX5;
|
||||
RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));
|
||||
m_DicSize = dicSize;
|
||||
}
|
||||
else if (name.Left(3) == L"MEM")
|
||||
{
|
||||
UInt32 memSize = 1 << 24;
|
||||
RINOK(ParsePropDictionaryValue(name.Mid(3), prop, memSize));
|
||||
m_MemSize = memSize;
|
||||
}
|
||||
else if (name[0] == L'O')
|
||||
{
|
||||
UInt32 order = 8;
|
||||
RINOK(ParsePropValue(name.Mid(1), prop, order));
|
||||
m_Order = order;
|
||||
}
|
||||
else if (name.Left(4) == L"PASS")
|
||||
{
|
||||
UInt32 num = kDeflateNumPassesX9;
|
||||
RINOK(ParsePropValue(name.Mid(4), prop, num));
|
||||
m_NumPasses = num;
|
||||
}
|
||||
else if (name.Left(2) == L"FB")
|
||||
{
|
||||
UInt32 num = kDeflateNumFastBytesX9;
|
||||
RINOK(ParsePropValue(name.Mid(2), prop, num));
|
||||
m_NumFastBytes = num;
|
||||
}
|
||||
else if (name.Left(2) == L"MC")
|
||||
{
|
||||
UInt32 num = 0xFFFFFFFF;
|
||||
RINOK(ParsePropValue(name.Mid(2), prop, num));
|
||||
m_NumMatchFinderCycles = num;
|
||||
m_NumMatchFinderCyclesDefined = true;
|
||||
}
|
||||
else if (name.Left(2) == L"MT")
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));
|
||||
RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _props.NumThreads));
|
||||
_props.NumThreadsWasChanged = true;
|
||||
#endif
|
||||
}
|
||||
else if (name.Left(1) == L"A")
|
||||
{
|
||||
UInt32 num = kLzAlgoX5;
|
||||
RINOK(ParsePropValue(name.Mid(1), prop, num));
|
||||
m_Algo = num;
|
||||
}
|
||||
else if (name.CompareNoCase(L"TC") == 0)
|
||||
{
|
||||
RINOK(SetBoolProperty(m_WriteNtfsTimeExtra, prop));
|
||||
RINOK(PROPVARIANT_to_bool(prop, m_WriteNtfsTimeExtra));
|
||||
}
|
||||
else if (name.CompareNoCase(L"CL") == 0)
|
||||
{
|
||||
RINOK(SetBoolProperty(m_ForceLocal, prop));
|
||||
RINOK(PROPVARIANT_to_bool(prop, m_ForceLocal));
|
||||
if (m_ForceLocal)
|
||||
m_ForceUtf8 = false;
|
||||
}
|
||||
else if (name.CompareNoCase(L"CU") == 0)
|
||||
{
|
||||
RINOK(SetBoolProperty(m_ForceUtf8, prop));
|
||||
RINOK(PROPVARIANT_to_bool(prop, m_ForceUtf8));
|
||||
if (m_ForceUtf8)
|
||||
m_ForceLocal = false;
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
return _props.MethodInfo.ParseParamsFromPROPVARIANT(name, prop);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -756,6 +756,7 @@ void CEcd64::Parse(const Byte *p)
|
||||
|
||||
HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress)
|
||||
{
|
||||
IsOkHeaders = true;
|
||||
// m_Signature must be kLocalFileHeaderSignature or
|
||||
// kEndOfCentralDirSignature
|
||||
// m_Position points to next byte after signature
|
||||
@@ -852,6 +853,8 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
|
||||
|
||||
if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0)
|
||||
throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
|
||||
if (numCdItems != items.Size())
|
||||
IsOkHeaders = false;
|
||||
if ((UInt16)ecd64.numEntriesInCDOnThisDisk != ((UInt16)numCdItems) ||
|
||||
(UInt16)ecd64.numEntriesInCD != ((UInt16)numCdItems) ||
|
||||
(UInt32)ecd64.cdSize != (UInt32)cdSize ||
|
||||
@@ -861,7 +864,6 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
|
||||
|
||||
_inBufMode = false;
|
||||
_inBuffer.Free();
|
||||
IsOkHeaders = (numCdItems == items.Size());
|
||||
ArcInfo.FinishPosition = m_Position;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ bool CExtraSubBlock::ExtractNtfsTime(int index, FILETIME &ft) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CExtraSubBlock::ExtractUnixTime(int index, UInt32 &res) const
|
||||
bool CExtraSubBlock::ExtractUnixTime(bool isCentral, int index, UInt32 &res) const
|
||||
{
|
||||
res = 0;
|
||||
UInt32 size = (UInt32)Data.GetCapacity();
|
||||
@@ -60,6 +60,15 @@ bool CExtraSubBlock::ExtractUnixTime(int index, UInt32 &res) const
|
||||
const Byte *p = (const Byte *)Data;
|
||||
Byte flags = *p++;
|
||||
size--;
|
||||
if (isCentral)
|
||||
{
|
||||
if (index != NFileHeader::NUnixTime::kMTime ||
|
||||
(flags & (1 << NFileHeader::NUnixTime::kMTime)) == 0 ||
|
||||
size < 4)
|
||||
return false;
|
||||
res = GetUi32(p);
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < 3; i++)
|
||||
if ((flags & (1 << i)) != 0)
|
||||
{
|
||||
@@ -88,7 +97,7 @@ bool CItem::IsDir() const
|
||||
if (!FromCentral)
|
||||
return false;
|
||||
WORD highAttributes = WORD((ExternalAttributes >> 16 ) & 0xFFFF);
|
||||
switch(MadeByVersion.HostOS)
|
||||
switch (MadeByVersion.HostOS)
|
||||
{
|
||||
case NFileHeader::NHostOS::kAMIGA:
|
||||
switch (highAttributes & NFileHeader::NAmigaAttribute::kIFMT)
|
||||
@@ -109,44 +118,41 @@ bool CItem::IsDir() const
|
||||
case NFileHeader::NHostOS::kAcorn:
|
||||
case NFileHeader::NHostOS::kMVS:
|
||||
return false; // change it throw kUnknownAttributes;
|
||||
case NFileHeader::NHostOS::kUnix:
|
||||
return (highAttributes & NFileHeader::NUnixAttribute::kIFDIR) != 0;
|
||||
default:
|
||||
/*
|
||||
switch (highAttributes & NFileHeader::NUnixAttribute::kIFMT)
|
||||
{
|
||||
case NFileHeader::NUnixAttribute::kIFDIR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 CLocalItem::GetWinAttributes() const
|
||||
UInt32 CItem::GetWinAttrib() const
|
||||
{
|
||||
DWORD winAttributes = 0;
|
||||
if (IsDir())
|
||||
winAttributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
return winAttributes;
|
||||
}
|
||||
|
||||
UInt32 CItem::GetWinAttributes() const
|
||||
{
|
||||
DWORD winAttributes = 0;
|
||||
switch(MadeByVersion.HostOS)
|
||||
DWORD winAttrib = 0;
|
||||
switch (MadeByVersion.HostOS)
|
||||
{
|
||||
case NFileHeader::NHostOS::kFAT:
|
||||
case NFileHeader::NHostOS::kNTFS:
|
||||
if (FromCentral)
|
||||
winAttributes = ExternalAttributes;
|
||||
winAttrib = ExternalAttributes;
|
||||
break;
|
||||
default:
|
||||
winAttributes = 0; // must be converted from unix value;
|
||||
}
|
||||
if (IsDir()) // test it;
|
||||
winAttributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
return winAttributes;
|
||||
if (IsDir()) // test it;
|
||||
winAttrib |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
return winAttrib;
|
||||
}
|
||||
|
||||
bool CItem::GetPosixAttrib(UInt32 &attrib) const
|
||||
{
|
||||
// some archivers can store PosixAttrib in high 16 bits even with HostOS=FAT.
|
||||
if (FromCentral && MadeByVersion.HostOS == NFileHeader::NHostOS::kUnix)
|
||||
{
|
||||
attrib = ExternalAttributes >> 16;
|
||||
return (attrib != 0);
|
||||
}
|
||||
attrib = 0;
|
||||
if (IsDir())
|
||||
attrib = NFileHeader::NUnixAttribute::kIFDIR;
|
||||
return false;
|
||||
}
|
||||
|
||||
void CLocalItem::SetFlagBits(int startBitNumber, int numBits, int value)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#ifndef __ARCHIVE_ZIP_ITEM_H
|
||||
#define __ARCHIVE_ZIP_ITEM_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
#include "Common/MyString.h"
|
||||
#include "Common/Buffer.h"
|
||||
#include "Common/UTFConvert.h"
|
||||
@@ -28,7 +27,7 @@ struct CExtraSubBlock
|
||||
UInt16 ID;
|
||||
CByteBuffer Data;
|
||||
bool ExtractNtfsTime(int index, FILETIME &ft) const;
|
||||
bool ExtractUnixTime(int index, UInt32 &res) const;
|
||||
bool ExtractUnixTime(bool isCentral, int index, UInt32 &res) const;
|
||||
};
|
||||
|
||||
struct CWzAesExtraField
|
||||
@@ -152,13 +151,13 @@ struct CExtraBlock
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetUnixTime(int index, UInt32 &res) const
|
||||
bool GetUnixTime(bool isCentral, int index, UInt32 &res) const
|
||||
{
|
||||
for (int i = 0; i < SubBlocks.Size(); i++)
|
||||
{
|
||||
const CExtraSubBlock &sb = SubBlocks[i];
|
||||
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
|
||||
return sb.ExtractUnixTime(index, res);
|
||||
return sb.ExtractUnixTime(isCentral, index, res);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -205,7 +204,6 @@ public:
|
||||
|
||||
bool IsDir() const;
|
||||
bool IgnoreItem() const { return false; }
|
||||
UInt32 GetWinAttributes() const;
|
||||
|
||||
bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; }
|
||||
|
||||
@@ -252,7 +250,8 @@ public:
|
||||
bool NtfsTimeIsDefined;
|
||||
|
||||
bool IsDir() const;
|
||||
UInt32 GetWinAttributes() const;
|
||||
UInt32 GetWinAttrib() const;
|
||||
bool GetPosixAttrib(UInt32 &attrib) const;
|
||||
|
||||
bool IsThereCrc() const
|
||||
{
|
||||
@@ -277,5 +276,3 @@ public:
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -473,6 +473,9 @@ static HRESULT Update2St(
|
||||
items.Add(item);
|
||||
lps->ProgressOffset += NFileHeader::kLocalBlockSize;
|
||||
}
|
||||
lps->InSize = unpackSizeTotal;
|
||||
lps->OutSize = packSizeTotal;
|
||||
RINOK(lps->SetCur());
|
||||
archive.WriteCentralDir(items, comment);
|
||||
return S_OK;
|
||||
}
|
||||
@@ -493,7 +496,7 @@ static HRESULT Update2(
|
||||
UInt64 numBytesToCompress = 0;
|
||||
|
||||
int i;
|
||||
for(i = 0; i < updateItems.Size(); i++)
|
||||
for (i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &ui = updateItems[i];
|
||||
if (ui.NewData)
|
||||
@@ -527,6 +530,10 @@ static HRESULT Update2(
|
||||
|
||||
complexity = 0;
|
||||
|
||||
CCompressionMethodMode options2;
|
||||
if (options != 0)
|
||||
options2 = *options;
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
|
||||
const size_t kNumMaxThreads = (1 << 10);
|
||||
@@ -537,53 +544,58 @@ static HRESULT Update2(
|
||||
const size_t kMemPerThread = (1 << 25);
|
||||
const size_t kBlockSize = 1 << 16;
|
||||
|
||||
CCompressionMethodMode options2;
|
||||
if (options != 0)
|
||||
options2 = *options;
|
||||
|
||||
bool mtMode = ((options != 0) && (numThreads > 1));
|
||||
|
||||
if (numFilesToCompress <= 1)
|
||||
mtMode = false;
|
||||
|
||||
if (mtMode)
|
||||
if (!mtMode)
|
||||
{
|
||||
if (numThreads < 2)
|
||||
if (options2.MethodInfo.FindProp(NCoderPropID::kNumThreads) < 0 &&
|
||||
options2.NumThreadsWasChanged)
|
||||
options2.MethodInfo.AddNumThreadsProp(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Byte method = options->MethodSequence.Front();
|
||||
if (method == NFileHeader::NCompressionMethod::kStored && !options->PasswordIsDefined)
|
||||
mtMode = false;
|
||||
numThreads = 1;
|
||||
if (method == NFileHeader::NCompressionMethod::kBZip2)
|
||||
{
|
||||
UInt64 averageSize = numBytesToCompress / numFilesToCompress;
|
||||
UInt32 blockSize = options->DicSize;
|
||||
if (blockSize == 0)
|
||||
blockSize = 1;
|
||||
UInt64 averageNumberOfBlocks = averageSize / blockSize;
|
||||
UInt32 numBZip2Threads = 32;
|
||||
if (averageNumberOfBlocks < numBZip2Threads)
|
||||
numBZip2Threads = (UInt32)averageNumberOfBlocks;
|
||||
if (numBZip2Threads < 1)
|
||||
numBZip2Threads = 1;
|
||||
numThreads = numThreads / numBZip2Threads;
|
||||
options2.NumThreads = numBZip2Threads;
|
||||
if (numThreads <= 1)
|
||||
mtMode = false;
|
||||
bool fixedNumber;
|
||||
UInt32 numBZip2Threads = options2.MethodInfo.Get_BZip2_NumThreads(fixedNumber);
|
||||
if (!fixedNumber)
|
||||
{
|
||||
UInt64 averageSize = numBytesToCompress / numFilesToCompress;
|
||||
UInt32 blockSize = options2.MethodInfo.Get_BZip2_BlockSize();
|
||||
UInt64 averageNumberOfBlocks = averageSize / blockSize + 1;
|
||||
numBZip2Threads = 32;
|
||||
if (averageNumberOfBlocks < numBZip2Threads)
|
||||
numBZip2Threads = (UInt32)averageNumberOfBlocks;
|
||||
options2.MethodInfo.AddNumThreadsProp(numBZip2Threads);
|
||||
}
|
||||
numThreads /= numBZip2Threads;
|
||||
}
|
||||
if (method == NFileHeader::NCompressionMethod::kLZMA)
|
||||
{
|
||||
UInt32 numLZMAThreads = (options->Algo > 0 ? 2 : 1);
|
||||
bool fixedNumber;
|
||||
// we suppose that default LZMA is 2 thread. So we don't change it
|
||||
UInt32 numLZMAThreads = options2.MethodInfo.Get_Lzma_NumThreads(fixedNumber);
|
||||
numThreads /= numLZMAThreads;
|
||||
options2.NumThreads = numLZMAThreads;
|
||||
if (numThreads <= 1)
|
||||
mtMode = false;
|
||||
}
|
||||
if (numThreads > numFilesToCompress)
|
||||
numThreads = (UInt32)numFilesToCompress;
|
||||
if (numThreads <= 1)
|
||||
mtMode = false;
|
||||
}
|
||||
|
||||
if (!mtMode)
|
||||
#endif
|
||||
return Update2St(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
archive, inArchive,inStream,
|
||||
inputItems, updateItems, options, comment, updateCallback);
|
||||
archive, inArchive, inStream,
|
||||
inputItems, updateItems, &options2, comment, updateCallback);
|
||||
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
@@ -606,7 +618,7 @@ static HRESULT Update2(
|
||||
|
||||
{
|
||||
RINOK(memManager.AllocateSpaceAlways((size_t)numThreads * (kMemPerThread / kBlockSize)));
|
||||
for(i = 0; i < updateItems.Size(); i++)
|
||||
for (i = 0; i < updateItems.Size(); i++)
|
||||
refs.Refs.Add(CMemBlocks2());
|
||||
|
||||
UInt32 i;
|
||||
@@ -796,6 +808,7 @@ static HRESULT Update2(
|
||||
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
|
||||
itemIndex++;
|
||||
}
|
||||
RINOK(mtCompressProgressMixer.SetRatioInfo(0, NULL, NULL));
|
||||
archive.WriteCentralDir(items, comment);
|
||||
return S_OK;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user