mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-09 06:07:05 -06:00
21.02
This commit is contained in:
@@ -57,18 +57,20 @@ struct CCompressionMethodMode
|
||||
#endif
|
||||
|
||||
bool PasswordIsDefined;
|
||||
UString Password;
|
||||
UString Password; // _Wipe
|
||||
|
||||
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
|
||||
CCompressionMethodMode():
|
||||
DefaultMethod_was_Inserted(false),
|
||||
Filter_was_Inserted(false),
|
||||
PasswordIsDefined(false)
|
||||
DefaultMethod_was_Inserted(false)
|
||||
, Filter_was_Inserted(false)
|
||||
#ifndef _7ZIP_ST
|
||||
, NumThreads(1)
|
||||
, MultiThreadMixer(true)
|
||||
#endif
|
||||
, PasswordIsDefined(false)
|
||||
{}
|
||||
|
||||
~CCompressionMethodMode() { Password.Wipe_and_Empty(); }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -158,7 +158,7 @@ STDMETHODIMP CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *
|
||||
|
||||
if (_pos != _glob->Pos)
|
||||
{
|
||||
RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL));
|
||||
RINOK(_glob->Stream->Seek((Int64)_pos, STREAM_SEEK_SET, NULL));
|
||||
_glob->Pos = _pos;
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ STDMETHODIMP CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *
|
||||
{
|
||||
if (_pos != _glob->Pos)
|
||||
{
|
||||
RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL));
|
||||
RINOK(_glob->Stream->Seek((Int64)_pos, STREAM_SEEK_SET, NULL));
|
||||
_glob->Pos = _pos;
|
||||
}
|
||||
|
||||
@@ -276,6 +276,7 @@ HRESULT CDecoder::Decode(
|
||||
|
||||
if (!_bindInfoPrev_Defined || !AreBindInfoExEqual(bindInfo, _bindInfoPrev))
|
||||
{
|
||||
_bindInfoPrev_Defined = false;
|
||||
_mixerRef.Release();
|
||||
|
||||
#ifdef USE_MIXER_MT
|
||||
@@ -348,7 +349,7 @@ HRESULT CDecoder::Decode(
|
||||
_bindInfoPrev_Defined = true;
|
||||
}
|
||||
|
||||
_mixer->ReInit();
|
||||
RINOK(_mixer->ReInit2());
|
||||
|
||||
UInt32 packStreamIndex = 0;
|
||||
UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex];
|
||||
@@ -396,10 +397,10 @@ HRESULT CDecoder::Decode(
|
||||
if (setDecoderProperties)
|
||||
{
|
||||
const CByteBuffer &props = coderInfo.Props;
|
||||
size_t size = props.Size();
|
||||
if (size > 0xFFFFFFFF)
|
||||
const UInt32 size32 = (UInt32)props.Size();
|
||||
if (props.Size() != size32)
|
||||
return E_NOTIMPL;
|
||||
HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size);
|
||||
HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, size32);
|
||||
if (res == E_INVALIDARG)
|
||||
res = E_NOTIMPL;
|
||||
RINOK(res);
|
||||
@@ -415,17 +416,17 @@ HRESULT CDecoder::Decode(
|
||||
isEncrypted = true;
|
||||
if (!getTextPassword)
|
||||
return E_NOTIMPL;
|
||||
CMyComBSTR passwordBSTR;
|
||||
CMyComBSTR_Wipe passwordBSTR;
|
||||
RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
|
||||
passwordIsDefined = true;
|
||||
password.Empty();
|
||||
password.Wipe_and_Empty();
|
||||
size_t len = 0;
|
||||
if (passwordBSTR)
|
||||
{
|
||||
password = passwordBSTR;
|
||||
len = password.Len();
|
||||
}
|
||||
CByteBuffer buffer(len * 2);
|
||||
CByteBuffer_Wipe buffer(len * 2);
|
||||
for (size_t k = 0; k < len; k++)
|
||||
{
|
||||
wchar_t c = passwordBSTR[k];
|
||||
@@ -444,7 +445,7 @@ HRESULT CDecoder::Decode(
|
||||
if (setFinishMode)
|
||||
{
|
||||
finishMode = fullUnpack;
|
||||
RINOK(setFinishMode->SetFinishMode(BoolToInt(finishMode)));
|
||||
RINOK(setFinishMode->SetFinishMode(BoolToUInt(finishMode)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,36 +488,49 @@ HRESULT CDecoder::Decode(
|
||||
CLockedInStream *lockedInStreamSpec = new CLockedInStream;
|
||||
CMyComPtr<IUnknown> lockedInStream = lockedInStreamSpec;
|
||||
|
||||
bool needMtLock = false;
|
||||
#ifdef USE_MIXER_MT
|
||||
#ifdef USE_MIXER_ST
|
||||
bool needMtLock = _useMixerMT;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (folderInfo.PackStreams.Size() > 1)
|
||||
{
|
||||
// lockedInStream.Pos = (UInt64)(Int64)-1;
|
||||
// RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &lockedInStream.Pos));
|
||||
RINOK(inStream->Seek(startPos + packPositions[0], STREAM_SEEK_SET, &lockedInStreamSpec->Pos));
|
||||
RINOK(inStream->Seek((Int64)(startPos + packPositions[0]), STREAM_SEEK_SET, &lockedInStreamSpec->Pos));
|
||||
lockedInStreamSpec->Stream = inStream;
|
||||
|
||||
#ifdef USE_MIXER_MT
|
||||
#ifdef USE_MIXER_ST
|
||||
if (_mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex))
|
||||
#endif
|
||||
/*
|
||||
For ST-mixer mode:
|
||||
If parallel input stream reading from pack streams is possible,
|
||||
we must use MT-lock for packed streams.
|
||||
Internal decoders in 7-Zip will not read pack streams in parallel in ST-mixer mode.
|
||||
So we force to needMtLock mode only if there is unknown (external) decoder.
|
||||
*/
|
||||
if (!needMtLock && _mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex))
|
||||
needMtLock = true;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++)
|
||||
{
|
||||
CMyComPtr<ISequentialInStream> packStream;
|
||||
UInt64 packPos = startPos + packPositions[j];
|
||||
const UInt64 packPos = startPos + packPositions[j];
|
||||
|
||||
if (folderInfo.PackStreams.Size() == 1)
|
||||
{
|
||||
RINOK(inStream->Seek(packPos, STREAM_SEEK_SET, NULL));
|
||||
RINOK(inStream->Seek((Int64)packPos, STREAM_SEEK_SET, NULL));
|
||||
packStream = inStream;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_MIXER_MT
|
||||
#ifdef USE_MIXER_ST
|
||||
if (_useMixerMT || needMtLock)
|
||||
if (needMtLock)
|
||||
#endif
|
||||
{
|
||||
CLockedSequentialInStreamMT *lockedStreamImpSpec = new CLockedSequentialInStreamMT;
|
||||
@@ -542,7 +556,7 @@ HRESULT CDecoder::Decode(
|
||||
streamSpec->Init(packPositions[j + 1] - packPositions[j]);
|
||||
}
|
||||
|
||||
unsigned num = inStreams.Size();
|
||||
const unsigned num = inStreams.Size();
|
||||
CObjArray<ISequentialInStream *> inStreamPointers(num);
|
||||
for (i = 0; i < num; i++)
|
||||
inStreamPointers[i] = inStreams[i];
|
||||
|
||||
@@ -158,7 +158,7 @@ HRESULT CEncoder::CreateMixerCoder(
|
||||
{
|
||||
RINOK(CreateCoder_Index(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
methodFull.CodecIndex, true, cod));
|
||||
(unsigned)methodFull.CodecIndex, true, cod));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -215,7 +215,7 @@ HRESULT CEncoder::CreateMixerCoder(
|
||||
if (cryptoSetPassword)
|
||||
{
|
||||
const unsigned sizeInBytes = _options.Password.Len() * 2;
|
||||
CByteBuffer buffer(sizeInBytes);
|
||||
CByteBuffer_Wipe buffer(sizeInBytes);
|
||||
for (unsigned i = 0; i < _options.Password.Len(); i++)
|
||||
{
|
||||
wchar_t c = _options.Password[i];
|
||||
@@ -249,11 +249,12 @@ public:
|
||||
|
||||
STDMETHODIMP CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed)
|
||||
{
|
||||
if (!_buf->Write(data, size))
|
||||
HRESULT res = _buf->Write_HRESULT(data, size);
|
||||
if (res != S_OK)
|
||||
{
|
||||
if (processed)
|
||||
*processed = 0;
|
||||
return E_FAIL;
|
||||
return res;
|
||||
}
|
||||
if (processed)
|
||||
*processed = size;
|
||||
@@ -309,7 +310,7 @@ HRESULT CEncoder::Encode(
|
||||
RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
|
||||
}
|
||||
|
||||
_mixer->ReInit();
|
||||
RINOK(_mixer->ReInit2());
|
||||
|
||||
CMtEncMultiProgress *mtProgressSpec = NULL;
|
||||
CMyComPtr<ICompressProgressInfo> mtProgress;
|
||||
@@ -478,7 +479,7 @@ HRESULT CEncoder::Encode(
|
||||
unpackSize = streamSize;
|
||||
}
|
||||
else
|
||||
streamSize = _mixer->GetBondStreamSize(bond);
|
||||
streamSize = _mixer->GetBondStreamSize((unsigned)bond);
|
||||
coderUnpackSizes.Add(streamSize);
|
||||
}
|
||||
|
||||
@@ -609,13 +610,13 @@ HRESULT CEncoder::EncoderConstr()
|
||||
int bond = _bindInfo.FindBond_for_PackStream(outIndex);
|
||||
if (bond >= 0)
|
||||
{
|
||||
ci = _bindInfo.Bonds[bond].UnpackIndex;
|
||||
ci = _bindInfo.Bonds[(unsigned)bond].UnpackIndex;
|
||||
continue;
|
||||
}
|
||||
|
||||
int si = _bindInfo.FindStream_in_PackStreams(outIndex);
|
||||
if (si >= 0)
|
||||
_bindInfo.PackStreams.MoveToFront(si);
|
||||
_bindInfo.PackStreams.MoveToFront((unsigned)si);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
};
|
||||
|
||||
class CEncoder
|
||||
class CEncoder MY_UNCOPYABLE
|
||||
{
|
||||
#ifdef USE_MIXER_ST
|
||||
NCoderMixer2::CMixerST *_mixerST;
|
||||
|
||||
@@ -217,6 +217,10 @@ HRESULT CFolderOutStream::FlushCorrupted(Int32 callbackOperationResult)
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
|
||||
{
|
||||
// for GCC
|
||||
// CFolderOutStream *folderOutStream = new CFolderOutStream;
|
||||
// CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
|
||||
|
||||
COM_TRY_BEGIN
|
||||
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||
@@ -350,7 +354,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
#ifndef _NO_CRYPTO
|
||||
bool isEncrypted = false;
|
||||
bool passwordIsDefined = false;
|
||||
UString password;
|
||||
UString_Wipe password;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -411,7 +415,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
||||
// continue;
|
||||
return E_FAIL;
|
||||
// return E_FAIL;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -107,34 +107,62 @@ static void ConvertMethodIdToString(AString &res, UInt64 id)
|
||||
res += s + len - ConvertMethodIdToString_Back(s + len, id);
|
||||
}
|
||||
|
||||
static unsigned GetStringForSizeValue(char *s, UInt32 val)
|
||||
|
||||
static char *GetStringForSizeValue(char *s, UInt32 val)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i <= 31; i++)
|
||||
if (((UInt32)1 << i) == val)
|
||||
{
|
||||
if (i < 10)
|
||||
if (i >= 10)
|
||||
{
|
||||
s[0] = (char)('0' + i);
|
||||
s[1] = 0;
|
||||
return 1;
|
||||
*s++= (char)('0' + i / 10);
|
||||
i %= 10;
|
||||
}
|
||||
if (i < 20) { s[0] = '1'; s[1] = (char)('0' + i - 10); }
|
||||
else if (i < 30) { s[0] = '2'; s[1] = (char)('0' + i - 20); }
|
||||
else { s[0] = '3'; s[1] = (char)('0' + i - 30); }
|
||||
s[2] = 0;
|
||||
return 2;
|
||||
*s++ = (char)('0' + i);
|
||||
*s = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
char c = 'b';
|
||||
if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
|
||||
else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
|
||||
::ConvertUInt32ToString(val, s);
|
||||
unsigned pos = MyStringLen(s);
|
||||
s[pos++] = c;
|
||||
s[pos] = 0;
|
||||
return pos;
|
||||
s = ConvertUInt32ToString(val, s);
|
||||
*s++ = c;
|
||||
*s = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
static void GetLzma2String(char *s, unsigned d)
|
||||
{
|
||||
if (d > 40)
|
||||
{
|
||||
*s = 0;
|
||||
return;
|
||||
// s = MyStpCpy(s, "unsup");
|
||||
}
|
||||
else if ((d & 1) == 0)
|
||||
d = (d >> 1) + 12;
|
||||
else
|
||||
{
|
||||
// s = GetStringForSizeValue(s, (UInt32)3 << ((d >> 1) + 11));
|
||||
d = (d >> 1) + 1;
|
||||
char c = 'k';
|
||||
if (d >= 10)
|
||||
{
|
||||
c = 'm';
|
||||
d -= 10;
|
||||
}
|
||||
s = ConvertUInt32ToString((UInt32)3 << d, s);
|
||||
*s++ = c;
|
||||
*s = 0;
|
||||
return;
|
||||
}
|
||||
ConvertUInt32ToString(d, s);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
static inline void AddHexToString(UString &res, Byte value)
|
||||
{
|
||||
@@ -147,8 +175,7 @@ static char *AddProp32(char *s, const char *name, UInt32 v)
|
||||
{
|
||||
*s++ = ':';
|
||||
s = MyStpCpy(s, name);
|
||||
::ConvertUInt32ToString(v, s);
|
||||
return s + MyStringLen(s);
|
||||
return ConvertUInt32ToString(v, s);
|
||||
}
|
||||
|
||||
void CHandler::AddMethodName(AString &s, UInt64 id)
|
||||
@@ -184,10 +211,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
if (id == k_LZMA2)
|
||||
{
|
||||
s += "LZMA2:";
|
||||
if ((pm.Lzma2Prop & 1) == 0)
|
||||
ConvertUInt32ToString((pm.Lzma2Prop >> 1) + 12, temp);
|
||||
else
|
||||
GetStringForSizeValue(temp, 3 << ((pm.Lzma2Prop >> 1) + 11));
|
||||
GetLzma2String(temp, pm.Lzma2Prop);
|
||||
s += temp;
|
||||
}
|
||||
else if (id == k_LZMA)
|
||||
@@ -244,14 +268,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
break;
|
||||
}
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
return prop.Detach(value);
|
||||
#ifndef _SFX
|
||||
COM_TRY_END
|
||||
#endif
|
||||
}
|
||||
|
||||
static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, int index)
|
||||
static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, unsigned index)
|
||||
{
|
||||
UInt64 value;
|
||||
if (v.GetItem(index, value))
|
||||
@@ -416,7 +439,7 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
|
||||
if (propsSize == 5)
|
||||
{
|
||||
UInt32 dicSize = GetUi32((const Byte *)props + 1);
|
||||
char *dest = s + GetStringForSizeValue(s, dicSize);
|
||||
char *dest = GetStringForSizeValue(s, dicSize);
|
||||
UInt32 d = props[0];
|
||||
if (d != 0x5D)
|
||||
{
|
||||
@@ -434,24 +457,16 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
|
||||
{
|
||||
name = "LZMA2";
|
||||
if (propsSize == 1)
|
||||
{
|
||||
Byte d = props[0];
|
||||
if ((d & 1) == 0)
|
||||
ConvertUInt32ToString((UInt32)((d >> 1) + 12), s);
|
||||
else
|
||||
GetStringForSizeValue(s, 3 << ((d >> 1) + 11));
|
||||
}
|
||||
GetLzma2String(s, props[0]);
|
||||
}
|
||||
else if (id == k_PPMD)
|
||||
{
|
||||
name = "PPMD";
|
||||
if (propsSize == 5)
|
||||
{
|
||||
Byte order = *props;
|
||||
char *dest = s;
|
||||
*dest++ = 'o';
|
||||
ConvertUInt32ToString(order, dest);
|
||||
dest += MyStringLen(dest);
|
||||
dest = ConvertUInt32ToString(*props, dest);
|
||||
dest = MyStpCpy(dest, ":mem");
|
||||
GetStringForSizeValue(dest, GetUi32(props + 1));
|
||||
}
|
||||
@@ -534,7 +549,7 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
PropVariant_Clear(value);
|
||||
RINOK(PropVariant_Clear(value));
|
||||
// COM_TRY_BEGIN
|
||||
// NCOM::CPropVariant prop;
|
||||
|
||||
@@ -637,7 +652,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
|
||||
#endif
|
||||
}
|
||||
// prop.Detach(value);
|
||||
// return prop.Detach(value);
|
||||
return S_OK;
|
||||
// COM_TRY_END
|
||||
}
|
||||
@@ -708,7 +723,7 @@ STDMETHODIMP CHandler::Close()
|
||||
#ifndef _NO_CRYPTO
|
||||
_isEncrypted = false;
|
||||
_passwordIsDefined = false;
|
||||
_password.Empty();
|
||||
_password.Wipe_and_Empty();
|
||||
#endif
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
|
||||
@@ -129,6 +129,10 @@ public:
|
||||
DECL_ISetCompressCodecsInfo
|
||||
|
||||
CHandler();
|
||||
~CHandler()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private:
|
||||
CMyComPtr<IInStream> _inStream;
|
||||
@@ -137,7 +141,7 @@ private:
|
||||
#ifndef _NO_CRYPTO
|
||||
bool _isEncrypted;
|
||||
bool _passwordIsDefined;
|
||||
UString _password;
|
||||
UString _password; // _Wipe
|
||||
#endif
|
||||
|
||||
#ifdef EXTRACT_ONLY
|
||||
|
||||
@@ -111,7 +111,7 @@ HRESULT CHandler::SetMainMethod(
|
||||
}
|
||||
|
||||
const UInt64 kSolidBytes_Min = (1 << 24);
|
||||
const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
|
||||
const UInt64 kSolidBytes_Max = ((UInt64)1 << 32);
|
||||
|
||||
bool needSolid = false;
|
||||
|
||||
@@ -140,26 +140,52 @@ HRESULT CHandler::SetMainMethod(
|
||||
case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break;
|
||||
case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break;
|
||||
case k_Deflate: dicSize = (UInt32)1 << 15; break;
|
||||
case k_Deflate64: dicSize = (UInt32)1 << 16; break;
|
||||
case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
|
||||
default: continue;
|
||||
}
|
||||
|
||||
_numSolidBytes = (UInt64)dicSize << 7;
|
||||
if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
|
||||
if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
|
||||
|
||||
if (methodFull.Id == k_LZMA2)
|
||||
{
|
||||
// he we calculate default chunk Size for LZMA2 as defined in LZMA2 encoder code
|
||||
UInt64 cs = (UInt64)dicSize << 2;
|
||||
const UInt32 kMinSize = (UInt32)1 << 20;
|
||||
const UInt32 kMaxSize = (UInt32)1 << 28;
|
||||
if (cs < kMinSize) cs = kMinSize;
|
||||
if (cs > kMaxSize) cs = kMaxSize;
|
||||
if (cs < dicSize) cs = dicSize;
|
||||
cs += (kMinSize - 1);
|
||||
cs &= ~(UInt64)(kMinSize - 1);
|
||||
// we want to use at least 64 chunks (threads) per one solid block.
|
||||
_numSolidBytes = cs << 6;
|
||||
const UInt64 kSolidBytes_Lzma2_Max = ((UInt64)1 << 34);
|
||||
if (_numSolidBytes > kSolidBytes_Lzma2_Max)
|
||||
_numSolidBytes = kSolidBytes_Lzma2_Max;
|
||||
}
|
||||
else
|
||||
{
|
||||
_numSolidBytes = (UInt64)dicSize << 7;
|
||||
if (_numSolidBytes > kSolidBytes_Max)
|
||||
_numSolidBytes = kSolidBytes_Max;
|
||||
}
|
||||
|
||||
if (_numSolidBytes < kSolidBytes_Min)
|
||||
_numSolidBytes = kSolidBytes_Min;
|
||||
_numSolidBytesDefined = true;
|
||||
}
|
||||
|
||||
if (!_numSolidBytesDefined)
|
||||
{
|
||||
if (needSolid)
|
||||
_numSolidBytes = kSolidBytes_Max;
|
||||
else
|
||||
_numSolidBytes = 0;
|
||||
}
|
||||
_numSolidBytesDefined = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, UInt64 &ft, bool &ftDefined)
|
||||
static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, unsigned index, PROPID propID, UInt64 &ft, bool &ftDefined)
|
||||
{
|
||||
// ft = 0;
|
||||
// ftDefined = false;
|
||||
@@ -289,8 +315,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
|
||||
bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
|
||||
bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
|
||||
bool need_Attrib = (Write_Attrib.Def && Write_Attrib.Val || !Write_Attrib.Def);
|
||||
bool need_MTime = (Write_MTime.Def ? Write_MTime.Val : true);
|
||||
bool need_Attrib = (Write_Attrib.Def ? Write_Attrib.Val : true);
|
||||
|
||||
if (db && !db->Files.IsEmpty())
|
||||
{
|
||||
@@ -313,7 +339,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
CUpdateItem ui;
|
||||
ui.NewProps = IntToBool(newProps);
|
||||
ui.NewData = IntToBool(newData);
|
||||
ui.IndexInArchive = indexInArchive;
|
||||
ui.IndexInArchive = (int)indexInArchive;
|
||||
ui.IndexInClient = i;
|
||||
ui.IsAnti = false;
|
||||
ui.Size = 0;
|
||||
@@ -322,23 +348,23 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
// bool isAltStream = false;
|
||||
if (ui.IndexInArchive != -1)
|
||||
{
|
||||
if (db == 0 || (unsigned)ui.IndexInArchive >= db->Files.Size())
|
||||
if (!db || (unsigned)ui.IndexInArchive >= db->Files.Size())
|
||||
return E_INVALIDARG;
|
||||
const CFileItem &fi = db->Files[ui.IndexInArchive];
|
||||
const CFileItem &fi = db->Files[(unsigned)ui.IndexInArchive];
|
||||
if (!ui.NewProps)
|
||||
{
|
||||
_db.GetPath(ui.IndexInArchive, name);
|
||||
_db.GetPath((unsigned)ui.IndexInArchive, name);
|
||||
}
|
||||
ui.IsDir = fi.IsDir;
|
||||
ui.Size = fi.Size;
|
||||
// isAltStream = fi.IsAltStream;
|
||||
ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
|
||||
ui.IsAnti = db->IsItemAnti((unsigned)ui.IndexInArchive);
|
||||
|
||||
if (!ui.NewProps)
|
||||
{
|
||||
ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
|
||||
ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
|
||||
ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
|
||||
ui.CTimeDefined = db->CTime.GetItem((unsigned)ui.IndexInArchive, ui.CTime);
|
||||
ui.ATimeDefined = db->ATime.GetItem((unsigned)ui.IndexInArchive, ui.ATime);
|
||||
ui.MTimeDefined = db->MTime.GetItem((unsigned)ui.IndexInArchive, ui.MTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,10 +596,10 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2);
|
||||
|
||||
methodMode.PasswordIsDefined = false;
|
||||
methodMode.Password.Empty();
|
||||
methodMode.Password.Wipe_and_Empty();
|
||||
if (getPassword2)
|
||||
{
|
||||
CMyComBSTR password;
|
||||
CMyComBSTR_Wipe password;
|
||||
Int32 passwordIsDefined;
|
||||
RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password));
|
||||
methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
|
||||
@@ -751,7 +777,7 @@ HRESULT COutHandler::SetSolidFromString(const UString &s)
|
||||
_solidExtension = true;
|
||||
continue;
|
||||
}
|
||||
i += (int)(end - start);
|
||||
i += (unsigned)(end - start);
|
||||
if (i == s2.Len())
|
||||
return E_INVALIDARG;
|
||||
wchar_t c = s2[i++];
|
||||
@@ -829,7 +855,7 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
|
||||
}
|
||||
|
||||
UInt32 number;
|
||||
int index = ParseStringToUInt32(name, number);
|
||||
unsigned index = ParseStringToUInt32(name, number);
|
||||
// UString realName = name.Ptr(index);
|
||||
if (index == 0)
|
||||
{
|
||||
|
||||
@@ -108,8 +108,9 @@ const UInt32 k_SWAP4 = 0x20304;
|
||||
const UInt32 k_LZMA = 0x30101;
|
||||
const UInt32 k_PPMD = 0x30401;
|
||||
|
||||
const UInt32 k_Deflate = 0x40108;
|
||||
const UInt32 k_BZip2 = 0x40202;
|
||||
const UInt32 k_Deflate = 0x40108;
|
||||
const UInt32 k_Deflate64 = 0x40109;
|
||||
const UInt32 k_BZip2 = 0x40202;
|
||||
|
||||
const UInt32 k_BCJ = 0x3030103;
|
||||
const UInt32 k_BCJ2 = 0x303011B;
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "../../../../C/7zCrc.h"
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
// #include "../../../Common/UTFConvert.h"
|
||||
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
@@ -32,6 +34,7 @@ using namespace NCOM;
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
unsigned BoolVector_CountSum(const CBoolVector &v);
|
||||
unsigned BoolVector_CountSum(const CBoolVector &v)
|
||||
{
|
||||
unsigned sum = 0;
|
||||
@@ -59,9 +62,13 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
|
||||
class CInArchiveException {};
|
||||
class CUnsupportedFeatureException: public CInArchiveException {};
|
||||
|
||||
MY_ATTR_NORETURN
|
||||
static void ThrowException() { throw CInArchiveException(); }
|
||||
MY_ATTR_NORETURN
|
||||
static inline void ThrowEndOfData() { ThrowException(); }
|
||||
MY_ATTR_NORETURN
|
||||
static inline void ThrowUnsupported() { throw CUnsupportedFeatureException(); }
|
||||
MY_ATTR_NORETURN
|
||||
static inline void ThrowIncorrect() { ThrowException(); }
|
||||
|
||||
class CStreamSwitch
|
||||
@@ -328,7 +335,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
|
||||
{
|
||||
memcpy(_header, p, kHeaderSize);
|
||||
_arhiveBeginStreamPosition += offset + pos;
|
||||
return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL);
|
||||
return stream->Seek((Int64)(_arhiveBeginStreamPosition + kHeaderSize), STREAM_SEEK_SET, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +351,7 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
|
||||
Close();
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition))
|
||||
RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL))
|
||||
RINOK(stream->Seek((Int64)_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL))
|
||||
RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
|
||||
_stream = stream;
|
||||
return S_OK;
|
||||
@@ -478,7 +485,7 @@ void CDatabase::GetPath(unsigned index, UString &path) const
|
||||
|
||||
#if defined(_WIN32) && defined(MY_CPU_LE)
|
||||
|
||||
wmemcpy(s, (const wchar_t *)p, size);
|
||||
wmemcpy(s, (const wchar_t *)(const void *)p, size);
|
||||
|
||||
#else
|
||||
|
||||
@@ -506,10 +513,27 @@ HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
|
||||
if (size >= (1 << 14))
|
||||
return S_OK;
|
||||
|
||||
// (size) includes null terminator
|
||||
|
||||
/*
|
||||
#if WCHAR_MAX > 0xffff
|
||||
|
||||
const Byte *p = ((const Byte *)NamesBuf + offset * 2);
|
||||
size = Utf16LE__Get_Num_WCHARs(p, size - 1);
|
||||
// (size) doesn't include null terminator
|
||||
RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size));
|
||||
wchar_t *s = path->bstrVal;
|
||||
wchar_t *sEnd = Utf16LE__To_WCHARs_Sep(p, size, s);
|
||||
*sEnd = 0;
|
||||
if (s + size != sEnd) return E_FAIL;
|
||||
|
||||
#else
|
||||
*/
|
||||
|
||||
RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1));
|
||||
wchar_t *s = path->bstrVal;
|
||||
|
||||
const Byte *p = ((const Byte *)NamesBuf + offset * 2);
|
||||
// Utf16LE__To_WCHARs_Sep(p, size, s);
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
@@ -518,10 +542,14 @@ HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
|
||||
#if WCHAR_PATH_SEPARATOR != L'/'
|
||||
if (c == L'/')
|
||||
c = WCHAR_PATH_SEPARATOR;
|
||||
else if (c == L'\\')
|
||||
c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme
|
||||
#endif
|
||||
*s++ = c;
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
return S_OK;
|
||||
|
||||
/*
|
||||
@@ -673,7 +701,7 @@ void CInArchive::ReadUnpackInfo(
|
||||
{
|
||||
UInt32 indexOfMainStream = 0;
|
||||
UInt32 numPackStreams = 0;
|
||||
folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
|
||||
folders.FoCodersDataOffset[fo] = (size_t)(_inByteBack->GetPtr() - startBufPtr);
|
||||
|
||||
CNum numInStreams = 0;
|
||||
CNum numCoders = inByte->ReadNum();
|
||||
@@ -794,10 +822,10 @@ void CInArchive::ReadUnpackInfo(
|
||||
folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
|
||||
}
|
||||
|
||||
size_t dataSize = _inByteBack->GetPtr() - startBufPtr;
|
||||
const size_t dataSize = (size_t)(_inByteBack->GetPtr() - startBufPtr);
|
||||
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
|
||||
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
|
||||
folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
|
||||
folders.FoCodersDataOffset[fo] = (size_t)(_inByteBack->GetPtr() - startBufPtr);
|
||||
folders.CodersData.CopyFrom(startBufPtr, dataSize);
|
||||
|
||||
// if (folders.NumPackStreams != packStreamIndex) ThrowUnsupported();
|
||||
@@ -962,6 +990,8 @@ void CInArchive::ReadSubStreamsInfo(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CInArchive::ReadStreamsInfo(
|
||||
const CObjectVector<CByteBuffer> *dataVector,
|
||||
UInt64 &dataOffset,
|
||||
@@ -974,7 +1004,11 @@ void CInArchive::ReadStreamsInfo(
|
||||
if (type == NID::kPackInfo)
|
||||
{
|
||||
dataOffset = ReadNumber();
|
||||
if (dataOffset > _rangeLimit)
|
||||
ThrowIncorrect();
|
||||
ReadPackInfo(folders);
|
||||
if (folders.PackPositions[folders.NumPackStreams] > _rangeLimit - dataOffset)
|
||||
ThrowIncorrect();
|
||||
type = ReadID();
|
||||
}
|
||||
|
||||
@@ -1029,7 +1063,7 @@ void CInArchive::ReadBoolVector(unsigned numItems, CBoolVector &v)
|
||||
mask = 0x80;
|
||||
}
|
||||
p[i] = ((b & mask) != 0);
|
||||
mask >>= 1;
|
||||
mask = (Byte)(mask >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1090,8 +1124,8 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
||||
for (CNum i = 0; i < folders.NumFolders; i++)
|
||||
{
|
||||
CByteBuffer &data = dataVector.AddNew();
|
||||
UInt64 unpackSize64 = folders.GetFolderUnpackSize(i);
|
||||
size_t unpackSize = (size_t)unpackSize64;
|
||||
const UInt64 unpackSize64 = folders.GetFolderUnpackSize(i);
|
||||
const size_t unpackSize = (size_t)unpackSize64;
|
||||
if (unpackSize != unpackSize64)
|
||||
ThrowUnsupported();
|
||||
data.Alloc(unpackSize);
|
||||
@@ -1106,7 +1140,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
_stream, baseOffset + dataOffset,
|
||||
folders, i,
|
||||
NULL, // *unpackSize
|
||||
NULL, // &unpackSize64
|
||||
|
||||
outStream,
|
||||
NULL, // *compressProgress
|
||||
@@ -1127,6 +1161,9 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
||||
if (dataAfterEnd_Error)
|
||||
ThereIsHeaderError = true;
|
||||
|
||||
if (unpackSize != outStreamSpec->GetPos())
|
||||
ThrowIncorrect();
|
||||
|
||||
if (folders.FolderCRCs.ValidAndDefined(i))
|
||||
if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
|
||||
ThrowIncorrect();
|
||||
@@ -1226,8 +1263,8 @@ HRESULT CInArchive::ReadHeader(
|
||||
unsigned i;
|
||||
for (i = 0; i < numFiles; i++)
|
||||
{
|
||||
size_t curRem = (rem - pos) / 2;
|
||||
const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos);
|
||||
const size_t curRem = (rem - pos) / 2;
|
||||
const UInt16 *buf = (const UInt16 *)(const void *)(db.NamesBuf + pos);
|
||||
size_t j;
|
||||
for (j = 0; j < curRem && buf[j] != 0; j++);
|
||||
if (j == curRem)
|
||||
@@ -1519,13 +1556,13 @@ HRESULT CInArchive::ReadDatabase2(
|
||||
const unsigned kCheckSize = 512;
|
||||
Byte buf[kCheckSize];
|
||||
RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize));
|
||||
UInt64 rem = fileSize - cur;
|
||||
const UInt64 rem = fileSize - cur;
|
||||
unsigned checkSize = kCheckSize;
|
||||
if (rem < kCheckSize)
|
||||
checkSize = (unsigned)(rem);
|
||||
if (checkSize < 3)
|
||||
return S_FALSE;
|
||||
RINOK(_stream->Seek(fileSize - checkSize, STREAM_SEEK_SET, NULL));
|
||||
RINOK(_stream->Seek((Int64)(fileSize - checkSize), STREAM_SEEK_SET, NULL));
|
||||
RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize));
|
||||
|
||||
if (buf[checkSize - 1] != 0)
|
||||
@@ -1534,8 +1571,8 @@ HRESULT CInArchive::ReadDatabase2(
|
||||
unsigned i;
|
||||
for (i = checkSize - 2;; i--)
|
||||
{
|
||||
if (buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo ||
|
||||
buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo)
|
||||
if ((buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo) ||
|
||||
(buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo))
|
||||
break;
|
||||
if (i == 0)
|
||||
return S_FALSE;
|
||||
@@ -1543,7 +1580,7 @@ HRESULT CInArchive::ReadDatabase2(
|
||||
nextHeaderSize = checkSize - i;
|
||||
nextHeaderOffset = rem - nextHeaderSize;
|
||||
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
|
||||
RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
|
||||
RINOK(_stream->Seek((Int64)cur, STREAM_SEEK_SET, NULL));
|
||||
db.StartHeaderWasRecovered = true;
|
||||
}
|
||||
else
|
||||
@@ -1560,25 +1597,32 @@ HRESULT CInArchive::ReadDatabase2(
|
||||
if ((Int64)nextHeaderOffset < 0 ||
|
||||
nextHeaderSize > ((UInt64)1 << 62))
|
||||
return S_FALSE;
|
||||
|
||||
HeadersSize = kHeaderSize;
|
||||
|
||||
if (nextHeaderSize == 0)
|
||||
{
|
||||
if (nextHeaderOffset != 0)
|
||||
return S_FALSE;
|
||||
db.IsArc = true;
|
||||
db.HeadersSize = HeadersSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (!db.StartHeaderWasRecovered)
|
||||
db.IsArc = true;
|
||||
|
||||
HeadersSize += kHeaderSize + nextHeaderSize;
|
||||
HeadersSize += nextHeaderSize;
|
||||
// db.EndHeaderOffset = nextHeaderOffset;
|
||||
_rangeLimit = nextHeaderOffset;
|
||||
|
||||
db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;
|
||||
if (_fileEndPosition - db.ArcInfo.StartPositionAfterHeader < nextHeaderOffset + nextHeaderSize)
|
||||
{
|
||||
db.UnexpectedEnd = true;
|
||||
return S_FALSE;
|
||||
}
|
||||
RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
|
||||
RINOK(_stream->Seek((Int64)nextHeaderOffset, STREAM_SEEK_CUR, NULL));
|
||||
|
||||
size_t nextHeaderSize_t = (size_t)nextHeaderSize;
|
||||
if (nextHeaderSize_t != nextHeaderSize)
|
||||
|
||||
@@ -174,13 +174,14 @@ struct CDatabase: public CFolders
|
||||
HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw();
|
||||
};
|
||||
|
||||
|
||||
struct CInArchiveInfo
|
||||
{
|
||||
CArchiveVersion Version;
|
||||
UInt64 StartPosition;
|
||||
UInt64 StartPositionAfterHeader;
|
||||
UInt64 DataStartPosition;
|
||||
UInt64 DataStartPosition2;
|
||||
UInt64 StartPosition; // in stream
|
||||
UInt64 StartPositionAfterHeader; // in stream
|
||||
UInt64 DataStartPosition; // in stream
|
||||
UInt64 DataStartPosition2; // in stream. it's for headers
|
||||
CRecordVector<UInt64> FileInfoPopIDs;
|
||||
|
||||
void Clear()
|
||||
@@ -193,6 +194,7 @@ struct CInArchiveInfo
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CDbEx: public CDatabase
|
||||
{
|
||||
CInArchiveInfo ArcInfo;
|
||||
@@ -202,6 +204,7 @@ struct CDbEx: public CDatabase
|
||||
|
||||
UInt64 HeadersSize;
|
||||
UInt64 PhySize;
|
||||
// UInt64 EndHeaderOffset; // relative to position after StartHeader (32 bytes)
|
||||
|
||||
/*
|
||||
CRecordVector<size_t> SecureOffsets;
|
||||
@@ -255,6 +258,7 @@ struct CDbEx: public CDatabase
|
||||
|
||||
HeadersSize = 0;
|
||||
PhySize = 0;
|
||||
// EndHeaderOffset = 0;
|
||||
}
|
||||
|
||||
bool CanUpdate() const
|
||||
@@ -349,6 +353,8 @@ class CInArchive
|
||||
UInt64 _arhiveBeginStreamPosition;
|
||||
UInt64 _fileEndPosition;
|
||||
|
||||
UInt64 _rangeLimit; // relative to position after StartHeader (32 bytes)
|
||||
|
||||
Byte _header[kHeaderSize];
|
||||
|
||||
UInt64 HeadersSize;
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
{
|
||||
FOR_VECTOR(i, PackStreams)
|
||||
if (PackStreams[i] == packStream)
|
||||
return i;
|
||||
return (int)i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
{
|
||||
FOR_VECTOR(i, Bonds)
|
||||
if (Bonds[i].PackIndex == packStream)
|
||||
return i;
|
||||
return (int)i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "../../../../C/7zCrc.h"
|
||||
|
||||
#include "../../../Common/AutoPtr.h"
|
||||
// #include "../../../Common/UTFConvert.h"
|
||||
|
||||
#include "../../Common/StreamObjects.h"
|
||||
|
||||
@@ -196,7 +197,7 @@ void COutArchive::WriteNumber(UInt64 value)
|
||||
break;
|
||||
}
|
||||
firstByte |= mask;
|
||||
mask >>= 1;
|
||||
mask = (Byte)(mask >> 1);
|
||||
}
|
||||
WriteByte(firstByte);
|
||||
for (; i > 0; i--)
|
||||
@@ -206,9 +207,9 @@ void COutArchive::WriteNumber(UInt64 value)
|
||||
}
|
||||
}
|
||||
|
||||
static UInt32 GetBigNumberSize(UInt64 value)
|
||||
static unsigned GetBigNumberSize(UInt64 value)
|
||||
{
|
||||
int i;
|
||||
unsigned i;
|
||||
for (i = 1; i < 9; i++)
|
||||
if (value < (((UInt64)1 << (i * 7))))
|
||||
break;
|
||||
@@ -264,18 +265,18 @@ void COutArchive::WriteFolder(const CFolder &folder)
|
||||
for (idSize = 1; idSize < sizeof(id); idSize++)
|
||||
if ((id >> (8 * idSize)) == 0)
|
||||
break;
|
||||
idSize &= 0xF;
|
||||
// idSize &= 0xF; // idSize is smaller than 16 already
|
||||
Byte temp[16];
|
||||
for (unsigned t = idSize; t != 0; t--, id >>= 8)
|
||||
temp[t] = (Byte)(id & 0xFF);
|
||||
|
||||
Byte b = (Byte)(idSize);
|
||||
bool isComplex = !coder.IsSimpleCoder();
|
||||
unsigned b = idSize;
|
||||
const bool isComplex = !coder.IsSimpleCoder();
|
||||
b |= (isComplex ? 0x10 : 0);
|
||||
|
||||
size_t propsSize = coder.Props.Size();
|
||||
const size_t propsSize = coder.Props.Size();
|
||||
b |= ((propsSize != 0) ? 0x20 : 0);
|
||||
temp[0] = b;
|
||||
temp[0] = (Byte)b;
|
||||
WriteBytes(temp, idSize + 1);
|
||||
if (isComplex)
|
||||
{
|
||||
@@ -309,7 +310,7 @@ void COutArchive::WriteBoolVector(const CBoolVector &boolVector)
|
||||
{
|
||||
if (boolVector[i])
|
||||
b |= mask;
|
||||
mask >>= 1;
|
||||
mask = (Byte)(mask >> 1);
|
||||
if (mask == 0)
|
||||
{
|
||||
WriteByte(b);
|
||||
@@ -476,7 +477,7 @@ void COutArchive::WriteAlignedBools(const CBoolVector &v, unsigned numDefined, B
|
||||
{
|
||||
const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);
|
||||
const UInt64 dataSize = ((UInt64)numDefined << itemSizeShifts) + bvSize + 2;
|
||||
SkipToAligned(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSizeShifts);
|
||||
SkipToAligned(3 + bvSize + GetBigNumberSize(dataSize), itemSizeShifts);
|
||||
|
||||
WriteByte(type);
|
||||
WriteNumber(dataSize);
|
||||
@@ -545,7 +546,39 @@ void COutArchive::WriteHeader(
|
||||
|
||||
WriteByte(NID::kHeader);
|
||||
|
||||
// Archive Properties
|
||||
/*
|
||||
{
|
||||
// It's example for per archive properies writing
|
||||
|
||||
WriteByte(NID::kArchiveProperties);
|
||||
|
||||
// you must use random 40-bit number that will identify you
|
||||
// then you can use same kDeveloperID for any properties and methods
|
||||
const UInt64 kDeveloperID = 0x123456789A; // change that value to real random 40-bit number
|
||||
|
||||
#define GENERATE_7Z_ID(developerID, subID) (((UInt64)0x3F << 56) | ((UInt64)developerID << 16) | subID)
|
||||
|
||||
{
|
||||
const UInt64 kSubID = 0x1; // you can use small number for subID
|
||||
const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID);
|
||||
WriteNumber(kID);
|
||||
const unsigned kPropsSize = 3; // it's example size
|
||||
WriteNumber(kPropsSize);
|
||||
for (unsigned i = 0; i < kPropsSize; i++)
|
||||
WriteByte((Byte)(i & 0xFF));
|
||||
}
|
||||
{
|
||||
const UInt64 kSubID = 0x2; // you can use small number for subID
|
||||
const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID);
|
||||
WriteNumber(kID);
|
||||
const unsigned kPropsSize = 5; // it's example size
|
||||
WriteNumber(kPropsSize);
|
||||
for (unsigned i = 0; i < kPropsSize; i++)
|
||||
WriteByte((Byte)(i + 16));
|
||||
}
|
||||
WriteByte(NID::kEnd);
|
||||
}
|
||||
*/
|
||||
|
||||
if (db.Folders.Size() > 0)
|
||||
{
|
||||
@@ -637,7 +670,15 @@ void COutArchive::WriteHeader(
|
||||
const UString &name = db.Names[i];
|
||||
if (!name.IsEmpty())
|
||||
numDefined++;
|
||||
namesDataSize += (name.Len() + 1) * 2;
|
||||
const size_t numUtfChars =
|
||||
/*
|
||||
#if WCHAR_MAX > 0xffff
|
||||
Get_Num_Utf16_chars_from_wchar_string(name.Ptr());
|
||||
#else
|
||||
*/
|
||||
name.Len();
|
||||
// #endif
|
||||
namesDataSize += (numUtfChars + 1) * 2;
|
||||
}
|
||||
|
||||
if (numDefined > 0)
|
||||
@@ -654,6 +695,25 @@ void COutArchive::WriteHeader(
|
||||
for (unsigned t = 0; t <= name.Len(); t++)
|
||||
{
|
||||
wchar_t c = name[t];
|
||||
|
||||
/*
|
||||
#if WCHAR_MAX > 0xffff
|
||||
if (c >= 0x10000)
|
||||
{
|
||||
c -= 0x10000;
|
||||
if (c < (1 << 20))
|
||||
{
|
||||
unsigned c0 = 0xd800 + ((c >> 10) & 0x3FF);
|
||||
WriteByte((Byte)c0);
|
||||
WriteByte((Byte)(c0 >> 8));
|
||||
c = 0xdc00 + (c & 0x3FF);
|
||||
}
|
||||
else
|
||||
c = '_'; // we change character unsupported by UTF16
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
WriteByte((Byte)c);
|
||||
WriteByte((Byte)(c >> 8));
|
||||
}
|
||||
@@ -855,7 +915,7 @@ HRESULT COutArchive::WriteDatabase(
|
||||
h.NextHeaderSize = headerSize;
|
||||
h.NextHeaderCRC = headerCRC;
|
||||
h.NextHeaderOffset = headerOffset;
|
||||
RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL));
|
||||
RINOK(Stream->Seek((Int64)_prefixHeaderPos, STREAM_SEEK_SET, NULL));
|
||||
return WriteStartHeader(h);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,8 +55,8 @@ struct CFilterMode
|
||||
#define PE_SIG 0x00004550
|
||||
#define PE_OptHeader_Magic_32 0x10B
|
||||
#define PE_OptHeader_Magic_64 0x20B
|
||||
#define PE_SectHeaderSize 40
|
||||
#define PE_SECT_EXECUTE 0x20000000
|
||||
// #define PE_SectHeaderSize 40
|
||||
// #define PE_SECT_EXECUTE 0x20000000
|
||||
|
||||
static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
|
||||
{
|
||||
@@ -254,10 +254,12 @@ static BoolInt Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
|
||||
if (subChunkSize < 0x10 || subChunkSize > 0x12 || GetUi16(buf + 0x14) != 1)
|
||||
return False;
|
||||
|
||||
unsigned numChannels = GetUi16(buf + 0x16);
|
||||
unsigned bitsPerSample = GetUi16(buf + 0x22);
|
||||
|
||||
if ((bitsPerSample & 0x7) != 0 || bitsPerSample >= 256 || numChannels >= 256)
|
||||
const unsigned numChannels = GetUi16(buf + 0x16);
|
||||
const unsigned bitsPerSample = GetUi16(buf + 0x22);
|
||||
if ((bitsPerSample & 0x7) != 0)
|
||||
return False;
|
||||
const UInt32 delta = (UInt32)numChannels * (bitsPerSample >> 3);
|
||||
if (delta == 0 || delta > 256)
|
||||
return False;
|
||||
|
||||
pos = 0x14 + subChunkSize;
|
||||
@@ -271,9 +273,6 @@ static BoolInt Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
|
||||
subChunkSize = GetUi32(buf + pos + 4);
|
||||
if (GetUi32(buf + pos) == WAV_SUBCHUNK_data)
|
||||
{
|
||||
unsigned delta = numChannels * (bitsPerSample >> 3);
|
||||
if (delta >= 256)
|
||||
return False;
|
||||
filterMode->Id = k_Delta;
|
||||
filterMode->Delta = delta;
|
||||
return True;
|
||||
@@ -418,7 +417,7 @@ static unsigned Get_FilterGroup_for_Folder(
|
||||
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
UInt64 position, UInt64 size, ICompressProgressInfo *progress)
|
||||
{
|
||||
RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));
|
||||
RINOK(inStream->Seek((Int64)position, STREAM_SEEK_SET, 0));
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
|
||||
streamSpec->SetStream(inStream);
|
||||
@@ -642,13 +641,13 @@ struct CRefItem
|
||||
if (sortByType)
|
||||
{
|
||||
int slashPos = ui.Name.ReverseFind_PathSepar();
|
||||
NamePos = slashPos + 1;
|
||||
NamePos = (unsigned)(slashPos + 1);
|
||||
int dotPos = ui.Name.ReverseFind_Dot();
|
||||
if (dotPos <= slashPos)
|
||||
ExtensionPos = ui.Name.Len();
|
||||
else
|
||||
{
|
||||
ExtensionPos = dotPos + 1;
|
||||
ExtensionPos = (unsigned)(dotPos + 1);
|
||||
if (ExtensionPos != ui.Name.Len())
|
||||
{
|
||||
AString s;
|
||||
@@ -836,7 +835,7 @@ HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMo
|
||||
{
|
||||
const wchar_t *ext;
|
||||
if (dotPos > slashPos)
|
||||
ext = ui.Name.Ptr(dotPos + 1);
|
||||
ext = ui.Name.Ptr((unsigned)(dotPos + 1));
|
||||
else
|
||||
ext = ui.Name.RightPtr(0);
|
||||
|
||||
@@ -1071,12 +1070,12 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode,
|
||||
if (alignBits != 0)
|
||||
{
|
||||
if (alignBits > 2 || filterMode.Id == k_Delta)
|
||||
nextMethod.AddProp32(NCoderPropID::kPosStateBits, alignBits);
|
||||
nextMethod.AddProp32(NCoderPropID::kPosStateBits, (unsigned)alignBits);
|
||||
unsigned lc = 0;
|
||||
if (alignBits < 3)
|
||||
lc = 3 - alignBits;
|
||||
lc = (unsigned)(3 - alignBits);
|
||||
nextMethod.AddProp32(NCoderPropID::kLitContextBits, lc);
|
||||
nextMethod.AddProp32(NCoderPropID::kLitPosBits, alignBits);
|
||||
nextMethod.AddProp32(NCoderPropID::kLitPosBits, (unsigned)alignBits);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1453,7 +1452,7 @@ public:
|
||||
|
||||
UInt64 StartPos;
|
||||
const CFolders *Folders;
|
||||
int FolderIndex;
|
||||
unsigned FolderIndex;
|
||||
|
||||
// bool send_UnpackSize;
|
||||
// UInt64 UnpackSize;
|
||||
@@ -1609,7 +1608,10 @@ HRESULT Update(
|
||||
|
||||
CRecordVector<CFilterMode2> filters;
|
||||
CObjectVector<CSolidGroup> groups;
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
bool thereAreRepacks = false;
|
||||
#endif
|
||||
|
||||
bool useFilters = options.UseFilters;
|
||||
if (useFilters)
|
||||
@@ -1636,7 +1638,7 @@ HRESULT Update(
|
||||
{
|
||||
int index = updateItems[i].IndexInArchive;
|
||||
if (index != -1)
|
||||
fileIndexToUpdateIndexMap[(unsigned)index] = i;
|
||||
fileIndexToUpdateIndexMap[(unsigned)index] = (int)i;
|
||||
}
|
||||
|
||||
for (i = 0; i < db->NumFolders; i++)
|
||||
@@ -1656,7 +1658,7 @@ HRESULT Update(
|
||||
{
|
||||
indexInFolder++;
|
||||
int updateIndex = fileIndexToUpdateIndexMap[fi];
|
||||
if (updateIndex >= 0 && !updateItems[updateIndex].NewData)
|
||||
if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData)
|
||||
{
|
||||
numCopyItems++;
|
||||
repackSize += file.Size;
|
||||
@@ -1688,7 +1690,9 @@ HRESULT Update(
|
||||
complexity += db->GetFolderFullPackSize(i);
|
||||
else
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
thereAreRepacks = true;
|
||||
#endif
|
||||
complexity += repackSize;
|
||||
if (inSizeForReduce2 < repackSize)
|
||||
inSizeForReduce2 = repackSize;
|
||||
@@ -1727,10 +1731,12 @@ HRESULT Update(
|
||||
#ifndef _7ZIP_ST
|
||||
|
||||
CStreamBinder sb;
|
||||
/*
|
||||
if (options.MultiThreadMixer)
|
||||
{
|
||||
RINOK(sb.CreateEvents());
|
||||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1742,7 +1748,9 @@ HRESULT Update(
|
||||
#ifdef EXTERNAL_CODECS
|
||||
threadDecoder.__externalCodecs = __externalCodecs;
|
||||
#endif
|
||||
RINOK(threadDecoder.Create());
|
||||
WRes wres = threadDecoder.Create();
|
||||
if (wres != 0)
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1887,7 +1895,7 @@ HRESULT Update(
|
||||
if (ui.HasStream())
|
||||
continue;
|
||||
}
|
||||
else if (ui.IndexInArchive != -1 && db->Files[ui.IndexInArchive].HasStream)
|
||||
else if (ui.IndexInArchive != -1 && db->Files[(unsigned)ui.IndexInArchive].HasStream)
|
||||
continue;
|
||||
/*
|
||||
if (ui.TreeFolderIndex >= 0)
|
||||
@@ -1912,8 +1920,8 @@ HRESULT Update(
|
||||
}
|
||||
else
|
||||
{
|
||||
GetFile(*db, ui.IndexInArchive, file, file2);
|
||||
db->GetPath(ui.IndexInArchive, name);
|
||||
GetFile(*db, (unsigned)ui.IndexInArchive, file, file2);
|
||||
db->GetPath((unsigned)ui.IndexInArchive, name);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2065,7 +2073,7 @@ HRESULT Update(
|
||||
{
|
||||
indexInFolder++;
|
||||
int updateIndex = fileIndexToUpdateIndexMap[fi];
|
||||
if (updateIndex >= 0 && !updateItems[updateIndex].NewData)
|
||||
if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData)
|
||||
needExtract = true;
|
||||
// decodeSize += file.Size;
|
||||
}
|
||||
@@ -2099,8 +2107,8 @@ HRESULT Update(
|
||||
{
|
||||
repackBase = threadDecoder.FosSpec;
|
||||
CMyComPtr<ISequentialOutStream> sbOutStream;
|
||||
sb.CreateStreams(&sbInStream, &sbOutStream);
|
||||
sb.ReInit();
|
||||
sb.CreateStreams2(sbInStream, sbOutStream);
|
||||
RINOK(sb.Create_ReInit());
|
||||
|
||||
threadDecoder.FosSpec->_stream = sbOutStream;
|
||||
|
||||
@@ -2171,7 +2179,9 @@ HRESULT Update(
|
||||
#ifndef _7ZIP_ST
|
||||
if (options.MultiThreadMixer)
|
||||
{
|
||||
threadDecoder.Start();
|
||||
WRes wres = threadDecoder.Start();
|
||||
if (wres != 0)
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2197,7 +2207,11 @@ HRESULT Update(
|
||||
inStreamSizeCount.Release();
|
||||
sbInStream.Release();
|
||||
|
||||
threadDecoder.WaitExecuteFinish();
|
||||
{
|
||||
WRes wres = threadDecoder.WaitExecuteFinish();
|
||||
if (wres != 0)
|
||||
return HRESULT_FROM_WIN32(wres);
|
||||
}
|
||||
|
||||
HRESULT decodeRes = threadDecoder.Result;
|
||||
// if (res == k_My_HRESULT_CRC_ERROR)
|
||||
@@ -2259,7 +2273,7 @@ HRESULT Update(
|
||||
int updateIndex = fileIndexToUpdateIndexMap[fi];
|
||||
if (updateIndex >= 0)
|
||||
{
|
||||
const CUpdateItem &ui = updateItems[updateIndex];
|
||||
const CUpdateItem &ui = updateItems[(unsigned)updateIndex];
|
||||
if (ui.NewData)
|
||||
continue;
|
||||
|
||||
@@ -2347,7 +2361,7 @@ HRESULT Update(
|
||||
{
|
||||
int slashPos = ui.Name.ReverseFind_PathSepar();
|
||||
int dotPos = ui.Name.ReverseFind_Dot();
|
||||
const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : dotPos + 1);
|
||||
const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : (unsigned)(dotPos + 1));
|
||||
if (numSubFiles == 0)
|
||||
prevExtension = ext;
|
||||
else if (!StringsAreEqualNoCase(ext, prevExtension))
|
||||
@@ -2403,8 +2417,8 @@ HRESULT Update(
|
||||
}
|
||||
else
|
||||
{
|
||||
GetFile(*db, ui.IndexInArchive, file, file2);
|
||||
db->GetPath(ui.IndexInArchive, name);
|
||||
GetFile(*db, (unsigned)ui.IndexInArchive, file, file2);
|
||||
db->GetPath((unsigned)ui.IndexInArchive, name);
|
||||
}
|
||||
if (file2.IsAnti || file.IsDir)
|
||||
return E_FAIL;
|
||||
|
||||
@@ -31,7 +31,7 @@ struct CTreeFolder
|
||||
struct CUpdateItem
|
||||
{
|
||||
int IndexInArchive;
|
||||
int IndexInClient;
|
||||
unsigned IndexInClient;
|
||||
|
||||
UInt64 CTime;
|
||||
UInt64 ATime;
|
||||
|
||||
Reference in New Issue
Block a user