mirror of
https://github.com/Xevion/easy7zip.git
synced 2026-02-01 06:24:12 -06:00
9.34
This commit is contained in:
committed by
Kornel Lesiński
parent
83f8ddcc5b
commit
f08f4dcc3c
Executable → Regular
+160
-138
@@ -4,12 +4,12 @@
|
||||
|
||||
#include "../../../../C/Alloc.h"
|
||||
|
||||
#include "Common/AutoPtr.h"
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "../../../Common/AutoPtr.h"
|
||||
#include "../../../Common/Defs.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
|
||||
#include "Windows/Defs.h"
|
||||
#include "Windows/Thread.h"
|
||||
#include "../../../Windows/Defs.h"
|
||||
#include "../../../Windows/Thread.h"
|
||||
|
||||
#include "../../Common/CreateCoder.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
@@ -44,12 +44,12 @@ static const Byte kExtractHostOS = kHostOS;
|
||||
|
||||
static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStored;
|
||||
|
||||
static HRESULT CopyBlockToArchive(ISequentialInStream *inStream,
|
||||
static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, UInt64 size,
|
||||
COutArchive &outArchive, ICompressProgressInfo *progress)
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> outStream;
|
||||
outArchive.CreateStreamForCopying(&outStream);
|
||||
return NCompress::CopyStream(inStream, outStream, progress);
|
||||
return NCompress::CopyStream_ExactSize(inStream, outStream, size, progress);
|
||||
}
|
||||
|
||||
static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive,
|
||||
@@ -57,13 +57,7 @@ static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive,
|
||||
{
|
||||
UInt64 position;
|
||||
RINOK(inStream->Seek(range.Position, STREAM_SEEK_SET, &position));
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
|
||||
streamSpec->SetStream(inStream);
|
||||
streamSpec->Init(range.Size);
|
||||
|
||||
RINOK(CopyBlockToArchive(inStreamLimited, outArchive, progress));
|
||||
RINOK(CopyBlockToArchive(inStream, range.Size, outArchive, progress));
|
||||
return progress->SetRatioInfo(&range.Size, &range.Size);
|
||||
}
|
||||
|
||||
@@ -71,42 +65,42 @@ static void SetFileHeader(
|
||||
COutArchive &archive,
|
||||
const CCompressionMethodMode &options,
|
||||
const CUpdateItem &ui,
|
||||
CItem &item)
|
||||
CItemOut &item)
|
||||
{
|
||||
item.UnPackSize = ui.Size;
|
||||
item.Size = ui.Size;
|
||||
bool isDir;
|
||||
|
||||
item.ClearFlags();
|
||||
|
||||
if (ui.NewProperties)
|
||||
if (ui.NewProps)
|
||||
{
|
||||
isDir = ui.IsDir;
|
||||
item.Name = ui.Name;
|
||||
item.SetUtf8(ui.IsUtf8);
|
||||
item.ExternalAttributes = ui.Attributes;
|
||||
item.ExternalAttrib = ui.Attrib;
|
||||
item.Time = ui.Time;
|
||||
item.NtfsMTime = ui.NtfsMTime;
|
||||
item.NtfsATime = ui.NtfsATime;
|
||||
item.NtfsCTime = ui.NtfsCTime;
|
||||
item.Ntfs_MTime = ui.Ntfs_MTime;
|
||||
item.Ntfs_ATime = ui.Ntfs_ATime;
|
||||
item.Ntfs_CTime = ui.Ntfs_CTime;
|
||||
item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined;
|
||||
}
|
||||
else
|
||||
isDir = item.IsDir();
|
||||
|
||||
item.LocalHeaderPosition = archive.GetCurrentPosition();
|
||||
item.LocalHeaderPos = archive.GetCurPos();
|
||||
item.MadeByVersion.HostOS = kMadeByHostOS;
|
||||
item.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion;
|
||||
|
||||
item.ExtractVersion.HostOS = kExtractHostOS;
|
||||
|
||||
item.InternalAttributes = 0; // test it
|
||||
item.InternalAttrib = 0; // test it
|
||||
item.SetEncrypted(!isDir && options.PasswordIsDefined);
|
||||
if (isDir)
|
||||
{
|
||||
item.ExtractVersion.Version = NFileHeader::NCompressionMethod::kExtractVersion_Dir;
|
||||
item.CompressionMethod = kMethodForDirectory;
|
||||
item.Method = kMethodForDirectory;
|
||||
item.PackSize = 0;
|
||||
item.FileCRC = 0; // test it
|
||||
item.Crc = 0; // test it
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,9 +108,9 @@ static void SetItemInfoFromCompressingResult(const CCompressingResult &compressi
|
||||
bool isAesMode, Byte aesKeyMode, CItem &item)
|
||||
{
|
||||
item.ExtractVersion.Version = compressingResult.ExtractVersion;
|
||||
item.CompressionMethod = compressingResult.Method;
|
||||
item.FileCRC = compressingResult.CRC;
|
||||
item.UnPackSize = compressingResult.UnpackSize;
|
||||
item.Method = compressingResult.Method;
|
||||
item.Crc = compressingResult.CRC;
|
||||
item.Size = compressingResult.UnpackSize;
|
||||
item.PackSize = compressingResult.PackSize;
|
||||
|
||||
item.LocalExtra.Clear();
|
||||
@@ -124,11 +118,11 @@ static void SetItemInfoFromCompressingResult(const CCompressingResult &compressi
|
||||
|
||||
if (isAesMode)
|
||||
{
|
||||
CWzAesExtraField wzAesField;
|
||||
CWzAesExtra wzAesField;
|
||||
wzAesField.Strength = aesKeyMode;
|
||||
wzAesField.Method = compressingResult.Method;
|
||||
item.CompressionMethod = NFileHeader::NCompressionMethod::kWzAES;
|
||||
item.FileCRC = 0;
|
||||
item.Method = NFileHeader::NCompressionMethod::kWzAES;
|
||||
item.Crc = 0;
|
||||
CExtraSubBlock sb;
|
||||
wzAesField.SetSubBlock(sb);
|
||||
item.LocalExtra.SubBlocks.Add(sb);
|
||||
@@ -142,10 +136,7 @@ static THREAD_FUNC_DECL CoderThread(void *threadCoderInfo);
|
||||
|
||||
struct CThreadInfo
|
||||
{
|
||||
#ifdef EXTERNAL_CODECS
|
||||
CMyComPtr<ICompressCodecsInfo> _codecsInfo;
|
||||
const CObjectVector<CCodecInfoEx> *_externalCodecs;
|
||||
#endif
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS2;
|
||||
|
||||
NWindows::CThread Thread;
|
||||
NWindows::NSynchronization::CAutoResetEvent CompressEvent;
|
||||
@@ -202,9 +193,7 @@ void CThreadInfo::WaitAndCode()
|
||||
if (ExitThread)
|
||||
return;
|
||||
Result = Coder.Compress(
|
||||
#ifdef EXTERNAL_CODECS
|
||||
_codecsInfo, _externalCodecs,
|
||||
#endif
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
InStream, OutStream, Progress, CompressingResult);
|
||||
if (Result == S_OK && Progress)
|
||||
Result = Progress->SetRatioInfo(&CompressingResult.UnpackSize, &CompressingResult.PackSize);
|
||||
@@ -224,7 +213,7 @@ public:
|
||||
CObjectVector<CThreadInfo> Threads;
|
||||
~CThreads()
|
||||
{
|
||||
for (int i = 0; i < Threads.Size(); i++)
|
||||
FOR_VECTOR (i, Threads)
|
||||
Threads[i].StopWaitClose();
|
||||
}
|
||||
};
|
||||
@@ -245,7 +234,7 @@ public:
|
||||
CMemRefs(CMemBlockManagerMt *manager): Manager(manager) {} ;
|
||||
~CMemRefs()
|
||||
{
|
||||
for (int i = 0; i < Refs.Size(); i++)
|
||||
FOR_VECTOR (i, Refs)
|
||||
Refs[i].FreeOpt(Manager);
|
||||
}
|
||||
};
|
||||
@@ -335,69 +324,74 @@ STDMETHODIMP CMtProgressMixer::SetRatioInfo(const UInt64 *inSize, const UInt64 *
|
||||
#endif
|
||||
|
||||
|
||||
static HRESULT UpdateItemOldData(COutArchive &archive,
|
||||
IInStream *inStream,
|
||||
const CUpdateItem &ui, CItemEx &item,
|
||||
static HRESULT UpdateItemOldData(
|
||||
COutArchive &archive,
|
||||
CInArchive *inArchive,
|
||||
const CItemEx &itemEx,
|
||||
const CUpdateItem &ui,
|
||||
CItemOut &item,
|
||||
/* bool izZip64, */
|
||||
ICompressProgressInfo *progress,
|
||||
UInt64 &complexity)
|
||||
{
|
||||
if (ui.NewProperties)
|
||||
if (ui.NewProps)
|
||||
{
|
||||
if (item.HasDescriptor())
|
||||
return E_NOTIMPL;
|
||||
|
||||
// use old name size.
|
||||
// CUpdateRange range(item.GetLocalExtraPosition(), item.LocalExtraSize + item.PackSize);
|
||||
CUpdateRange range(item.GetDataPosition(), item.PackSize);
|
||||
CUpdateRange range(inArchive->GetOffsetInStream(itemEx.GetDataPosition()), itemEx.PackSize);
|
||||
|
||||
// item.ExternalAttributes = ui.Attributes;
|
||||
// Test it
|
||||
// we keep ExternalAttrib and some another properties from old archive
|
||||
// item.ExternalAttrib = ui.Attrib;
|
||||
|
||||
item.Name = ui.Name;
|
||||
item.SetUtf8(ui.IsUtf8);
|
||||
item.Time = ui.Time;
|
||||
item.NtfsMTime = ui.NtfsMTime;
|
||||
item.NtfsATime = ui.NtfsATime;
|
||||
item.NtfsCTime = ui.NtfsCTime;
|
||||
item.Ntfs_MTime = ui.Ntfs_MTime;
|
||||
item.Ntfs_ATime = ui.Ntfs_ATime;
|
||||
item.Ntfs_CTime = ui.Ntfs_CTime;
|
||||
item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined;
|
||||
|
||||
item.CentralExtra.RemoveUnknownSubBlocks();
|
||||
item.LocalExtra.RemoveUnknownSubBlocks();
|
||||
|
||||
archive.PrepareWriteCompressedData2((UInt16)item.Name.Length(), item.UnPackSize, item.PackSize, item.LocalExtra.HasWzAesField());
|
||||
item.LocalHeaderPosition = archive.GetCurrentPosition();
|
||||
archive.SeekToPackedDataPosition();
|
||||
RINOK(WriteRange(inStream, archive, range, progress));
|
||||
complexity += range.Size;
|
||||
item.LocalHeaderPos = archive.GetCurPos();
|
||||
|
||||
archive.PrepareWriteCompressedData2(item.Name.Len(), item.Size, item.PackSize, item.LocalExtra.HasWzAes());
|
||||
archive.WriteLocalHeader(item);
|
||||
RINOK(WriteRange(inArchive->Stream, archive, range, progress));
|
||||
complexity += range.Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
CUpdateRange range(item.LocalHeaderPosition, item.GetLocalFullSize());
|
||||
CUpdateRange range(inArchive->GetOffsetInStream(itemEx.LocalHeaderPos), itemEx.GetLocalFullSize());
|
||||
|
||||
// set new header position
|
||||
item.LocalHeaderPosition = archive.GetCurrentPosition();
|
||||
item.LocalHeaderPos = archive.GetCurPos();
|
||||
|
||||
RINOK(WriteRange(inStream, archive, range, progress));
|
||||
RINOK(WriteRange(inArchive->Stream, archive, range, progress));
|
||||
complexity += range.Size;
|
||||
archive.MoveBasePosition(range.Size);
|
||||
archive.MoveCurPos(range.Size);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options,
|
||||
const CUpdateItem &ui, CItemEx &item)
|
||||
const CUpdateItem &ui, CItemOut &item)
|
||||
{
|
||||
SetFileHeader(archive, *options, ui, item);
|
||||
archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), ui.Size, options->IsRealAesMode());
|
||||
archive.WriteLocalHeader(item);
|
||||
archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size,
|
||||
// options->IsRealAesMode()
|
||||
false // fixed 9.31
|
||||
);
|
||||
archive.WriteLocalHeader_And_SeekToNextFile(item);
|
||||
}
|
||||
|
||||
static HRESULT Update2St(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
COutArchive &archive,
|
||||
CInArchive *inArchive,
|
||||
IInStream *inStream,
|
||||
const CObjectVector<CItemEx> &inputItems,
|
||||
const CObjectVector<CUpdateItem> &updateItems,
|
||||
const CCompressionMethodMode *options,
|
||||
@@ -410,26 +404,29 @@ static HRESULT Update2St(
|
||||
|
||||
CAddCommon compressor(*options);
|
||||
|
||||
CObjectVector<CItem> items;
|
||||
CObjectVector<CItemOut> items;
|
||||
UInt64 unpackSizeTotal = 0, packSizeTotal = 0;
|
||||
|
||||
for (int itemIndex = 0; itemIndex < updateItems.Size(); itemIndex++)
|
||||
FOR_VECTOR (itemIndex, updateItems)
|
||||
{
|
||||
lps->InSize = unpackSizeTotal;
|
||||
lps->OutSize = packSizeTotal;
|
||||
RINOK(lps->SetCur());
|
||||
const CUpdateItem &ui = updateItems[itemIndex];
|
||||
CItemEx item;
|
||||
if (!ui.NewProperties || !ui.NewData)
|
||||
CItemEx itemEx;
|
||||
CItemOut item;
|
||||
|
||||
if (!ui.NewProps || !ui.NewData)
|
||||
{
|
||||
item = inputItems[ui.IndexInArchive];
|
||||
if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK)
|
||||
itemEx = inputItems[ui.IndexInArc];
|
||||
if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK)
|
||||
return E_NOTIMPL;
|
||||
(CItem &)item = itemEx;
|
||||
}
|
||||
|
||||
if (ui.NewData)
|
||||
{
|
||||
bool isDir = ((ui.NewProperties) ? ui.IsDir : item.IsDir());
|
||||
bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir());
|
||||
if (isDir)
|
||||
{
|
||||
WriteDirHeader(archive, options, ui, item);
|
||||
@@ -445,10 +442,12 @@ static HRESULT Update2St(
|
||||
continue;
|
||||
}
|
||||
RINOK(res);
|
||||
if (!fileInStream)
|
||||
return E_INVALIDARG;
|
||||
|
||||
// file Size can be 64-bit !!!
|
||||
SetFileHeader(archive, *options, ui, item);
|
||||
archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), ui.Size, options->IsRealAesMode());
|
||||
archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, options->IsRealAesMode());
|
||||
CCompressingResult compressingResult;
|
||||
CMyComPtr<IOutStream> outStream;
|
||||
archive.CreateStreamForCompressing(&outStream);
|
||||
@@ -456,9 +455,9 @@ static HRESULT Update2St(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
fileInStream, outStream, progress, compressingResult));
|
||||
SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item);
|
||||
archive.WriteLocalHeader(item);
|
||||
archive.WriteLocalHeader_And_SeekToNextFile(item);
|
||||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
unpackSizeTotal += item.UnPackSize;
|
||||
unpackSizeTotal += item.Size;
|
||||
packSizeTotal += item.PackSize;
|
||||
}
|
||||
}
|
||||
@@ -466,12 +465,12 @@ static HRESULT Update2St(
|
||||
{
|
||||
UInt64 complexity = 0;
|
||||
lps->SendRatio = false;
|
||||
RINOK(UpdateItemOldData(archive, inStream, ui, item, progress, complexity));
|
||||
RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, complexity));
|
||||
lps->SendRatio = true;
|
||||
lps->ProgressOffset += complexity;
|
||||
}
|
||||
items.Add(item);
|
||||
lps->ProgressOffset += NFileHeader::kLocalBlockSize;
|
||||
lps->ProgressOffset += kLocalHeaderSize;
|
||||
}
|
||||
lps->InSize = unpackSizeTotal;
|
||||
lps->OutSize = packSizeTotal;
|
||||
@@ -484,7 +483,6 @@ static HRESULT Update2(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
COutArchive &archive,
|
||||
CInArchive *inArchive,
|
||||
IInStream *inStream,
|
||||
const CObjectVector<CItemEx> &inputItems,
|
||||
const CObjectVector<CUpdateItem> &updateItems,
|
||||
const CCompressionMethodMode *options,
|
||||
@@ -495,7 +493,7 @@ static HRESULT Update2(
|
||||
UInt64 numFilesToCompress = 0;
|
||||
UInt64 numBytesToCompress = 0;
|
||||
|
||||
int i;
|
||||
unsigned i;
|
||||
for (i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
const CUpdateItem &ui = updateItems[i];
|
||||
@@ -511,18 +509,18 @@ static HRESULT Update2(
|
||||
}
|
||||
else
|
||||
{
|
||||
CItemEx inputItem = inputItems[ui.IndexInArchive];
|
||||
CItemEx inputItem = inputItems[ui.IndexInArc];
|
||||
if (inArchive->ReadLocalItemAfterCdItemFull(inputItem) != S_OK)
|
||||
return E_NOTIMPL;
|
||||
complexity += inputItem.GetLocalFullSize();
|
||||
// complexity += inputItem.GetCentralExtraPlusCommentSize();
|
||||
}
|
||||
complexity += NFileHeader::kLocalBlockSize;
|
||||
complexity += NFileHeader::kCentralBlockSize;
|
||||
complexity += kLocalHeaderSize;
|
||||
complexity += kCentralHeaderSize;
|
||||
}
|
||||
|
||||
if (comment)
|
||||
complexity += comment->GetCapacity();
|
||||
complexity += comment->Size();
|
||||
complexity++; // end of central
|
||||
updateCallback->SetTotal(complexity);
|
||||
|
||||
@@ -540,6 +538,9 @@ static HRESULT Update2(
|
||||
UInt32 numThreads = options->NumThreads;
|
||||
if (numThreads > kNumMaxThreads)
|
||||
numThreads = kNumMaxThreads;
|
||||
if (numThreads < 1)
|
||||
numThreads = 1;
|
||||
|
||||
|
||||
const size_t kMemPerThread = (1 << 25);
|
||||
const size_t kBlockSize = 1 << 16;
|
||||
@@ -549,16 +550,18 @@ static HRESULT Update2(
|
||||
if (numFilesToCompress <= 1)
|
||||
mtMode = false;
|
||||
|
||||
Byte method = options->MethodSequence.Front();
|
||||
if (!mtMode)
|
||||
{
|
||||
if (numThreads < 2)
|
||||
if (options2.MethodInfo.FindProp(NCoderPropID::kNumThreads) < 0 &&
|
||||
options2.NumThreadsWasChanged)
|
||||
options2.MethodInfo.AddNumThreadsProp(1);
|
||||
if (options2.MethodInfo.FindProp(NCoderPropID::kNumThreads) < 0)
|
||||
{
|
||||
// fixed for 9.31. bzip2 default is just one thread.
|
||||
if (options2.NumThreadsWasChanged || method == NFileHeader::NCompressionMethod::kBZip2)
|
||||
options2.MethodInfo.AddNumThreadsProp(numThreads);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Byte method = options->MethodSequence.Front();
|
||||
if (method == NFileHeader::NCompressionMethod::kStored && !options->PasswordIsDefined)
|
||||
numThreads = 1;
|
||||
if (method == NFileHeader::NCompressionMethod::kBZip2)
|
||||
@@ -594,13 +597,13 @@ static HRESULT Update2(
|
||||
#endif
|
||||
return Update2St(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
archive, inArchive, inStream,
|
||||
archive, inArchive,
|
||||
inputItems, updateItems, &options2, comment, updateCallback);
|
||||
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
|
||||
CObjectVector<CItem> items;
|
||||
CObjectVector<CItemOut> items;
|
||||
|
||||
CMtProgressMixer *mtProgressMixerSpec = new CMtProgressMixer;
|
||||
CMyComPtr<ICompressProgressInfo> progress = mtProgressMixerSpec;
|
||||
@@ -629,8 +632,7 @@ static HRESULT Update2(
|
||||
{
|
||||
CThreadInfo &threadInfo = threads.Threads[i];
|
||||
#ifdef EXTERNAL_CODECS
|
||||
threadInfo._codecsInfo = codecsInfo;
|
||||
threadInfo._externalCodecs = externalCodecs;
|
||||
threadInfo.__externalCodecs = __externalCodecs;
|
||||
#endif
|
||||
RINOK(threadInfo.CreateEvents());
|
||||
threadInfo.OutStreamSpec = new COutMemStream(&memManager);
|
||||
@@ -643,9 +645,9 @@ static HRESULT Update2(
|
||||
RINOK(threadInfo.CreateThread());
|
||||
}
|
||||
}
|
||||
int mtItemIndex = 0;
|
||||
unsigned mtItemIndex = 0;
|
||||
|
||||
int itemIndex = 0;
|
||||
unsigned itemIndex = 0;
|
||||
int lastRealStreamItemIndex = -1;
|
||||
|
||||
while (itemIndex < updateItems.Size())
|
||||
@@ -655,17 +657,19 @@ static HRESULT Update2(
|
||||
const CUpdateItem &ui = updateItems[mtItemIndex++];
|
||||
if (!ui.NewData)
|
||||
continue;
|
||||
CItemEx item;
|
||||
if (ui.NewProperties)
|
||||
CItemEx itemEx;
|
||||
CItemOut item;
|
||||
if (ui.NewProps)
|
||||
{
|
||||
if (ui.IsDir)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = inputItems[ui.IndexInArchive];
|
||||
if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK)
|
||||
itemEx = inputItems[ui.IndexInArc];
|
||||
if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK)
|
||||
return E_NOTIMPL;
|
||||
(CItem &)item = itemEx;
|
||||
if (item.IsDir())
|
||||
continue;
|
||||
}
|
||||
@@ -676,13 +680,15 @@ static HRESULT Update2(
|
||||
if (res == S_FALSE)
|
||||
{
|
||||
complexity += ui.Size;
|
||||
complexity += NFileHeader::kLocalBlockSize;
|
||||
complexity += kLocalHeaderSize;
|
||||
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
|
||||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
refs.Refs[mtItemIndex - 1].Skip = true;
|
||||
continue;
|
||||
}
|
||||
RINOK(res);
|
||||
if (!fileInStream)
|
||||
return E_INVALIDARG;
|
||||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
}
|
||||
|
||||
@@ -719,29 +725,31 @@ static HRESULT Update2(
|
||||
|
||||
const CUpdateItem &ui = updateItems[itemIndex];
|
||||
|
||||
CItemEx item;
|
||||
if (!ui.NewProperties || !ui.NewData)
|
||||
CItemEx itemEx;
|
||||
CItemOut item;
|
||||
if (!ui.NewProps || !ui.NewData)
|
||||
{
|
||||
item = inputItems[ui.IndexInArchive];
|
||||
if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK)
|
||||
itemEx = inputItems[ui.IndexInArc];
|
||||
if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK)
|
||||
return E_NOTIMPL;
|
||||
(CItem &)item = itemEx;
|
||||
}
|
||||
|
||||
if (ui.NewData)
|
||||
{
|
||||
bool isDir = ((ui.NewProperties) ? ui.IsDir : item.IsDir());
|
||||
bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir());
|
||||
if (isDir)
|
||||
{
|
||||
WriteDirHeader(archive, options, ui, item);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lastRealStreamItemIndex < itemIndex)
|
||||
if (lastRealStreamItemIndex < (int)itemIndex)
|
||||
{
|
||||
lastRealStreamItemIndex = itemIndex;
|
||||
SetFileHeader(archive, *options, ui, item);
|
||||
// file Size can be 64-bit !!!
|
||||
archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), ui.Size, options->IsRealAesMode());
|
||||
archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, options->IsRealAesMode());
|
||||
}
|
||||
|
||||
CMemBlocks2 &memRef = refs.Refs[itemIndex];
|
||||
@@ -750,10 +758,13 @@ static HRESULT Update2(
|
||||
CMyComPtr<IOutStream> outStream;
|
||||
archive.CreateStreamForCompressing(&outStream);
|
||||
memRef.WriteToStream(memManager.GetBlockSize(), outStream);
|
||||
SetFileHeader(archive, *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);
|
||||
SetFileHeader(archive, *options, ui, item);
|
||||
archive.WriteLocalHeader(item);
|
||||
archive.WriteLocalHeader_And_SeekToNextFile(item);
|
||||
// RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
memRef.FreeOpt(&memManager);
|
||||
}
|
||||
@@ -783,10 +794,10 @@ static HRESULT Update2(
|
||||
{
|
||||
RINOK(threadInfo.OutStreamSpec->WriteToRealStream());
|
||||
threadInfo.OutStreamSpec->ReleaseOutStream();
|
||||
SetFileHeader(archive, *options, ui, item);
|
||||
SetItemInfoFromCompressingResult(threadInfo.CompressingResult,
|
||||
options->IsRealAesMode(), options->AesKeyMode, item);
|
||||
SetFileHeader(archive, *options, ui, item);
|
||||
archive.WriteLocalHeader(item);
|
||||
archive.WriteLocalHeader_And_SeekToNextFile(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -801,10 +812,10 @@ static HRESULT Update2(
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(UpdateItemOldData(archive, inStream, ui, item, progress, complexity));
|
||||
RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, complexity));
|
||||
}
|
||||
items.Add(item);
|
||||
complexity += NFileHeader::kLocalBlockSize;
|
||||
complexity += kLocalHeaderSize;
|
||||
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
|
||||
itemIndex++;
|
||||
}
|
||||
@@ -993,15 +1004,18 @@ STDMETHODIMP CCacheOutStream::Write(const void *data, UInt32 size, UInt32 *proce
|
||||
|
||||
STDMETHODIMP CCacheOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
|
||||
{
|
||||
switch(seekOrigin)
|
||||
switch (seekOrigin)
|
||||
{
|
||||
case STREAM_SEEK_SET: _virtPos = offset; break;
|
||||
case STREAM_SEEK_CUR: _virtPos += offset; break;
|
||||
case STREAM_SEEK_END: _virtPos = _virtSize + offset; break;
|
||||
case STREAM_SEEK_SET: break;
|
||||
case STREAM_SEEK_CUR: offset += _virtPos; break;
|
||||
case STREAM_SEEK_END: offset += _virtSize; break;
|
||||
default: return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
if (offset < 0)
|
||||
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
|
||||
_virtPos = offset;
|
||||
if (newPosition)
|
||||
*newPosition = _virtPos;
|
||||
*newPosition = offset;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -1029,16 +1043,33 @@ HRESULT Update(
|
||||
const CObjectVector<CItemEx> &inputItems,
|
||||
const CObjectVector<CUpdateItem> &updateItems,
|
||||
ISequentialOutStream *seqOutStream,
|
||||
CInArchive *inArchive,
|
||||
CInArchive *inArchive, bool removeSfx,
|
||||
CCompressionMethodMode *compressionMethodMode,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
if (inArchive)
|
||||
{
|
||||
if (!inArchive->CanUpdate())
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
CMyComPtr<IOutStream> outStream;
|
||||
{
|
||||
CMyComPtr<IOutStream> outStreamReal;
|
||||
seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStreamReal);
|
||||
if (!outStreamReal)
|
||||
return E_NOTIMPL;
|
||||
|
||||
if (inArchive)
|
||||
{
|
||||
if (inArchive->ArcInfo.Base > 0 && !removeSfx)
|
||||
{
|
||||
RINOK(inArchive->Stream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
RINOK(NCompress::CopyStream_ExactSize(inArchive->Stream, outStreamReal, inArchive->ArcInfo.Base, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
CCacheOutStream *cacheStream = new CCacheOutStream();
|
||||
outStream = cacheStream;
|
||||
if (!cacheStream->Allocate())
|
||||
@@ -1046,32 +1077,23 @@ HRESULT Update(
|
||||
RINOK(cacheStream->Init(outStreamReal));
|
||||
}
|
||||
|
||||
if (inArchive)
|
||||
{
|
||||
if (inArchive->ArcInfo.Base != 0 ||
|
||||
inArchive->ArcInfo.StartPosition != 0 ||
|
||||
!inArchive->IsOkHeaders)
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
COutArchive outArchive;
|
||||
outArchive.Create(outStream);
|
||||
/*
|
||||
if (inArchive && inArchive->ArcInfo.StartPosition > 0)
|
||||
{
|
||||
CMyComPtr<ISequentialInStream> inStream;
|
||||
inStream.Attach(inArchive->CreateLimitedStream(0, inArchive->ArcInfo.StartPosition));
|
||||
RINOK(CopyBlockToArchive(inStream, outArchive, NULL));
|
||||
outArchive.MoveBasePosition(inArchive->ArcInfo.StartPosition);
|
||||
}
|
||||
*/
|
||||
CMyComPtr<IInStream> inStream;
|
||||
RINOK(outArchive.Create(outStream));
|
||||
|
||||
if (inArchive)
|
||||
inStream.Attach(inArchive->CreateStream());
|
||||
{
|
||||
if ((Int64)inArchive->ArcInfo.MarkerPos2 > inArchive->ArcInfo.Base)
|
||||
{
|
||||
RINOK(inArchive->Stream->Seek(inArchive->ArcInfo.Base, STREAM_SEEK_SET, NULL));
|
||||
UInt64 embStubSize = inArchive->ArcInfo.MarkerPos2 - inArchive->ArcInfo.Base;
|
||||
RINOK(NCompress::CopyStream_ExactSize(inArchive->Stream, outStream, embStubSize, NULL));
|
||||
outArchive.MoveCurPos(embStubSize);
|
||||
}
|
||||
}
|
||||
|
||||
return Update2(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
outArchive, inArchive, inStream,
|
||||
outArchive, inArchive,
|
||||
inputItems, updateItems,
|
||||
compressionMethodMode,
|
||||
inArchive ? &inArchive->ArcInfo.Comment : NULL,
|
||||
|
||||
Reference in New Issue
Block a user