From 051769bbc577aeede90558b6ab5c9be187940ca0 Mon Sep 17 00:00:00 2001 From: Igor Pavlov Date: Mon, 27 Aug 2007 00:00:00 +0000 Subject: 4.53 beta --- CPP/7zip/Archive/7z/7zEncode.cpp | 20 +- CPP/7zip/Archive/7z/7zExtract.cpp | 28 ++- CPP/7zip/Archive/7z/7zHandler.cpp | 123 +++++++---- CPP/7zip/Archive/7z/7zItem.h | 7 + CPP/7zip/Archive/7z/7zProperties.cpp | 8 +- CPP/7zip/Archive/7z/7zUpdate.cpp | 98 +++------ CPP/7zip/Archive/ArchiveExports.cpp | 14 +- CPP/7zip/Archive/Arj/ArjHandler.cpp | 341 +++++++---------------------- CPP/7zip/Archive/Arj/ArjHandler.h | 1 - CPP/7zip/Archive/BZip2/BZip2Handler.cpp | 110 +++------- CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp | 21 +- CPP/7zip/Archive/Cab/CabHandler.cpp | 151 +++++++------ CPP/7zip/Archive/Chm/ChmHandler.cpp | 172 +++++++-------- CPP/7zip/Archive/Com/ComHandler.cpp | 65 ++---- CPP/7zip/Archive/Com/ComIn.cpp | 2 +- CPP/7zip/Archive/Com/ComRegister.cpp | 2 +- CPP/7zip/Archive/Common/CoderMixer2MT.cpp | 24 +- CPP/7zip/Archive/Common/CoderMixer2MT.h | 1 + CPP/7zip/Archive/Common/CoderMixerMT.cpp | 24 +- CPP/7zip/Archive/Common/CoderMixerMT.h | 1 + CPP/7zip/Archive/Common/DummyOutStream.cpp | 24 +- CPP/7zip/Archive/Common/DummyOutStream.h | 10 +- CPP/7zip/Archive/Cpio/CpioHandler.cpp | 182 ++++++--------- CPP/7zip/Archive/Cpio/CpioHandler.h | 4 +- CPP/7zip/Archive/Deb/DebHandler.cpp | 151 +++++-------- CPP/7zip/Archive/GZip/GZipHandler.cpp | 153 +++++-------- CPP/7zip/Archive/GZip/GZipHandlerOut.cpp | 46 ++-- CPP/7zip/Archive/GZip/GZipUpdate.cpp | 18 +- CPP/7zip/Archive/IArchive.h | 44 +++- CPP/7zip/Archive/Iso/IsoHandler.cpp | 122 ++++------- CPP/7zip/Archive/Lzh/LzhHandler.cpp | 215 ++++++------------ CPP/7zip/Archive/Nsis/NsisHandler.cpp | 121 +++++----- CPP/7zip/Archive/Nsis/NsisHandler.h | 1 + CPP/7zip/Archive/Nsis/NsisIn.cpp | 4 +- CPP/7zip/Archive/RPM/RpmHandler.cpp | 82 ++----- CPP/7zip/Archive/Rar/RarHandler.cpp | 276 ++++++++--------------- CPP/7zip/Archive/Rar/RarIn.cpp | 2 +- CPP/7zip/Archive/Rar/RarIn.h | 4 +- CPP/7zip/Archive/Rar/RarRegister.cpp | 2 +- CPP/7zip/Archive/Split/SplitHandler.cpp | 115 +++------- CPP/7zip/Archive/Split/SplitHandlerOut.cpp | 28 +-- CPP/7zip/Archive/Tar/TarHandler.cpp | 155 +++++-------- CPP/7zip/Archive/Tar/TarHandlerOut.cpp | 46 ++-- CPP/7zip/Archive/Tar/TarUpdate.cpp | 79 +++---- CPP/7zip/Archive/Wim/WimHandler.cpp | 197 ++++++++--------- CPP/7zip/Archive/Wim/WimIn.h | 17 ++ CPP/7zip/Archive/Z/DllExports.cpp | 91 -------- CPP/7zip/Archive/Z/ZHandler.cpp | 91 ++------ CPP/7zip/Archive/Zip/ZipHandler.cpp | 108 +++------ CPP/7zip/Archive/Zip/ZipIn.cpp | 4 + CPP/7zip/Archive/Zip/ZipItem.h | 2 +- CPP/7zip/Archive/Zip/ZipUpdate.cpp | 139 +++++++++--- 52 files changed, 1463 insertions(+), 2283 deletions(-) delete mode 100755 CPP/7zip/Archive/Z/DllExports.cpp (limited to 'CPP/7zip/Archive') diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp index 8c229362..3a5cfcd5 100755 --- a/CPP/7zip/Archive/7z/7zEncode.cpp +++ b/CPP/7zip/Archive/7z/7zEncode.cpp @@ -13,7 +13,9 @@ #include "../../Common/CreateCoder.h" #include "../../Common/FilterCoder.h" -static UInt64 k_AES = 0x06F10701; +static const UInt64 k_AES = 0x06F10701; +static const UInt64 k_BCJ = 0x03030103; +static const UInt64 k_BCJ2 = 0x0303011B; namespace NArchive { namespace N7z { @@ -59,7 +61,8 @@ HRESULT CEncoder::CreateMixerCoder( { const CMethodFull &methodFull = _options.Methods[i]; _codersInfo.Add(CCoderInfo()); - // CCoderInfo &encodingInfo = _codersInfo.Back(); + CCoderInfo &encodingInfo = _codersInfo.Back(); + encodingInfo.MethodID = methodFull.Id; CMyComPtr encoder; CMyComPtr encoder2; @@ -176,7 +179,7 @@ HRESULT CEncoder::Encode( return E_FAIL; UInt32 mainCoderIndex, mainStreamIndex; _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex); - _mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex); + if (inStreamSize != NULL) { CRecordVector sizePointers; @@ -234,6 +237,17 @@ HRESULT CEncoder::Encode( memmove(encodingInfo.Properties, outStreamSpec->GetBuffer(), size); } } + + UInt32 progressIndex = mainCoderIndex; + + for (i = 0; i < _codersInfo.Size(); i++) + { + const CCoderInfo &e = _codersInfo[i]; + if ((e.MethodID == k_BCJ || e.MethodID == k_BCJ2) && i + 1 < _codersInfo.Size()) + progressIndex = i + 1; + } + + _mixerCoderSpec->SetProgressCoderIndex(progressIndex); RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1, &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress)); diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp index 2f2423ee..65f9c9eb 100755 --- a/CPP/7zip/Archive/7z/7zExtract.cpp +++ b/CPP/7zip/Archive/7z/7zExtract.cpp @@ -149,16 +149,27 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, ); // CDecoder1 decoder; - UInt64 currentImportantTotalUnPacked = 0; + UInt64 currentTotalPacked = 0; + UInt64 currentTotalUnPacked = 0; UInt64 totalFolderUnPacked; + UInt64 totalFolderPacked; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); for(int i = 0; i < extractFolderInfoVector.Size(); i++, - currentImportantTotalUnPacked += totalFolderUnPacked) + currentTotalUnPacked += totalFolderUnPacked, + currentTotalPacked += totalFolderPacked) { + lps->OutSize = currentTotalUnPacked; + lps->InSize = currentTotalPacked; + RINOK(lps->SetCur()); + const CExtractFolderInfo &efi = extractFolderInfoVector[i]; totalFolderUnPacked = efi.UnPackSize; - RINOK(extractCallback->SetCompleted(¤tImportantTotalUnPacked)); + totalFolderPacked = 0; CFolderOutStream *folderOutStream = new CFolderOutStream; CMyComPtr outStream(folderOutStream); @@ -194,14 +205,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CNum folderIndex = efi.FolderIndex; const CFolder &folderInfo = database.Folders[folderIndex]; - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); - - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, NULL, ¤tImportantTotalUnPacked); + totalFolderPacked = _database.GetFolderFullPackSize(folderIndex); CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex]; UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0); @@ -225,7 +229,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, &database.PackSizes[packStreamIndex], folderInfo, outStream, - compressProgress + progress #ifndef _NO_CRYPTO , getTextPassword #endif diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp index 9fc45848..d5dc8720 100755 --- a/CPP/7zip/Archive/7z/7zHandler.cpp +++ b/CPP/7zip/Archive/7z/7zHandler.cpp @@ -53,14 +53,10 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) return S_OK; } -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - return S_OK; -} - #ifdef _SFX +IMP_IInArchive_ArcProps_NO + STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */) { return E_NOTIMPL; @@ -72,27 +68,64 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */, return E_NOTIMPL; } -#endif +#else -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +STATPROPSTG kArcProps[] = { - *numProperties = 0; - return S_OK; -} + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidSolid, VT_BOOL}, + { NULL, kpidNumBlocks, VT_UI4} +}; -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { - return E_NOTIMPL; + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidMethod: + { + UString resString; + CRecordVector ids; + int i; + for (i = 0; i < _database.Folders.Size(); i++) + { + const CFolder &f = _database.Folders[i]; + for (int j = f.Coders.Size() - 1; j >= 0; j--) + ids.AddToUniqueSorted(f.Coders[j].MethodID); + } + + for (i = 0; i < ids.Size(); i++) + { + UInt64 id = ids[i]; + UString methodName; + /* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName); + if (methodName.IsEmpty()) + methodName = ConvertMethodIdToString(id); + if (!resString.IsEmpty()) + resString += L' '; + resString += methodName; + } + prop = resString; + break; + } + case kpidSolid: prop = _database.IsSolid(); break; + case kpidNumBlocks: prop = (UInt32)_database.Folders.Size(); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END } +IMP_IInArchive_ArcProps + +#endif -static void MySetFileTime(bool timeDefined, FILETIME unixTime, - NWindows::NCOM::CPropVariant &propVariant) +static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop) { if (timeDefined) - propVariant = unixTime; + prop = unixTime; } #ifndef _SFX @@ -171,7 +204,7 @@ bool CHandler::IsEncrypted(UInt32 index2) const STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; + NWindows::NCOM::CPropVariant prop; /* const CRef2 &ref2 = _refs[index]; @@ -196,68 +229,68 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va case kpidPath: { if (!item.Name.IsEmpty()) - propVariant = NItemName::GetOSName(item.Name); + prop = NItemName::GetOSName(item.Name); break; } case kpidIsFolder: - propVariant = item.IsDirectory; + prop = item.IsDirectory; break; case kpidSize: { - propVariant = item.UnPackSize; - // propVariant = ref2.UnPackSize; + prop = item.UnPackSize; + // prop = ref2.UnPackSize; break; } case kpidPosition: { /* if (ref2.Refs.Size() > 1) - propVariant = ref2.StartPos; + prop = ref2.StartPos; else */ if (item.IsStartPosDefined) - propVariant = item.StartPos; + prop = item.StartPos; break; } case kpidPackedSize: { - // propVariant = ref2.PackSize; + // prop = ref2.PackSize; { CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) { if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2) - propVariant = _database.GetFolderFullPackSize(folderIndex); + prop = _database.GetFolderFullPackSize(folderIndex); /* else - propVariant = UInt64(0); + prop = (UInt64)0; */ } else - propVariant = UInt64(0); + prop = (UInt64)0; } break; } case kpidLastAccessTime: - MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, propVariant); + MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop); break; case kpidCreationTime: - MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, propVariant); + MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop); break; case kpidLastWriteTime: - MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, propVariant); + MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop); break; case kpidAttributes: if (item.AreAttributesDefined) - propVariant = item.Attributes; + prop = item.Attributes; break; case kpidCRC: if (item.IsFileCRCDefined) - propVariant = item.FileCRC; + prop = item.FileCRC; break; case kpidEncrypted: { - propVariant = IsEncrypted(index2); + prop = IsEncrypted(index2); break; } #ifndef _SFX @@ -357,7 +390,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va } } } - propVariant = methodsString; + prop = methodsString; } } break; @@ -365,7 +398,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va { CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; if (folderIndex != kNumNoIndex) - propVariant = (UInt32)folderIndex; + prop = (UInt32)folderIndex; } break; case kpidPackedSize0: @@ -381,21 +414,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 && folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0)) { - propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0); + prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0); } else - propVariant = UInt64(0); + prop = (UInt64)0; } else - propVariant = UInt64(0); + prop = (UInt64)0; } break; #endif case kpidIsAnti: - propVariant = item.IsAnti; + prop = item.IsAnti; break; } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -522,11 +555,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream, { UString baseName; { - NCOM::CPropVariant propVariant; - RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); - if (propVariant.vt != VT_BSTR) + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + if (prop.vt != VT_BSTR) break; - baseName = propVariant.bstrVal; + baseName = prop.bstrVal; } seqName.InitName(baseName); } diff --git a/CPP/7zip/Archive/7z/7zItem.h b/CPP/7zip/Archive/7z/7zItem.h index 388f19d3..31c5ce2d 100755 --- a/CPP/7zip/Archive/7z/7zItem.h +++ b/CPP/7zip/Archive/7z/7zItem.h @@ -170,6 +170,13 @@ struct CArchiveDatabase NumUnPackStreamsVector.IsEmpty() && Files.IsEmpty()); } + bool IsSolid() const + { + for (int i = 0; i < NumUnPackStreamsVector.Size(); i++) + if (NumUnPackStreamsVector[i] > 1) + return true; + return false; + } }; }} diff --git a/CPP/7zip/Archive/7z/7zProperties.cpp b/CPP/7zip/Archive/7z/7zProperties.cpp index 316f4f09..3452a030 100755 --- a/CPP/7zip/Archive/7z/7zProperties.cpp +++ b/CPP/7zip/Archive/7z/7zProperties.cpp @@ -37,18 +37,14 @@ CPropMap kPropMap[] = { NID::kWinAttributes, NULL, kpidAttributes, VT_UI4}, { NID::kStartPos, NULL, kpidPosition, VT_UI4}, - { NID::kCRC, NULL, kpidCRC, VT_UI4}, - { NID::kAnti, L"Anti", kpidIsAnti, VT_BOOL}, + { NID::kAnti, NULL, kpidIsAnti, VT_BOOL}, // { 97, NULL, kpidSolid, VT_BOOL}, #ifndef _SFX { 98, NULL, kpidMethod, VT_BSTR}, - { 99, L"Block", kpidBlock, VT_UI4} + { 99, NULL, kpidBlock, VT_UI4} #endif - // { L"ID", kpidID, VT_BSTR}, - // { L"UnPack Version", kpidUnPackVersion, VT_UI1}, - // { L"Host OS", kpidHostOS, VT_BSTR} }; static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]); diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp index 59e7c4fc..68f4604d 100755 --- a/CPP/7zip/Archive/7z/7zUpdate.cpp +++ b/CPP/7zip/Archive/7z/7zUpdate.cpp @@ -22,52 +22,19 @@ static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20; static const UInt32 kAlgorithmForBCJ2_LZMA = 1; static const UInt32 kNumFastBytesForBCJ2_LZMA = 64; -static HRESULT CopyBlock(ISequentialInStream *inStream, - ISequentialOutStream *outStream, ICompressProgressInfo *progress) +static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream, + UInt64 position, UInt64 size, ICompressProgressInfo *progress) { - CMyComPtr copyCoder = new NCompress::CCopyCoder; - return copyCoder->Code(inStream, outStream, NULL, NULL, progress); -} - -static HRESULT WriteRange( - ISequentialInStream *inStream, - ISequentialOutStream *outStream, - UInt64 size, - IProgress *progress, - UInt64 ¤tComplexity) -{ - CLimitedSequentialInStream *streamSpec = new - CLimitedSequentialInStream; + RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0)); + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr inStreamLimited(streamSpec); streamSpec->SetStream(inStream); streamSpec->Init(size); - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr localProgress = localProgressSpec; - localProgressSpec->Init(progress, true); - - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - - localCompressProgressSpec->Init(localProgress, ¤tComplexity, ¤tComplexity); - - HRESULT result = CopyBlock(inStreamLimited, outStream, compressProgress); - currentComplexity += size; - return result; -} - - -static HRESULT WriteRange(IInStream *inStream, - ISequentialOutStream *outStream, - UInt64 position, - UInt64 size, - IProgress *progress, - UInt64 ¤tComplexity) -{ - inStream->Seek(position, STREAM_SEEK_SET, 0); - return WriteRange(inStream, outStream, - size, progress, currentComplexity); + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; + CMyComPtr copyCoder = copyCoderSpec; + RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); + return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL); } static int GetReverseSlashPos(const UString &name) @@ -94,14 +61,6 @@ UString CUpdateItem::GetExtension() const return Name.Mid(GetExtensionPos()); } -/* -struct CFolderRef -{ - const CArchiveDatabaseEx *Database; - int FolderIndex; -}; -*/ - #define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2) @@ -522,16 +481,10 @@ static HRESULT Update2( return E_NOTIMPL; */ - UInt64 startBlockSize = database != 0 ? - database->ArchiveInfo.StartPosition: 0; + UInt64 startBlockSize = database != 0 ? database->ArchiveInfo.StartPosition: 0; if (startBlockSize > 0 && !options.RemoveSfxBlock) { - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr limitedStream(streamSpec); - RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); - streamSpec->SetStream(inStream); - streamSpec->Init(startBlockSize); - RINOK(CopyBlock(limitedStream, seqOutStream, NULL)); + RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL)); } CRecordVector fileIndexToUpdateIndexMap; @@ -607,6 +560,11 @@ static HRESULT Update2( complexity = 0; RINOK(updateCallback->SetCompleted(&complexity)); + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(updateCallback, true); + ///////////////////////////////////////// // Write Copy Items @@ -614,10 +572,11 @@ static HRESULT Update2( { int folderIndex = folderRefs[i]; + lps->ProgressOffset = complexity; + UInt64 packSize = database->GetFolderFullPackSize(folderIndex); RINOK(WriteRange(inStream, archive.SeqStream, - database->GetFolderStreamPos(folderIndex, 0), - database->GetFolderFullPackSize(folderIndex), - updateCallback, complexity)); + database->GetFolderStreamPos(folderIndex, 0), packSize, progress)); + complexity += packSize; const CFolder &folder = database->Folders[folderIndex]; CNum startIndex = database->FolderStartPackStreamIndex[folderIndex]; @@ -736,18 +695,17 @@ static HRESULT Update2( inStreamSpec->Init(updateCallback, &indices[i], numSubFiles); CFolder folderItem; - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr localProgress = localProgressSpec; - localProgressSpec->Init(updateCallback, true); - CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(localProgress, &complexity, NULL); - + + int startPackIndex = newDatabase.PackSizes.Size(); RINOK(encoder.Encode( EXTERNAL_CODECS_LOC_VARS solidInStream, NULL, &inSizeForReduce, folderItem, - archive.SeqStream, newDatabase.PackSizes, compressProgress)); + archive.SeqStream, newDatabase.PackSizes, progress)); + + for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++) + lps->OutSize += newDatabase.PackSizes[startPackIndex]; + lps->InSize += folderItem.GetUnPackSize(); // for() // newDatabase.PackCRCsDefined.Add(false); // newDatabase.PackCRCs.Add(0); @@ -783,7 +741,6 @@ static HRESULT Update2( file.IsFileCRCDefined = true; file.HasStream = true; numUnPackStreams++; - complexity += file.UnPackSize; } else { @@ -935,8 +892,7 @@ HRESULT UpdateVolume( CMyComPtr inCrcStream = inCrcStreamSpec; inCrcStreamSpec->Init(fileStream); - RINOK(WriteRange(inCrcStream, volumeStream, pureSize, - updateCallback, complexity)); + RINOK(WriteRange(inCrcStream, volumeStream, pureSize, updateCallback, complexity)); file.UnPackSize = inCrcStreamSpec->GetSize(); if (file.UnPackSize == 0) break; diff --git a/CPP/7zip/Archive/ArchiveExports.cpp b/CPP/7zip/Archive/ArchiveExports.cpp index 294b14d1..a60303a5 100755 --- a/CPP/7zip/Archive/ArchiveExports.cpp +++ b/CPP/7zip/Archive/ArchiveExports.cpp @@ -85,11 +85,11 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value if (formatIndex >= g_NumArcs) return E_INVALIDARG; const CArcInfo &arc = *g_Arcs[formatIndex]; - NWindows::NCOM::CPropVariant propVariant; + NWindows::NCOM::CPropVariant prop; switch(propID) { case NArchive::kName: - propVariant = arc.Name; + prop = arc.Name; break; case NArchive::kClassID: { @@ -99,22 +99,22 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value } case NArchive::kExtension: if (arc.Ext != 0) - propVariant = arc.Ext; + prop = arc.Ext; break; case NArchive::kAddExtension: if (arc.AddExt != 0) - propVariant = arc.AddExt; + prop = arc.AddExt; break; case NArchive::kUpdate: - propVariant = (bool)(arc.CreateOutArchive != 0); + prop = (bool)(arc.CreateOutArchive != 0); break; case NArchive::kKeepName: - propVariant = arc.KeepName; + prop = arc.KeepName; break; case NArchive::kStartSignature: return SetPropString((const char *)arc.Signature, arc.SignatureSize, value); } - propVariant.Detach(value); + prop.Detach(value); return S_OK; } diff --git a/CPP/7zip/Archive/Arj/ArjHandler.cpp b/CPP/7zip/Archive/Arj/ArjHandler.cpp index b5227e54..d154fd76 100755 --- a/CPP/7zip/Archive/Arj/ArjHandler.cpp +++ b/CPP/7zip/Archive/Arj/ArjHandler.cpp @@ -51,16 +51,7 @@ const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); const wchar_t *kUnknownOS = L"Unknown"; -/* -enum // PropID -{ - kpidHostOS = kpidUserDefined, - kpidUnPackVersion, - kpidMethod, -}; -*/ - -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidIsFolder, VT_BOOL}, @@ -68,59 +59,15 @@ STATPROPSTG kProperties[] = { NULL, kpidPackedSize, VT_UI8}, { NULL, kpidLastWriteTime, VT_FILETIME}, { NULL, kpidAttributes, VT_UI4}, - { NULL, kpidEncrypted, VT_BOOL}, - // { NULL, kpidCommented, VT_BOOL}, - { NULL, kpidCRC, VT_UI4}, - { NULL, kpidMethod, VT_UI1}, + // { NULL, kpidUnpackVer, VT_UI1}, { NULL, kpidHostOS, VT_BSTR} - - // { L"UnPack Version", kpidUnPackVersion, VT_UI1}, - // { L"Method", kpidMethod, VT_UI1}, - // { L"Host OS", kpidHostOS, VT_BSTR} }; - -CHandler::CHandler() -{} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - 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 = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_NOTIMPL; -} +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { @@ -131,27 +78,19 @@ 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 = _items[index]; switch(propID) { - case kpidPath: - propVariant = - NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); - /* - NItemName::GetOSName2( - MultiByteToUnicodeString(item.Name, item.GetCodePage())); - */ - break; - case kpidIsFolder: - propVariant = item.IsDirectory(); - break; - case kpidSize: - propVariant = item.Size; - break; - case kpidPackedSize: - propVariant = item.PackSize; - break; + case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; + case kpidIsFolder: prop = item.IsDirectory(); break; + case kpidSize: prop = item.Size; break; + case kpidPackedSize: prop = item.PackSize; break; + case kpidAttributes: prop = item.GetWinAttributes(); break; + case kpidEncrypted: prop = item.IsEncrypted(); break; + case kpidCRC: prop = item.FileCRC; break; + case kpidMethod: prop = item.Method; break; + case kpidHostOS: prop = (item.HostOS < kNumHostOSes) ? (kHostOS[item.HostOS]) : kUnknownOS; break; case kpidLastWriteTime: { FILETIME localFileTime, utcFileTime; @@ -162,52 +101,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va } else utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; - propVariant = utcFileTime; + prop = utcFileTime; break; } - case kpidAttributes: - propVariant = item.GetWinAttributes(); - break; - case kpidEncrypted: - propVariant = item.IsEncrypted(); - break; - /* - case kpidCommented: - propVariant = item.IsCommented(); - break; - */ - case kpidCRC: - propVariant = item.FileCRC; - break; - case kpidMethod: - propVariant = item.Method; - break; - case kpidHostOS: - propVariant = (item.HostOS < kNumHostOSes) ? - (kHostOS[item.HostOS]) : kUnknownOS; - break; } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } -/* -class CPropgressImp: public CProgressVirt -{ -public: - CMyComPtr Callback; - STDMETHOD(SetCompleted)(const UInt64 *numFiles); -}; - -STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) -{ - if (Callback) - return Callback->SetCompleted(numFiles, NULL); - return S_OK; -} -*/ - STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) { @@ -226,17 +128,17 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, } for (;;) { - CItemEx itemInfo; + CItemEx item; bool filled; - HRESULT result = archive.GetNextItem(filled, itemInfo); + HRESULT result = archive.GetNextItem(filled, item); if (result == S_FALSE) return S_FALSE; if (result != S_OK) return S_FALSE; if (!filled) break; - _items.Add(itemInfo); - archive.IncreaseRealPosition(itemInfo.PackSize); + _items.Add(item); + archive.IncreaseRealPosition(item.PackSize); if (callback != NULL) { UInt64 numFiles = _items.Size(); @@ -279,9 +181,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, UInt32 i; for(i = 0; i < numItems; i++) { - const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]]; - totalUnPacked += itemInfo.Size; - totalPacked += itemInfo.PackSize; + const CItemEx &item = _items[allFilesMode ? i : indices[i]]; + totalUnPacked += item.Size; + totalPacked += item.PackSize; } extractCallback->SetTotal(totalUnPacked); @@ -290,29 +192,40 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr arj1Decoder; CMyComPtr arj2Decoder; - CMyComPtr copyCoder; + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + streamSpec->SetStream(_stream); for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, currentTotalPacked += currentItemPacked) { - currentItemUnPacked = 0; - currentItemPacked = 0; + lps->InSize = currentTotalPacked; + lps->OutSize = currentTotalUnPacked; + RINOK(lps->SetCur()); + + currentItemUnPacked = currentItemPacked = 0; - RINOK(extractCallback->SetCompleted(¤tTotalUnPacked)); CMyComPtr realOutStream; - Int32 askMode; - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; - const CItemEx &itemInfo = _items[index]; + const CItemEx &item = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if(itemInfo.IsDirectory()) + if(item.IsDirectory()) { // if (!testMode) { RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); } continue; } @@ -321,8 +234,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, continue; RINOK(extractCallback->PrepareOperation(askMode)); - currentItemUnPacked = itemInfo.Size; - currentItemPacked = itemInfo.PackSize; + currentItemUnPacked = item.Size; + currentItemPacked = item.PackSize; { COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; @@ -330,150 +243,64 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, outStreamSpec->SetStream(realOutStream); outStreamSpec->Init(); realOutStream.Release(); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); + + streamSpec->Init(item.PackSize); UInt64 pos; - _stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos); - - streamSpec->SetStream(_stream); - streamSpec->Init(itemInfo.PackSize); - - - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); + _stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos); + HRESULT result = S_OK; + Int32 opRes = NExtract::NOperationResult::kOK; - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, - ¤tTotalPacked, - ¤tTotalUnPacked); - - if (itemInfo.IsEncrypted()) + if (item.IsEncrypted()) { - RINOK(extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kUnSupportedMethod)); - continue; + opRes = NExtract::NOperationResult::kUnSupportedMethod; } - - HRESULT result; - - switch(itemInfo.Method) + else { - case NFileHeader::NCompressionMethod::kStored: + switch(item.Method) + { + case NFileHeader::NCompressionMethod::kStored: { - if(!copyCoder) - copyCoder = new NCompress::CCopyCoder; - try - { - if (itemInfo.IsEncrypted()) - { - RINOK(extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kUnSupportedMethod)); - continue; - } - else - { - result = copyCoder->Code(inStream, outStream, - NULL, NULL, compressProgress); - } - if (result == S_FALSE) - throw "data error"; - if (result != S_OK) - return result; - } - catch(...) - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kDataError)); - continue; - } + result = copyCoder->Code(inStream, outStream, NULL, NULL, progress); + if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize) + result = S_FALSE; break; } - case NFileHeader::NCompressionMethod::kCompressed1a: - case NFileHeader::NCompressionMethod::kCompressed1b: - case NFileHeader::NCompressionMethod::kCompressed1c: + case NFileHeader::NCompressionMethod::kCompressed1a: + case NFileHeader::NCompressionMethod::kCompressed1b: + case NFileHeader::NCompressionMethod::kCompressed1c: { - if(!arj1Decoder) - { + if (!arj1Decoder) arj1Decoder = new NCompress::NArj::NDecoder1::CCoder; - } - try - { - if (itemInfo.IsEncrypted()) - { - RINOK(extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kUnSupportedMethod)); - continue; - } - else - { - result = arj1Decoder->Code(inStream, outStream, - NULL, ¤tItemUnPacked, compressProgress); - } - if (result == S_FALSE) - throw "data error"; - if (result != S_OK) - return result; - } - catch(...) - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kDataError)); - continue; - } + result = arj1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress); break; } - case NFileHeader::NCompressionMethod::kCompressed2: + case NFileHeader::NCompressionMethod::kCompressed2: { - if(!arj2Decoder) - { + if (!arj2Decoder) arj2Decoder = new NCompress::NArj::NDecoder2::CCoder; - } - try - { - if (itemInfo.IsEncrypted()) - { - RINOK(extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kUnSupportedMethod)); - continue; - } - else - { - result = arj2Decoder->Code(inStream, outStream, - NULL, ¤tItemUnPacked, compressProgress); - } - if (result == S_FALSE) - throw "data error"; - if (result != S_OK) - return result; - } - catch(...) - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kDataError)); - continue; - } + result = arj2Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress); break; } - default: - RINOK(extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kUnSupportedMethod)); - continue; + default: + opRes = NExtract::NOperationResult::kUnSupportedMethod; + } + } + if (opRes == NExtract::NOperationResult::kOK) + { + if (result == S_FALSE) + opRes = NExtract::NOperationResult::kDataError; + else + { + RINOK(result); + opRes = (outStreamSpec->GetCRC() == item.FileCRC) ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kCRCError; + } } - bool crcOK = outStreamSpec->GetCRC() == itemInfo.FileCRC; outStream.Release(); - if(crcOK) - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) - else - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)) + RINOK(extractCallback->SetOperationResult(opRes)); } } return S_OK; diff --git a/CPP/7zip/Archive/Arj/ArjHandler.h b/CPP/7zip/Archive/Arj/ArjHandler.h index 1f43808a..4351b26f 100755 --- a/CPP/7zip/Archive/Arj/ArjHandler.h +++ b/CPP/7zip/Archive/Arj/ArjHandler.h @@ -19,7 +19,6 @@ public: INTERFACE_IInArchive(;) - CHandler(); private: CObjectVector _items; CMyComPtr _stream; diff --git a/CPP/7zip/Archive/BZip2/BZip2Handler.cpp b/CPP/7zip/Archive/BZip2/BZip2Handler.cpp index c60045fa..0b790c68 100755 --- a/CPP/7zip/Archive/BZip2/BZip2Handler.cpp +++ b/CPP/7zip/Archive/BZip2/BZip2Handler.cpp @@ -21,49 +21,13 @@ namespace NBZip2 { static const CMethodId kMethodId_BZip2 = 0x040202; -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { - { NULL, kpidPath, VT_BSTR}, - // { NULL, kpidIsFolder, VT_BOOL}, - // { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8} }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - 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 = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; -} +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { @@ -71,24 +35,15 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) { - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; - if (index != 0) - return E_INVALIDARG; + NWindows::NCOM::CPropVariant prop; switch(propID) { - case kpidIsFolder: - propVariant = false; - break; - case kpidPackedSize: - propVariant = _item.PackSize; - break; + case kpidPackedSize: prop = _item.PackSize; break; } - propVariant.Detach(value); + prop.Detach(value); return S_OK; - COM_TRY_END } STDMETHODIMP CHandler::Open(IInStream *stream, @@ -148,14 +103,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, extractCallback->SetTotal(_item.PackSize); - UInt64 currentTotalPacked = 0, currentTotalUnPacked = 0; + UInt64 currentTotalPacked = 0; RINOK(extractCallback->SetCompleted(¤tTotalPacked)); CMyComPtr realOutStream; Int32 askMode; - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + askMode = testMode ? NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); @@ -171,7 +126,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, kMethodId_BZip2, decoder, false); if (loadResult != S_OK || !decoder) { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod)); return S_OK; } @@ -188,29 +143,26 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CDummyOutStream *outStreamSpec = new CDummyOutStream; CMyComPtr outStream(outStreamSpec); - outStreamSpec->Init(realOutStream); + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); realOutStream.Release(); - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, true); - - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, true); RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL)); - HRESULT result = S_OK; bool firstItem = true; for (;;) { - localCompressProgressSpec->Init(progress, - ¤tTotalPacked, - ¤tTotalUnPacked); + lps->InSize = currentTotalPacked; + lps->OutSize = outStreamSpec->GetSize(); + + RINOK(lps->SetCur()); const int kSignatureSize = 3; Byte buffer[kSignatureSize]; @@ -226,26 +178,22 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { if (firstItem) return E_FAIL; - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) - return S_OK; + break; } firstItem = false; UInt64 dataStartPos; RINOK(_stream->Seek((UInt64)(Int64)(-3), STREAM_SEEK_CUR, &dataStartPos)); - result = decoder->Code(_stream, outStream, NULL, NULL, compressProgress); + result = decoder->Code(_stream, outStream, NULL, NULL, progress); if (result != S_OK) break; CMyComPtr getInStreamProcessedSize; - decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, - &getInStreamProcessedSize); + decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, &getInStreamProcessedSize); if (!getInStreamProcessedSize) break; - UInt64 packSize; RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize)); UInt64 pos; @@ -254,17 +202,15 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } outStream.Release(); - int retResult; + Int32 retResult; if (result == S_OK) - retResult = NArchive::NExtract::NOperationResult::kOK; + retResult = NExtract::NOperationResult::kOK; else if (result == S_FALSE) - retResult = NArchive::NExtract::NOperationResult::kDataError; + retResult = NExtract::NOperationResult::kDataError; else return result; + return extractCallback->SetOperationResult(retResult); - RINOK(extractCallback->SetOperationResult(retResult)); - - return S_OK; COM_TRY_END } diff --git a/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp b/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp index 134d4124..33c9d0bf 100755 --- a/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp +++ b/CPP/7zip/Archive/BZip2/BZip2HandlerOut.cpp @@ -49,20 +49,19 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt UInt32 indexInArchive; if (!updateCallback) return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(0, - &newData, &newProperties, &indexInArchive)); + RINOK(updateCallback->GetUpdateItemInfo(0,&newData, &newProperties, &indexInArchive)); if (IntToBool(newProperties)) { { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(0, kpidIsFolder, &propVariant)); - if (propVariant.vt == VT_BOOL) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidIsFolder, &prop)); + if (prop.vt == VT_BOOL) { - if (propVariant.boolVal != VARIANT_FALSE) + if (prop.boolVal != VARIANT_FALSE) return E_INVALIDARG; } - else if (propVariant.vt != VT_EMPTY) + else if (prop.vt != VT_EMPTY) return E_INVALIDARG; } } @@ -71,11 +70,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt { UInt64 size; { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(0, kpidSize, &propVariant)); - if (propVariant.vt != VT_UI8) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); + if (prop.vt != VT_UI8) return E_INVALIDARG; - size = propVariant.uhVal.QuadPart; + size = prop.uhVal.QuadPart; } UInt32 dicSize = _dicSize; diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp index 2ce9d9ce..b3e65d90 100755 --- a/CPP/7zip/Archive/Cab/CabHandler.cpp +++ b/CPP/7zip/Archive/Cab/CabHandler.cpp @@ -14,6 +14,8 @@ #include "CabHandler.h" #include "CabBlockInStream.h" +#include "../../Common/ProgressUtils.h" + #include "../../Compress/Copy/CopyCoder.h" #include "../../Compress/Deflate/DeflateDecoder.h" #include "../../Compress/Lzx/LzxDecoder.h" @@ -31,13 +33,11 @@ namespace NCab { #ifdef _CAB_DETAILS enum { - kpidBlockReal = kpidUserDefined, - kpidOffset, - kpidVolume, + kpidBlockReal = kpidUserDefined }; #endif -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, // { NULL, kpidIsFolder, VT_BOOL}, @@ -49,8 +49,8 @@ STATPROPSTG kProperties[] = #ifdef _CAB_DETAILS , { L"BlockReal", kpidBlockReal, VT_UI4}, - { L"Offset", kpidOffset, VT_UI4}, - { L"Volume", kpidVolume, VT_UI4} + { NULL, kpidOffset, VT_UI4}, + { NULL, kpidVolume, VT_UI4} #endif }; @@ -65,49 +65,69 @@ static const wchar_t *kMethods[] = static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); static const wchar_t *kUnknownMethod = L"Unknown"; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +STATPROPSTG kArcProps[] = { - *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); - return S_OK; -} + { NULL, kpidMethod, VT_BSTR}, + // { NULL, kpidSolid, VT_BOOL}, + { NULL, kpidNumBlocks, VT_UI4}, + { NULL, kpidNumVolumes, VT_UI4} +}; -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; - if (srcItem.lpwstrName == 0) - *name = 0; - else - *name = ::SysAllocString(srcItem.lpwstrName); - return S_OK; -} +IMP_IInArchive_Props +IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { - *numProperties = 0; + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidMethod: + { + UString resString; + CRecordVector ids; + int i; + for (int v = 0; v < m_Database.Volumes.Size(); v++) + { + const CDatabaseEx &de = m_Database.Volumes[v]; + for (i = 0; i < de.Folders.Size(); i++) + ids.AddToUniqueSorted(de.Folders[i].GetCompressionMethod()); + } + for (i = 0; i < ids.Size(); i++) + { + Byte id = ids[i]; + UString method = (id < kNumMethods) ? kMethods[id] : kUnknownMethod; + if (!resString.IsEmpty()) + resString += L' '; + resString += method; + } + prop = resString; + break; + } + // case kpidSolid: prop = _database.IsSolid(); break; + case kpidNumBlocks: + { + UInt32 numFolders = 0; + for (int v = 0; v < m_Database.Volumes.Size(); v++) + numFolders += m_Database.Volumes[v].Folders.Size(); + prop = numFolders; + break; + } + case kpidNumVolumes: + { + prop = (UInt32)m_Database.Volumes.Size(); + break; + } + } + prop.Detach(value); return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; + COM_TRY_END } STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; + NWindows::NCOM::CPropVariant prop; const CMvItem &mvItem = m_Database.Items[index]; const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex]; @@ -122,14 +142,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va ConvertUTF8ToUnicode(item.Name, unicodeName); else unicodeName = MultiByteToUnicodeString(item.Name, CP_ACP); - propVariant = (const wchar_t *)NItemName::WinNameToOSName(unicodeName); + prop = (const wchar_t *)NItemName::WinNameToOSName(unicodeName); break; } case kpidIsFolder: - propVariant = item.IsDirectory(); + prop = item.IsDirectory(); break; case kpidSize: - propVariant = item.Size; + prop = item.Size; break; case kpidLastWriteTime: { @@ -141,11 +161,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va } else utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; - propVariant = utcFileTime; + prop = utcFileTime; break; } case kpidAttributes: - propVariant = item.GetWinAttributes(); + prop = item.GetWinAttributes(); break; case kpidMethod: @@ -162,28 +182,28 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va ConvertUInt64ToString(folder.CompressionTypeMinor, temp); method += temp; } - propVariant = method; + prop = method; break; } case kpidBlock: - propVariant = (Int32)m_Database.GetFolderIndex(&mvItem); + prop = (Int32)m_Database.GetFolderIndex(&mvItem); break; #ifdef _CAB_DETAILS case kpidBlockReal: - propVariant = UInt32(item.FolderIndex); + prop = UInt32(item.FolderIndex); break; case kpidOffset: - propVariant = (UInt32)item.Offset; + prop = (UInt32)item.Offset; break; case kpidVolume: - propVariant = (UInt32)mvItem.VolumeIndex; + prop = (UInt32)mvItem.VolumeIndex; break; - + #endif } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -568,8 +588,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, totalUnPacked = 0; - NCompress::CCopyCoder *copyCoderSpec = NULL; - CMyComPtr copyCoder; + UInt64 totalPacked = 0; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; + CMyComPtr copyCoder = copyCoderSpec; NCompress::NDeflate::NDecoder::CCOMCoder *deflateDecoderSpec = NULL; CMyComPtr deflateDecoder; @@ -648,8 +674,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, curUnpack = item.GetEndOffset(); } - RINOK(extractCallback->SetCompleted(&totalUnPacked)); - + lps->OutSize = totalUnPacked; + lps->InSize = totalPacked; + RINOK(lps->SetCur()); + CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream; CMyComPtr outStream(cabFolderOutStream); @@ -662,11 +690,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, switch(folder.GetCompressionMethod()) { case NHeader::NCompressionMethodMajor::kNone: - if(copyCoderSpec == NULL) - { - copyCoderSpec = new NCompress::CCopyCoder; - copyCoder = copyCoderSpec; - } break; case NHeader::NCompressionMethodMajor::kMSZip: if(deflateDecoderSpec == NULL) @@ -748,9 +771,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (keepInputBuffer) continue; - UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFolder(); - RINOK(extractCallback->SetCompleted(&totalUnPacked2)); + totalPacked += packSize; + + lps->OutSize = totalUnPacked2; + lps->InSize = totalPacked; + RINOK(lps->SetCur()); + UInt64 unpackRemain = cabFolderOutStream->GetRemain(); const UInt32 kBlockSizeMax = (1 << 15); diff --git a/CPP/7zip/Archive/Chm/ChmHandler.cpp b/CPP/7zip/Archive/Chm/ChmHandler.cpp index a3c3b6a0..d1499328 100755 --- a/CPP/7zip/Archive/Chm/ChmHandler.cpp +++ b/CPP/7zip/Archive/Chm/ChmHandler.cpp @@ -34,13 +34,12 @@ namespace NChm { enum { - kpidSection = kpidUserDefined, - kpidOffset + kpidSection = kpidUserDefined }; #endif -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, // { NULL, kpidIsFolder, VT_BOOL}, @@ -51,62 +50,63 @@ STATPROPSTG kProperties[] = #ifdef _CHM_DETAILS , { L"Section", kpidSection, VT_UI4}, - { L"Offset", kpidOffset, VT_UI4} + { NULL, kpidOffset, VT_UI4} #endif }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +STATPROPSTG kArcProps[] = { - value->vt = VT_EMPTY; - return S_OK; -} + { NULL, kpidNumBlocks, VT_UI8} +}; -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) -{ - *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); - return S_OK; -} +IMP_IInArchive_Props -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; - if (srcItem.lpwstrName == 0) - *name = 0; - else - *name = ::SysAllocString(srcItem.lpwstrName); - return S_OK; -} +IMP_IInArchive_ArcProps_NO +/* +IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { - *numProperties = 0; + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidNumBlocks: + { + UInt64 numBlocks = 0; + for (int i = 0; i < m_Database.Sections.Size(); i++) + { + const CSectionInfo &s = m_Database.Sections[i]; + for (int j = 0; j < s.Methods.Size(); j++) + { + const CMethodInfo &m = s.Methods[j]; + if (m.IsLzx()) + numBlocks += m.LzxInfo.ResetTable.GetNumBlocks(); + } + } + prop = numBlocks; + break; + } + } + prop.Detach(value); return S_OK; + COM_TRY_END } - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; -} +*/ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; + NWindows::NCOM::CPropVariant prop; if (m_Database.NewFormat) { switch(propID) { case kpidSize: - propVariant = (UInt64)m_Database.NewFormatString.Length(); + prop = (UInt64)m_Database.NewFormatString.Length(); break; } - propVariant.Detach(value); + prop.Detach(value); return S_OK; } int entryIndex; @@ -128,44 +128,44 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va if (us[0] == L'/') us.Delete(0); } - propVariant = NItemName::GetOSName2(us); + prop = NItemName::GetOSName2(us); } break; } case kpidIsFolder: - propVariant = item.IsDirectory(); + prop = item.IsDirectory(); break; case kpidSize: - propVariant = item.Size; + prop = item.Size; break; case kpidMethod: { if (!item.IsDirectory()) if (item.Section == 0) - propVariant = L"Copy"; + prop = L"Copy"; else if (item.Section < m_Database.Sections.Size()) - propVariant = m_Database.Sections[(int)item.Section].GetMethodName(); + prop = m_Database.Sections[(int)item.Section].GetMethodName(); break; } case kpidBlock: if (m_Database.LowLevel) - propVariant = item.Section; + prop = item.Section; else if (item.Section != 0) - propVariant = m_Database.GetFolder(index); + prop = m_Database.GetFolder(index); break; #ifdef _CHM_DETAILS case kpidSection: - propVariant = (UInt32)item.Section; + prop = (UInt32)item.Section; break; case kpidOffset: - propVariant = (UInt32)item.Offset; + prop = (UInt32)item.Offset; break; #endif } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -295,7 +295,7 @@ HRESULT CChmFolderOutStream::WriteEmptyFiles() { if (m_FileIsOpen) return S_OK; - for(;m_CurrentIndex < m_NumFiles; m_CurrentIndex++) + for (;m_CurrentIndex < m_NumFiles; m_CurrentIndex++) { UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex); if (fileSize != 0) @@ -421,17 +421,23 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, (m_Database.LowLevel ? m_Database.Items.Size(): m_Database.Indices.Size()); - if(numItems == 0) + if (numItems == 0) return S_OK; bool testMode = (_aTestMode != 0); UInt64 currentTotalSize = 0; - CMyComPtr copyCoder; + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr copyCoder = copyCoderSpec; UInt32 i; + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr inStream(streamSpec); + streamSpec->SetStream(m_Stream); if (m_Database.LowLevel) { @@ -440,17 +446,21 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, if (m_Database.NewFormat) totalSize = m_Database.NewFormatString.Length(); else - for(i = 0; i < numItems; i++) + for (i = 0; i < numItems; i++) totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size; extractCallback->SetTotal(totalSize); - for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) { - RINOK(extractCallback->SetCompleted(¤tTotalSize)); + currentItemSize = 0; + lps->InSize = currentTotalSize; // Change it + lps->OutSize = currentTotalSize; + + RINOK(lps->SetCur()); CMyComPtr realOutStream; - Int32 askMode; - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + Int32 askMode= testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -458,7 +468,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { if (index != 0) return E_FAIL; - if(!testMode && (!realOutStream)) + if (!testMode && (!realOutStream)) continue; if (!testMode) { @@ -472,7 +482,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, currentItemSize = item.Size; - if(!testMode && (!realOutStream)) + if (!testMode && (!realOutStream)) continue; RINOK(extractCallback->PrepareOperation(askMode)); if (item.Section != 0) @@ -488,28 +498,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); - streamSpec->SetStream(m_Stream); streamSpec->Init(item.Size); - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); - - CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, ¤tTotalSize, ¤tTotalSize); - - if(!copyCoder) - copyCoder = new NCompress::CCopyCoder; - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress)); + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); } return S_OK; } UInt64 lastFolderIndex = ((UInt64)0 - 1); - for(i = 0; i < numItems; i++) + for (i = 0; i < numItems; i++) { UInt32 index = allFilesMode ? i : indices[i]; int entryIndex = m_Database.Indices[index]; @@ -545,7 +546,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, currentTotalSize = 0; CRecordVector extractStatuses; - for(i = 0; i < numItems;) + for (i = 0; i < numItems;) { RINOK(extractCallback->SetCompleted(¤tTotalSize)); UInt32 index = allFilesMode ? i : indices[i]; @@ -566,32 +567,27 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, continue; } - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); - - CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, NULL, ¤tTotalSize); + lps->InSize = currentTotalSize; // Change it + lps->OutSize = currentTotalSize; if (item.Size == 0 || sectionIndex == 0) { CMyComPtr realOutStream; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if(!testMode && (!realOutStream)) + if (!testMode && (!realOutStream)) continue; RINOK(extractCallback->PrepareOperation(askMode)); + Int32 opRes = NArchive::NExtract::NOperationResult::kOK; if (!testMode && item.Size != 0) { RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); - streamSpec->SetStream(m_Stream); streamSpec->Init(item.Size); - if(!copyCoder) - copyCoder = new NCompress::CCopyCoder; - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress)); + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); + if (copyCoderSpec->TotalSize != item.Size) + opRes = NArchive::NExtract::NOperationResult::kDataError; } realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(opRes)); currentTotalSize += item.Size; continue; } @@ -652,7 +648,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, chmFolderOutStream->m_StartIndex = index; if (limitFolderIndex == folderIndex) { - for(; i < numItems; i++) + for (; i < numItems; i++) { UInt32 nextIndex = allFilesMode ? i : indices[i]; int entryIndex = m_Database.Indices[nextIndex]; diff --git a/CPP/7zip/Archive/Com/ComHandler.cpp b/CPP/7zip/Archive/Com/ComHandler.cpp index 6d548256..aa9bf859 100755 --- a/CPP/7zip/Archive/Com/ComHandler.cpp +++ b/CPP/7zip/Archive/Com/ComHandler.cpp @@ -10,7 +10,7 @@ namespace NArchive { namespace NCom { -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidIsFolder, VT_BOOL}, @@ -21,49 +21,32 @@ STATPROPSTG kProperties[] = { NULL, kpidLastWriteTime, VT_FILETIME} }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - return S_OK; -} -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) +STATPROPSTG kArcProps[] = { - *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); - return S_OK; -} + { NULL, kpidClusterSize, VT_UI4} +}; -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; - if (srcItem.lpwstrName == 0) - *name = 0; - else - *name = ::SysAllocString(srcItem.lpwstrName); - return S_OK; -} +IMP_IInArchive_Props +IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { - *numProperties = 0; + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidClusterSize: prop = (UInt32)1 << _db.SectorSizeBits; break; + } + prop.Detach(value); return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; + COM_TRY_END } STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; + NWindows::NCOM::CPropVariant prop; const CRef &ref = _db.Refs[index]; const CItem &item = _db.Items[ref.Did]; @@ -72,21 +55,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val case kpidPath: { UString name = _db.GetItemPath(index); - propVariant = name; + prop = name; break; } case kpidIsFolder: - propVariant = item.IsDir(); + prop = item.IsDir(); break; case kpidCreationTime: - propVariant = item.CreationTime; + prop = item.CreationTime; break; case kpidLastWriteTime: - propVariant = item.LastWriteTime; + prop = item.LastWriteTime; break; /* case kpidAttributes: - propVariant = item.Falgs; + prop = item.Falgs; break; */ case kpidPackedSize: @@ -95,15 +78,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val int numBits = _db.IsLargeStream(item.Size) ? _db.SectorSizeBits : _db.MiniSectorSizeBits; - propVariant = (item.Size + ((UInt32)1 << numBits) - 1) >> numBits << numBits; + prop = (item.Size + ((UInt64)1 << numBits) - 1) >> numBits << numBits; break; } case kpidSize: if (!item.IsDir()) - propVariant = (UInt64)item.Size; + prop = (UInt64)item.Size; break; } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } diff --git a/CPP/7zip/Archive/Com/ComIn.cpp b/CPP/7zip/Archive/Com/ComIn.cpp index 0db3f1c6..c3549609 100755 --- a/CPP/7zip/Archive/Com/ComIn.cpp +++ b/CPP/7zip/Archive/Com/ComIn.cpp @@ -338,7 +338,7 @@ HRESULT OpenArchive(IInStream *inStream, CDatabase &db) if (!db.MiniSids.Allocate(numSectorsInMiniStream)) return S_FALSE; { - UInt64 matSize64 = (root.Size + (1 << miniSectorSizeBits) - 1) >> miniSectorSizeBits; + UInt64 matSize64 = (root.Size + ((UInt64)1 << miniSectorSizeBits) - 1) >> miniSectorSizeBits; if (matSize64 > NFatID::kMaxValue) return S_FALSE; db.MatSize = (UInt32)matSize64; diff --git a/CPP/7zip/Archive/Com/ComRegister.cpp b/CPP/7zip/Archive/Com/ComRegister.cpp index 688c9803..c744b04f 100755 --- a/CPP/7zip/Archive/Com/ComRegister.cpp +++ b/CPP/7zip/Archive/Com/ComRegister.cpp @@ -8,6 +8,6 @@ static IInArchive *CreateArc() { return new NArchive::NCom::CHandler; } static CArcInfo g_ArcInfo = - { L"Com", L"msi doc xls ppt", 0, 0xE5, { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }, 8, false, CreateArc, 0 }; + { L"Compound", L"msi doc xls ppt", 0, 0xE5, { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }, 8, false, CreateArc, 0 }; REGISTER_ARC(Com) diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp index a297eb7f..2ef1fa95 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp @@ -167,6 +167,14 @@ HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStre return S_OK; } +HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code) +{ + for (int i = 0; i < _coders.Size(); i++) + if (_coders[i].Result == code) + return code; + return S_OK; +} + STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams, const UInt64 ** /* inSizes */, UInt32 numInStreams, @@ -198,18 +206,10 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams, if (i != _progressCoderIndex) _coders[i].WaitFinish(); - for (i = 0; i < _coders.Size(); i++) - { - HRESULT result = _coders[i].Result; - if (result == E_ABORT) - return result; - } - for (i = 0; i < _coders.Size(); i++) - { - HRESULT result = _coders[i].Result; - if (result == S_FALSE) - return result; - } + RINOK(ReturnIfError(E_ABORT)); + RINOK(ReturnIfError(E_OUTOFMEMORY)); + RINOK(ReturnIfError(S_FALSE)); + for (i = 0; i < _coders.Size(); i++) { HRESULT result = _coders[i].Result; diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.h b/CPP/7zip/Archive/Common/CoderMixer2MT.h index 3cd3282b..505f1a88 100755 --- a/CPP/7zip/Archive/Common/CoderMixer2MT.h +++ b/CPP/7zip/Archive/Common/CoderMixer2MT.h @@ -51,6 +51,7 @@ class CCoderMixer2MT: void AddCoderCommon(); HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams); + HRESULT ReturnIfError(HRESULT code); public: CObjectVector _coders; MY_UNKNOWN_IMP diff --git a/CPP/7zip/Archive/Common/CoderMixerMT.cpp b/CPP/7zip/Archive/Common/CoderMixerMT.cpp index ad32896c..6319c5da 100755 --- a/CPP/7zip/Archive/Common/CoderMixerMT.cpp +++ b/CPP/7zip/Archive/Common/CoderMixerMT.cpp @@ -30,6 +30,14 @@ void CCoderMixerMT::ReInit() _coders[i].ReInit(); } +HRESULT CCoderMixerMT::ReturnIfError(HRESULT code) +{ + for (int i = 0; i < _coders.Size(); i++) + if (_coders[i].Result == code) + return code; + return S_OK; +} + STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 * /* outSize */, @@ -67,18 +75,10 @@ STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream, if (i != _progressCoderIndex) _coders[i].WaitFinish(); - for (i = 0; i < _coders.Size(); i++) - { - HRESULT result = _coders[i].Result; - if (result == E_ABORT) - return result; - } - for (i = 0; i < _coders.Size(); i++) - { - HRESULT result = _coders[i].Result; - if (result == S_FALSE) - return result; - } + RINOK(ReturnIfError(E_ABORT)); + RINOK(ReturnIfError(E_OUTOFMEMORY)); + RINOK(ReturnIfError(S_FALSE)); + for (i = 0; i < _coders.Size(); i++) { HRESULT result = _coders[i].Result; diff --git a/CPP/7zip/Archive/Common/CoderMixerMT.h b/CPP/7zip/Archive/Common/CoderMixerMT.h index 88b6e3e6..6fd1ba44 100755 --- a/CPP/7zip/Archive/Common/CoderMixerMT.h +++ b/CPP/7zip/Archive/Common/CoderMixerMT.h @@ -42,6 +42,7 @@ class CCoderMixerMT: CObjectVector _streamBinders; int _progressCoderIndex; + HRESULT ReturnIfError(HRESULT code); public: CObjectVector _coders; MY_UNKNOWN_IMP diff --git a/CPP/7zip/Archive/Common/DummyOutStream.cpp b/CPP/7zip/Archive/Common/DummyOutStream.cpp index b1d49913..54bcfec1 100755 --- a/CPP/7zip/Archive/Common/DummyOutStream.cpp +++ b/CPP/7zip/Archive/Common/DummyOutStream.cpp @@ -4,17 +4,19 @@ #include "DummyOutStream.h" -void CDummyOutStream::Init(ISequentialOutStream *outStream) +STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) { - m_Stream = outStream; -} - -STDMETHODIMP CDummyOutStream::Write(const void *data, - UInt32 size, UInt32 *processedSize) -{ - if(m_Stream) - return m_Stream->Write(data, size, processedSize); + UInt32 realProcessedSize; + HRESULT result; + if(!_stream) + { + realProcessedSize = size; + result = S_OK; + } + else + result = _stream->Write(data, size, &realProcessedSize); + _size += realProcessedSize; if(processedSize != NULL) - *processedSize = size; - return S_OK; + *processedSize = realProcessedSize; + return result; } diff --git a/CPP/7zip/Archive/Common/DummyOutStream.h b/CPP/7zip/Archive/Common/DummyOutStream.h index 51690787..d19b3111 100755 --- a/CPP/7zip/Archive/Common/DummyOutStream.h +++ b/CPP/7zip/Archive/Common/DummyOutStream.h @@ -10,14 +10,14 @@ class CDummyOutStream: public ISequentialOutStream, public CMyUnknownImp { + CMyComPtr _stream; + UInt64 _size; public: + void SetStream(ISequentialOutStream *outStream) { _stream = outStream; } + void Init() { _size = 0; } MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -private: - CMyComPtr m_Stream; -public: - void Init(ISequentialOutStream *outStream); + UInt64 GetSize() const { return _size; } }; #endif diff --git a/CPP/7zip/Archive/Cpio/CpioHandler.cpp b/CPP/7zip/Archive/Cpio/CpioHandler.cpp index 601afbd6..e2392b86 100755 --- a/CPP/7zip/Archive/Cpio/CpioHandler.cpp +++ b/CPP/7zip/Archive/Cpio/CpioHandler.cpp @@ -3,6 +3,7 @@ #include "StdAfx.h" #include "CpioHandler.h" +#include "CpioIn.h" #include "Common/Defs.h" #include "Common/StringConvert.h" @@ -16,8 +17,8 @@ #include "../../Common//LimitedStreams.h" #include "../../Compress/Copy/CopyCoder.h" + #include "../Common/ItemNameUtils.h" -#include "CpioIn.h" using namespace NWindows; using namespace NTime; @@ -25,13 +26,15 @@ using namespace NTime; namespace NArchive { namespace NCpio { +/* enum // PropID { kpidinode = kpidUserDefined, kpidiChkSum }; +*/ -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidIsFolder, VT_BOOL}, @@ -44,43 +47,10 @@ STATPROPSTG kProperties[] = // { L"CheckSum", kpidiChkSum, VT_UI4} }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - 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; -} +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) -{ - *numProperties = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, +STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *openArchiveCallback) { @@ -89,41 +59,41 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, { CInArchive archive; - if(archive.Open(inStream) != S_OK) + if (archive.Open(stream) != S_OK) return S_FALSE; - m_Items.Clear(); + _items.Clear(); if (openArchiveCallback != NULL) { RINOK(openArchiveCallback->SetTotal(NULL, NULL)); - UInt64 numFiles = m_Items.Size(); + UInt64 numFiles = _items.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } for (;;) { - CItemEx itemInfo; + CItemEx item; bool filled; - HRESULT result = archive.GetNextItem(filled, itemInfo); + HRESULT result = archive.GetNextItem(filled, item); if (result == S_FALSE) return S_FALSE; if (result != S_OK) return S_FALSE; if (!filled) break; - m_Items.Add(itemInfo); - archive.SkeepDataRecords(itemInfo.Size, itemInfo.Align); + _items.Add(item); + archive.SkeepDataRecords(item.Size, item.Align); if (openArchiveCallback != NULL) { - UInt64 numFiles = m_Items.Size(); + UInt64 numFiles = _items.Size(); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); } } - if (m_Items.Size() == 0) + if (_items.Size() == 0) return S_FALSE; - m_InStream = inStream; + _inStream = stream; } /* catch(...) @@ -137,35 +107,35 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, STDMETHODIMP CHandler::Close() { - m_Items.Clear(); - m_InStream.Release(); + _items.Clear(); + _inStream.Release(); return S_OK; } STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { - *numItems = m_Items.Size(); + *numItems = _items.Size(); return S_OK; } STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; - const CItemEx &item = m_Items[index]; + NWindows::NCOM::CPropVariant prop; + const CItemEx &item = _items[index]; switch(propID) { case kpidPath: - propVariant = (const wchar_t *)NItemName::GetOSName( + prop = (const wchar_t *)NItemName::GetOSName( MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; case kpidIsFolder: - propVariant = item.IsDirectory(); + prop = item.IsDirectory(); break; case kpidSize: case kpidPackedSize: - propVariant = item.Size; + prop = (UInt64)item.Size; break; case kpidLastWriteTime: { @@ -177,19 +147,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val utcFileTime.dwLowDateTime = 0; utcFileTime.dwHighDateTime = 0; } - propVariant = utcFileTime; + prop = utcFileTime; break; } + /* case kpidinode: - propVariant = item.inode; + prop = item.inode; break; - /* case kpidiChkSum: - propVariant = item.ChkSum; + prop = item.ChkSum; break; */ } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -198,89 +168,65 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, Int32 _aTestMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) - numItems = m_Items.Size(); - if(numItems == 0) + numItems = _items.Size(); + if (numItems == 0) return S_OK; - bool testMode = (_aTestMode != 0); UInt64 totalSize = 0; UInt32 i; - for(i = 0; i < numItems; i++) - totalSize += m_Items[allFilesMode ? i : indices[i]].Size; + for (i = 0; i < numItems; i++) + totalSize += _items[allFilesMode ? i : indices[i]].Size; extractCallback->SetTotal(totalSize); UInt64 currentTotalSize = 0; UInt64 currentItemSize; - CMyComPtr copyCoder; + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr copyCoder = copyCoderSpec; - for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + streamSpec->SetStream(_inStream); + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) { - RINOK(extractCallback->SetCompleted(¤tTotalSize)); + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); CMyComPtr realOutStream; - Int32 askMode; - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; - const CItemEx &itemInfo = m_Items[index]; - + const CItemEx &item = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - currentItemSize = itemInfo.Size; - - if(itemInfo.IsDirectory()) + currentItemSize = item.Size; + if (item.IsDirectory()) { RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); continue; } - if(!testMode && (!realOutStream)) - { + if (!testMode && (!realOutStream)) continue; - } RINOK(extractCallback->PrepareOperation(askMode)); + if (testMode) { - if (testMode) - { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); - continue; - } - - RINOK(m_InStream->Seek(itemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL)); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(m_InStream); - streamSpec->Init(itemInfo.Size); - - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); - - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, - ¤tTotalSize, ¤tTotalSize); - - if(copyCoder == NULL) - { - copyCoder = new NCompress::CCopyCoder; - } - try - { - RINOK(copyCoder->Code(inStream, realOutStream, - NULL, NULL, compressProgress)); - } - catch(...) - { - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); - continue; - } - realOutStream.Release(); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; } + RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); + streamSpec->Init(item.Size); + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END diff --git a/CPP/7zip/Archive/Cpio/CpioHandler.h b/CPP/7zip/Archive/Cpio/CpioHandler.h index e9320e61..3b4e7036 100755 --- a/CPP/7zip/Archive/Cpio/CpioHandler.h +++ b/CPP/7zip/Archive/Cpio/CpioHandler.h @@ -21,8 +21,8 @@ public: INTERFACE_IInArchive(;) private: - CObjectVector m_Items; - CMyComPtr m_InStream; + CObjectVector _items; + CMyComPtr _inStream; }; }} diff --git a/CPP/7zip/Archive/Deb/DebHandler.cpp b/CPP/7zip/Archive/Deb/DebHandler.cpp index 8728cec8..19cf310b 100755 --- a/CPP/7zip/Archive/Deb/DebHandler.cpp +++ b/CPP/7zip/Archive/Deb/DebHandler.cpp @@ -26,51 +26,16 @@ using namespace NTime; namespace NArchive { namespace NDeb { -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - // { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, { NULL, kpidPackedSize, VT_UI8}, { NULL, kpidLastWriteTime, VT_FILETIME} }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - 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 = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; -} - +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, @@ -92,17 +57,17 @@ STDMETHODIMP CHandler::Open(IInStream *stream, for (;;) { - CItemEx itemInfo; + CItemEx item; bool filled; - HRESULT result = archive.GetNextItem(filled, itemInfo); + HRESULT result = archive.GetNextItem(filled, item); if (result == S_FALSE) return S_FALSE; if (result != S_OK) return S_FALSE; if (!filled) break; - _items.Add(itemInfo); - archive.SkeepData(itemInfo.Size); + _items.Add(item); + archive.SkeepData(item.Size); if (openArchiveCallback != NULL) { UInt64 numFiles = _items.Size(); @@ -131,21 +96,21 @@ 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 = _items[index]; switch(propID) { case kpidPath: - propVariant = (const wchar_t *)NItemName::GetOSName2( + prop = (const wchar_t *)NItemName::GetOSName2( MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; case kpidIsFolder: - propVariant = false; + prop = false; break; case kpidSize: case kpidPackedSize: - propVariant = item.Size; + prop = item.Size; break; case kpidLastWriteTime: { @@ -157,11 +122,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val utcFileTime.dwLowDateTime = 0; utcFileTime.dwHighDateTime = 0; } - propVariant = utcFileTime; + prop = utcFileTime; break; } } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -170,83 +135,65 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, Int32 _aTestMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN + bool testMode = (_aTestMode != 0); bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) numItems = _items.Size(); - if(numItems == 0) + if (numItems == 0) return S_OK; - bool testMode = (_aTestMode != 0); UInt64 totalSize = 0; UInt32 i; - for(i = 0; i < numItems; i++) + for (i = 0; i < numItems; i++) totalSize += _items[allFilesMode ? i : indices[i]].Size; extractCallback->SetTotal(totalSize); UInt64 currentTotalSize = 0; UInt64 currentItemSize; - CMyComPtr copyCoder; + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr copyCoder = copyCoderSpec; - for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + streamSpec->SetStream(_inStream); + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) { - RINOK(extractCallback->SetCompleted(¤tTotalSize)); + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); CMyComPtr realOutStream; - Int32 askMode; - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; - const CItemEx &itemInfo = _items[index]; - + const CItemEx &item = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - currentItemSize = itemInfo.Size; - - if(!testMode && (!realOutStream)) - { + currentItemSize = item.Size; + + + + + + + if (!testMode && (!realOutStream)) continue; - } RINOK(extractCallback->PrepareOperation(askMode)); + if (testMode) { - if (testMode) - { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); - continue; - } - - RINOK(_inStream->Seek(itemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL)); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_inStream); - streamSpec->Init(itemInfo.Size); - - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); - - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, - ¤tTotalSize, ¤tTotalSize); - - if(copyCoder == NULL) - { - copyCoder = new NCompress::CCopyCoder; - } - try - { - RINOK(copyCoder->Code(inStream, realOutStream, - NULL, NULL, compressProgress)); - } - catch(...) - { - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); - continue; - } - realOutStream.Release(); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; } + RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); + streamSpec->Init(item.Size); + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END diff --git a/CPP/7zip/Archive/GZip/GZipHandler.cpp b/CPP/7zip/Archive/GZip/GZipHandler.cpp index 427098ce..48d85fa4 100755 --- a/CPP/7zip/Archive/GZip/GZipHandler.cpp +++ b/CPP/7zip/Archive/GZip/GZipHandler.cpp @@ -59,15 +59,13 @@ enum // PropID }; */ -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, - // { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, { NULL, kpidPackedSize, VT_UI8}, { NULL, kpidLastWriteTime, VT_FILETIME}, - // { NULL, kpidCommented, VT_BOOL}, // { NULL, kpidMethod, VT_UI1}, { NULL, kpidHostOS, VT_BSTR}, @@ -77,39 +75,8 @@ STATPROPSTG kProperties[] = // { L"Is Text", kpidIsText, VT_BOOL}, }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - 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) -{ - const STATPROPSTG &prop = kProperties[index]; - *propID = prop.propid; - *varType = prop.vt; - *name = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) -{ - *numProperties = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_NOTIMPL; -} +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { @@ -120,15 +87,12 @@ 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; switch(propID) { case kpidPath: if (m_Item.NameIsPresent()) - propVariant = MultiByteToUnicodeString(m_Item.Name, CP_ACP); - break; - case kpidIsFolder: - propVariant = false; + prop = MultiByteToUnicodeString(m_Item.Name, CP_ACP); break; case kpidLastWriteTime: { @@ -136,47 +100,47 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA if (m_Item.Time != 0) { NTime::UnixTimeToFileTime((UInt32)m_Item.Time, utcTime); - propVariant = utcTime; + prop = utcTime; } else { // utcTime.dwLowDateTime = utcTime.dwHighDateTime = 0; - // propVariant = utcTime; + // prop = utcTime; } break; } case kpidSize: - propVariant = UInt64(m_Item.UnPackSize32); + prop = UInt64(m_Item.UnPackSize32); break; case kpidPackedSize: - propVariant = m_PackSize; + prop = m_PackSize; break; case kpidCommented: - propVariant = m_Item.CommentIsPresent(); + prop = m_Item.CommentIsPresent(); break; case kpidHostOS: - propVariant = (m_Item.HostOS < kNumHostOSes) ? + prop = (m_Item.HostOS < kNumHostOSes) ? kHostOS[m_Item.HostOS] : kUnknownOS; break; case kpidMethod: - propVariant = m_Item.CompressionMethod; + prop = m_Item.CompressionMethod; break; case kpidCRC: - propVariant = m_Item.FileCRC; + prop = m_Item.FileCRC; break; /* case kpidExtraFlags: - propVariant = m_Item.ExtraFlags; + prop = m_Item.ExtraFlags; break; case kpidIsText: - propVariant = m_Item.IsText(); + prop = m_Item.IsText(); break; case kpidExtraIsPresent: - propVariant = m_Item.ExtraFieldIsPresent(); + prop = m_Item.ExtraFieldIsPresent(); break; */ } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -232,7 +196,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, extractCallback->SetTotal(m_PackSize); - UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; + UInt64 currentTotalPacked = 0; RINOK(extractCallback->SetCompleted(¤tTotalPacked)); CMyComPtr realOutStream; @@ -253,22 +217,18 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, outStreamSpec->Init(); realOutStream.Release(); - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, true); - - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, true); CMyComPtr deflateDecoder; bool firstItem = true; RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); + Int32 opRes; for (;;) { - localCompressProgressSpec->Init(progress, - ¤tTotalPacked, - ¤tTotalUnPacked); + lps->InSize = currentTotalPacked; + lps->OutSize = outStreamSpec->GetSize(); CInArchive archive; CItem item; @@ -277,9 +237,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { if (firstItem) return E_FAIL; - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) - return S_OK; + opRes = NArchive::NExtract::NOperationResult::kOK; + break; } firstItem = false; @@ -288,45 +247,32 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, outStreamSpec->InitCRC(); - switch(item.CompressionMethod) + if (item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflate) + { + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + break; + } + + if (!deflateDecoder) { - case NFileHeader::NCompressionMethod::kDeflate: + RINOK(CreateCoder( + EXTERNAL_CODECS_VARS + kMethodId_Deflate, deflateDecoder, false)); + if (!deflateDecoder) { - if(!deflateDecoder) - { - RINOK(CreateCoder( - EXTERNAL_CODECS_VARS - kMethodId_Deflate, deflateDecoder, false)); - if (!deflateDecoder) - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); - return S_OK; - } - } - try - { - HRESULT result = deflateDecoder->Code(m_Stream, outStream, NULL, NULL, compressProgress); - if (result == S_FALSE) - throw "data error"; - if (result != S_OK) - return result; - } - catch(...) - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kDataError)); - return S_OK; - } + opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod; break; } - default: - outStream.Release(); - RINOK(extractCallback->SetOperationResult( - NArchive::NExtract::NOperationResult::kUnSupportedMethod)); - return S_OK; } + result = deflateDecoder->Code(m_Stream, outStream, NULL, NULL, progress); + if (result != S_OK) + { + if (result != S_FALSE) + return result; + opRes = NArchive::NExtract::NOperationResult::kDataError; + break; + } + CMyComPtr getInStreamProcessedSize; RINOK(deflateDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, &getInStreamProcessedSize)); @@ -342,12 +288,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, return E_FAIL; if((outStreamSpec->GetCRC() != postItem.FileCRC)) { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)) + opRes = NArchive::NExtract::NOperationResult::kCRCError; break; } } + outStream.Release(); + return extractCallback->SetOperationResult(opRes); COM_TRY_END - return S_OK; } IMPL_ISetCompressCodecsInfo diff --git a/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp b/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp index 76cfd642..f2776adb 100755 --- a/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp +++ b/CPP/7zip/Archive/GZip/GZipHandlerOut.cpp @@ -70,41 +70,41 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt UString name; bool isDirectory; { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(itemIndex, kpidAttributes, &propVariant)); - if (propVariant.vt == VT_EMPTY) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(itemIndex, kpidAttributes, &prop)); + if (prop.vt == VT_EMPTY) attributes = 0; - else if (propVariant.vt != VT_UI4) + else if (prop.vt != VT_UI4) return E_INVALIDARG; else - attributes = propVariant.ulVal; + attributes = prop.ulVal; } { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(itemIndex, kpidLastWriteTime, &propVariant)); - if (propVariant.vt != VT_FILETIME) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(itemIndex, kpidLastWriteTime, &prop)); + if (prop.vt != VT_FILETIME) return E_INVALIDARG; - utcTime = propVariant.filetime; + utcTime = prop.filetime; } { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(itemIndex, kpidPath, &propVariant)); - if (propVariant.vt == VT_EMPTY) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(itemIndex, kpidPath, &prop)); + if (prop.vt == VT_EMPTY) name.Empty(); - else if (propVariant.vt != VT_BSTR) + else if (prop.vt != VT_BSTR) return E_INVALIDARG; else - name = propVariant.bstrVal; + name = prop.bstrVal; } { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(itemIndex, kpidIsFolder, &propVariant)); - if (propVariant.vt == VT_EMPTY) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(itemIndex, kpidIsFolder, &prop)); + if (prop.vt == VT_EMPTY) isDirectory = false; - else if (propVariant.vt != VT_BOOL) + else if (prop.vt != VT_BOOL) return E_INVALIDARG; else - isDirectory = (propVariant.boolVal != VARIANT_FALSE); + isDirectory = (prop.boolVal != VARIANT_FALSE); } if (isDirectory || NFile::NFind::NAttributes::IsDirectory(attributes)) return E_INVALIDARG; @@ -121,11 +121,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt if (IntToBool(newData)) { { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(itemIndex, kpidSize, &propVariant)); - if (propVariant.vt != VT_UI8) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(itemIndex, kpidSize, &prop)); + if (prop.vt != VT_UI8) return E_INVALIDARG; - size = propVariant.uhVal.QuadPart; + size = prop.uhVal.QuadPart; } newItem.UnPackSize32 = (UInt32)size; diff --git a/CPP/7zip/Archive/GZip/GZipUpdate.cpp b/CPP/7zip/Archive/GZip/GZipUpdate.cpp index 17e27c9f..1f5ebd0e 100755 --- a/CPP/7zip/Archive/GZip/GZipUpdate.cpp +++ b/CPP/7zip/Archive/GZip/GZipUpdate.cpp @@ -34,9 +34,7 @@ HRESULT UpdateArchive( int indexInClient, IArchiveUpdateCallback *updateCallback) { - UInt64 complexity = 0; - - complexity += unpackSize; + UInt64 complexity = unpackSize; RINOK(updateCallback->SetTotal(complexity)); @@ -54,13 +52,9 @@ HRESULT UpdateArchive( inStreamSpec->SetStream(fileInStream); inStreamSpec->Init(); - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr localProgress = localProgressSpec; - localProgressSpec->Init(updateCallback, true); - - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(updateCallback, true); COutArchive outArchive; outArchive.Create(outStream); @@ -72,8 +66,6 @@ HRESULT UpdateArchive( RINOK(outArchive.WriteHeader(item)); - localCompressProgressSpec->Init(localProgress, &complexity, NULL); - { RINOK(CreateCoder( EXTERNAL_CODECS_LOC_VARS @@ -102,7 +94,7 @@ HRESULT UpdateArchive( RINOK(deflateEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties)); RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps)); } - RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, compressProgress)); + RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress)); item.FileCRC = inStreamSpec->GetCRC(); item.UnPackSize32 = (UInt32)inStreamSpec->GetSize(); diff --git a/CPP/7zip/Archive/IArchive.h b/CPP/7zip/Archive/IArchive.h index 5fe20a72..e0ae7aa1 100755 --- a/CPP/7zip/Archive/IArchive.h +++ b/CPP/7zip/Archive/IArchive.h @@ -7,12 +7,7 @@ #include "../IProgress.h" #include "../PropID.h" -// MIDL_INTERFACE("23170F69-40C1-278A-0000-000600xx0000") -#define ARCHIVE_INTERFACE_SUB(i, base, x) \ -DEFINE_GUID(IID_ ## i, \ -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x06, 0x00, x, 0x00, 0x00); \ -struct i: public base - +#define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x) #define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x) namespace NFileTimeType @@ -172,4 +167,41 @@ ARCHIVE_INTERFACE(ISetProperties, 0x03) }; +#define IMP_IInArchive_GetProp(k) \ + (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ + { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \ + const STATPROPSTG &srcItem = k[index]; \ + *propID = srcItem.propid; *varType = srcItem.vt; *name = 0; return S_OK; } \ + +#define IMP_IInArchive_GetProp_WITH_NAME(k) \ + (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ + { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \ + const STATPROPSTG &srcItem = k[index]; \ + *propID = srcItem.propid; *varType = srcItem.vt; \ + if (srcItem.lpwstrName == 0) *name = 0; else *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } \ + +#define IMP_IInArchive_Props \ + STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \ + { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \ + STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps) + +#define IMP_IInArchive_Props_WITH_NAME \ + STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \ + { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \ + STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps) + + +#define IMP_IInArchive_ArcProps \ + STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \ + { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \ + STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps) + +#define IMP_IInArchive_ArcProps_NO \ + STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \ + { *numProperties = 0; return S_OK; } \ + STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \ + { return E_NOTIMPL; } \ + STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \ + { value->vt = VT_EMPTY; return S_OK; } + #endif diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp index 1b20f257..0ab39c4f 100755 --- a/CPP/7zip/Archive/Iso/IsoHandler.cpp +++ b/CPP/7zip/Archive/Iso/IsoHandler.cpp @@ -15,6 +15,7 @@ #include "../../Common/ProgressUtils.h" #include "../../Common/LimitedStreams.h" + #include "../../Compress/Copy/CopyCoder.h" #include "../Common/ItemNameUtils.h" @@ -25,7 +26,7 @@ using namespace NTime; namespace NArchive { namespace NIso { -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidIsFolder, VT_BOOL}, @@ -34,41 +35,8 @@ STATPROPSTG kProperties[] = { NULL, kpidLastWriteTime, VT_FILETIME} }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - 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 = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; -} +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, @@ -103,7 +71,7 @@ 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; if (index >= (UInt32)_archive.Refs.Size()) { index -= _archive.Refs.Size(); @@ -118,16 +86,16 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val // s += name; // s += L"-"; s += be.GetName(); - propVariant = (const wchar_t *)s; + prop = (const wchar_t *)s; break; } case kpidIsFolder: - propVariant = false; + prop = false; break; case kpidSize: case kpidPackedSize: { - propVariant = (UInt64)_archive.GetBootItemSize(index); + prop = (UInt64)_archive.GetBootItemSize(index); break; } } @@ -154,22 +122,22 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val if (!s.IsEmpty()) if (s[s.Length() - 1] == L'.') s = s.Left(s.Length() - 1); - propVariant = (const wchar_t *)NItemName::GetOSName2(s); + prop = (const wchar_t *)NItemName::GetOSName2(s); } break; case kpidIsFolder: - propVariant = item.IsDir(); + prop = item.IsDir(); break; case kpidSize: case kpidPackedSize: if (!item.IsDir()) - propVariant = (UInt64)item.DataLength; + prop = (UInt64)item.DataLength; break; case kpidLastWriteTime: { FILETIME utcFileTime; if (item.DateTime.GetFileTime(utcFileTime)) - propVariant = utcFileTime; + prop = utcFileTime; /* else { @@ -181,7 +149,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val } } } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -194,9 +162,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) numItems = _archive.Refs.Size(); - UInt64 totalSize = 0; if(numItems == 0) return S_OK; + UInt64 totalSize = 0; UInt32 i; for(i = 0; i < numItems; i++) { @@ -217,12 +185,22 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, UInt64 currentTotalSize = 0; UInt64 currentItemSize; - CMyComPtr copyCoder; + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + streamSpec->SetStream(_inStream); for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); currentItemSize = 0; - RINOK(extractCallback->SetCompleted(¤tTotalSize)); CMyComPtr realOutStream; Int32 askMode; askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; @@ -252,47 +230,21 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, blockIndex = be.LoadRBA; } - if(!testMode && (!realOutStream)) + if (!testMode && (!realOutStream)) continue; - RINOK(extractCallback->PrepareOperation(askMode)); + if (testMode) { - if (testMode) - { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); - continue; - } - - RINOK(_inStream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL)); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_inStream); - streamSpec->Init(currentItemSize); - - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); - - CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, ¤tTotalSize, ¤tTotalSize); - - Int32 res = NArchive::NExtract::NOperationResult::kOK; - if(!copyCoder) - { - copyCoder = new NCompress::CCopyCoder; - } - try - { - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress)); - } - catch(...) - { - res = NArchive::NExtract::NOperationResult::kDataError; - } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(res)); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; } + RINOK(_inStream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL)); + streamSpec->Init(currentItemSize); + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == currentItemSize) ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END diff --git a/CPP/7zip/Archive/Lzh/LzhHandler.cpp b/CPP/7zip/Archive/Lzh/LzhHandler.cpp index 03af11d1..c5123f56 100755 --- a/CPP/7zip/Archive/Lzh/LzhHandler.cpp +++ b/CPP/7zip/Archive/Lzh/LzhHandler.cpp @@ -67,7 +67,7 @@ static const wchar_t *GetOS(Byte osId) return kUnknownOS; }; -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidIsFolder, VT_BOOL}, @@ -85,45 +85,10 @@ STATPROPSTG kProperties[] = }; +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO -CHandler::CHandler() -{} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - 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 = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_NOTIMPL; -} +CHandler::CHandler() {} STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { @@ -134,7 +99,7 @@ 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 = _items[index]; switch(propID) { @@ -145,18 +110,18 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va { if (s[s.Length() - 1] == WCHAR_PATH_SEPARATOR) s.Delete(s.Length() - 1); - propVariant = s; + prop = s; } break; } case kpidIsFolder: - propVariant = item.IsDirectory(); + prop = item.IsDirectory(); break; case kpidSize: - propVariant = item.Size; + prop = item.Size; break; case kpidPackedSize: - propVariant = item.PackSize; + prop = item.PackSize; break; case kpidLastWriteTime: { @@ -177,19 +142,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va else utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; } - propVariant = utcFileTime; + prop = utcFileTime; break; } /* case kpidAttributes: - propVariant = (UInt32)item.Attributes; + prop = (UInt32)item.Attributes; break; case kpidCommented: - propVariant = item.IsCommented(); + prop = item.IsCommented(); break; */ case kpidCRC: - propVariant = (UInt32)item.CRC; + prop = (UInt32)item.CRC; break; case kpidMethod: { @@ -197,14 +162,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va method2[kMethodIdSize] = 0; for (int i = 0; i < kMethodIdSize; i++) method2[i] = item.Method[i]; - propVariant = method2; + prop = method2; break; } case kpidHostOS: - propVariant = GetOS(item.OsId); + prop = GetOS(item.OsId); break; } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -242,17 +207,17 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, } for (;;) { - CItemEx itemInfo; + CItemEx item; bool filled; - HRESULT result = archive.GetNextItem(filled, itemInfo); + HRESULT result = archive.GetNextItem(filled, item); if (result == S_FALSE) return S_FALSE; if (result != S_OK) return S_FALSE; if (!filled) break; - _items.Add(itemInfo); - archive.Skeep(itemInfo.PackSize); + _items.Add(item); + archive.Skeep(item.PackSize); if (callback != NULL) { UInt64 numFiles = _items.Size(); @@ -298,9 +263,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, UInt32 i; for(i = 0; i < numItems; i++) { - const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]]; - totalUnPacked += itemInfo.Size; - totalPacked += itemInfo.PackSize; + const CItemEx &item = _items[allFilesMode ? i : indices[i]]; + totalUnPacked += item.Size; + totalPacked += item.PackSize; } extractCallback->SetTotal(totalUnPacked); @@ -311,7 +276,17 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr lzhDecoder; CMyComPtr lzh1Decoder; CMyComPtr arj2Decoder; - CMyComPtr copyCoder; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + streamSpec->SetStream(_stream); for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, currentTotalPacked += currentItemPacked) @@ -319,21 +294,24 @@ 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 realOutStream; Int32 askMode; - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + askMode = testMode ? NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; - const CItemEx &itemInfo = _items[index]; + const CItemEx &item = _items[index]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if(itemInfo.IsDirectory()) + if(item.IsDirectory()) { // if (!testMode) { RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); } continue; } @@ -342,8 +320,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, continue; RINOK(extractCallback->PrepareOperation(askMode)); - currentItemUnPacked = itemInfo.Size; - currentItemPacked = itemInfo.PackSize; + currentItemUnPacked = item.Size; + currentItemPacked = item.PackSize; { COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; @@ -351,109 +329,58 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, outStreamSpec->Init(realOutStream); realOutStream.Release(); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - UInt64 pos; - _stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos); - - streamSpec->SetStream(_stream); - streamSpec->Init(itemInfo.PackSize); - + _stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos); - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); + streamSpec->Init(item.PackSize); + HRESULT result = S_OK; + Int32 opRes = NExtract::NOperationResult::kOK; - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, - ¤tTotalPacked, - ¤tTotalUnPacked); - - HRESULT result; - - if (itemInfo.IsCopyMethod()) + if (item.IsCopyMethod()) { - if(!copyCoder) - copyCoder = new NCompress::CCopyCoder; - try - { - result = copyCoder->Code(inStream, outStream, NULL, NULL, compressProgress); - if (result == S_FALSE) - throw "data error"; - if (result != S_OK) - return result; - } - catch(...) - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); - continue; - } + result = copyCoder->Code(inStream, outStream, NULL, NULL, progress); + if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize) + result = S_FALSE; } - else if (itemInfo.IsLh4GroupMethod()) + else if (item.IsLh4GroupMethod()) { if(!lzhDecoder) { lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; lzhDecoder = lzhDecoderSpec; } - try - { - lzhDecoderSpec->SetDictionary(itemInfo.GetNumDictBits()); - result = lzhDecoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, compressProgress); - if (result == S_FALSE) - throw "data error"; - if (result != S_OK) - return result; - } - catch(...) - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); - continue; - } + lzhDecoderSpec->SetDictionary(item.GetNumDictBits()); + result = lzhDecoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress); } /* - else if (itemInfo.IsLh1GroupMethod()) + else if (item.IsLh1GroupMethod()) { if(!lzh1Decoder) { lzh1DecoderSpec = new NCompress::NLzh1::NDecoder::CCoder; lzh1Decoder = lzh1DecoderSpec; } - try - { - lzh1DecoderSpec->SetDictionary(itemInfo.GetNumDictBits()); - result = lzh1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, compressProgress); - if (result == S_FALSE) - throw "data error"; - if (result != S_OK) - return result; - } - catch(...) - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); - continue; - } + lzh1DecoderSpec->SetDictionary(item.GetNumDictBits()); + result = lzh1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress); } */ else + opRes = NExtract::NOperationResult::kUnSupportedMethod; + + if (opRes == NExtract::NOperationResult::kOK) { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); - continue; + if (result == S_FALSE) + opRes = NExtract::NOperationResult::kDataError; + else + { + RINOK(result); + if (outStreamSpec->GetCRC() != item.CRC) + opRes = NExtract::NOperationResult::kCRCError; + } } - - bool crcOK = (outStreamSpec->GetCRC() == itemInfo.CRC); outStream.Release(); - if(crcOK) - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) - else - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)) + RINOK(extractCallback->SetOperationResult(opRes)); } } return S_OK; diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp index 07fd2c4e..62c7ab38 100755 --- a/CPP/7zip/Archive/Nsis/NsisHandler.cpp +++ b/CPP/7zip/Archive/Nsis/NsisHandler.cpp @@ -31,7 +31,7 @@ static const wchar_t *kMethods[] = static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidIsFolder, VT_BOOL}, @@ -42,43 +42,44 @@ STATPROPSTG kProperties[] = { NULL, kpidSolid, VT_BOOL} }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) +STATPROPSTG kArcProps[] = { - value->vt = VT_EMPTY; - return S_OK; -} + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidSolid, VT_BOOL} +}; -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) -{ - *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); - return S_OK; -} +IMP_IInArchive_Props +IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { - 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 = 0; + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidMethod: + { + UInt32 dict = 1; + bool filter = false; + for (int i = 0; i < _archive.Items.Size(); i++) + { + const CItem &item = _archive.Items[i]; + filter |= item.UseFilter; + if (item.DictionarySize > dict) + dict = item.DictionarySize; + } + prop = GetMethod(filter, dict); + break; + } + case kpidSolid: prop = _archive.IsSolid; break; + } + prop.Detach(value); return S_OK; + COM_TRY_END } -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; -} -STDMETHODIMP CHandler::Open( - IInStream *stream, const UInt64 * maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */) +STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */) { COM_TRY_BEGIN Close(); @@ -142,6 +143,24 @@ static UString GetStringForSizeValue(UInt32 value) return result; } +UString CHandler::GetMethod(bool useItemFilter, UInt32 dictionary) const +{ + NMethodType::EEnum methodIndex = _archive.Method; + UString method; + if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && useItemFilter) + { + method += kBcjMethod; + method += L" "; + } + method += (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod; + if (methodIndex == NMethodType::kLZMA) + { + method += L":"; + method += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: dictionary); + } + return method; +} + bool CHandler::GetUncompressedSize(int index, UInt32 &size) { size = 0; @@ -185,24 +204,24 @@ bool CHandler::GetCompressedSize(int index, UInt32 &size) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; + NWindows::NCOM::CPropVariant prop; #ifdef NSIS_SCRIPT if (index >= (UInt32)_archive.Items.Size()) { switch(propID) { case kpidPath: - propVariant = L"[NSIS].nsi"; + prop = L"[NSIS].nsi"; break; case kpidIsFolder: - propVariant = false; + prop = false; break; case kpidSize: case kpidPackedSize: - propVariant = (UInt64)_archive.Script.Length(); + prop = (UInt64)_archive.Script.Length(); break; case kpidSolid: - propVariant = false; + prop = false; break; } } @@ -215,57 +234,44 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val case kpidPath: { const UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetReducedName(), CP_ACP)); - propVariant = (const wchar_t *)s; + prop = (const wchar_t *)s; break; } case kpidIsFolder: - propVariant = false; + prop = false; break; case kpidSize: { UInt32 size; if (GetUncompressedSize(index, size)) - propVariant = (UInt64)size; + prop = (UInt64)size; break; } case kpidPackedSize: { UInt32 size; if (GetCompressedSize(index, size)) - propVariant = (UInt64)size; + prop = (UInt64)size; break; } case kpidLastWriteTime: { if (item.DateTime.dwHighDateTime > 0x01000000 && item.DateTime.dwHighDateTime < 0xFF000000) - propVariant = item.DateTime; + prop = item.DateTime; break; } case kpidMethod: { - NMethodType::EEnum methodIndex = _archive.Method; - UString method; - if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && item.UseFilter) - { - method += kBcjMethod; - method += L" "; - } - method += (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod; - if (methodIndex == NMethodType::kLZMA) - { - method += L":"; - method += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: item.DictionarySize); - } - propVariant = method; + prop = GetMethod(item.UseFilter, item.DictionarySize); break; } case kpidSolid: - propVariant = _archive.IsSolid; + prop = _archive.IsSolid; break; } } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -478,8 +484,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } } } - if (!testMode) - realOutStream.Release(); + realOutStream.Release(); RINOK(extractCallback->SetOperationResult(dataError ? NArchive::NExtract::NOperationResult::kDataError : NArchive::NExtract::NOperationResult::kOK)); diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.h b/CPP/7zip/Archive/Nsis/NsisHandler.h index 82e76139..5dc30107 100755 --- a/CPP/7zip/Archive/Nsis/NsisHandler.h +++ b/CPP/7zip/Archive/Nsis/NsisHandler.h @@ -26,6 +26,7 @@ class CHandler: bool GetUncompressedSize(int index, UInt32 &size); bool GetCompressedSize(int index, UInt32 &size); + UString GetMethod(bool useItemFilter, UInt32 dictionary) const; public: MY_QUERYINTERFACE_BEGIN2(IInArchive) QUERY_ENTRY_ISetCompressCodecsInfo diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp index aa1e456f..83080448 100755 --- a/CPP/7zip/Archive/Nsis/NsisIn.cpp +++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp @@ -905,10 +905,10 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) { Items.Sort(CompareItems, 0); int i; - if (IsSolid) + // if (IsSolid) for (i = 0; i + 1 < Items.Size();) { - if (Items[i].Pos == Items[i + 1].Pos) + if (Items[i].Pos == Items[i + 1].Pos && (IsSolid || Items[i].Name == Items[i + 1].Name)) Items.Delete(i + 1); else i++; diff --git a/CPP/7zip/Archive/RPM/RpmHandler.cpp b/CPP/7zip/Archive/RPM/RpmHandler.cpp index b1a5bf7d..7cd881a1 100755 --- a/CPP/7zip/Archive/RPM/RpmHandler.cpp +++ b/CPP/7zip/Archive/RPM/RpmHandler.cpp @@ -25,49 +25,14 @@ using namespace NWindows; namespace NArchive { namespace NRpm { -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { -// { NULL, kpidPath, VT_BSTR}, -// { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, { NULL, kpidPackedSize, VT_UI8} }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - 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 = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; -} +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 * /* maxCheckStartPosition */, @@ -106,27 +71,16 @@ 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; switch(propID) { - /* - case kpidPath: - propVariant = (const wchar_t *)L"a.cpio.gz"; - break; - */ - case kpidIsFolder: - propVariant = false; - break; case kpidSize: case kpidPackedSize: - propVariant = m_Size; + prop = m_Size; break; } - propVariant.Detach(value); + prop.Detach(value); return S_OK; - COM_TRY_END } STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, @@ -149,8 +103,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(extractCallback->SetTotal(m_Size)); RINOK(extractCallback->SetCompleted(¤tTotalSize)); CMyComPtr realOutStream; - Int32 askMode; - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; Int32 index = 0; @@ -171,23 +125,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CMyComPtr copyCoder = new NCompress::CCopyCoder; - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); - try - { - RINOK(copyCoder->Code(m_InStream, realOutStream, NULL, NULL, progress)); - } - catch(...) - { - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); - return S_OK; - } + RINOK(copyCoder->Code(m_InStream, realOutStream, NULL, NULL, progress)); realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); - return S_OK; + return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK); COM_TRY_END } diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp index 7dbcee3d..6664cb07 100755 --- a/CPP/7zip/Archive/Rar/RarHandler.cpp +++ b/CPP/7zip/Archive/Rar/RarHandler.cpp @@ -42,12 +42,7 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); static const wchar_t *kUnknownOS = L"Unknown"; -enum // PropID -{ - kpidUnPackVersion = kpidUserDefined -}; - -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidIsFolder, VT_BOOL}, @@ -58,7 +53,6 @@ STATPROPSTG kProperties[] = { NULL, kpidLastAccessTime, VT_FILETIME}, { NULL, kpidAttributes, VT_UI4}, - { NULL, kpidEncrypted, VT_BOOL}, { NULL, kpidSolid, VT_BOOL}, { NULL, kpidCommented, VT_BOOL}, @@ -66,17 +60,23 @@ STATPROPSTG kProperties[] = { NULL, kpidSplitAfter, VT_BOOL}, { NULL, kpidCRC, VT_UI4}, { NULL, kpidHostOS, VT_BSTR}, - { NULL, kpidMethod, VT_BSTR} - // { NULL, kpidDictionarySize, VT_UI4}, - // { L"UnPack Version", kpidUnPackVersion, VT_UI1} + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidUnpackVer, VT_UI1} }; -STATPROPSTG kArchiveProperties[] = +STATPROPSTG kArcProps[] = { { NULL, kpidSolid, VT_BOOL}, - { NULL, kpidCommented, VT_BOOL}, + { NULL, kpidNumBlocks, VT_UI4}, + { NULL, kpidEncrypted, VT_BOOL}, + { NULL, kpidIsVolume, VT_BOOL}, + { NULL, kpidNumVolumes, VT_UI4}, + // { NULL, kpidCommented, VT_BOOL} }; +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + UInt64 CHandler::GetPackSize(int refIndex) const { const CRefItem &refItem = _refItems[refIndex]; @@ -88,56 +88,29 @@ UInt64 CHandler::GetPackSize(int refIndex) const STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; + // COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; switch(propID) { - case kpidSolid: - propVariant = _archiveInfo.IsSolid(); - break; - case kpidCommented: - propVariant = _archiveInfo.IsCommented(); + case kpidSolid: prop = _archiveInfo.IsSolid(); break; + case kpidEncrypted: prop = _archiveInfo.IsEncrypted(); break; + case kpidIsVolume: prop = _archiveInfo.IsVolume(); break; + case kpidNumBlocks: + { + UInt32 numBlocks = 0; + for (int i = 0; i < _refItems.Size(); i++) + if (!IsSolid(i)) + numBlocks++; + prop = (UInt32)numBlocks; break; - } - propVariant.Detach(value); - return S_OK; - COM_TRY_END -} - -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(kArchiveProperties) / sizeof(kArchiveProperties[0]); - return S_OK; -} + } + case kpidNumVolumes: prop = (UInt32)(_archives.Size() - 1); -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType) -{ - if(index >= sizeof(kArchiveProperties) / sizeof(kArchiveProperties[0])) - return E_INVALIDARG; - const STATPROPSTG &srcItem = kArchiveProperties[index]; - *propID = srcItem.propid; - *varType = srcItem.vt; - *name = 0; + // case kpidCommented: prop = _archiveInfo.IsCommented(); break; + } + prop.Detach(value); return S_OK; + // COM_TRY_END } STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) @@ -160,10 +133,23 @@ static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &result) return true; } +static void RarTimeToProp(const CRarTime &rarTime, NWindows::NCOM::CPropVariant &prop) +{ + FILETIME localFileTime, utcFileTime; + if (RarTimeToFileTime(rarTime, localFileTime)) + { + if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + } + else + utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; + prop = utcFileTime; +} + STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; + NWindows::NCOM::CPropVariant prop; const CRefItem &refItem = _refItems[index]; const CItemEx &item = _items[refItem.ItemIndex]; switch(propID) @@ -175,102 +161,28 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va u = item.UnicodeName; else u = MultiByteToUnicodeString(item.Name, CP_OEMCP); - propVariant = (const wchar_t *)NItemName::WinNameToOSName(u); - break; - } - case kpidIsFolder: - propVariant = item.IsDirectory(); - break; - case kpidSize: - propVariant = item.UnPackSize; - break; - case kpidPackedSize: - { - propVariant = GetPackSize(index); - break; - } - case kpidLastWriteTime: - { - FILETIME localFileTime, utcFileTime; - if (RarTimeToFileTime(item.LastWriteTime, localFileTime)) - { - if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) - utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; - } - else - utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; - propVariant = utcFileTime; - break; - } - case kpidCreationTime: - { - if (item.IsCreationTimeDefined) - { - FILETIME localFileTime, utcFileTime; - if (RarTimeToFileTime(item.CreationTime, localFileTime)) - { - if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) - utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; - } - else - utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; - propVariant = utcFileTime; - } + prop = (const wchar_t *)NItemName::WinNameToOSName(u); break; } - case kpidLastAccessTime: - { - if (item.IsLastAccessTimeDefined) - { - FILETIME localFileTime, utcFileTime; - if (RarTimeToFileTime(item.LastAccessTime, localFileTime)) - { - if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) - utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; - } - else - utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; - propVariant = utcFileTime; - } - break; - } - case kpidAttributes: - propVariant = item.GetWinAttributes(); - break; - case kpidEncrypted: - propVariant = item.IsEncrypted(); - break; - case kpidSolid: - propVariant = IsSolid(index); - break; - case kpidCommented: - propVariant = item.IsCommented(); - break; - case kpidSplitBefore: - propVariant = item.IsSplitBefore(); - break; - case kpidSplitAfter: - propVariant = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); - break; - /* - case kpidDictionarySize: - if (!item.IsDirectory()) - propVariant = UInt32(0x10000 << item.GetDictSize()); - break; - */ + case kpidIsFolder: prop = item.IsDirectory(); break; + case kpidSize: prop = item.UnPackSize; break; + case kpidPackedSize: prop = GetPackSize(index); break; + case kpidLastWriteTime: RarTimeToProp(item.LastWriteTime, prop); + case kpidCreationTime: if (item.IsCreationTimeDefined) RarTimeToProp(item.CreationTime, prop); break; + case kpidLastAccessTime: if (item.IsLastAccessTimeDefined) RarTimeToProp(item.LastAccessTime, prop); break; + case kpidAttributes: prop = item.GetWinAttributes(); break; + case kpidEncrypted: prop = item.IsEncrypted(); break; + case kpidSolid: prop = IsSolid(index); break; + case kpidCommented: prop = item.IsCommented(); break; + case kpidSplitBefore: prop = item.IsSplitBefore(); break; + case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break; case kpidCRC: { - const CItemEx &lastItem = - _items[refItem.ItemIndex + refItem.NumItems - 1]; - if (lastItem.IsSplitAfter()) - propVariant = item.FileCRC; - else - propVariant = lastItem.FileCRC; + const CItemEx &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; + prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC); break; } - case kpidUnPackVersion: - propVariant = item.UnPackVersion; - break; + case kpidUnpackVer: prop = item.UnPackVersion; break; case kpidMethod: { UString method; @@ -293,15 +205,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va ConvertUInt64ToString(item.Method, temp); method += temp; } - propVariant = method; + prop = method; break; } - case kpidHostOS: - propVariant = (item.HostOS < kNumHostOSes) ? - (kHostOS[item.HostOS]) : kUnknownOS; - break; + case kpidHostOS: prop = (item.HostOS < kNumHostOSes) ? (kHostOS[item.HostOS]) : kUnknownOS; break; } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -325,8 +234,12 @@ public: if (dotPos >= 0) { UString ext = name.Mid(dotPos + 1); - if (ext.CompareNoCase(L"RAR")==0 || - ext.CompareNoCase(L"EXE") == 0) + if (ext.CompareNoCase(L"rar") == 0) + { + _afterPart = name.Mid(dotPos); + basePart = name.Left(dotPos); + } + else if (ext.CompareNoCase(L"exe") == 0) { _afterPart = L".rar"; basePart = name.Left(dotPos); @@ -338,11 +251,11 @@ public: _afterPart.Empty(); _unchangedPart = basePart + UString(L"."); _changedPart = L"r00"; - return true;; + return true; } int numLetters = 1; - if (basePart.Right(numLetters) == L"1") + if (basePart.Right(numLetters) == L"1" || basePart.Right(numLetters) == L"0") { while (numLetters < basePart.Length()) { @@ -427,11 +340,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream, break; UString baseName; { - NCOM::CPropVariant propVariant; - RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); - if (propVariant.vt != VT_BSTR) + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + if (prop.vt != VT_BSTR) break; - baseName = propVariant.bstrVal; + baseName = prop.bstrVal; } seqName.InitName(baseName, _archiveInfo.HaveNewVolumeName()); } @@ -572,8 +485,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CObjectVector methodItems; - NCompress::CCopyCoder *copyCoderSpec = NULL; - CMyComPtr copyCoder; + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; + CMyComPtr copyCoder = copyCoderSpec; CFilterCoder *filterStreamSpec = new CFilterCoder; CMyComPtr filterStream = filterStreamSpec; @@ -586,18 +499,24 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, CFolderInStream *folderInStreamSpec = NULL; CMyComPtr folderInStream; + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + bool solidStart = true; for(int i = 0; i < importantIndexes.Size(); i++, currentImportantTotalUnPacked += currentUnPackSize, currentImportantTotalPacked += currentPackSize) { - RINOK(extractCallback->SetCompleted( - ¤tImportantTotalUnPacked)); + lps->InSize = currentImportantTotalPacked; + lps->OutSize = currentImportantTotalUnPacked; + RINOK(lps->SetCur()); CMyComPtr realOutStream; Int32 askMode; if(extractStatuses[i]) - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; else askMode = NArchive::NExtract::NAskMode::kSkip; @@ -648,9 +567,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, outStreamSpec->Init(); realOutStream.Release(); - UInt64 packedPos = currentImportantTotalPacked; - UInt64 unpackedPos = currentImportantTotalUnPacked; - /* for (int partIndex = 0; partIndex < 1; partIndex++) { @@ -672,18 +588,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, folderInStreamSpec->Init(&_archives, &_items, refItem); - - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); - - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, - &packedPos, - &unpackedPos); - UInt64 packSize = currentPackSize; // packedPos += item.PackSize; @@ -773,11 +677,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { case '0': { - if(copyCoderSpec == NULL) - { - copyCoderSpec = new NCompress::CCopyCoder; - copyCoder = copyCoderSpec; - } commonCoder = copyCoder; break; } @@ -850,8 +749,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); continue; } - HRESULT result = commonCoder->Code(inStream, outStream, - &packSize, &item.UnPackSize, compressProgress); + HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &item.UnPackSize, progress); if (item.IsEncrypted()) filterStreamSpec->ReleaseInStream(); if (result == S_FALSE) diff --git a/CPP/7zip/Archive/Rar/RarIn.cpp b/CPP/7zip/Archive/Rar/RarIn.cpp index 7340cc1f..0af72a48 100755 --- a/CPP/7zip/Archive/Rar/RarIn.cpp +++ b/CPP/7zip/Archive/Rar/RarIn.cpp @@ -439,7 +439,7 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa const UInt32 kSaltSize = 8; Byte salt[kSaltSize]; if(!ReadBytesAndTestSize(salt, kSaltSize)) - return false; + return S_FALSE; m_Position += kSaltSize; RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize)) // Password diff --git a/CPP/7zip/Archive/Rar/RarIn.h b/CPP/7zip/Archive/Rar/RarIn.h index 9cb66512..f1dee321 100755 --- a/CPP/7zip/Archive/Rar/RarIn.h +++ b/CPP/7zip/Archive/Rar/RarIn.h @@ -33,9 +33,9 @@ class CInArchiveInfo { public: UInt64 StartPosition; - WORD Flags; + UInt16 Flags; UInt64 CommentPosition; - WORD CommentSize; + UInt16 CommentSize; bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; } bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; } bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; } diff --git a/CPP/7zip/Archive/Rar/RarRegister.cpp b/CPP/7zip/Archive/Rar/RarRegister.cpp index def6e480..a79fd026 100755 --- a/CPP/7zip/Archive/Rar/RarRegister.cpp +++ b/CPP/7zip/Archive/Rar/RarRegister.cpp @@ -8,6 +8,6 @@ static IInArchive *CreateArc() { return new NArchive::NRar::CHandler; } static CArcInfo g_ArcInfo = - { L"Rar", L"rar", 0, 3, {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}, 7, false, CreateArc, 0, }; + { L"Rar", L"rar r00", 0, 3, {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}, 7, false, CreateArc, 0, }; REGISTER_ARC(Rar) diff --git a/CPP/7zip/Archive/Split/SplitHandler.cpp b/CPP/7zip/Archive/Split/SplitHandler.cpp index e919154f..0cd31639 100755 --- a/CPP/7zip/Archive/Split/SplitHandler.cpp +++ b/CPP/7zip/Archive/Split/SplitHandler.cpp @@ -23,7 +23,7 @@ using namespace NTime; namespace NArchive { namespace NSplit { -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, // { NULL, kpidIsFolder, VT_BOOL}, @@ -31,41 +31,8 @@ STATPROPSTG kProperties[] = { NULL, kpidPackedSize, VT_UI8}, }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - 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 = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; -} +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO class CSeqName { @@ -158,11 +125,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream, return S_FALSE; { - NCOM::CPropVariant propVariant; - RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); - if (propVariant.vt != VT_BSTR) + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + if (prop.vt != VT_BSTR) return S_FALSE; - _name = propVariant.bstrVal; + _name = prop.bstrVal; } int dotPos = _name.ReverseFind('.'); @@ -219,11 +186,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream, _totalSize = 0; UInt64 size; { - NCOM::CPropVariant propVariant; - RINOK(openVolumeCallback->GetProperty(kpidSize, &propVariant)); - if (propVariant.vt != VT_UI8) + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidSize, &prop)); + if (prop.vt != VT_UI8) return E_INVALIDARG; - size = propVariant.uhVal.QuadPart; + size = prop.uhVal.QuadPart; } _totalSize += size; _sizes.Add(size); @@ -247,11 +214,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream, if (!stream) break; { - NCOM::CPropVariant propVariant; - RINOK(openVolumeCallback->GetProperty(kpidSize, &propVariant)); - if (propVariant.vt != VT_UI8) + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidSize, &prop)); + if (prop.vt != VT_UI8) return E_INVALIDARG; - size = propVariant.uhVal.QuadPart; + size = prop.uhVal.QuadPart; } _totalSize += size; _sizes.Add(size); @@ -288,25 +255,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; switch(propID) { case kpidPath: - propVariant = _subName; + prop = _subName; break; case kpidIsFolder: - propVariant = false; + prop = false; break; case kpidSize: case kpidPackedSize: - propVariant = _totalSize; + prop = _totalSize; break; } - propVariant.Detach(value); + prop.Detach(value); return S_OK; - COM_TRY_END } STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, @@ -348,47 +312,28 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); return S_OK; } - // currentItemSize = itemInfo.Size; - if(!testMode && (!realOutStream)) - { + if (!testMode && (!realOutStream)) return S_OK; - } NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; CMyComPtr copyCoder = copyCoderSpec; - for(int i = 0; i < _streams.Size(); i++, currentTotalSize += currentItemSize) - { - // CMyComPtr inStream; - // RINOK(volumeExtractCallback->GetInStream(_names[i], &inStream)); + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, - ¤tTotalSize, ¤tTotalSize); + for (int i = 0; i < _streams.Size(); i++, currentTotalSize += currentItemSize) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); IInStream *inStream = _streams[i]; RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); - try - { - RINOK(copyCoder->Code(inStream, realOutStream, - NULL, NULL, compressProgress)); - } - catch(...) - { - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); - return S_OK;; - } + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); currentItemSize = copyCoderSpec->TotalSize; } realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); - return S_OK; + return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK); COM_TRY_END } diff --git a/CPP/7zip/Archive/Split/SplitHandlerOut.cpp b/CPP/7zip/Archive/Split/SplitHandlerOut.cpp index ea86c281..26e19669 100755 --- a/CPP/7zip/Archive/Split/SplitHandlerOut.cpp +++ b/CPP/7zip/Archive/Split/SplitHandlerOut.cpp @@ -48,30 +48,30 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt if (newProperties != 0) { { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(fileIndex, kpidIsFolder, &propVariant)); - if (propVariant.vt == VT_EMPTY) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(fileIndex, kpidIsFolder, &prop)); + if (prop.vt == VT_EMPTY) { } - else if (propVariant.vt != VT_BOOL) + else if (prop.vt != VT_BOOL) return E_INVALIDARG; else { - if (propVariant.boolVal != VARIANT_FALSE) + if (prop.boolVal != VARIANT_FALSE) return E_INVALIDARG; } } { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(fileIndex, kpidIsAnti, &propVariant)); - if (propVariant.vt == VT_EMPTY) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(fileIndex, kpidIsAnti, &prop)); + if (prop.vt == VT_EMPTY) { } - else if (propVariant.vt != VT_BOOL) + else if (prop.vt != VT_BOOL) return E_INVALIDARG; else { - if (propVariant.boolVal != VARIANT_FALSE) + if (prop.boolVal != VARIANT_FALSE) return E_INVALIDARG; } } @@ -80,11 +80,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt bool thereIsCopyData = false; if (newData != 0) { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(fileIndex, kpidSize, &propVariant)); - if (propVariant.vt != VT_UI8) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(fileIndex, kpidSize, &prop)); + if (prop.vt != VT_UI8) return E_INVALIDARG; - newSize = propVariant.uhVal.QuadPart; + newSize = prop.uhVal.QuadPart; } else thereIsCopyData = true; diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp index f2c83caf..d16307ca 100755 --- a/CPP/7zip/Archive/Tar/TarHandler.cpp +++ b/CPP/7zip/Archive/Tar/TarHandler.cpp @@ -1,4 +1,4 @@ -// Tar/Handler.cpp +/ Tar/Handler.cpp #include "StdAfx.h" @@ -15,6 +15,7 @@ #include "../../Common/ProgressUtils.h" #include "../../Common/LimitedStreams.h" + #include "../../Compress/Copy/CopyCoder.h" #include "../Common/ItemNameUtils.h" @@ -25,7 +26,7 @@ using namespace NTime; namespace NArchive { namespace NTar { -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidIsFolder, VT_BOOL}, @@ -36,41 +37,16 @@ STATPROPSTG kProperties[] = { NULL, kpidGroup, VT_BSTR}, }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - 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 = 0; - return S_OK; -} -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; -} + + + + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, @@ -81,7 +57,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, { CInArchive archive; - if(archive.Open(stream) != S_OK) + if (archive.Open(stream) != S_OK) return S_FALSE; _items.Clear(); @@ -120,11 +96,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream, openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); if (!openVolumeCallback) return S_FALSE; - NCOM::CPropVariant propVariant; - RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); - if (propVariant.vt != VT_BSTR) + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + if (prop.vt != VT_BSTR) return S_FALSE; - UString baseName = propVariant.bstrVal; + UString baseName = prop.bstrVal; baseName = baseName.Right(4); if (baseName.CompareNoCase(L".tar") != 0) return S_FALSE; @@ -157,45 +133,45 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; - const NArchive::NTar::CItemEx &item = _items[index]; + NWindows::NCOM::CPropVariant prop; + const CItemEx &item = _items[index]; switch(propID) { case kpidPath: - propVariant = (const wchar_t *)NItemName::GetOSName2( + prop = (const wchar_t *)NItemName::GetOSName2( MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; case kpidIsFolder: - propVariant = item.IsDirectory(); + prop = item.IsDirectory(); break; case kpidSize: case kpidPackedSize: - propVariant = (UInt64)item.Size; + prop = (UInt64)item.Size; break; case kpidLastWriteTime: { FILETIME utcFileTime; if (item.ModificationTime != 0) - NTime::UnixTimeToFileTime((UInt32)item.ModificationTime, utcFileTime); + NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime); else { utcFileTime.dwLowDateTime = 0; utcFileTime.dwHighDateTime = 0; } - propVariant = utcFileTime; + prop = utcFileTime; break; } case kpidUser: - propVariant = (const wchar_t *) + prop = (const wchar_t *) MultiByteToUnicodeString(item.UserName, CP_OEMCP); break; case kpidGroup: - propVariant = (const wchar_t *) + prop = (const wchar_t *) MultiByteToUnicodeString(item.GroupName, CP_OEMCP); break; } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -208,86 +184,61 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, bool allFilesMode = (numItems == UInt32(-1)); if (allFilesMode) numItems = _items.Size(); - UInt64 totalSize = 0; - if(numItems == 0) + if (numItems == 0) return S_OK; + UInt64 totalSize = 0; UInt32 i; - for(i = 0; i < numItems; i++) + for (i = 0; i < numItems; i++) totalSize += _items[allFilesMode ? i : indices[i]].Size; extractCallback->SetTotal(totalSize); UInt64 currentTotalSize = 0; UInt64 currentItemSize; - CMyComPtr copyCoder; + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr copyCoder = copyCoderSpec; - for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + streamSpec->SetStream(_inStream); + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) { - RINOK(extractCallback->SetCompleted(¤tTotalSize)); + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()); CMyComPtr realOutStream; - Int32 askMode; - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; Int32 index = allFilesMode ? i : indices[i]; const CItemEx &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - currentItemSize = item.Size; - - if(item.IsDirectory()) + if (item.IsDirectory()) { RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); continue; } - if(!testMode && (!realOutStream)) - { + if (!testMode && (!realOutStream)) continue; - } RINOK(extractCallback->PrepareOperation(askMode)); + if (testMode) { - if (testMode) - { - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); - continue; - } - - RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_inStream); - streamSpec->Init(item.Size); - - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); - - - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, - ¤tTotalSize, ¤tTotalSize); - - if(!copyCoder) - { - copyCoder = new NCompress::CCopyCoder; - } - try - { - RINOK(copyCoder->Code(inStream, realOutStream, - NULL, NULL, compressProgress)); - } - catch(...) - { - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); - continue; - } - realOutStream.Release(); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; } + RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); + streamSpec->Init(item.Size); + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); } return S_OK; COM_TRY_END diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp index 110833fb..ea39d7e2 100755 --- a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp +++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp @@ -53,42 +53,42 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt bool isDirectoryStatusDefined; UInt32 attributes; { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant)); - if (propVariant.vt == VT_EMPTY) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidAttributes, &prop)); + if (prop.vt == VT_EMPTY) attributes = 0; - else if (propVariant.vt != VT_UI4) + else if (prop.vt != VT_UI4) return E_INVALIDARG; else - attributes = propVariant.ulVal; + attributes = prop.ulVal; } { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant)); - if (propVariant.vt != VT_FILETIME) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &prop)); + if (prop.vt != VT_FILETIME) return E_INVALIDARG; - utcTime = propVariant.filetime; + utcTime = prop.filetime; } { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant)); - if (propVariant.vt == VT_EMPTY) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidPath, &prop)); + if (prop.vt == VT_EMPTY) name.Empty(); - else if (propVariant.vt != VT_BSTR) + else if (prop.vt != VT_BSTR) return E_INVALIDARG; else - name = propVariant.bstrVal; + name = prop.bstrVal; } { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant)); - if (propVariant.vt == VT_EMPTY) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidIsFolder, &prop)); + if (prop.vt == VT_EMPTY) isDirectoryStatusDefined = false; - else if (propVariant.vt != VT_BOOL) + else if (prop.vt != VT_BOOL) return E_INVALIDARG; else { - updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE); + updateItem.IsDirectory = (prop.boolVal != VARIANT_FALSE); isDirectoryStatusDefined = true; } } @@ -109,11 +109,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt { UInt64 size; { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); - if (propVariant.vt != VT_UI8) + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidSize, &prop)); + if (prop.vt != VT_UI8) return E_INVALIDARG; - size = propVariant.uhVal.QuadPart; + size = prop.uhVal.QuadPart; } updateItem.Size = size; } diff --git a/CPP/7zip/Archive/Tar/TarUpdate.cpp b/CPP/7zip/Archive/Tar/TarUpdate.cpp index 9a6f64e2..b4241e0d 100755 --- a/CPP/7zip/Archive/Tar/TarUpdate.cpp +++ b/CPP/7zip/Archive/Tar/TarUpdate.cpp @@ -13,23 +13,9 @@ #include "TarOut.h" #include "TarUpdate.h" -static const UInt64 kOneItemComplexity = 512; - namespace NArchive { namespace NTar { -static HRESULT CopyBlock(ISequentialInStream *inStream, - ISequentialOutStream *outStream, ICompressProgressInfo *progress, - UInt64 *totalSize = NULL) -{ - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - HRESULT result = copyCoder->Code(inStream, outStream, NULL, NULL, progress); - if (totalSize != NULL) - *totalSize = copyCoderSpec->TotalSize; - return result; -} - HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, const CObjectVector &inputItems, const CObjectVector &updateItems, @@ -48,25 +34,27 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, complexity += updateItem.Size; else complexity += inputItems[updateItem.IndexInArchive].GetFullSize(); - complexity += kOneItemComplexity; } RINOK(updateCallback->SetTotal(complexity)); + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; + CMyComPtr copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(updateCallback, true); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStreamLimited(streamSpec); + streamSpec->SetStream(inStream); + complexity = 0; for(i = 0; i < updateItems.Size(); i++) { - RINOK(updateCallback->SetCompleted(&complexity)); - - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr localProgress = localProgressSpec; - localProgressSpec->Init(updateCallback, true); - - CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; - - localCompressProgressSpec->Init(localProgress, &complexity, NULL); + lps->InSize = lps->OutSize = complexity; + RINOK(lps->SetCur()); const CUpdateItemInfo &updateItem = updateItems[i]; CItem item; @@ -76,13 +64,13 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, item.Name = (updateItem.Name); if (updateItem.IsDirectory) { - item.LinkFlag = NFileHeader::NLinkFlag::kDirectory; - item.Size = 0; + item.LinkFlag = NFileHeader::NLinkFlag::kDirectory; + item.Size = 0; } else { - item.LinkFlag = NFileHeader::NLinkFlag::kNormal; - item.Size = updateItem.Size; + item.LinkFlag = NFileHeader::NLinkFlag::kNormal; + item.Size = updateItem.Size; } item.ModificationTime = updateItem.Time; item.DeviceMajorDefined = false; @@ -118,45 +106,40 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, RINOK(outArchive.WriteHeader(item)); if (!updateItem.IsDirectory) { - UInt64 totalSize; - RINOK(CopyBlock(fileInStream, outStream, compressProgress, &totalSize)); - if (totalSize != item.Size) + RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress)); + if (copyCoderSpec->TotalSize != item.Size) return E_FAIL; RINOK(outArchive.FillDataResidual(item.Size)); } } complexity += updateItem.Size; - RINOK(updateCallback->SetOperationResult( - NArchive::NUpdate::NOperationResult::kOK)); + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); } else { - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStreamLimited(streamSpec); const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; + UInt64 size; if (updateItem.NewProperties) { RINOK(outArchive.WriteHeader(item)); - RINOK(inStream->Seek(existItemInfo.GetDataPosition(), - STREAM_SEEK_SET, NULL)); - streamSpec->SetStream(inStream); - streamSpec->Init(existItemInfo.Size); + RINOK(inStream->Seek(existItemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL)); + size = existItemInfo.Size; } else { - RINOK(inStream->Seek(existItemInfo.HeaderPosition, - STREAM_SEEK_SET, NULL)); - streamSpec->SetStream(inStream); - streamSpec->Init(existItemInfo.GetFullSize()); + RINOK(inStream->Seek(existItemInfo.HeaderPosition, STREAM_SEEK_SET, NULL)); + size = existItemInfo.GetFullSize(); } - RINOK(CopyBlock(inStreamLimited, outStream, compressProgress)); + streamSpec->Init(size); + + RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); + if (copyCoderSpec->TotalSize != size) + return E_FAIL; RINOK(outArchive.FillDataResidual(existItemInfo.Size)); - complexity += existItemInfo.GetFullSize(); + complexity += size; } - complexity += kOneItemComplexity; } return outArchive.WriteFinishHeader(); } }} - diff --git a/CPP/7zip/Archive/Wim/WimHandler.cpp b/CPP/7zip/Archive/Wim/WimHandler.cpp index aa9300a2..38c1c6ae 100755 --- a/CPP/7zip/Archive/Wim/WimHandler.cpp +++ b/CPP/7zip/Archive/Wim/WimHandler.cpp @@ -20,18 +20,7 @@ namespace NWim { #define WIM_DETAILS -#ifdef WIM_DETAILS - -enum -{ - kpidVolume = kpidUserDefined, - kpidOffset, - kpidLinks -}; - -#endif - -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidIsFolder, VT_BOOL}, @@ -44,59 +33,63 @@ STATPROPSTG kProperties[] = { NULL, kpidLastWriteTime, VT_FILETIME} #ifdef WIM_DETAILS - , { L"Volume", kpidVolume, VT_UI4} - , { L"Offset", kpidOffset, VT_UI8} - , { L"Links", kpidLinks, VT_UI4} + , { NULL, kpidVolume, VT_UI4} + , { NULL, kpidOffset, VT_UI8} + , { NULL, kpidLinks, VT_UI4} #endif }; +STATPROPSTG kArcProps[] = +{ + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidIsVolume, VT_BOOL}, + { NULL, kpidVolume, VT_UI4}, + { NULL, kpidNumVolumes, VT_UI4} +}; + static const wchar_t *kStreamsNamePrefix = L"Files" WSTRING_PATH_SEPARATOR; static const wchar_t *kMethodLZX = L"LZX"; static const wchar_t *kMethodCopy = L"Copy"; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - 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; - if (srcItem.lpwstrName == 0) - *name = 0; - else - *name = ::SysAllocString(srcItem.lpwstrName); - return S_OK; -} +IMP_IInArchive_Props +IMP_IInArchive_ArcProps -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { - *numProperties = 0; + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidSize: prop = m_Database.GetUnpackSize(); break; + case kpidPackedSize: prop = m_Database.GetPackSize(); break; + case kpidIsVolume: + if (m_Xmls.Size() > 0) + { + UInt16 volIndex = m_Xmls[0].VolIndex; + if (volIndex < m_Volumes.Size()) + prop = (m_Volumes[volIndex].Header.NumParts > 1); + } + break; + case kpidVolume: + if (m_Xmls.Size() > 0) + { + UInt16 volIndex = m_Xmls[0].VolIndex; + if (volIndex < m_Volumes.Size()) + prop = m_Volumes[volIndex].Header.PartNumber; + } + break; + case kpidNumVolumes: if (m_Volumes.Size() > 0) prop = (UInt32)(m_Volumes.Size() - 1); + } + prop.Detach(value); return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; + COM_TRY_END } STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; + NWindows::NCOM::CPropVariant prop; if (index < (UInt32)m_Database.Items.Size()) { const CItem &item = m_Database.Items[index]; @@ -108,7 +101,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val { case kpidPath: if (item.HasMetadata) - propVariant = item.Name; + prop = item.Name; else { wchar_t sz[32]; @@ -117,62 +110,62 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val while (s.Length() < m_NameLenForStreams) s = L'0' + s; s = UString(kStreamsNamePrefix) + s; - propVariant = s; + prop = s; break; } break; case kpidIsFolder: - propVariant = item.IsDirectory(); + prop = item.IsDirectory(); break; case kpidAttributes: if (item.HasMetadata) - propVariant = item.Attributes; + prop = item.Attributes; break; case kpidCreationTime: if (item.HasMetadata) - propVariant = item.CreationTime; + prop = item.CreationTime; break; case kpidLastAccessTime: if (item.HasMetadata) - propVariant = item.LastAccessTime; + prop = item.LastAccessTime; break; case kpidLastWriteTime: if (item.HasMetadata) - propVariant = item.LastWriteTime; + prop = item.LastWriteTime; break; case kpidPackedSize: if (si) - propVariant = si->Resource.PackSize; + prop = si->Resource.PackSize; else - propVariant = (UInt64)0; + prop = (UInt64)0; break; case kpidSize: if (si) - propVariant = si->Resource.UnpackSize; + prop = si->Resource.UnpackSize; else - propVariant = (UInt64)0; + prop = (UInt64)0; break; case kpidMethod: if (si) if (si->Resource.IsCompressed()) - propVariant = kMethodLZX; + prop = kMethodLZX; else - propVariant = kMethodCopy; + prop = kMethodCopy; break; #ifdef WIM_DETAILS case kpidVolume: if (si) - propVariant = (UInt32)si->PartNumber; + prop = (UInt32)si->PartNumber; break; case kpidOffset: if (si) - propVariant = (UInt64)si->Resource.Offset; + prop = (UInt64)si->Resource.Offset; break; case kpidLinks: if (si) - propVariant = (UInt32)si->RefCount; + prop = (UInt32)si->RefCount; else - propVariant = (UInt64)0; + prop = (UInt64)0; break; #endif } @@ -188,23 +181,23 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val wchar_t sz[32]; ConvertUInt64ToString(m_Xmls[index].VolIndex, sz); UString s = (UString)sz + L".xml"; - propVariant = s; + prop = s; break; } case kpidIsFolder: - propVariant = false; + prop = false; break; case kpidPackedSize: case kpidSize: - propVariant = (UInt64)m_Xmls[index].Data.GetCapacity(); + prop = (UInt64)m_Xmls[index].Data.GetCapacity(); break; case kpidMethod: - propVariant = L"Copy"; + prop = L"Copy"; break; } } } - propVariant.Detach(value); + prop.Detach(value); return S_OK; COM_TRY_END } @@ -317,11 +310,11 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, break; numVolumes = header.NumParts; { - NCOM::CPropVariant propVariant; - RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); - if (propVariant.vt != VT_BSTR) + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); + if (prop.vt != VT_BSTR) break; - seqName.InitName(propVariant.bstrVal); + seqName.InitName(prop.bstrVal); } } } @@ -381,29 +374,33 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(extractCallback->SetTotal(totalSize)); - UInt64 currentTotalSize = 0; - UInt64 currentItemSize = 0; - + UInt64 currentTotalPacked = 0; + UInt64 currentTotalUnPacked = 0; + UInt64 currentItemUnPacked, currentItemPacked; + int prevSuccessStreamIndex = -1; CUnpacker unpacker; - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); - - CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); - for (i = 0; i < numItems; currentTotalSize += currentItemSize) + for (i = 0; i < numItems; currentTotalUnPacked += currentItemUnPacked, + currentTotalPacked += currentItemPacked) { - currentItemSize = 0; - RINOK(extractCallback->SetCompleted(¤tTotalSize)); + currentItemUnPacked = 0; + currentItemPacked = 0; + + lps->InSize = currentTotalPacked; + lps->OutSize = currentTotalUnPacked; + + RINOK(lps->SetCur()); UInt32 index = allFilesMode ? i : indices[i]; i++; Int32 askMode = testMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; CMyComPtr realOutStream; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -413,13 +410,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, continue; RINOK(extractCallback->PrepareOperation(askMode)); const CByteBuffer &data = m_Xmls[index - (UInt32)m_Database.Items.Size()].Data; - currentItemSize = data.GetCapacity(); + currentItemUnPacked = data.GetCapacity(); if (realOutStream) { RINOK(WriteStream(realOutStream, (const Byte *)data, (UInt32)data.GetCapacity(), NULL)); realOutStream.Release(); } - RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); continue; } @@ -432,32 +429,32 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(extractCallback->PrepareOperation(askMode)); realOutStream.Release(); RINOK(extractCallback->SetOperationResult(item.HasStream() ? - NArchive::NExtract::NOperationResult::kDataError : - NArchive::NExtract::NOperationResult::kOK)); + NExtract::NOperationResult::kDataError : + NExtract::NOperationResult::kOK)); continue; } const CStreamInfo &si = m_Database.Streams[streamIndex]; - currentItemSize = si.Resource.UnpackSize; + currentItemUnPacked = si.Resource.UnpackSize; + currentItemPacked = si.Resource.PackSize; if(!testMode && (!realOutStream)) continue; RINOK(extractCallback->PrepareOperation(askMode)); - Int32 opRes = NArchive::NExtract::NOperationResult::kOK; + Int32 opRes = NExtract::NOperationResult::kOK; if (streamIndex != prevSuccessStreamIndex || realOutStream) { Byte digest[20]; - localCompressProgressSpec->Init(progress, ¤tTotalSize, ¤tTotalSize); - HRESULT res = unpacker.Unpack(m_Volumes[si.PartNumber].Stream, si.Resource, realOutStream, compressProgress, digest); + HRESULT res = unpacker.Unpack(m_Volumes[si.PartNumber].Stream, si.Resource, realOutStream, progress, digest); if (res == S_OK) { if (memcmp(digest, si.Hash, kHashSize) == 0) prevSuccessStreamIndex = streamIndex; else - opRes = NArchive::NExtract::NOperationResult::kCRCError; + opRes = NExtract::NOperationResult::kCRCError; } else if (res == S_FALSE) - opRes = NArchive::NExtract::NOperationResult::kDataError; + opRes = NExtract::NOperationResult::kDataError; else return res; } diff --git a/CPP/7zip/Archive/Wim/WimIn.h b/CPP/7zip/Archive/Wim/WimIn.h index bc74f61b..467b99ae 100755 --- a/CPP/7zip/Archive/Wim/WimIn.h +++ b/CPP/7zip/Archive/Wim/WimIn.h @@ -107,6 +107,23 @@ struct CDatabase { CRecordVector Streams; CObjectVector Items; + + UInt64 GetUnpackSize() const + { + UInt64 res = 0; + for (int i = 0; i < Streams.Size(); i++) + res += Streams[i].Resource.UnpackSize; + return res; + } + + UInt64 GetPackSize() const + { + UInt64 res = 0; + for (int i = 0; i < Streams.Size(); i++) + res += Streams[i].Resource.PackSize; + return res; + } + void Clear() { Streams.Clear(); diff --git a/CPP/7zip/Archive/Z/DllExports.cpp b/CPP/7zip/Archive/Z/DllExports.cpp deleted file mode 100755 index b8df85f4..00000000 --- a/CPP/7zip/Archive/Z/DllExports.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// DLLExports.cpp - -#include "StdAfx.h" - -#include "Common/MyInitGuid.h" -#include "Common/ComTry.h" -#include "Windows/PropVariant.h" -#include "ZHandler.h" -#include "../../ICoder.h" - -// {23170F69-40C1-278A-1000-000110050000} -DEFINE_GUID(CLSID_CZHandler, -0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00); - -extern "C" -BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */) -{ - return TRUE; -} - -STDAPI CreateObject( - const GUID *classID, - const GUID *interfaceID, - void **outObject) -{ - COM_TRY_BEGIN - *outObject = 0; - if (*classID != CLSID_CZHandler) - return CLASS_E_CLASSNOTAVAILABLE; - int needIn = *interfaceID == IID_IInArchive; - int needOut = *interfaceID == IID_IOutArchive; - if (needIn || needOut) - { - NArchive::NZ::CHandler *temp = new NArchive::NZ::CHandler; - if (needIn) - { - CMyComPtr inArchive = (IInArchive *)temp; - *outObject = inArchive.Detach(); - } - else - { - CMyComPtr outArchive = (IOutArchive *)temp; - *outObject = outArchive.Detach(); - } - } - else - return E_NOINTERFACE; - COM_TRY_END - return S_OK; -} - - -STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) -{ - NWindows::NCOM::CPropVariant propVariant; - switch(propID) - { - case NArchive::kName: - propVariant = L"Z"; - break; - case NArchive::kClassID: - { - if ((value->bstrVal = ::SysAllocStringByteLen( - (const char *)&CLSID_CZHandler, sizeof(GUID))) != 0) - value->vt = VT_BSTR; - return S_OK; - } - case NArchive::kExtension: - propVariant = L"z taz"; - break; - case NArchive::kAddExtension: - propVariant = L"* .tar"; - break; - case NArchive::kUpdate: - propVariant = false; - break; - case NArchive::kKeepName: - propVariant = true; - break; - case NArchive::kStartSignature: - { - const unsigned char sig[] = { 0x1F, 0x9D }; - if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0) - value->vt = VT_BSTR; - return S_OK; - } - - } - propVariant.Detach(value); - return S_OK; -} diff --git a/CPP/7zip/Archive/Z/ZHandler.cpp b/CPP/7zip/Archive/Z/ZHandler.cpp index 33887690..73f391f7 100755 --- a/CPP/7zip/Archive/Z/ZHandler.cpp +++ b/CPP/7zip/Archive/Z/ZHandler.cpp @@ -19,47 +19,13 @@ namespace NArchive { namespace NZ { -STATPROPSTG kProperties[] = +STATPROPSTG kProps[] = { - { NULL, kpidPath, VT_BSTR}, { NULL, kpidPackedSize, VT_UI8}, }; -STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) -{ - value->vt = VT_EMPTY; - 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 = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_INVALIDARG; -} +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { @@ -67,24 +33,15 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) return S_OK; } -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) { - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant propVariant; - if (index != 0) - return E_INVALIDARG; + NWindows::NCOM::CPropVariant prop; switch(propID) { - case kpidIsFolder: - propVariant = false; - break; - case kpidPackedSize: - propVariant = _packSize; - break; + case kpidPackedSize: prop = _packSize; break; } - propVariant.Detach(value); + prop.Detach(value); return S_OK; - COM_TRY_END } static const int kSignatureSize = 3; @@ -151,26 +108,26 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, RINOK(extractCallback->SetCompleted(¤tTotalPacked)); CMyComPtr realOutStream; - Int32 askMode; - askMode = testMode ? NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); - if(!testMode && !realOutStream) + if (!testMode && !realOutStream) return S_OK; extractCallback->PrepareOperation(askMode); CDummyOutStream *outStreamSpec = new CDummyOutStream; CMyComPtr outStream(outStreamSpec); - outStreamSpec->Init(realOutStream); - + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); realOutStream.Release(); - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr progress = localProgressSpec; - localProgressSpec->Init(extractCallback, true); + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); RINOK(_stream->Seek(_streamStartPosition + kSignatureSize, STREAM_SEEK_SET, NULL)); @@ -182,20 +139,20 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, int opResult; if (result != S_OK) - opResult = NArchive::NExtract::NOperationResult::kUnSupportedMethod; + opResult = NExtract::NOperationResult::kUnSupportedMethod; else { result = decoder->Code(_stream, outStream, NULL, NULL, progress); - outStream.Release(); if (result == S_FALSE) - opResult = NArchive::NExtract::NOperationResult::kDataError; - else if (result == S_OK) - opResult = NArchive::NExtract::NOperationResult::kOK; + opResult = NExtract::NOperationResult::kDataError; else - return result; + { + RINOK(result); + opResult = NExtract::NOperationResult::kOK; + } } - RINOK(extractCallback->SetOperationResult(opResult)); - return S_OK; + outStream.Release(); + return extractCallback->SetOperationResult(opResult); COM_TRY_END } 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 progress = localProgressSpec; - CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; + CLocalProgress *lps = new CLocalProgress; + CMyComPtr 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 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)) 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 Progress; + CMyComPtr 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 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 localProgress = localProgressSpec; - localProgressSpec->Init(updateCallback, true); - - CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; - CMyComPtr compressProgress = localCompressProgressSpec; + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(updateCallback, true); CAddCommon compressor(*options); CObjectVector 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 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 items; - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr localProgress = localProgressSpec; - localProgressSpec->Init(updateCallback, true); + CMtProgressMixer *mtProgressMixerSpec = new CMtProgressMixer; + CMyComPtr 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 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 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); -- cgit v1.2.3