mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 10:07:02 -06:00
17.00
This commit is contained in:
@@ -226,11 +226,13 @@ HRESULT CDecoder::Decode(
|
||||
|
||||
, ISequentialOutStream *outStream
|
||||
, ICompressProgressInfo *compressProgress
|
||||
|
||||
, ISequentialInStream **
|
||||
#ifdef USE_MIXER_ST
|
||||
inStreamMainRes
|
||||
#endif
|
||||
|
||||
#ifdef USE_MIXER_ST
|
||||
inStreamMainRes
|
||||
#endif
|
||||
, bool &dataAfterEnd_Error
|
||||
|
||||
_7Z_DECODER_CRYPRO_VARS_DECL
|
||||
|
||||
@@ -239,6 +241,8 @@ HRESULT CDecoder::Decode(
|
||||
#endif
|
||||
)
|
||||
{
|
||||
dataAfterEnd_Error = false;
|
||||
|
||||
const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]];
|
||||
CFolderEx folderInfo;
|
||||
folders.ParseFolderEx(folderIndex, folderInfo);
|
||||
@@ -415,12 +419,14 @@ HRESULT CDecoder::Decode(
|
||||
}
|
||||
#endif
|
||||
|
||||
bool finishMode = false;
|
||||
{
|
||||
CMyComPtr<ICompressSetFinishMode> setFinishMode;
|
||||
decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
|
||||
if (setFinishMode)
|
||||
{
|
||||
RINOK(setFinishMode->SetFinishMode(BoolToInt(fullUnpack)));
|
||||
finishMode = fullUnpack;
|
||||
RINOK(setFinishMode->SetFinishMode(BoolToInt(finishMode)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,7 +456,7 @@ HRESULT CDecoder::Decode(
|
||||
unpackSize :
|
||||
&folders.CoderUnpackSizes[unpackStreamIndexStart + i];
|
||||
|
||||
_mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers);
|
||||
_mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers, finishMode);
|
||||
}
|
||||
|
||||
if (outStream)
|
||||
@@ -530,7 +536,9 @@ HRESULT CDecoder::Decode(
|
||||
progress2 = new CDecProgress(compressProgress);
|
||||
|
||||
ISequentialOutStream *outStreamPointer = outStream;
|
||||
return _mixer->Code(inStreamPointers, &outStreamPointer, progress2 ? (ICompressProgressInfo *)progress2 : compressProgress);
|
||||
return _mixer->Code(inStreamPointers, &outStreamPointer,
|
||||
progress2 ? (ICompressProgressInfo *)progress2 : compressProgress,
|
||||
dataAfterEnd_Error);
|
||||
}
|
||||
|
||||
#ifdef USE_MIXER_ST
|
||||
|
||||
@@ -53,7 +53,9 @@ public:
|
||||
|
||||
, ISequentialOutStream *outStream
|
||||
, ICompressProgressInfo *compressProgress
|
||||
|
||||
, ISequentialInStream **inStreamMainRes
|
||||
, bool &dataAfterEnd_Error
|
||||
|
||||
_7Z_DECODER_CRYPRO_VARS_DECL
|
||||
|
||||
|
||||
@@ -333,7 +333,7 @@ HRESULT CEncoder::Encode(
|
||||
}
|
||||
|
||||
for (i = 0; i < numMethods; i++)
|
||||
_mixer->SetCoderInfo(i, NULL, NULL);
|
||||
_mixer->SetCoderInfo(i, NULL, NULL, false);
|
||||
|
||||
|
||||
/* inStreamSize can be used by BCJ2 to set optimal range of conversion.
|
||||
@@ -429,10 +429,12 @@ HRESULT CEncoder::Encode(
|
||||
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
|
||||
outStreamPointers.Add(tempBuffers[i - 1]);
|
||||
|
||||
bool dataAfterEnd_Error;
|
||||
|
||||
RINOK(_mixer->Code(
|
||||
&inStreamPointer,
|
||||
&outStreamPointers.Front(),
|
||||
mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress));
|
||||
mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress, dataAfterEnd_Error));
|
||||
|
||||
if (_bindInfo.PackStreams.Size() != 0)
|
||||
packSizes.Add(outStreamSizeCountSpec->GetSize());
|
||||
|
||||
@@ -348,6 +348,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
#endif
|
||||
|
||||
|
||||
bool dataAfterEnd_Error = false;
|
||||
|
||||
HRESULT result = decoder.Decode(
|
||||
EXTERNAL_CODECS_VARS
|
||||
_inStream,
|
||||
@@ -358,6 +360,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
outStream,
|
||||
progress,
|
||||
NULL // *inStreamMainRes
|
||||
, dataAfterEnd_Error
|
||||
|
||||
_7Z_DECODER_CRYPRO_VARS
|
||||
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
||||
@@ -365,13 +368,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
#endif
|
||||
);
|
||||
|
||||
if (result == S_FALSE || result == E_NOTIMPL)
|
||||
if (result == S_FALSE || result == E_NOTIMPL || dataAfterEnd_Error)
|
||||
{
|
||||
bool wasFinished = folderOutStream->WasWritingFinished();
|
||||
|
||||
int resOp = (result == S_FALSE ?
|
||||
NExtract::NOperationResult::kDataError :
|
||||
NExtract::NOperationResult::kUnsupportedMethod);
|
||||
|
||||
int resOp = NExtract::NOperationResult::kDataError;
|
||||
|
||||
if (result != S_FALSE)
|
||||
{
|
||||
if (result == E_NOTIMPL)
|
||||
resOp = NExtract::NOperationResult::kUnsupportedMethod;
|
||||
else if (wasFinished && dataAfterEnd_Error)
|
||||
resOp = NExtract::NOperationResult::kDataAfterEnd;
|
||||
}
|
||||
|
||||
RINOK(folderOutStream->FlushCorrupted(resOp));
|
||||
|
||||
|
||||
@@ -540,7 +540,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
*/
|
||||
|
||||
const CFileItem &item = _db.Files[index];
|
||||
UInt32 index2 = index;
|
||||
const UInt32 index2 = index;
|
||||
|
||||
switch (propID)
|
||||
{
|
||||
@@ -575,7 +575,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
case kpidCTime: SetFileTimeProp_From_UInt64Def(value, _db.CTime, index2); break;
|
||||
case kpidATime: SetFileTimeProp_From_UInt64Def(value, _db.ATime, index2); break;
|
||||
case kpidMTime: SetFileTimeProp_From_UInt64Def(value, _db.MTime, index2); break;
|
||||
case kpidAttrib: if (item.AttribDefined) PropVarEm_Set_UInt32(value, item.Attrib); break;
|
||||
case kpidAttrib: if (_db.Attrib.ValidAndDefined(index2)) PropVarEm_Set_UInt32(value, _db.Attrib.Vals[index2]); break;
|
||||
case kpidCRC: if (item.CrcDefined) PropVarEm_Set_UInt32(value, item.Crc); break;
|
||||
case kpidEncrypted: PropVarEm_Set_Bool(value, IsFolderEncrypted(_db.FileIndexToFolderIndexMap[index2])); break;
|
||||
case kpidIsAnti: PropVarEm_Set_Bool(value, _db.IsItemAnti(index2)); break;
|
||||
|
||||
@@ -54,6 +54,7 @@ public:
|
||||
CBoolPair Write_CTime;
|
||||
CBoolPair Write_ATime;
|
||||
CBoolPair Write_MTime;
|
||||
CBoolPair Write_Attrib;
|
||||
|
||||
bool _useMultiThreadMixer;
|
||||
|
||||
|
||||
@@ -18,11 +18,12 @@ using namespace NWindows;
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
static const char *k_LZMA_Name = "LZMA";
|
||||
static const char *kDefaultMethodName = "LZMA2";
|
||||
static const char *k_Copy_Name = "Copy";
|
||||
#define k_LZMA_Name "LZMA"
|
||||
#define kDefaultMethodName "LZMA2"
|
||||
#define k_Copy_Name "Copy"
|
||||
|
||||
#define k_MatchFinder_ForHeaders "BT2"
|
||||
|
||||
static const char *k_MatchFinder_ForHeaders = "BT2";
|
||||
static const UInt32 k_NumFastBytes_ForHeaders = 273;
|
||||
static const UInt32 k_Level_ForHeaders = 5;
|
||||
static const UInt32 k_Dictionary_ForHeaders =
|
||||
@@ -113,11 +114,11 @@ HRESULT CHandler::SetMainMethod(
|
||||
FOR_VECTOR (i, methods)
|
||||
{
|
||||
COneMethodInfo &oneMethodInfo = methods[i];
|
||||
SetGlobalLevelAndThreads(oneMethodInfo
|
||||
#ifndef _7ZIP_ST
|
||||
, numThreads
|
||||
#endif
|
||||
);
|
||||
|
||||
SetGlobalLevelTo(oneMethodInfo);
|
||||
#ifndef _7ZIP_ST
|
||||
CMultiMethodProps::SetMethodThreadsTo(oneMethodInfo, numThreads);
|
||||
#endif
|
||||
|
||||
CMethodFull &methodFull = methodMode.Methods.AddNew();
|
||||
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
|
||||
@@ -282,15 +283,18 @@ 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);
|
||||
|
||||
if (db && !db->Files.IsEmpty())
|
||||
{
|
||||
if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
|
||||
if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
|
||||
if (!Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty();
|
||||
if (!Write_Attrib.Def) need_Attrib = !db->Attrib.Defs.IsEmpty();
|
||||
}
|
||||
|
||||
UString s;
|
||||
// UString s;
|
||||
UString name;
|
||||
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
@@ -307,7 +311,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
ui.IsAnti = false;
|
||||
ui.Size = 0;
|
||||
|
||||
UString name;
|
||||
name.Empty();
|
||||
// bool isAltStream = false;
|
||||
if (ui.IndexInArchive != -1)
|
||||
{
|
||||
@@ -334,6 +338,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
if (ui.NewProps)
|
||||
{
|
||||
bool folderStatusIsDefined;
|
||||
if (need_Attrib)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
|
||||
@@ -377,7 +382,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
{
|
||||
name = NItemName::MakeLegalName(prop.bstrVal);
|
||||
name = prop.bstrVal;
|
||||
NItemName::ReplaceSlashes_OsToUnix(name);
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -614,6 +620,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
options.HeaderOptions.WriteCTime = Write_CTime;
|
||||
options.HeaderOptions.WriteATime = Write_ATime;
|
||||
options.HeaderOptions.WriteMTime = Write_MTime;
|
||||
options.HeaderOptions.WriteAttrib = Write_Attrib;
|
||||
*/
|
||||
|
||||
options.NumSolidFiles = _numSolidFiles;
|
||||
@@ -705,6 +712,7 @@ void COutHandler::InitProps()
|
||||
Write_CTime.Init();
|
||||
Write_ATime.Init();
|
||||
Write_MTime.Init();
|
||||
Write_Attrib.Init();
|
||||
|
||||
_useMultiThreadMixer = true;
|
||||
|
||||
@@ -830,6 +838,8 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
|
||||
if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
|
||||
if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
|
||||
|
||||
if (name.IsEqualTo("tr")) return PROPVARIANT_to_BoolPair(value, Write_Attrib);
|
||||
|
||||
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
|
||||
|
||||
if (name.IsEqualTo("qs")) return PROPVARIANT_to_bool(value, _useTypeSorting);
|
||||
|
||||
@@ -32,6 +32,21 @@ using namespace NCOM;
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
unsigned BoolVector_CountSum(const CBoolVector &v)
|
||||
{
|
||||
unsigned sum = 0;
|
||||
const unsigned size = v.Size();
|
||||
for (unsigned i = 0; i < size; i++)
|
||||
if (v[i])
|
||||
sum++;
|
||||
return sum;
|
||||
}
|
||||
|
||||
static inline bool BoolVector_Item_IsValidAndTrue(const CBoolVector &v, unsigned i)
|
||||
{
|
||||
return (i < v.Size() ? v[i] : false);
|
||||
}
|
||||
|
||||
static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
|
||||
{
|
||||
v.ClearAndSetSize(size);
|
||||
@@ -40,6 +55,7 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
|
||||
p[i] = false;
|
||||
}
|
||||
|
||||
|
||||
class CInArchiveException {};
|
||||
class CUnsupportedFeatureException: public CInArchiveException {};
|
||||
|
||||
@@ -566,21 +582,30 @@ void CInArchive::WaitId(UInt64 id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CInArchive::Read_UInt32_Vector(CUInt32DefVector &v)
|
||||
{
|
||||
unsigned numItems = v.Defs.Size();
|
||||
v.Vals.ClearAndSetSize(numItems);
|
||||
UInt32 *p = &v.Vals[0];
|
||||
const bool *defs = &v.Defs[0];
|
||||
for (unsigned i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 a = 0;
|
||||
if (defs[i])
|
||||
a = ReadUInt32();
|
||||
p[i] = a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
|
||||
{
|
||||
ReadBoolVector2(numItems, crcs.Defs);
|
||||
crcs.Vals.ClearAndSetSize(numItems);
|
||||
UInt32 *p = &crcs.Vals[0];
|
||||
const bool *defs = &crcs.Defs[0];
|
||||
for (unsigned i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 crc = 0;
|
||||
if (defs[i])
|
||||
crc = ReadUInt32();
|
||||
p[i] = crc;
|
||||
}
|
||||
Read_UInt32_Vector(crcs);
|
||||
}
|
||||
|
||||
|
||||
#define k_Scan_NumCoders_MAX 64
|
||||
#define k_Scan_NumCodersStreams_in_Folder_MAX 64
|
||||
|
||||
@@ -1075,6 +1100,8 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
||||
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
|
||||
outStreamSpec->Init(data, unpackSize);
|
||||
|
||||
bool dataAfterEnd_Error = false;
|
||||
|
||||
HRESULT result = decoder.Decode(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
_stream, baseOffset + dataOffset,
|
||||
@@ -1083,16 +1110,23 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
||||
|
||||
outStream,
|
||||
NULL, // *compressProgress
|
||||
|
||||
NULL // **inStreamMainRes
|
||||
, dataAfterEnd_Error
|
||||
|
||||
_7Z_DECODER_CRYPRO_VARS
|
||||
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
||||
, false // mtMode
|
||||
, 1 // numThreads
|
||||
#endif
|
||||
|
||||
);
|
||||
|
||||
RINOK(result);
|
||||
|
||||
if (dataAfterEnd_Error)
|
||||
ThereIsHeaderError = true;
|
||||
|
||||
if (folders.FolderCRCs.ValidAndDefined(i))
|
||||
if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
|
||||
ThrowIncorrect();
|
||||
@@ -1148,19 +1182,10 @@ HRESULT CInArchive::ReadHeader(
|
||||
type = ReadID();
|
||||
}
|
||||
|
||||
db.Files.Clear();
|
||||
|
||||
if (type == NID::kFilesInfo)
|
||||
{
|
||||
|
||||
const CNum numFiles = ReadNum();
|
||||
db.Files.ClearAndSetSize(numFiles);
|
||||
/*
|
||||
db.Files.Reserve(numFiles);
|
||||
CNum i;
|
||||
for (i = 0; i < numFiles; i++)
|
||||
db.Files.Add(CFileItem());
|
||||
*/
|
||||
|
||||
db.ArcInfo.FileInfoPopIDs.Add(NID::kSize);
|
||||
// if (!db.PackSizes.IsEmpty())
|
||||
@@ -1169,7 +1194,6 @@ HRESULT CInArchive::ReadHeader(
|
||||
db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC);
|
||||
|
||||
CBoolVector emptyStreamVector;
|
||||
BoolVector_Fill_False(emptyStreamVector, (unsigned)numFiles);
|
||||
CBoolVector emptyFileVector;
|
||||
CBoolVector antiFileVector;
|
||||
CNum numEmptyStreams = 0;
|
||||
@@ -1197,10 +1221,10 @@ HRESULT CInArchive::ReadHeader(
|
||||
size_t rem = _inByteBack->GetRem();
|
||||
db.NamesBuf.Alloc(rem);
|
||||
ReadBytes(db.NamesBuf, rem);
|
||||
db.NameOffsets.Alloc(db.Files.Size() + 1);
|
||||
db.NameOffsets.Alloc(numFiles + 1);
|
||||
size_t pos = 0;
|
||||
unsigned i;
|
||||
for (i = 0; i < db.Files.Size(); i++)
|
||||
for (i = 0; i < numFiles; i++)
|
||||
{
|
||||
size_t curRem = (rem - pos) / 2;
|
||||
const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos);
|
||||
@@ -1216,36 +1240,31 @@ HRESULT CInArchive::ReadHeader(
|
||||
ThereIsHeaderError = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case NID::kWinAttrib:
|
||||
{
|
||||
CBoolVector boolVector;
|
||||
ReadBoolVector2(db.Files.Size(), boolVector);
|
||||
ReadBoolVector2(numFiles, db.Attrib.Defs);
|
||||
CStreamSwitch streamSwitch;
|
||||
streamSwitch.Set(this, &dataVector);
|
||||
for (CNum i = 0; i < numFiles; i++)
|
||||
{
|
||||
CFileItem &file = db.Files[i];
|
||||
file.AttribDefined = boolVector[i];
|
||||
if (file.AttribDefined)
|
||||
file.Attrib = ReadUInt32();
|
||||
}
|
||||
Read_UInt32_Vector(db.Attrib);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
case NID::kIsAux:
|
||||
{
|
||||
ReadBoolVector(db.Files.Size(), db.IsAux);
|
||||
ReadBoolVector(numFiles, db.IsAux);
|
||||
break;
|
||||
}
|
||||
case NID::kParent:
|
||||
{
|
||||
db.IsTree = true;
|
||||
// CBoolVector boolVector;
|
||||
// ReadBoolVector2(db.Files.Size(), boolVector);
|
||||
// ReadBoolVector2(numFiles, boolVector);
|
||||
// CStreamSwitch streamSwitch;
|
||||
// streamSwitch.Set(this, &dataVector);
|
||||
CBoolVector boolVector;
|
||||
ReadBoolVector2(db.Files.Size(), boolVector);
|
||||
ReadBoolVector2(numFiles, boolVector);
|
||||
|
||||
db.ThereAreAltStreams = false;
|
||||
for (i = 0; i < numFiles; i++)
|
||||
@@ -1264,14 +1283,9 @@ HRESULT CInArchive::ReadHeader(
|
||||
case NID::kEmptyStream:
|
||||
{
|
||||
ReadBoolVector(numFiles, emptyStreamVector);
|
||||
numEmptyStreams = 0;
|
||||
for (CNum i = 0; i < (CNum)emptyStreamVector.Size(); i++)
|
||||
if (emptyStreamVector[i])
|
||||
numEmptyStreams++;
|
||||
|
||||
BoolVector_Fill_False(emptyFileVector, numEmptyStreams);
|
||||
BoolVector_Fill_False(antiFileVector, numEmptyStreams);
|
||||
|
||||
numEmptyStreams = BoolVector_CountSum(emptyStreamVector);
|
||||
emptyFileVector.Clear();
|
||||
antiFileVector.Clear();
|
||||
break;
|
||||
}
|
||||
case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break;
|
||||
@@ -1314,7 +1328,7 @@ HRESULT CInArchive::ReadHeader(
|
||||
ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset);
|
||||
}
|
||||
db.SecureIDs.Clear();
|
||||
for (unsigned i = 0; i < db.Files.Size(); i++)
|
||||
for (unsigned i = 0; i < numFiles; i++)
|
||||
{
|
||||
db.SecureIDs.Add(ReadNum());
|
||||
// db.SecureIDs.Add(ReadUInt32());
|
||||
@@ -1359,22 +1373,21 @@ HRESULT CInArchive::ReadHeader(
|
||||
CNum emptyFileIndex = 0;
|
||||
CNum sizeIndex = 0;
|
||||
|
||||
CNum numAntiItems = 0;
|
||||
const CNum numAntiItems = BoolVector_CountSum(antiFileVector);
|
||||
|
||||
CNum i;
|
||||
if (numAntiItems != 0)
|
||||
db.IsAnti.ClearAndSetSize(numFiles);
|
||||
|
||||
for (i = 0; i < numEmptyStreams; i++)
|
||||
if (antiFileVector[i])
|
||||
numAntiItems++;
|
||||
db.Files.ClearAndSetSize(numFiles);
|
||||
|
||||
for (i = 0; i < numFiles; i++)
|
||||
for (CNum i = 0; i < numFiles; i++)
|
||||
{
|
||||
CFileItem &file = db.Files[i];
|
||||
bool isAnti;
|
||||
file.HasStream = !emptyStreamVector[i];
|
||||
file.Crc = 0;
|
||||
if (file.HasStream)
|
||||
if (!BoolVector_Item_IsValidAndTrue(emptyStreamVector, i))
|
||||
{
|
||||
file.HasStream = true;
|
||||
file.IsDir = false;
|
||||
isAnti = false;
|
||||
file.Size = unpackSizes[sizeIndex];
|
||||
@@ -1385,26 +1398,31 @@ HRESULT CInArchive::ReadHeader(
|
||||
}
|
||||
else
|
||||
{
|
||||
file.IsDir = !emptyFileVector[emptyFileIndex];
|
||||
isAnti = antiFileVector[emptyFileIndex];
|
||||
file.HasStream = false;
|
||||
file.IsDir = !BoolVector_Item_IsValidAndTrue(emptyFileVector, emptyFileIndex);
|
||||
isAnti = BoolVector_Item_IsValidAndTrue(antiFileVector, emptyFileIndex);
|
||||
emptyFileIndex++;
|
||||
file.Size = 0;
|
||||
file.CrcDefined = false;
|
||||
}
|
||||
if (numAntiItems != 0)
|
||||
db.IsAnti.Add(isAnti);
|
||||
db.IsAnti[i] = isAnti;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
db.FillLinks();
|
||||
/*
|
||||
if (type != NID::kEnd)
|
||||
ThrowIncorrect();
|
||||
if (_inByteBack->GetRem() != 0)
|
||||
ThrowIncorrect();
|
||||
*/
|
||||
|
||||
if (type != NID::kEnd || _inByteBack->GetRem() != 0)
|
||||
{
|
||||
db.UnsupportedFeatureWarning = true;
|
||||
// ThrowIncorrect();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
void CDbEx::FillLinks()
|
||||
{
|
||||
FolderStartFileIndex.Alloc(NumFolders);
|
||||
@@ -1466,6 +1484,7 @@ void CDbEx::FillLinks()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HRESULT CInArchive::ReadDatabase2(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CDbEx &db
|
||||
@@ -1610,6 +1629,7 @@ HRESULT CInArchive::ReadDatabase2(
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
HRESULT CInArchive::ReadDatabase(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CDbEx &db
|
||||
|
||||
@@ -115,6 +115,7 @@ struct CDatabase: public CFolders
|
||||
CUInt64DefVector ATime;
|
||||
CUInt64DefVector MTime;
|
||||
CUInt64DefVector StartPos;
|
||||
CUInt32DefVector Attrib;
|
||||
CBoolVector IsAnti;
|
||||
/*
|
||||
CBoolVector IsAux;
|
||||
@@ -146,6 +147,7 @@ struct CDatabase: public CFolders
|
||||
ATime.Clear();
|
||||
MTime.Clear();
|
||||
StartPos.Clear();
|
||||
Attrib.Clear();
|
||||
IsAnti.Clear();
|
||||
// IsAux.Clear();
|
||||
}
|
||||
@@ -369,6 +371,8 @@ class CInArchive
|
||||
void SkipData() { _inByteBack->SkipData(); }
|
||||
void WaitId(UInt64 id);
|
||||
|
||||
void Read_UInt32_Vector(CUInt32DefVector &v);
|
||||
|
||||
void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
|
||||
void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs);
|
||||
|
||||
|
||||
@@ -26,12 +26,14 @@ struct CCoderInfo
|
||||
bool IsSimpleCoder() const { return NumStreams == 1; }
|
||||
};
|
||||
|
||||
|
||||
struct CBond
|
||||
{
|
||||
UInt32 PackIndex;
|
||||
UInt32 UnpackIndex;
|
||||
};
|
||||
|
||||
|
||||
struct CFolder
|
||||
{
|
||||
CLASS_NO_COPY(CFolder)
|
||||
@@ -87,6 +89,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CUInt32DefVector
|
||||
{
|
||||
CBoolVector Defs;
|
||||
@@ -110,9 +113,25 @@ struct CUInt32DefVector
|
||||
Vals.ReserveDown();
|
||||
}
|
||||
|
||||
bool GetItem(unsigned index, UInt32 &value) const
|
||||
{
|
||||
if (index < Defs.Size() && Defs[index])
|
||||
{
|
||||
value = Vals[index];
|
||||
return true;
|
||||
}
|
||||
value = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; }
|
||||
|
||||
bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
|
||||
|
||||
void SetItem(unsigned index, bool defined, UInt32 value);
|
||||
};
|
||||
|
||||
|
||||
struct CUInt64DefVector
|
||||
{
|
||||
CBoolVector Defs;
|
||||
@@ -141,15 +160,15 @@ struct CUInt64DefVector
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetItem(unsigned index, bool defined, UInt64 value);
|
||||
|
||||
bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
|
||||
|
||||
void SetItem(unsigned index, bool defined, UInt64 value);
|
||||
};
|
||||
|
||||
|
||||
struct CFileItem
|
||||
{
|
||||
UInt64 Size;
|
||||
UInt32 Attrib;
|
||||
UInt32 Crc;
|
||||
/*
|
||||
int Parent;
|
||||
@@ -159,23 +178,23 @@ struct CFileItem
|
||||
// stream in some folder. It can be empty stream
|
||||
bool IsDir;
|
||||
bool CrcDefined;
|
||||
bool AttribDefined;
|
||||
|
||||
/*
|
||||
void Clear()
|
||||
{
|
||||
HasStream = true;
|
||||
IsDir = false;
|
||||
CrcDefined = false;
|
||||
}
|
||||
|
||||
CFileItem():
|
||||
/*
|
||||
Parent(-1),
|
||||
IsAltStream(false),
|
||||
*/
|
||||
// Parent(-1),
|
||||
// IsAltStream(false),
|
||||
HasStream(true),
|
||||
IsDir(false),
|
||||
CrcDefined(false),
|
||||
AttribDefined(false)
|
||||
{}
|
||||
void SetAttrib(UInt32 attrib)
|
||||
{
|
||||
AttribDefined = true;
|
||||
Attrib = attrib;
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -330,13 +330,11 @@ void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector)
|
||||
WriteBoolVector(boolVector);
|
||||
}
|
||||
|
||||
unsigned BoolVector_CountSum(const CBoolVector &v);
|
||||
|
||||
void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
|
||||
{
|
||||
unsigned numDefined = 0;
|
||||
unsigned i;
|
||||
for (i = 0; i < digests.Defs.Size(); i++)
|
||||
if (digests.Defs[i])
|
||||
numDefined++;
|
||||
const unsigned numDefined = BoolVector_CountSum(digests.Defs);
|
||||
if (numDefined == 0)
|
||||
return;
|
||||
|
||||
@@ -348,7 +346,8 @@ void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
|
||||
WriteByte(0);
|
||||
WriteBoolVector(digests.Defs);
|
||||
}
|
||||
for (i = 0; i < digests.Defs.Size(); i++)
|
||||
|
||||
for (unsigned i = 0; i < digests.Defs.Size(); i++)
|
||||
if (digests.Defs[i])
|
||||
WriteUInt32(digests.Vals[i]);
|
||||
}
|
||||
@@ -453,10 +452,12 @@ void COutArchive::WriteSubStreamsInfo(const CObjectVector<CFolder> &folders,
|
||||
|
||||
// 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field.
|
||||
|
||||
void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
|
||||
void COutArchive::SkipToAligned(unsigned pos, unsigned alignShifts)
|
||||
{
|
||||
if (!_useAlign)
|
||||
return;
|
||||
|
||||
const unsigned alignSize = (unsigned)1 << alignShifts;
|
||||
pos += (unsigned)GetPos();
|
||||
pos &= (alignSize - 1);
|
||||
if (pos == 0)
|
||||
@@ -471,11 +472,11 @@ void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
|
||||
WriteByte(0);
|
||||
}
|
||||
|
||||
void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize)
|
||||
void COutArchive::WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts)
|
||||
{
|
||||
const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);
|
||||
const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2;
|
||||
SkipAlign(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSize);
|
||||
const UInt64 dataSize = ((UInt64)numDefined << itemSizeShifts) + bvSize + 2;
|
||||
SkipToAligned(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSizeShifts);
|
||||
|
||||
WriteByte(type);
|
||||
WriteNumber(dataSize);
|
||||
@@ -486,24 +487,18 @@ void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefin
|
||||
WriteByte(0);
|
||||
WriteBoolVector(v);
|
||||
}
|
||||
WriteByte(0);
|
||||
WriteByte(0); // 0 means no switching to external stream
|
||||
}
|
||||
|
||||
void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type)
|
||||
{
|
||||
unsigned numDefined = 0;
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < v.Defs.Size(); i++)
|
||||
if (v.Defs[i])
|
||||
numDefined++;
|
||||
|
||||
const unsigned numDefined = BoolVector_CountSum(v.Defs);
|
||||
if (numDefined == 0)
|
||||
return;
|
||||
|
||||
WriteAlignedBoolHeader(v.Defs, numDefined, type, 8);
|
||||
WriteAlignedBools(v.Defs, numDefined, type, 3);
|
||||
|
||||
for (i = 0; i < v.Defs.Size(); i++)
|
||||
for (unsigned i = 0; i < v.Defs.Size(); i++)
|
||||
if (v.Defs[i])
|
||||
WriteUInt64(v.Vals[i]);
|
||||
}
|
||||
@@ -648,7 +643,7 @@ void COutArchive::WriteHeader(
|
||||
if (numDefined > 0)
|
||||
{
|
||||
namesDataSize++;
|
||||
SkipAlign(2 + GetBigNumberSize(namesDataSize), 16);
|
||||
SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4);
|
||||
|
||||
WriteByte(NID::kName);
|
||||
WriteNumber(namesDataSize);
|
||||
@@ -673,28 +668,15 @@ void COutArchive::WriteHeader(
|
||||
|
||||
{
|
||||
/* ---------- Write Attrib ---------- */
|
||||
CBoolVector boolVector;
|
||||
boolVector.ClearAndSetSize(db.Files.Size());
|
||||
unsigned numDefined = 0;
|
||||
|
||||
{
|
||||
FOR_VECTOR (i, db.Files)
|
||||
{
|
||||
bool defined = db.Files[i].AttribDefined;
|
||||
boolVector[i] = defined;
|
||||
if (defined)
|
||||
numDefined++;
|
||||
}
|
||||
}
|
||||
const unsigned numDefined = BoolVector_CountSum(db.Attrib.Defs);
|
||||
|
||||
if (numDefined != 0)
|
||||
{
|
||||
WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttrib, 4);
|
||||
FOR_VECTOR (i, db.Files)
|
||||
WriteAlignedBools(db.Attrib.Defs, numDefined, NID::kWinAttrib, 2);
|
||||
FOR_VECTOR (i, db.Attrib.Defs)
|
||||
{
|
||||
const CFileItem &file = db.Files[i];
|
||||
if (file.AttribDefined)
|
||||
WriteUInt32(file.Attrib);
|
||||
if (db.Attrib.Defs[i])
|
||||
WriteUInt32(db.Attrib.Vals[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -702,18 +684,8 @@ void COutArchive::WriteHeader(
|
||||
/*
|
||||
{
|
||||
// ---------- Write IsAux ----------
|
||||
unsigned numAux = 0;
|
||||
const CBoolVector &isAux = db.IsAux;
|
||||
for (i = 0; i < isAux.Size(); i++)
|
||||
if (isAux[i])
|
||||
numAux++;
|
||||
if (numAux > 0)
|
||||
{
|
||||
const unsigned bvSize = Bv_GetSizeInBytes(isAux);
|
||||
WriteByte(NID::kIsAux);
|
||||
WriteNumber(bvSize);
|
||||
WriteBoolVector(isAux);
|
||||
}
|
||||
if (BoolVector_CountSum(db.IsAux) != 0)
|
||||
WritePropBoolVector(NID::kIsAux, db.IsAux);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -734,10 +706,10 @@ void COutArchive::WriteHeader(
|
||||
}
|
||||
if (numParentLinks > 0)
|
||||
{
|
||||
// WriteAlignedBoolHeader(boolVector, numDefined, NID::kParent, 4);
|
||||
// WriteAlignedBools(boolVector, numDefined, NID::kParent, 2);
|
||||
const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector);
|
||||
const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1;
|
||||
SkipAlign(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 4);
|
||||
SkipToAligned(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 2);
|
||||
|
||||
WriteByte(NID::kParent);
|
||||
WriteNumber(dataSize);
|
||||
@@ -765,7 +737,7 @@ void COutArchive::WriteHeader(
|
||||
// secureDataSize += db.SecureIDs.Size() * 4;
|
||||
for (i = 0; i < db.SecureIDs.Size(); i++)
|
||||
secureDataSize += GetBigNumberSize(db.SecureIDs[i]);
|
||||
SkipAlign(2 + GetBigNumberSize(secureDataSize), 4);
|
||||
SkipToAligned(2 + GetBigNumberSize(secureDataSize), 2);
|
||||
WriteByte(NID::kNtSecure);
|
||||
WriteNumber(secureDataSize);
|
||||
WriteByte(0);
|
||||
@@ -888,6 +860,18 @@ HRESULT COutArchive::WriteDatabase(
|
||||
}
|
||||
}
|
||||
|
||||
void CUInt32DefVector::SetItem(unsigned index, bool defined, UInt32 value)
|
||||
{
|
||||
while (index >= Defs.Size())
|
||||
Defs.Add(false);
|
||||
Defs[index] = defined;
|
||||
if (!defined)
|
||||
return;
|
||||
while (index >= Vals.Size())
|
||||
Vals.Add(0);
|
||||
Vals[index] = value;
|
||||
}
|
||||
|
||||
void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value)
|
||||
{
|
||||
while (index >= Defs.Size())
|
||||
@@ -907,6 +891,7 @@ void CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2
|
||||
ATime.SetItem(index, file2.ATimeDefined, file2.ATime);
|
||||
MTime.SetItem(index, file2.MTimeDefined, file2.MTime);
|
||||
StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos);
|
||||
Attrib.SetItem(index, file2.AttribDefined, file2.Attrib);
|
||||
SetItem_Anti(index, file2.IsAnti);
|
||||
// SetItem_Aux(index, file2.IsAux);
|
||||
Names.Add(name);
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
size_t GetPos() const { return _pos; }
|
||||
};
|
||||
|
||||
|
||||
struct CHeaderOptions
|
||||
{
|
||||
bool CompressMainHeader;
|
||||
@@ -71,24 +72,31 @@ struct CFileItem2
|
||||
UInt64 ATime;
|
||||
UInt64 MTime;
|
||||
UInt64 StartPos;
|
||||
UInt32 Attrib;
|
||||
|
||||
bool CTimeDefined;
|
||||
bool ATimeDefined;
|
||||
bool MTimeDefined;
|
||||
bool StartPosDefined;
|
||||
bool AttribDefined;
|
||||
bool IsAnti;
|
||||
// bool IsAux;
|
||||
|
||||
/*
|
||||
void Init()
|
||||
{
|
||||
CTimeDefined = false;
|
||||
ATimeDefined = false;
|
||||
MTimeDefined = false;
|
||||
StartPosDefined = false;
|
||||
AttribDefined = false;
|
||||
IsAnti = false;
|
||||
// IsAux = false;
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
struct COutFolders
|
||||
{
|
||||
CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
|
||||
@@ -111,6 +119,7 @@ struct COutFolders
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CArchiveDatabaseOut: public COutFolders
|
||||
{
|
||||
CRecordVector<UInt64> PackSizes;
|
||||
@@ -123,10 +132,11 @@ struct CArchiveDatabaseOut: public COutFolders
|
||||
CUInt64DefVector ATime;
|
||||
CUInt64DefVector MTime;
|
||||
CUInt64DefVector StartPos;
|
||||
CRecordVector<bool> IsAnti;
|
||||
CUInt32DefVector Attrib;
|
||||
CBoolVector IsAnti;
|
||||
|
||||
/*
|
||||
CRecordVector<bool> IsAux;
|
||||
CBoolVector IsAux;
|
||||
|
||||
CByteBuffer SecureBuf;
|
||||
CRecordVector<UInt32> SecureSizes;
|
||||
@@ -154,6 +164,7 @@ struct CArchiveDatabaseOut: public COutFolders
|
||||
ATime.Clear();
|
||||
MTime.Clear();
|
||||
StartPos.Clear();
|
||||
Attrib.Clear();
|
||||
IsAnti.Clear();
|
||||
|
||||
/*
|
||||
@@ -176,6 +187,7 @@ struct CArchiveDatabaseOut: public COutFolders
|
||||
ATime.ReserveDown();
|
||||
MTime.ReserveDown();
|
||||
StartPos.ReserveDown();
|
||||
Attrib.ReserveDown();
|
||||
IsAnti.ReserveDown();
|
||||
|
||||
/*
|
||||
@@ -196,11 +208,12 @@ struct CArchiveDatabaseOut: public COutFolders
|
||||
{
|
||||
unsigned size = Files.Size();
|
||||
return (
|
||||
CTime.CheckSize(size) &&
|
||||
ATime.CheckSize(size) &&
|
||||
MTime.CheckSize(size) &&
|
||||
StartPos.CheckSize(size) &&
|
||||
(size == IsAnti.Size() || IsAnti.Size() == 0));
|
||||
CTime.CheckSize(size)
|
||||
&& ATime.CheckSize(size)
|
||||
&& MTime.CheckSize(size)
|
||||
&& StartPos.CheckSize(size)
|
||||
&& Attrib.CheckSize(size)
|
||||
&& (size == IsAnti.Size() || IsAnti.Size() == 0));
|
||||
}
|
||||
|
||||
bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
|
||||
@@ -224,6 +237,7 @@ struct CArchiveDatabaseOut: public COutFolders
|
||||
void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name);
|
||||
};
|
||||
|
||||
|
||||
class COutArchive
|
||||
{
|
||||
UInt64 _prefixHeaderPos;
|
||||
@@ -261,8 +275,8 @@ class COutArchive
|
||||
const CRecordVector<UInt64> &unpackSizes,
|
||||
const CUInt32DefVector &digests);
|
||||
|
||||
void SkipAlign(unsigned pos, unsigned alignSize);
|
||||
void WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize);
|
||||
void SkipToAligned(unsigned pos, unsigned alignShifts);
|
||||
void WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts);
|
||||
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
|
||||
|
||||
HRESULT EncodeStream(
|
||||
|
||||
@@ -1088,18 +1088,23 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode,
|
||||
}
|
||||
|
||||
|
||||
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
|
||||
CFileItem &file, CFileItem2 &file2)
|
||||
static void UpdateItem_To_FileItem2(const CUpdateItem &ui, CFileItem2 &file2)
|
||||
{
|
||||
if (ui.AttribDefined)
|
||||
file.SetAttrib(ui.Attrib);
|
||||
|
||||
file2.Attrib = ui.Attrib; file2.AttribDefined = ui.AttribDefined;
|
||||
file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined;
|
||||
file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined;
|
||||
file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined;
|
||||
file2.IsAnti = ui.IsAnti;
|
||||
// file2.IsAux = false;
|
||||
file2.StartPosDefined = false;
|
||||
// file2.StartPos = 0;
|
||||
}
|
||||
|
||||
|
||||
static void UpdateItem_To_FileItem(const CUpdateItem &ui,
|
||||
CFileItem &file, CFileItem2 &file2)
|
||||
{
|
||||
UpdateItem_To_FileItem2(ui, file2);
|
||||
|
||||
file.Size = ui.Size;
|
||||
file.IsDir = ui.IsDir;
|
||||
@@ -1107,6 +1112,8 @@ static void FromUpdateItemToFileItem(const CUpdateItem &ui,
|
||||
// file.IsAltStream = ui.IsAltStream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CRepackInStreamWithSizes:
|
||||
public ISequentialInStream,
|
||||
public ICompressGetSubStreamSize,
|
||||
@@ -1437,6 +1444,7 @@ public:
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
|
||||
bool dataAfterEnd_Error;
|
||||
HRESULT Result;
|
||||
CMyComPtr<IInStream> InStream;
|
||||
|
||||
@@ -1479,7 +1487,9 @@ void CThreadDecoder::Execute()
|
||||
bool passwordIsDefined = false;
|
||||
UString password;
|
||||
#endif
|
||||
|
||||
|
||||
dataAfterEnd_Error = false;
|
||||
|
||||
Result = Decoder.Decode(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
InStream,
|
||||
@@ -1491,12 +1501,15 @@ void CThreadDecoder::Execute()
|
||||
|
||||
Fos,
|
||||
NULL, // compressProgress
|
||||
|
||||
NULL // *inStreamMainRes
|
||||
, dataAfterEnd_Error
|
||||
|
||||
_7Z_DECODER_CRYPRO_VARS
|
||||
#ifndef _7ZIP_ST
|
||||
, MtMode, NumThreads
|
||||
#endif
|
||||
|
||||
);
|
||||
}
|
||||
catch(...)
|
||||
@@ -1541,6 +1554,7 @@ static void GetFile(const CDatabase &inDb, unsigned index, CFileItem &file, CFil
|
||||
file2.ATimeDefined = inDb.ATime.GetItem(index, file2.ATime);
|
||||
file2.MTimeDefined = inDb.MTime.GetItem(index, file2.MTime);
|
||||
file2.StartPosDefined = inDb.StartPos.GetItem(index, file2.StartPos);
|
||||
file2.AttribDefined = inDb.Attrib.GetItem(index, file2.Attrib);
|
||||
file2.IsAnti = inDb.IsItemAnti(index);
|
||||
// file2.IsAux = inDb.IsItemAux(index);
|
||||
}
|
||||
@@ -1837,7 +1851,7 @@ HRESULT Update(
|
||||
continue;
|
||||
secureID = ui.SecureIndex;
|
||||
if (ui.NewProps)
|
||||
FromUpdateItemToFileItem(ui, file, file2);
|
||||
UpdateItem_To_FileItem(ui, file, file2);
|
||||
else
|
||||
GetFile(*db, ui.IndexInArchive, file, file2);
|
||||
}
|
||||
@@ -1887,7 +1901,8 @@ HRESULT Update(
|
||||
UString name;
|
||||
if (ui.NewProps)
|
||||
{
|
||||
FromUpdateItemToFileItem(ui, file, file2);
|
||||
UpdateItem_To_FileItem(ui, file, file2);
|
||||
file.CrcDefined = false;
|
||||
name = ui.Name;
|
||||
}
|
||||
else
|
||||
@@ -2107,6 +2122,8 @@ HRESULT Update(
|
||||
#endif
|
||||
|
||||
CMyComPtr<ISequentialInStream> decodedStream;
|
||||
bool dataAfterEnd_Error = false;
|
||||
|
||||
HRESULT res = threadDecoder.Decoder.Decode(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
inStream,
|
||||
@@ -2117,13 +2134,16 @@ HRESULT Update(
|
||||
|
||||
NULL, // *outStream
|
||||
NULL, // *compressProgress
|
||||
|
||||
&decodedStream
|
||||
, dataAfterEnd_Error
|
||||
|
||||
_7Z_DECODER_CRYPRO_VARS
|
||||
#ifndef _7ZIP_ST
|
||||
, false // mtMode
|
||||
, 1 // numThreads
|
||||
#endif
|
||||
|
||||
);
|
||||
|
||||
RINOK(res);
|
||||
@@ -2175,16 +2195,19 @@ HRESULT Update(
|
||||
|
||||
HRESULT decodeRes = threadDecoder.Result;
|
||||
// if (res == k_My_HRESULT_CRC_ERROR)
|
||||
if (decodeRes == S_FALSE)
|
||||
if (decodeRes == S_FALSE || threadDecoder.dataAfterEnd_Error)
|
||||
{
|
||||
if (extractCallback)
|
||||
{
|
||||
RINOK(extractCallback->ReportExtractResult(
|
||||
NEventIndexType::kInArcIndex, db->FolderStartFileIndex[folderIndex],
|
||||
// NEventIndexType::kBlockIndex, (UInt32)folderIndex,
|
||||
NExtract::NOperationResult::kDataError));
|
||||
(decodeRes != S_OK ?
|
||||
NExtract::NOperationResult::kDataError :
|
||||
NExtract::NOperationResult::kDataAfterEnd)));
|
||||
}
|
||||
return E_FAIL;
|
||||
if (decodeRes != S_OK)
|
||||
return E_FAIL;
|
||||
}
|
||||
RINOK(decodeRes);
|
||||
if (encodeRes == S_OK)
|
||||
@@ -2224,12 +2247,7 @@ HRESULT Update(
|
||||
CNum indexInFolder = 0;
|
||||
for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
|
||||
{
|
||||
CFileItem file;
|
||||
CFileItem2 file2;
|
||||
GetFile(*db, fi, file, file2);
|
||||
UString name;
|
||||
db->GetPath(fi, name);
|
||||
if (file.HasStream)
|
||||
if (db->Files[fi].HasStream)
|
||||
{
|
||||
indexInFolder++;
|
||||
int updateIndex = fileIndexToUpdateIndexMap[fi];
|
||||
@@ -2238,17 +2256,21 @@ HRESULT Update(
|
||||
const CUpdateItem &ui = updateItems[updateIndex];
|
||||
if (ui.NewData)
|
||||
continue;
|
||||
|
||||
UString name;
|
||||
CFileItem file;
|
||||
CFileItem2 file2;
|
||||
GetFile(*db, fi, file, file2);
|
||||
|
||||
if (ui.NewProps)
|
||||
{
|
||||
CFileItem uf;
|
||||
FromUpdateItemToFileItem(ui, uf, file2);
|
||||
uf.Size = file.Size;
|
||||
uf.Crc = file.Crc;
|
||||
uf.CrcDefined = file.CrcDefined;
|
||||
uf.HasStream = file.HasStream;
|
||||
file = uf;
|
||||
UpdateItem_To_FileItem2(ui, file2);
|
||||
file.IsDir = ui.IsDir;
|
||||
name = ui.Name;
|
||||
}
|
||||
else
|
||||
db->GetPath(fi, name);
|
||||
|
||||
/*
|
||||
file.Parent = ui.ParentFolderIndex;
|
||||
if (ui.TreeFolderIndex >= 0)
|
||||
@@ -2292,7 +2314,7 @@ HRESULT Update(
|
||||
const CUpdateItem &ui = updateItems[index];
|
||||
CFileItem file;
|
||||
if (ui.NewProps)
|
||||
FromUpdateItemToFileItem(ui, file);
|
||||
UpdateItem_To_FileItem(ui, file);
|
||||
else
|
||||
file = db.Files[ui.IndexInArchive];
|
||||
if (file.IsAnti || file.IsDir)
|
||||
@@ -2367,7 +2389,7 @@ HRESULT Update(
|
||||
UString name;
|
||||
if (ui.NewProps)
|
||||
{
|
||||
FromUpdateItemToFileItem(ui, file, file2);
|
||||
UpdateItem_To_FileItem(ui, file, file2);
|
||||
name = ui.Name;
|
||||
}
|
||||
else
|
||||
@@ -2386,7 +2408,7 @@ HRESULT Update(
|
||||
{
|
||||
skippedSize += ui.Size;
|
||||
continue;
|
||||
// file.Name.AddAscii(".locked");
|
||||
// file.Name += ".locked";
|
||||
}
|
||||
|
||||
file.Crc = inStreamSpec->CRCs[subIndex];
|
||||
|
||||
Reference in New Issue
Block a user