mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 18:07:15 -06:00
4.53 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
33ccab7e72
commit
051769bbc5
@@ -74,15 +74,7 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
|
||||
|
||||
static const wchar_t *kUnknownOS = L"Unknown";
|
||||
|
||||
|
||||
/*
|
||||
enum // PropID
|
||||
{
|
||||
kpidUnPackVersion,
|
||||
};
|
||||
*/
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -99,7 +91,7 @@ STATPROPSTG kProperties[] =
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
{ NULL, kpidHostOS, VT_BSTR}
|
||||
|
||||
// { L"UnPack Version", kpidUnPackVersion, VT_UI1},
|
||||
// { NULL, kpidUnpackVer, VT_UI1},
|
||||
};
|
||||
|
||||
const wchar_t *kMethods[] =
|
||||
@@ -147,7 +139,7 @@ CStrongCryptoPair g_StrongCryptoPairs[] =
|
||||
{ NStrongCryptoFlags::kRC4, L"RC4" }
|
||||
};
|
||||
|
||||
STATPROPSTG kArcProperties[] =
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidComment, VT_BSTR}
|
||||
};
|
||||
@@ -158,7 +150,7 @@ CHandler::CHandler():
|
||||
InitMethodProperties();
|
||||
}
|
||||
|
||||
static void StringToProp(const CByteBuffer &data, UINT codePage, NWindows::NCOM::CPropVariant &propVariant)
|
||||
static void StringToProp(const CByteBuffer &data, UINT codePage, NWindows::NCOM::CPropVariant &prop)
|
||||
{
|
||||
int size = (int)data.GetCapacity();
|
||||
if (size <= 0)
|
||||
@@ -168,62 +160,29 @@ static void StringToProp(const CByteBuffer &data, UINT codePage, NWindows::NCOM:
|
||||
memcpy(p, (const Byte *)data, size);
|
||||
p[size] = '\0';
|
||||
s.ReleaseBuffer();
|
||||
propVariant = MultiByteToUnicodeString(s, codePage);
|
||||
prop = MultiByteToUnicodeString(s, codePage);
|
||||
}
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidComment:
|
||||
{
|
||||
StringToProp(m_Archive.m_ArchiveInfo.Comment, CP_ACP, propVariant);
|
||||
StringToProp(m_Archive.m_ArchiveInfo.Comment, CP_ACP, prop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if (index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kArcProperties) / sizeof(kArcProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
||||
BSTR * name, PROPID * propID, VARTYPE *varType)
|
||||
{
|
||||
if (index >= sizeof(kArcProperties) / sizeof(kArcProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kArcProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = m_Items.Size();
|
||||
@@ -233,22 +192,22 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CItemEx &item = m_Items[index];
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant = NItemName::GetOSName2(
|
||||
prop = NItemName::GetOSName2(
|
||||
MultiByteToUnicodeString(item.Name, item.GetCodePage()));
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory();
|
||||
prop = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = item.UnPackSize;
|
||||
prop = item.UnPackSize;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
propVariant = item.PackSize;
|
||||
prop = item.PackSize;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
@@ -260,23 +219,23 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
}
|
||||
else
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
propVariant = utcFileTime;
|
||||
prop = utcFileTime;
|
||||
break;
|
||||
}
|
||||
case kpidAttributes:
|
||||
propVariant = item.GetWinAttributes();
|
||||
prop = item.GetWinAttributes();
|
||||
break;
|
||||
case kpidEncrypted:
|
||||
propVariant = item.IsEncrypted();
|
||||
prop = item.IsEncrypted();
|
||||
break;
|
||||
case kpidComment:
|
||||
{
|
||||
StringToProp(item.Comment, item.GetCodePage(), propVariant);
|
||||
StringToProp(item.Comment, item.GetCodePage(), prop);
|
||||
break;
|
||||
}
|
||||
case kpidCRC:
|
||||
if (item.IsThereCrc())
|
||||
propVariant = item.FileCRC;
|
||||
prop = item.FileCRC;
|
||||
break;
|
||||
case kpidMethod:
|
||||
{
|
||||
@@ -335,15 +294,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
ConvertUInt64ToString(methodId, s);
|
||||
method += s;
|
||||
}
|
||||
propVariant = method;
|
||||
prop = method;
|
||||
break;
|
||||
}
|
||||
case kpidHostOS:
|
||||
propVariant = (item.MadeByVersion.HostOS < kNumHostOSes) ?
|
||||
prop = (item.MadeByVersion.HostOS < kNumHostOSes) ?
|
||||
(kHostOS[item.MadeByVersion.HostOS]) : kUnknownOS;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -731,15 +690,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
totalUnPacked += item.UnPackSize;
|
||||
totalPacked += item.PackSize;
|
||||
}
|
||||
extractCallback->SetTotal(totalUnPacked);
|
||||
RINOK(extractCallback->SetTotal(totalUnPacked));
|
||||
|
||||
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
||||
UInt64 currentItemUnPacked, currentItemPacked;
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
|
||||
currentTotalPacked += currentItemPacked)
|
||||
@@ -747,7 +705,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
currentItemUnPacked = 0;
|
||||
currentItemPacked = 0;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalUnPacked));
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = currentTotalUnPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
@@ -792,14 +753,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
localCompressProgressSpec->Init(progress, ¤tTotalPacked, ¤tTotalUnPacked);
|
||||
|
||||
Int32 res;
|
||||
RINOK(myDecoder.Decode(
|
||||
EXTERNAL_CODECS_VARS
|
||||
m_Archive, item, realOutStream, extractCallback,
|
||||
compressProgress, _numThreads, res));
|
||||
progress, _numThreads, res));
|
||||
realOutStream.Release();
|
||||
|
||||
RINOK(extractCallback->SetOperationResult(res))
|
||||
|
||||
@@ -542,6 +542,10 @@ HRESULT CInArchive::FindCd(CCdInfo &cdInfo)
|
||||
// cdInfo.NumEntries = GetUInt16(buf + i + 10);
|
||||
cdInfo.Size = GetUInt32(buf + i + 12);
|
||||
cdInfo.Offset = GetUInt32(buf + i + 16);
|
||||
UInt64 curPos = endPosition - bufSize + i;
|
||||
UInt64 cdEnd = cdInfo.Size + cdInfo.Offset;
|
||||
if (curPos > cdEnd)
|
||||
m_ArchiveInfo.Base = curPos - cdEnd;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ public:
|
||||
if (CentralExtra.GetWzAesField(aesField))
|
||||
return aesField.NeedCrc();
|
||||
}
|
||||
return true;
|
||||
return (FileCRC != 0 || !IsDirectory());
|
||||
}
|
||||
|
||||
WORD GetCodePage() const
|
||||
|
||||
@@ -237,12 +237,93 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CMtProgressMixer2:
|
||||
public ICompressProgressInfo,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UInt64 ProgressOffset;
|
||||
UInt64 InSizes[2];
|
||||
UInt64 OutSizes[2];
|
||||
CMyComPtr<IProgress> Progress;
|
||||
CMyComPtr<ICompressProgressInfo> RatioProgress;
|
||||
bool _inSizeIsMain;
|
||||
public:
|
||||
NWindows::NSynchronization::CCriticalSection CriticalSection;
|
||||
MY_UNKNOWN_IMP
|
||||
void Create(IProgress *progress, bool inSizeIsMain);
|
||||
void SetProgressOffset(UInt64 progressOffset);
|
||||
HRESULT SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize);
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
};
|
||||
|
||||
void CMtProgressMixer2::Create(IProgress *progress, bool inSizeIsMain)
|
||||
{
|
||||
Progress = progress;
|
||||
Progress.QueryInterface(IID_ICompressProgressInfo, &RatioProgress);
|
||||
_inSizeIsMain = inSizeIsMain;
|
||||
ProgressOffset = InSizes[0] = InSizes[1] = OutSizes[0] = OutSizes[1] = 0;
|
||||
}
|
||||
|
||||
void CMtProgressMixer2::SetProgressOffset(UInt64 progressOffset)
|
||||
{
|
||||
CriticalSection.Enter();
|
||||
ProgressOffset = progressOffset;
|
||||
CriticalSection.Leave();
|
||||
}
|
||||
|
||||
HRESULT CMtProgressMixer2::SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize)
|
||||
{
|
||||
NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
|
||||
if (index == 0 && RatioProgress)
|
||||
{
|
||||
RINOK(RatioProgress->SetRatioInfo(inSize, outSize));
|
||||
}
|
||||
if (inSize != 0)
|
||||
InSizes[index] = *inSize;
|
||||
if (outSize != 0)
|
||||
OutSizes[index] = *outSize;
|
||||
UInt64 v = ProgressOffset + (_inSizeIsMain ?
|
||||
(InSizes[0] + InSizes[1]) :
|
||||
(OutSizes[0] + OutSizes[1]));
|
||||
return Progress->SetCompleted(&v);
|
||||
}
|
||||
|
||||
STDMETHODIMP CMtProgressMixer2::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
||||
{
|
||||
return SetRatioInfo(0, inSize, outSize);
|
||||
}
|
||||
|
||||
class CMtProgressMixer:
|
||||
public ICompressProgressInfo,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
CMtProgressMixer2 *Mixer2;
|
||||
CMyComPtr<ICompressProgressInfo> RatioProgress;
|
||||
void Create(IProgress *progress, bool inSizeIsMain);
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
};
|
||||
|
||||
void CMtProgressMixer::Create(IProgress *progress, bool inSizeIsMain)
|
||||
{
|
||||
Mixer2 = new CMtProgressMixer2;
|
||||
RatioProgress = Mixer2;
|
||||
Mixer2->Create(progress, inSizeIsMain);
|
||||
}
|
||||
|
||||
STDMETHODIMP CMtProgressMixer::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
||||
{
|
||||
return Mixer2->SetRatioInfo(1, inSize, outSize);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static HRESULT UpdateItemOldData(COutArchive &archive,
|
||||
IInStream *inStream,
|
||||
const CUpdateItem &updateItem, CItemEx &item, ICompressProgressInfo *progress,
|
||||
const CUpdateItem &updateItem, CItemEx &item, ICompressProgressInfo *progress,
|
||||
UInt64 &complexity)
|
||||
{
|
||||
if (updateItem.NewProperties)
|
||||
@@ -301,21 +382,20 @@ static HRESULT Update2St(
|
||||
const CByteBuffer &comment,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
localProgressSpec->Init(updateCallback, true);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(updateCallback, true);
|
||||
|
||||
CAddCommon compressor(*options);
|
||||
|
||||
CObjectVector<CItem> items;
|
||||
UInt64 complexity = 0;
|
||||
UInt64 unpackSizeTotal = 0, packSizeTotal = 0;
|
||||
|
||||
for (int itemIndex = 0; itemIndex < updateItems.Size(); itemIndex++)
|
||||
{
|
||||
RINOK(updateCallback->SetCompleted(&complexity));
|
||||
lps->InSize = unpackSizeTotal;
|
||||
lps->OutSize = packSizeTotal;
|
||||
RINOK(lps->SetCur());
|
||||
const CUpdateItem &updateItem = updateItems[itemIndex];
|
||||
CItemEx item;
|
||||
if (!updateItem.NewProperties || !updateItem.NewData)
|
||||
@@ -338,7 +418,7 @@ static HRESULT Update2St(
|
||||
HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
|
||||
if (res == S_FALSE)
|
||||
{
|
||||
complexity += updateItem.Size + NFileHeader::kLocalBlockSize;
|
||||
lps->ProgressOffset += updateItem.Size;
|
||||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
@@ -350,23 +430,26 @@ static HRESULT Update2St(
|
||||
CCompressingResult compressingResult;
|
||||
CMyComPtr<IOutStream> outStream;
|
||||
archive.CreateStreamForCompressing(&outStream);
|
||||
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
|
||||
RINOK(compressor.Compress(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
fileInStream, outStream, compressProgress, compressingResult));
|
||||
fileInStream, outStream, progress, compressingResult));
|
||||
SetItemInfoFromCompressingResult(compressingResult, options->IsAesMode, options->AesKeyMode, item);
|
||||
archive.WriteLocalHeader(item);
|
||||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
complexity += item.UnPackSize;
|
||||
unpackSizeTotal += item.UnPackSize;
|
||||
packSizeTotal += item.PackSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
|
||||
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, compressProgress, complexity));
|
||||
UInt64 complexity = 0;
|
||||
lps->SendRatio = false;
|
||||
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progress, complexity));
|
||||
lps->SendRatio = true;
|
||||
lps->ProgressOffset += complexity;
|
||||
}
|
||||
items.Add(item);
|
||||
complexity += NFileHeader::kLocalBlockSize;
|
||||
lps->ProgressOffset += NFileHeader::kLocalBlockSize;
|
||||
}
|
||||
archive.WriteCentralDir(items, comment);
|
||||
return S_OK;
|
||||
@@ -477,17 +560,12 @@ static HRESULT Update2(
|
||||
|
||||
CObjectVector<CItem> items;
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
localProgressSpec->Init(updateCallback, true);
|
||||
CMtProgressMixer *mtProgressMixerSpec = new CMtProgressMixer;
|
||||
CMyComPtr<ICompressProgressInfo> progress = mtProgressMixerSpec;
|
||||
mtProgressMixerSpec->Create(updateCallback, true);
|
||||
|
||||
CMtCompressProgressMixer mtCompressProgressMixer;
|
||||
mtCompressProgressMixer.Init(numThreads + 1, localProgress);
|
||||
|
||||
// we need one item for main stream
|
||||
CMtCompressProgress *progressMainSpec = new CMtCompressProgress();
|
||||
CMyComPtr<ICompressProgressInfo> progressMain = progressMainSpec;
|
||||
progressMainSpec->Init(&mtCompressProgressMixer, (int)numThreads);
|
||||
mtCompressProgressMixer.Init(numThreads, mtProgressMixerSpec->RatioProgress);
|
||||
|
||||
CMemBlockManagerMt memManager(kBlockSize);
|
||||
CMemRefs refs(&memManager);
|
||||
@@ -551,12 +629,13 @@ static HRESULT Update2(
|
||||
}
|
||||
CMyComPtr<ISequentialInStream> fileInStream;
|
||||
{
|
||||
NWindows::NSynchronization::CCriticalSectionLock lock(mtCompressProgressMixer.CriticalSection);
|
||||
NWindows::NSynchronization::CCriticalSectionLock lock(mtProgressMixerSpec->Mixer2->CriticalSection);
|
||||
HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
|
||||
if (res == S_FALSE)
|
||||
{
|
||||
complexity += updateItem.Size;
|
||||
complexity++;
|
||||
complexity += NFileHeader::kLocalBlockSize;
|
||||
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
|
||||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
refs.Refs[mtItemIndex - 1].Skip = true;
|
||||
continue;
|
||||
@@ -633,7 +712,6 @@ static HRESULT Update2(
|
||||
options->IsAesMode, options->AesKeyMode, item);
|
||||
SetFileHeader(archive, *options, updateItem, item);
|
||||
archive.WriteLocalHeader(item);
|
||||
complexity += item.UnPackSize;
|
||||
// RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
memRef.FreeOpt(&memManager);
|
||||
}
|
||||
@@ -667,7 +745,6 @@ static HRESULT Update2(
|
||||
options->IsAesMode, options->AesKeyMode, item);
|
||||
SetFileHeader(archive, *options, updateItem, item);
|
||||
archive.WriteLocalHeader(item);
|
||||
complexity += item.UnPackSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -682,11 +759,11 @@ static HRESULT Update2(
|
||||
}
|
||||
else
|
||||
{
|
||||
progressMainSpec->Reinit();
|
||||
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progressMain, complexity));
|
||||
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progress, complexity));
|
||||
}
|
||||
items.Add(item);
|
||||
complexity += NFileHeader::kLocalBlockSize;
|
||||
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
|
||||
itemIndex++;
|
||||
}
|
||||
archive.WriteCentralDir(items, comment);
|
||||
|
||||
Reference in New Issue
Block a user