Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2007-08-27 04:00:00 +0400
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:54 +0300
commit051769bbc577aeede90558b6ab5c9be187940ca0 (patch)
treee6330cb80f2d4a526d8aa27812528e053b0cda90 /CPP/7zip/Archive/Zip
parent33ccab7e728a996800e166d849fe1e92a17e1afe (diff)
4.53 beta
Diffstat (limited to 'CPP/7zip/Archive/Zip')
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandler.cpp108
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipIn.cpp4
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipItem.h2
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipUpdate.cpp139
4 files changed, 146 insertions, 107 deletions
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp
index 84269599..c3576eeb 100755
--- a/CPP/7zip/Archive/Zip/ZipHandler.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp
@@ -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(&currentTotalUnPacked));
+ 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, &currentTotalPacked, &currentTotalUnPacked);
-
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))
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
index bb45d1d1..bf3764f7 100755
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -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;
}
}
diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h
index 2395a37a..350e81b6 100755
--- a/CPP/7zip/Archive/Zip/ZipItem.h
+++ b/CPP/7zip/Archive/Zip/ZipItem.h
@@ -226,7 +226,7 @@ public:
if (CentralExtra.GetWzAesField(aesField))
return aesField.NeedCrc();
}
- return true;
+ return (FileCRC != 0 || !IsDirectory());
}
WORD GetCodePage() const
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
index 27284953..b08545c6 100755
--- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
@@ -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);