mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 15:14:59 -06:00
Update to 7-Zip 17.00 Beta
This commit is contained in:
@@ -42,32 +42,38 @@ static const Byte kHostOS =
|
||||
static const Byte kMadeByHostOS = kHostOS;
|
||||
static const Byte kExtractHostOS = kHostOS;
|
||||
|
||||
static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStored;
|
||||
static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStore;
|
||||
|
||||
static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, UInt64 size,
|
||||
COutArchive &outArchive, ICompressProgressInfo *progress)
|
||||
|
||||
static void AddAesExtra(CItem &item, Byte aesKeyMode, UInt16 method)
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> outStream;
|
||||
outArchive.CreateStreamForCopying(&outStream);
|
||||
return NCompress::CopyStream_ExactSize(inStream, outStream, size, progress);
|
||||
CWzAesExtra wzAesField;
|
||||
wzAesField.Strength = aesKeyMode;
|
||||
wzAesField.Method = method;
|
||||
item.Method = NFileHeader::NCompressionMethod::kWzAES;
|
||||
item.Crc = 0;
|
||||
CExtraSubBlock sb;
|
||||
wzAesField.SetSubBlock(sb);
|
||||
item.LocalExtra.SubBlocks.Add(sb);
|
||||
item.CentralExtra.SubBlocks.Add(sb);
|
||||
}
|
||||
|
||||
|
||||
static void SetFileHeader(
|
||||
COutArchive &archive,
|
||||
const CCompressionMethodMode &options,
|
||||
const CUpdateItem &ui,
|
||||
// bool isSeqMode,
|
||||
CItemOut &item)
|
||||
{
|
||||
item.Size = ui.Size;
|
||||
bool isDir;
|
||||
bool isDir = ui.IsDir;
|
||||
|
||||
item.ClearFlags();
|
||||
|
||||
if (ui.NewProps)
|
||||
{
|
||||
isDir = ui.IsDir;
|
||||
item.Name = ui.Name;
|
||||
item.Comment = ui.Comment;
|
||||
item.SetUtf8(ui.IsUtf8);
|
||||
item.ExternalAttrib = ui.Attrib;
|
||||
item.Time = ui.Time;
|
||||
@@ -76,10 +82,11 @@ static void SetFileHeader(
|
||||
item.Ntfs_CTime = ui.Ntfs_CTime;
|
||||
item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined;
|
||||
}
|
||||
/*
|
||||
else
|
||||
isDir = item.IsDir();
|
||||
*/
|
||||
|
||||
item.LocalHeaderPos = archive.GetCurPos();
|
||||
item.MadeByVersion.HostOS = kMadeByHostOS;
|
||||
item.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion;
|
||||
|
||||
@@ -97,14 +104,32 @@ static void SetFileHeader(
|
||||
item.Size = 0;
|
||||
item.Crc = 0;
|
||||
}
|
||||
|
||||
item.LocalExtra.Clear();
|
||||
item.CentralExtra.Clear();
|
||||
|
||||
if (isDir)
|
||||
{
|
||||
item.ExtractVersion.Version = NFileHeader::NCompressionMethod::kExtractVersion_Dir;
|
||||
item.Method = kMethodForDirectory;
|
||||
item.PackSize = 0;
|
||||
item.Size = 0;
|
||||
item.Crc = 0;
|
||||
}
|
||||
else if (options.IsRealAesMode())
|
||||
AddAesExtra(item, options.AesKeyMode, (Byte)(options.MethodSequence.IsEmpty() ? 8 : options.MethodSequence[0]));
|
||||
}
|
||||
|
||||
|
||||
// we call SetItemInfoFromCompressingResult() after SetFileHeader()
|
||||
|
||||
static void SetItemInfoFromCompressingResult(const CCompressingResult &compressingResult,
|
||||
bool isAesMode, Byte aesKeyMode, CItem &item)
|
||||
{
|
||||
item.ExtractVersion.Version = compressingResult.ExtractVersion;
|
||||
item.Method = compressingResult.Method;
|
||||
if (compressingResult.Method == NFileHeader::NCompressionMethod::kLZMA && compressingResult.LzmaEos)
|
||||
item.Flags |= NFileHeader::NFlags::kLzmaEOS;
|
||||
item.Crc = compressingResult.CRC;
|
||||
item.Size = compressingResult.UnpackSize;
|
||||
item.PackSize = compressingResult.PackSize;
|
||||
@@ -113,17 +138,7 @@ static void SetItemInfoFromCompressingResult(const CCompressingResult &compressi
|
||||
item.CentralExtra.Clear();
|
||||
|
||||
if (isAesMode)
|
||||
{
|
||||
CWzAesExtra wzAesField;
|
||||
wzAesField.Strength = aesKeyMode;
|
||||
wzAesField.Method = compressingResult.Method;
|
||||
item.Method = NFileHeader::NCompressionMethod::kWzAES;
|
||||
item.Crc = 0;
|
||||
CExtraSubBlock sb;
|
||||
wzAesField.SetSubBlock(sb);
|
||||
item.LocalExtra.SubBlocks.Add(sb);
|
||||
item.CentralExtra.SubBlocks.Add(sb);
|
||||
}
|
||||
AddAesExtra(item, aesKeyMode, compressingResult.Method);
|
||||
}
|
||||
|
||||
|
||||
@@ -151,6 +166,7 @@ struct CThreadInfo
|
||||
HRESULT Result;
|
||||
CCompressingResult CompressingResult;
|
||||
|
||||
bool SeqMode;
|
||||
bool IsFree;
|
||||
UInt32 UpdateIndex;
|
||||
UInt32 FileTime;
|
||||
@@ -160,6 +176,7 @@ struct CThreadInfo
|
||||
ProgressSpec(0),
|
||||
OutStreamSpec(0),
|
||||
Coder(options),
|
||||
SeqMode(false),
|
||||
FileTime(0)
|
||||
{}
|
||||
|
||||
@@ -193,7 +210,7 @@ void CThreadInfo::WaitAndCode()
|
||||
|
||||
Result = Coder.Compress(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
InStream, OutStream, FileTime, Progress, CompressingResult);
|
||||
InStream, OutStream, SeqMode, FileTime, Progress, CompressingResult);
|
||||
|
||||
if (Result == S_OK && Progress)
|
||||
Result = Progress->SetRatioInfo(&CompressingResult.UnpackSize, &CompressingResult.PackSize);
|
||||
@@ -342,6 +359,8 @@ static HRESULT UpdateItemOldData(
|
||||
NUpdateNotifyOp::kReplicate))
|
||||
}
|
||||
|
||||
UInt64 rangeSize;
|
||||
|
||||
if (ui.NewProps)
|
||||
{
|
||||
if (item.HasDescriptor())
|
||||
@@ -349,14 +368,11 @@ static HRESULT UpdateItemOldData(
|
||||
|
||||
// use old name size.
|
||||
|
||||
CMyComPtr<ISequentialInStream> packStream;
|
||||
RINOK(inArchive->GetItemStream(itemEx, true, packStream));
|
||||
if (!packStream)
|
||||
return E_NOTIMPL;
|
||||
|
||||
// we keep ExternalAttrib and some another properties from old archive
|
||||
// item.ExternalAttrib = ui.Attrib;
|
||||
|
||||
// if we don't change Comment, we keep Comment from OldProperties
|
||||
item.Comment = ui.Comment;
|
||||
item.Name = ui.Name;
|
||||
item.SetUtf8(ui.IsUtf8);
|
||||
item.Time = ui.Time;
|
||||
@@ -367,46 +383,37 @@ static HRESULT UpdateItemOldData(
|
||||
|
||||
item.CentralExtra.RemoveUnknownSubBlocks();
|
||||
item.LocalExtra.RemoveUnknownSubBlocks();
|
||||
item.LocalHeaderPos = archive.GetCurPos();
|
||||
|
||||
archive.PrepareWriteCompressedData2(item.Name.Len(), item.Size, item.PackSize, item.LocalExtra.HasWzAes());
|
||||
archive.WriteLocalHeader(item);
|
||||
|
||||
RINOK(CopyBlockToArchive(packStream, itemEx.PackSize, archive, progress));
|
||||
|
||||
complexity += itemEx.PackSize;
|
||||
rangeSize = item.GetPackSizeWithDescriptor();
|
||||
}
|
||||
else
|
||||
{
|
||||
CMyComPtr<ISequentialInStream> packStream;
|
||||
RINOK(inArchive->GetItemStream(itemEx, false, packStream));
|
||||
if (!packStream)
|
||||
return E_NOTIMPL;
|
||||
|
||||
// set new header position
|
||||
item.LocalHeaderPos = archive.GetCurPos();
|
||||
|
||||
const UInt64 rangeSize = itemEx.GetLocalFullSize();
|
||||
|
||||
RINOK(CopyBlockToArchive(packStream, rangeSize, archive, progress));
|
||||
|
||||
complexity += rangeSize;
|
||||
archive.MoveCurPos(rangeSize);
|
||||
rangeSize = itemEx.GetLocalFullSize();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
CMyComPtr<ISequentialInStream> packStream;
|
||||
|
||||
RINOK(inArchive->GetItemStream(itemEx, ui.NewProps, packStream));
|
||||
if (!packStream)
|
||||
return E_NOTIMPL;
|
||||
|
||||
complexity += rangeSize;
|
||||
|
||||
CMyComPtr<ISequentialOutStream> outStream;
|
||||
archive.CreateStreamForCopying(outStream);
|
||||
HRESULT res = NCompress::CopyStream_ExactSize(packStream, outStream, rangeSize, progress);
|
||||
archive.MoveCurPos(rangeSize);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static void WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options,
|
||||
const CUpdateItem &ui, CItemOut &item)
|
||||
{
|
||||
SetFileHeader(archive, *options, ui, item);
|
||||
archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size,
|
||||
// options->IsRealAesMode()
|
||||
false // fixed 9.31
|
||||
);
|
||||
archive.WriteLocalHeader_And_SeekToNextFile(item);
|
||||
SetFileHeader(*options, ui, item);
|
||||
archive.WriteLocalHeader(item);
|
||||
}
|
||||
|
||||
|
||||
@@ -490,6 +497,8 @@ static HRESULT Update2St(
|
||||
|
||||
if (!ui.NewProps || !ui.NewData)
|
||||
{
|
||||
// Note: for (ui.NewProps && !ui.NewData) it copies Props from old archive,
|
||||
// But we will rewrite all important properties later. But we can keep some properties like Comment
|
||||
itemEx = inputItems[ui.IndexInArc];
|
||||
if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK)
|
||||
return E_NOTIMPL;
|
||||
@@ -498,7 +507,8 @@ static HRESULT Update2St(
|
||||
|
||||
if (ui.NewData)
|
||||
{
|
||||
bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir());
|
||||
// bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir());
|
||||
bool isDir = ui.IsDir;
|
||||
if (isDir)
|
||||
{
|
||||
WriteDirHeader(archive, options, ui, item);
|
||||
@@ -517,28 +527,39 @@ static HRESULT Update2St(
|
||||
if (!fileInStream)
|
||||
return E_INVALIDARG;
|
||||
|
||||
// bool isSeqMode = false;
|
||||
/*
|
||||
bool seqMode;
|
||||
{
|
||||
CMyComPtr<IInStream> inStream2;
|
||||
fileInStream->QueryInterface(IID_IInStream, (void **)&inStream2);
|
||||
isSeqMode = (inStream2 == NULL);
|
||||
seqMode = (inStream2 == NULL);
|
||||
}
|
||||
*/
|
||||
// seqMode = true; // to test seqMode
|
||||
|
||||
UpdatePropsFromStream(ui, fileInStream, updateCallback, totalComplexity);
|
||||
SetFileHeader(archive, *options, ui, item);
|
||||
SetFileHeader(*options, ui, item);
|
||||
|
||||
item.SetDescriptorMode(seqMode);
|
||||
|
||||
// file Size can be 64-bit !!!
|
||||
archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, options->IsRealAesMode());
|
||||
|
||||
CCompressingResult compressingResult;
|
||||
|
||||
RINOK(compressor.Set_Pre_CompressionResult(
|
||||
seqMode,
|
||||
ui.Size,
|
||||
compressingResult));
|
||||
|
||||
SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item);
|
||||
|
||||
archive.WriteLocalHeader(item);
|
||||
|
||||
CMyComPtr<IOutStream> outStream;
|
||||
archive.CreateStreamForCompressing(&outStream);
|
||||
archive.CreateStreamForCompressing(outStream);
|
||||
|
||||
RINOK(compressor.Compress(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
fileInStream, outStream,
|
||||
ui.Time,
|
||||
seqMode, ui.Time,
|
||||
progress, compressingResult));
|
||||
|
||||
if (compressingResult.FileTimeWasUsed)
|
||||
@@ -551,7 +572,9 @@ static HRESULT Update2St(
|
||||
}
|
||||
|
||||
SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item);
|
||||
archive.WriteLocalHeader_And_SeekToNextFile(item);
|
||||
|
||||
archive.WriteLocalHeader_Replace(item);
|
||||
|
||||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
unpackSizeTotal += item.Size;
|
||||
packSizeTotal += item.PackSize;
|
||||
@@ -561,7 +584,9 @@ static HRESULT Update2St(
|
||||
{
|
||||
UInt64 complexity = 0;
|
||||
lps->SendRatio = false;
|
||||
|
||||
RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity));
|
||||
|
||||
lps->SendRatio = true;
|
||||
lps->ProgressOffset += complexity;
|
||||
}
|
||||
@@ -591,6 +616,7 @@ static HRESULT Update2(
|
||||
CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
|
||||
updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
|
||||
|
||||
bool unknownComplexity = false;
|
||||
UInt64 complexity = 0;
|
||||
UInt64 numFilesToCompress = 0;
|
||||
UInt64 numBytesToCompress = 0;
|
||||
@@ -602,7 +628,10 @@ static HRESULT Update2(
|
||||
const CUpdateItem &ui = updateItems[i];
|
||||
if (ui.NewData)
|
||||
{
|
||||
complexity += ui.Size;
|
||||
if (ui.Size == (UInt64)(Int64)-1)
|
||||
unknownComplexity = true;
|
||||
else
|
||||
complexity += ui.Size;
|
||||
numBytesToCompress += ui.Size;
|
||||
numFilesToCompress++;
|
||||
/*
|
||||
@@ -625,19 +654,49 @@ static HRESULT Update2(
|
||||
if (comment)
|
||||
complexity += comment->Size();
|
||||
complexity++; // end of central
|
||||
updateCallback->SetTotal(complexity);
|
||||
|
||||
if (!unknownComplexity)
|
||||
updateCallback->SetTotal(complexity);
|
||||
|
||||
UInt64 totalComplexity = complexity;
|
||||
|
||||
CAddCommon compressor(options);
|
||||
CCompressionMethodMode options2 = options;
|
||||
|
||||
if (options2._methods.IsEmpty())
|
||||
{
|
||||
// we need method item, if default method was used
|
||||
options2._methods.AddNew();
|
||||
}
|
||||
|
||||
CAddCommon compressor(options2);
|
||||
|
||||
complexity = 0;
|
||||
|
||||
CCompressionMethodMode options2 = options;
|
||||
const Byte method = options.MethodSequence.Front();
|
||||
|
||||
COneMethodInfo *oneMethodMain = NULL;
|
||||
if (!options2._methods.IsEmpty())
|
||||
oneMethodMain = &options2._methods[0];
|
||||
|
||||
{
|
||||
FOR_VECTOR (mi, options2._methods)
|
||||
{
|
||||
options2.SetGlobalLevelTo(options2._methods[mi]);
|
||||
}
|
||||
}
|
||||
|
||||
if (oneMethodMain)
|
||||
{
|
||||
// appnote recommends to use EOS marker for LZMA.
|
||||
if (method == NFileHeader::NCompressionMethod::kLZMA)
|
||||
oneMethodMain->AddProp_EndMarker_if_NotFound(true);
|
||||
}
|
||||
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
|
||||
UInt32 numThreads = options.NumThreads;
|
||||
UInt32 numThreads = options._numThreads;
|
||||
|
||||
const UInt32 kNumMaxThreads = 64;
|
||||
if (numThreads > kNumMaxThreads)
|
||||
numThreads = kNumMaxThreads;
|
||||
@@ -646,7 +705,6 @@ static HRESULT Update2(
|
||||
if (numThreads < 1)
|
||||
numThreads = 1;
|
||||
|
||||
|
||||
const size_t kMemPerThread = (1 << 25);
|
||||
const size_t kBlockSize = 1 << 16;
|
||||
|
||||
@@ -655,44 +713,69 @@ static HRESULT Update2(
|
||||
if (numFilesToCompress <= 1)
|
||||
mtMode = false;
|
||||
|
||||
Byte method = options.MethodSequence.Front();
|
||||
|
||||
if (!mtMode)
|
||||
{
|
||||
if (options2.MethodInfo.FindProp(NCoderPropID::kNumThreads) < 0)
|
||||
FOR_VECTOR (mi, options2._methods)
|
||||
{
|
||||
// fixed for 9.31. bzip2 default is just one thread.
|
||||
if (options2.NumThreadsWasChanged || method == NFileHeader::NCompressionMethod::kBZip2)
|
||||
options2.MethodInfo.AddProp_NumThreads(numThreads);
|
||||
COneMethodInfo &onem = options2._methods[mi];
|
||||
|
||||
if (onem.FindProp(NCoderPropID::kNumThreads) < 0)
|
||||
{
|
||||
// fixed for 9.31. bzip2 default is just one thread.
|
||||
onem.AddProp_NumThreads(numThreads);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (method == NFileHeader::NCompressionMethod::kStored && !options.PasswordIsDefined)
|
||||
if (method == NFileHeader::NCompressionMethod::kStore && !options.PasswordIsDefined)
|
||||
numThreads = 1;
|
||||
|
||||
if (oneMethodMain)
|
||||
{
|
||||
|
||||
if (method == NFileHeader::NCompressionMethod::kBZip2)
|
||||
{
|
||||
bool fixedNumber;
|
||||
UInt32 numBZip2Threads = options2.MethodInfo.Get_BZip2_NumThreads(fixedNumber);
|
||||
UInt32 numBZip2Threads = oneMethodMain->Get_BZip2_NumThreads(fixedNumber);
|
||||
if (!fixedNumber)
|
||||
{
|
||||
UInt64 averageSize = numBytesToCompress / numFilesToCompress;
|
||||
UInt32 blockSize = options2.MethodInfo.Get_BZip2_BlockSize();
|
||||
UInt64 averageNumberOfBlocks = averageSize / blockSize + 1;
|
||||
const UInt64 averageSize = numBytesToCompress / numFilesToCompress;
|
||||
const UInt32 blockSize = oneMethodMain->Get_BZip2_BlockSize();
|
||||
const UInt64 averageNumberOfBlocks = averageSize / blockSize + 1;
|
||||
numBZip2Threads = 32;
|
||||
if (averageNumberOfBlocks < numBZip2Threads)
|
||||
if (numBZip2Threads > averageNumberOfBlocks)
|
||||
numBZip2Threads = (UInt32)averageNumberOfBlocks;
|
||||
options2.MethodInfo.AddProp_NumThreads(numBZip2Threads);
|
||||
oneMethodMain->AddProp_NumThreads(numBZip2Threads);
|
||||
}
|
||||
numThreads /= numBZip2Threads;
|
||||
}
|
||||
if (method == NFileHeader::NCompressionMethod::kLZMA)
|
||||
|
||||
if (method == NFileHeader::NCompressionMethod::kXz)
|
||||
{
|
||||
bool fixedNumber;
|
||||
UInt32 numLzma2Threads = oneMethodMain->Get_Lzma2_NumThreads(fixedNumber);
|
||||
if (!fixedNumber)
|
||||
{
|
||||
const UInt64 averageSize = numBytesToCompress / numFilesToCompress;
|
||||
const UInt64 blockSize = oneMethodMain->Get_Lzma2_BlockSize();
|
||||
const UInt64 averageNumberOfBlocks = averageSize / blockSize + 1;
|
||||
numLzma2Threads = 2;
|
||||
if (numLzma2Threads > averageNumberOfBlocks)
|
||||
numLzma2Threads = (UInt32)averageNumberOfBlocks;
|
||||
oneMethodMain->AddProp_NumThreads(numLzma2Threads);
|
||||
}
|
||||
numThreads /= numLzma2Threads;
|
||||
}
|
||||
|
||||
if (method == NFileHeader::NCompressionMethod::kLZMA)
|
||||
{
|
||||
// we suppose that default LZMA is 2 thread. So we don't change it
|
||||
UInt32 numLZMAThreads = options2.MethodInfo.Get_Lzma_NumThreads(fixedNumber);
|
||||
UInt32 numLZMAThreads = oneMethodMain->Get_Lzma_NumThreads();
|
||||
numThreads /= numLZMAThreads;
|
||||
}
|
||||
}
|
||||
|
||||
if (numThreads > numFilesToCompress)
|
||||
numThreads = (UInt32)numFilesToCompress;
|
||||
if (numThreads <= 1)
|
||||
@@ -747,6 +830,7 @@ static HRESULT Update2(
|
||||
threadInfo.ProgressSpec = new CMtCompressProgress();
|
||||
threadInfo.Progress = threadInfo.ProgressSpec;
|
||||
threadInfo.ProgressSpec->Init(&mtCompressProgressMixer, (int)i);
|
||||
threadInfo.SeqMode = false; // fix it !
|
||||
threadInfo.FileTime = 0; // fix it !
|
||||
RINOK(threadInfo.CreateThread());
|
||||
}
|
||||
@@ -777,7 +861,9 @@ static HRESULT Update2(
|
||||
if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK)
|
||||
return E_NOTIMPL;
|
||||
(CItem &)item = itemEx;
|
||||
if (item.IsDir())
|
||||
if (item.IsDir() != ui.IsDir)
|
||||
return E_NOTIMPL;
|
||||
if (ui.IsDir)
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -849,7 +935,8 @@ static HRESULT Update2(
|
||||
|
||||
if (ui.NewData)
|
||||
{
|
||||
bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir());
|
||||
// bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir());
|
||||
bool isDir = ui.IsDir;
|
||||
|
||||
if (isDir)
|
||||
{
|
||||
@@ -857,39 +944,51 @@ static HRESULT Update2(
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lastRealStreamItemIndex < (int)itemIndex)
|
||||
{
|
||||
lastRealStreamItemIndex = itemIndex;
|
||||
SetFileHeader(archive, options, ui, item);
|
||||
// file Size can be 64-bit !!!
|
||||
archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, options.IsRealAesMode());
|
||||
}
|
||||
|
||||
CMemBlocks2 &memRef = refs.Refs[itemIndex];
|
||||
|
||||
if (memRef.Defined)
|
||||
{
|
||||
CMyComPtr<IOutStream> outStream;
|
||||
archive.CreateStreamForCompressing(&outStream);
|
||||
memRef.WriteToStream(memManager.GetBlockSize(), outStream);
|
||||
SetFileHeader(archive, options, ui, item);
|
||||
if (lastRealStreamItemIndex < (int)itemIndex)
|
||||
lastRealStreamItemIndex = itemIndex;
|
||||
|
||||
SetFileHeader(options, ui, item);
|
||||
// the BUG was fixed in 9.26:
|
||||
// SetItemInfoFromCompressingResult must be after SetFileHeader
|
||||
// to write correct Size.
|
||||
SetItemInfoFromCompressingResult(memRef.CompressingResult,
|
||||
options.IsRealAesMode(), options.AesKeyMode, item);
|
||||
archive.WriteLocalHeader_And_SeekToNextFile(item);
|
||||
archive.WriteLocalHeader(item);
|
||||
// RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
CMyComPtr<ISequentialOutStream> outStream;
|
||||
archive.CreateStreamForCopying(outStream);
|
||||
memRef.WriteToStream(memManager.GetBlockSize(), outStream);
|
||||
archive.MoveCurPos(item.PackSize);
|
||||
memRef.FreeOpt(&memManager);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lastRealStreamItemIndex < (int)itemIndex)
|
||||
{
|
||||
lastRealStreamItemIndex = itemIndex;
|
||||
SetFileHeader(options, ui, item);
|
||||
|
||||
CCompressingResult compressingResult;
|
||||
RINOK(compressor.Set_Pre_CompressionResult(
|
||||
false, // seqMode
|
||||
ui.Size,
|
||||
compressingResult));
|
||||
SetItemInfoFromCompressingResult(compressingResult, options.IsRealAesMode(), options.AesKeyMode, item);
|
||||
|
||||
// file Size can be 64-bit !!!
|
||||
archive.WriteLocalHeader(item);
|
||||
}
|
||||
|
||||
{
|
||||
CThreadInfo &thread = threads.Threads[threadIndices.Front()];
|
||||
if (!thread.OutStreamSpec->WasUnlockEventSent())
|
||||
{
|
||||
CMyComPtr<IOutStream> outStream;
|
||||
archive.CreateStreamForCompressing(&outStream);
|
||||
archive.CreateStreamForCompressing(outStream);
|
||||
thread.OutStreamSpec->SetOutStream(outStream);
|
||||
thread.OutStreamSpec->SetRealStreamMode();
|
||||
}
|
||||
@@ -918,10 +1017,10 @@ static HRESULT Update2(
|
||||
{
|
||||
RINOK(threadInfo.OutStreamSpec->WriteToRealStream());
|
||||
threadInfo.OutStreamSpec->ReleaseOutStream();
|
||||
SetFileHeader(archive, options, ui, item);
|
||||
SetFileHeader(options, ui, item);
|
||||
SetItemInfoFromCompressingResult(threadInfo.CompressingResult,
|
||||
options.IsRealAesMode(), options.AesKeyMode, item);
|
||||
archive.WriteLocalHeader_And_SeekToNextFile(item);
|
||||
archive.WriteLocalHeader_Replace(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user