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

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2009-06-02 04:00:00 +0400
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:59 +0300
commit829409452d85cd6dd9dfc9151f109d6e13a2bb1c (patch)
treee0acaea47044d167f35fa197584dee1bde41c329 /CPP/7zip/UI/Common
parent8874e4fbc9faabdcff719b9b2ac8ebad4f282bbe (diff)
9.04 beta
Diffstat (limited to 'CPP/7zip/UI/Common')
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveCommandLine.cpp95
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveCommandLine.h1
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveExtractCallback.cpp180
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveExtractCallback.h106
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveName.cpp18
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveOpenCallback.cpp7
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveOpenCallback.h8
-rwxr-xr-xCPP/7zip/UI/Common/CompressCall.cpp30
-rwxr-xr-xCPP/7zip/UI/Common/DirItem.h3
-rwxr-xr-xCPP/7zip/UI/Common/EnumDirItems.cpp12
-rwxr-xr-xCPP/7zip/UI/Common/Extract.cpp167
-rwxr-xr-xCPP/7zip/UI/Common/Extract.h29
-rwxr-xr-xCPP/7zip/UI/Common/ExtractingFilePath.cpp43
-rwxr-xr-xCPP/7zip/UI/Common/ExtractingFilePath.h7
-rwxr-xr-xCPP/7zip/UI/Common/LoadCodecs.cpp31
-rwxr-xr-xCPP/7zip/UI/Common/OpenArchive.cpp566
-rwxr-xr-xCPP/7zip/UI/Common/OpenArchive.h137
-rwxr-xr-xCPP/7zip/UI/Common/PropIDUtils.cpp87
-rwxr-xr-xCPP/7zip/UI/Common/PropIDUtils.h6
-rwxr-xr-xCPP/7zip/UI/Common/Update.cpp87
-rwxr-xr-xCPP/7zip/UI/Common/UpdateCallback.cpp21
-rwxr-xr-xCPP/7zip/UI/Common/UpdateCallback.h6
-rwxr-xr-xCPP/7zip/UI/Common/UpdatePair.cpp17
-rwxr-xr-xCPP/7zip/UI/Common/ZipRegistry.cpp8
24 files changed, 867 insertions, 805 deletions
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
index 46e8a2a1..96d47c08 100755
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -11,18 +11,18 @@
#include "Common/StringConvert.h"
#include "Common/StringToInt.h"
-#include "Windows/FileName.h"
#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
#ifdef _WIN32
#include "Windows/FileMapping.h"
#include "Windows/Synchronization.h"
#endif
#include "ArchiveCommandLine.h"
-#include "UpdateAction.h"
-#include "Update.h"
-#include "SortUtils.h"
#include "EnumDirItems.h"
+#include "SortUtils.h"
+#include "Update.h"
+#include "UpdateAction.h"
extern bool g_CaseSensitive;
@@ -38,6 +38,8 @@ using namespace NCommandLineParser;
using namespace NWindows;
using namespace NFile;
+int g_CodePage = -1;
+
namespace NKey {
enum Enum
{
@@ -69,10 +71,12 @@ enum Enum
kEmail,
kShowDialog,
kLargePages,
- kCharSet,
+ kListfileCharSet,
+ kConsoleCharSet,
kTechMode,
kShareForWrite,
- kCaseSensitive
+ kCaseSensitive,
+ kCalcCrc,
};
}
@@ -137,9 +141,11 @@ static const CSwitchForm kSwitchForms[] =
{ L"AD", NSwitchType::kSimple, false },
{ L"SLP", NSwitchType::kUnLimitedPostString, false, 0},
{ L"SCS", NSwitchType::kUnLimitedPostString, false, 0},
+ { L"SCC", NSwitchType::kUnLimitedPostString, false, 0},
{ L"SLT", NSwitchType::kSimple, false },
{ L"SSW", NSwitchType::kSimple, false },
- { L"SSC", NSwitchType::kPostChar, false, 0, 0, L"-" }
+ { L"SSC", NSwitchType::kPostChar, false, 0, 0, L"-" },
+ { L"SCRC", NSwitchType::kSimple, false }
};
static const CCommandForm g_CommandForms[] =
@@ -412,9 +418,9 @@ static void ConvertToLongName(const UString &prefix, UString &name)
{
if (name.IsEmpty() || DoesNameContainWildCard(name))
return;
- NFind::CFileInfoW fileInfo;
- if (NFind::FindFile(prefix + name, fileInfo))
- name = fileInfo.Name;
+ NFind::CFileInfoW fi;
+ if (fi.Find(prefix + name))
+ name = fi.Name;
}
static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
@@ -698,6 +704,7 @@ void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings,
options.IsInTerminal = MY_IS_TERMINAL(stdin);
options.IsStdOutTerminal = MY_IS_TERMINAL(stdout);
options.IsStdErrTerminal = MY_IS_TERMINAL(stderr);
+ options.StdInMode = parser[NKey::kStdIn].ThereIs;
options.StdOutMode = parser[NKey::kStdOut].ThereIs;
options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs;
options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs || parser[NKey::kHelp3].ThereIs;
@@ -722,11 +729,28 @@ struct CCodePagePair
static CCodePagePair g_CodePagePairs[] =
{
{ L"UTF-8", CP_UTF8 },
- { L"WIN", CP_ACP },
- { L"DOS", CP_OEMCP }
+ { L"WIN", CP_ACP },
+ { L"DOS", CP_OEMCP }
};
-static const int kNumCodePages = sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]);
+static int FindCharset(const NCommandLineParser::CParser &parser, int keyIndex, int defaultVal)
+{
+ if (!parser[keyIndex].ThereIs)
+ return defaultVal;
+
+ UString name = parser[keyIndex].PostStrings.Back();
+ name.MakeUpper();
+ int i;
+ for (i = 0; i < sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]); i++)
+ {
+ const CCodePagePair &pair = g_CodePagePairs[i];
+ if (name.Compare(pair.Name) == 0)
+ return pair.CodePage;
+ }
+ if (i == sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]))
+ ThrowUserErrorException();
+ return -1;
+}
static bool ConvertStringToUInt32(const wchar_t *s, UInt32 &v)
{
@@ -751,6 +775,7 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
ThrowUserErrorException();
options.TechMode = parser[NKey::kTechMode].ThereIs;
+ options.CalcCrc = parser[NKey::kCalcCrc].ThereIs;
if (parser[NKey::kCaseSensitive].ThereIs)
g_CaseSensitive = (parser[NKey::kCaseSensitive].PostCharIndex < 0);
@@ -761,24 +786,8 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
else
recursedType = NRecursedType::kNonRecursed;
- UINT codePage = CP_UTF8;
- if (parser[NKey::kCharSet].ThereIs)
- {
- UString name = parser[NKey::kCharSet].PostStrings.Front();
- name.MakeUpper();
- int i;
- for (i = 0; i < kNumCodePages; i++)
- {
- const CCodePagePair &pair = g_CodePagePairs[i];
- if (name.Compare(pair.Name) == 0)
- {
- codePage = pair.CodePage;
- break;
- }
- }
- if (i >= kNumCodePages)
- ThrowUserErrorException();
- }
+ g_CodePage = FindCharset(parser, NKey::kConsoleCharSet, -1);
+ UINT codePage = FindCharset(parser, NKey::kListfileCharSet, CP_UTF8);
bool thereAreSwitchIncludes = false;
if (parser[NKey::kInclude].ThereIs)
@@ -795,6 +804,13 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs &&
options.Command.CommandType != NCommandType::kBenchmark &&
options.Command.CommandType != NCommandType::kInfo;
+
+ bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
+ bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList;
+
+ if (isExtractOrList && options.StdInMode)
+ thereIsArchiveName = false;
+
if (thereIsArchiveName)
{
if (curCommandIndex >= numNonSwitchStrings)
@@ -808,7 +824,6 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
options.YesToAll = parser[NKey::kYes].ThereIs;
- bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
#ifndef _NO_CRYPTO
options.PasswordEnabled = parser[NKey::kPassword].ThereIs;
@@ -816,16 +831,13 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
options.Password = parser[NKey::kPassword].PostStrings[0];
#endif
- options.StdInMode = parser[NKey::kStdIn].ThereIs;
options.ShowDialog = parser[NKey::kShowDialog].ThereIs;
if (parser[NKey::kArchiveType].ThereIs)
options.ArcType = parser[NKey::kArchiveType].PostStrings[0];
- if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
+ if (isExtractOrList)
{
- if (options.StdInMode)
- ThrowException("Reading archives from stdin is not implemented");
if (!options.WildcardCensor.AllAreRelative())
ThrowException("Cannot use absolute pathnames for this command");
@@ -849,6 +861,15 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
archiveWildcardCensor.ExtendExclude();
+ if (options.StdInMode)
+ {
+ UString arcName = parser[NKey::kStdIn].PostStrings.Front();
+ options.ArchivePathsSorted.Add(arcName);
+ options.ArchivePathsFullSorted.Add(arcName);
+ }
+ else
+ {
+
UStringVector archivePaths;
{
@@ -889,6 +910,8 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
options.ArchivePathsSorted.Add(archivePaths[indices[i]]);
options.ArchivePathsFullSorted.Add(archivePathsFull[indices[i]]);
}
+
+ }
if (isExtractGroupCommand)
{
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h
index 9c37f336..6f79b7ee 100755
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.h
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h
@@ -73,6 +73,7 @@ struct CArchiveCommandLineOptions
bool TechMode;
// Extract
+ bool CalcCrc;
bool AppendName;
UString OutputDir;
NExtract::NOverwriteMode::EEnum OverwriteMode;
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
index 5af5286b..4c0cc90b 100755
--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
@@ -2,24 +2,19 @@
#include "StdAfx.h"
-#include "ArchiveExtractCallback.h"
-
-#include "Common/Wildcard.h"
-#include "Common/StringConvert.h"
#include "Common/ComTry.h"
+#include "Common/Wildcard.h"
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
-#include "Windows/Time.h"
-#include "Windows/Defs.h"
#include "Windows/PropVariant.h"
-
#include "Windows/PropVariantConversions.h"
#include "../../Common/FilePathAutoRename.h"
#include "../Common/ExtractingFilePath.h"
-#include "OpenArchive.h"
+
+#include "ArchiveExtractCallback.h"
using namespace NWindows;
@@ -27,20 +22,20 @@ static const wchar_t *kCantAutoRename = L"ERROR: Can not create file with auto n
static const wchar_t *kCantRenameFile = L"ERROR: Can not rename existing file ";
static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
-
void CArchiveExtractCallback::Init(
- IInArchive *archiveHandler,
+ const NWildcard::CCensorNode *wildcardCensor,
+ const CArc *arc,
IFolderArchiveExtractCallback *extractCallback2,
- bool stdOutMode,
+ bool stdOutMode, bool testMode, bool crcMode,
const UString &directoryPath,
const UStringVector &removePathParts,
- const UString &itemDefaultName,
- const FILETIME &utcMTimeDefault,
- UInt32 attributesDefault,
UInt64 packSize)
{
+ _wildcardCensor = wildcardCensor;
+
_stdOutMode = stdOutMode;
- _numErrors = 0;
+ _testMode = testMode;
+ _crcMode = crcMode;
_unpTotal = 1;
_packTotal = packSize;
@@ -51,11 +46,9 @@ void CArchiveExtractCallback::Init(
LocalProgressSpec->Init(extractCallback2, true);
LocalProgressSpec->SendProgress = false;
- _itemDefaultName = itemDefaultName;
- _utcMTimeDefault = utcMTimeDefault;
- _attributesDefault = attributesDefault;
+
_removePathParts = removePathParts;
- _archiveHandler = archiveHandler;
+ _arc = arc;
_directoryPath = directoryPath;
NFile::NName::NormalizeDirPathPrefix(_directoryPath);
}
@@ -117,7 +110,7 @@ STDMETHODIMP CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const U
void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath)
{
fullPath = _directoryPath;
- for(int i = 0; i < dirPathParts.Size(); i++)
+ for (int i = 0; i < dirPathParts.Size(); i++)
{
if (i > 0)
fullPath += wchar_t(NFile::NName::kDirDelimiter);
@@ -126,24 +119,11 @@ void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPat
}
}
-static UString MakePathNameFromParts(const UStringVector &parts)
-{
- UString result;
- for(int i = 0; i < parts.Size(); i++)
- {
- if(i != 0)
- result += wchar_t(NFile::NName::kDirDelimiter);
- result += parts[i];
- }
- return result;
-}
-
-
HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)
{
filetimeIsDefined = false;
NCOM::CPropVariant prop;
- RINOK(_archiveHandler->GetProperty(index, propID, &prop));
+ RINOK(_arc->Archive->GetProperty(index, propID, &prop));
if (prop.vt == VT_FILETIME)
{
filetime = prop.filetime;
@@ -154,26 +134,40 @@ HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &fil
return S_OK;
}
+HRESULT CArchiveExtractCallback::GetUnpackSize()
+{
+ NCOM::CPropVariant prop;
+ RINOK(_arc->Archive->GetProperty(_index, kpidSize, &prop));
+ _curSizeDefined = (prop.vt != VT_EMPTY);
+ if (_curSizeDefined)
+ _curSize = ConvertPropVariantToUInt64(prop);
+ return S_OK;
+}
+
STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
{
COM_TRY_BEGIN
+ _crcStream.Release();
*outStream = 0;
_outFileStream.Release();
_encrypted = false;
_isSplit = false;
_curSize = 0;
+ _curSizeDefined = false;
+ _index = index;
UString fullPath;
- RINOK(GetArchiveItemPath(_archiveHandler, index, _itemDefaultName, fullPath));
- RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDir));
+ IInArchive *archive = _arc->Archive;
+ RINOK(_arc->GetItemPath(index, fullPath));
+ RINOK(IsArchiveItemFolder(archive, index, _fi.IsDir));
_filePath = fullPath;
{
NCOM::CPropVariant prop;
- RINOK(_archiveHandler->GetProperty(index, kpidPosition, &prop));
+ RINOK(archive->GetProperty(index, kpidPosition, &prop));
if (prop.vt != VT_EMPTY)
{
if (prop.vt != VT_UI8)
@@ -183,22 +177,17 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
}
}
- RINOK(IsArchiveItemProp(_archiveHandler, index, kpidEncrypted, _encrypted));
+ RINOK(GetArchiveItemBoolProp(archive, index, kpidEncrypted, _encrypted));
+
+ RINOK(GetUnpackSize());
- bool newFileSizeDefined;
- UInt64 newFileSize;
+ if (_wildcardCensor)
{
- NCOM::CPropVariant prop;
- RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));
- newFileSizeDefined = (prop.vt != VT_EMPTY);
- if (newFileSizeDefined)
- {
- newFileSize = ConvertPropVariantToUInt64(prop);
- _curSize = newFileSize;
- }
+ if (!_wildcardCensor->CheckPath(fullPath, !_fi.IsDir))
+ return S_OK;
}
- if(askExtractMode == NArchive::NExtract::NAskMode::kExtract)
+ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
{
if (_stdOutMode)
{
@@ -209,32 +198,29 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
{
NCOM::CPropVariant prop;
- RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop));
- if (prop.vt == VT_EMPTY)
+ RINOK(archive->GetProperty(index, kpidAttrib, &prop));
+ if (prop.vt == VT_UI4)
{
- _processedFileInfo.Attributes = _attributesDefault;
- _processedFileInfo.AttributesAreDefined = false;
+ _fi.Attrib = prop.ulVal;
+ _fi.AttribDefined = true;
}
+ else if (prop.vt == VT_EMPTY)
+ _fi.AttribDefined = false;
else
- {
- if (prop.vt != VT_UI4)
- return E_FAIL;
- _processedFileInfo.Attributes = prop.ulVal;
- _processedFileInfo.AttributesAreDefined = true;
- }
+ return E_FAIL;
}
- RINOK(GetTime(index, kpidCTime, _processedFileInfo.CTime, _processedFileInfo.CTimeDefined));
- RINOK(GetTime(index, kpidATime, _processedFileInfo.ATime, _processedFileInfo.ATimeDefined));
- RINOK(GetTime(index, kpidMTime, _processedFileInfo.MTime, _processedFileInfo.MTimeDefined));
+ RINOK(GetTime(index, kpidCTime, _fi.CTime, _fi.CTimeDefined));
+ RINOK(GetTime(index, kpidATime, _fi.ATime, _fi.ATimeDefined));
+ RINOK(GetTime(index, kpidMTime, _fi.MTime, _fi.MTimeDefined));
bool isAnti = false;
- RINOK(IsArchiveItemProp(_archiveHandler, index, kpidIsAnti, isAnti));
+ RINOK(_arc->IsItemAnti(index, isAnti));
UStringVector pathParts;
SplitPathToParts(fullPath, pathParts);
- if(pathParts.IsEmpty())
+ if (pathParts.IsEmpty())
return E_FAIL;
int numRemovePathParts = 0;
switch(_pathMode)
@@ -262,7 +248,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
UString processedPath = MakePathNameFromParts(pathParts);
if (!isAnti)
{
- if (!_processedFileInfo.IsDir)
+ if (!_fi.IsDir)
{
if (!pathParts.IsEmpty())
pathParts.DeleteBack();
@@ -272,18 +258,18 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
{
UString fullPathNew;
CreateComplexDirectory(pathParts, fullPathNew);
- if (_processedFileInfo.IsDir)
+ if (_fi.IsDir)
NFile::NDirectory::SetDirTime(fullPathNew,
- (WriteCTime && _processedFileInfo.CTimeDefined) ? &_processedFileInfo.CTime : NULL,
- (WriteATime && _processedFileInfo.ATimeDefined) ? &_processedFileInfo.ATime : NULL,
- (WriteMTime && _processedFileInfo.MTimeDefined) ? &_processedFileInfo.MTime : &_utcMTimeDefault);
+ (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
+ (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
+ (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
}
}
UString fullProcessedPath = _directoryPath + processedPath;
- if(_processedFileInfo.IsDir)
+ if (_fi.IsDir)
{
_diskFilePath = fullProcessedPath;
if (isAnti)
@@ -294,7 +280,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
if (!_isSplit)
{
NFile::NFind::CFileInfoW fileInfo;
- if(NFile::NFind::FindFile(fullProcessedPath, fileInfo))
+ if (fileInfo.Find(fullProcessedPath))
{
switch(_overwriteMode)
{
@@ -305,8 +291,8 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
Int32 overwiteResult;
RINOK(_extractCallback2->AskOverwrite(
fullProcessedPath, &fileInfo.MTime, &fileInfo.Size, fullPath,
- _processedFileInfo.MTimeDefined ? &_processedFileInfo.MTime : NULL,
- newFileSizeDefined ? &newFileSize : NULL,
+ _fi.MTimeDefined ? &_fi.MTime : NULL,
+ _curSizeDefined ? &_curSize : NULL,
&overwiteResult))
switch(overwiteResult)
@@ -349,7 +335,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
RINOK(_extractCallback2->MessageError(message));
return E_FAIL;
}
- if(!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath))
+ if (!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath))
{
UString message = UString(kCantRenameFile) + fullProcessedPath;
RINOK(_extractCallback2->MessageError(message));
@@ -392,6 +378,17 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
{
*outStream = NULL;
}
+ if (_crcMode)
+ {
+ _crcStreamSpec = new COutStreamWithCRC;
+ _crcStream = _crcStreamSpec;
+ CMyComPtr<ISequentialOutStream> crcStream = _crcStreamSpec;
+ _crcStreamSpec->SetStream(*outStream);
+ if (*outStream)
+ (*outStream)->Release();
+ *outStream = crcStream.Detach();
+ _crcStreamSpec->Init(true);
+ }
return S_OK;
COM_TRY_END
}
@@ -403,9 +400,13 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
switch (askExtractMode)
{
case NArchive::NExtract::NAskMode::kExtract:
- _extractMode = true;
+ if (_testMode)
+ askExtractMode = NArchive::NExtract::NAskMode::kTest;
+ else
+ _extractMode = true;
+ break;
};
- return _extractCallback2->PrepareOperation(_filePath, _processedFileInfo.IsDir,
+ return _extractCallback2->PrepareOperation(_filePath, _fi.IsDir,
askExtractMode, _isSplit ? &_position: 0);
COM_TRY_END
}
@@ -424,24 +425,35 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
_outFileStream.Release();
return E_FAIL;
}
- if (_outFileStream != NULL)
+ if (_crcStream)
+ {
+ CrcSum += _crcStreamSpec->GetCRC();
+ _curSize = _crcStreamSpec->GetSize();
+ _curSizeDefined = true;
+ _crcStream.Release();
+ }
+ if (_outFileStream)
{
_outFileStreamSpec->SetTime(
- (WriteCTime && _processedFileInfo.CTimeDefined) ? &_processedFileInfo.CTime : NULL,
- (WriteATime && _processedFileInfo.ATimeDefined) ? &_processedFileInfo.ATime : NULL,
- (WriteMTime && _processedFileInfo.MTimeDefined) ? &_processedFileInfo.MTime : &_utcMTimeDefault);
+ (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
+ (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
+ (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
_curSize = _outFileStreamSpec->ProcessedSize;
+ _curSizeDefined = true;
RINOK(_outFileStreamSpec->Close());
_outFileStream.Release();
}
- UnpackSize += _curSize;
- if (_processedFileInfo.IsDir)
+ if (!_curSizeDefined)
+ GetUnpackSize();
+ if (_curSizeDefined)
+ UnpackSize += _curSize;
+ if (_fi.IsDir)
NumFolders++;
else
NumFiles++;
- if (_extractMode && _processedFileInfo.AttributesAreDefined)
- NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);
+ if (_extractMode && _fi.AttribDefined)
+ NFile::NDirectory::MySetFileAttributes(_diskFilePath, _fi.Attrib);
RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted));
return S_OK;
COM_TRY_END
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
index e895c54b..367e4b07 100755
--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.h
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
@@ -1,19 +1,23 @@
// ArchiveExtractCallback.h
-#ifndef __ARCHIVEEXTRACTCALLBACK_H
-#define __ARCHIVEEXTRACTCALLBACK_H
+#ifndef __ARCHIVE_EXTRACT_CALLBACK_H
+#define __ARCHIVE_EXTRACT_CALLBACK_H
-#include "../../Archive/IArchive.h"
-#include "IFileExtractCallback.h"
-
-#include "Common/MyString.h"
#include "Common/MyCom.h"
+#include "Common/Wildcard.h"
+
+#include "../../IPassword.h"
#include "../../Common/FileStreams.h"
#include "../../Common/ProgressUtils.h"
-#include "../../IPassword.h"
+
+#include "../../Archive/IArchive.h"
+
+#include "../../Archive/Common/OutStreamWithCRC.h"
#include "ExtractMode.h"
+#include "IFileExtractCallback.h"
+#include "OpenArchive.h"
class CArchiveExtractCallback:
public IArchiveExtractCallback,
@@ -22,22 +26,8 @@ class CArchiveExtractCallback:
public ICompressProgressInfo,
public CMyUnknownImp
{
-public:
- MY_UNKNOWN_IMP2(ICryptoGetTextPassword, ICompressProgressInfo)
- // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)
-
- INTERFACE_IArchiveExtractCallback(;)
-
- STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
-
- // IArchiveVolumeExtractCallback
- // STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream);
-
- // ICryptoGetTextPassword
- STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword);
-
-private:
- CMyComPtr<IInArchive> _archiveHandler;
+ const CArc *_arc;
+ const NWildcard::CCensorNode *_wildcardCensor;
CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
CMyComPtr<ICompressProgressInfo> _compressProgress;
CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
@@ -45,12 +35,11 @@ private:
NExtract::NPathMode::EEnum _pathMode;
NExtract::NOverwriteMode::EEnum _overwriteMode;
+ UString _diskFilePath;
UString _filePath;
UInt64 _position;
bool _isSplit;
- UString _diskFilePath;
-
bool _extractMode;
bool WriteCTime;
@@ -64,29 +53,61 @@ private:
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
- UInt32 Attributes;
+ UInt32 Attrib;
bool CTimeDefined;
bool ATimeDefined;
bool MTimeDefined;
+ bool AttribDefined;
bool IsDir;
- bool AttributesAreDefined;
- } _processedFileInfo;
+ } _fi;
+ UInt32 _index;
UInt64 _curSize;
+ bool _curSizeDefined;
COutFileStream *_outFileStreamSpec;
CMyComPtr<ISequentialOutStream> _outFileStream;
+
+ COutStreamWithCRC *_crcStreamSpec;
+ CMyComPtr<ISequentialOutStream> _crcStream;
+
UStringVector _removePathParts;
- UString _itemDefaultName;
- FILETIME _utcMTimeDefault;
- UInt32 _attributesDefault;
bool _stdOutMode;
+ bool _testMode;
+ bool _crcMode;
+ bool _multiArchives;
+
+ CMyComPtr<ICompressProgressInfo> _localProgress;
+ UInt64 _packTotal;
+ UInt64 _unpTotal;
void CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath);
HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
+ HRESULT GetUnpackSize();
+
public:
+
+ CLocalProgress *LocalProgressSpec;
+
+ UInt64 NumFolders;
+ UInt64 NumFiles;
+ UInt64 UnpackSize;
+ UInt32 CrcSum;
+
+ MY_UNKNOWN_IMP2(ICryptoGetTextPassword, ICompressProgressInfo)
+ // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)
+
+ INTERFACE_IArchiveExtractCallback(;)
+
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+
+ // IArchiveVolumeExtractCallback
+ // STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream);
+
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
CArchiveExtractCallback():
WriteCTime(true),
WriteATime(true),
@@ -97,37 +118,26 @@ public:
_localProgress = LocalProgressSpec;
}
- CLocalProgress *LocalProgressSpec;
- CMyComPtr<ICompressProgressInfo> _localProgress;
- UInt64 _packTotal;
- UInt64 _unpTotal;
-
- bool _multiArchives;
- UInt64 NumFolders;
- UInt64 NumFiles;
- UInt64 UnpackSize;
-
void InitForMulti(bool multiArchives,
NExtract::NPathMode::EEnum pathMode,
NExtract::NOverwriteMode::EEnum overwriteMode)
{
- _multiArchives = multiArchives; NumFolders = NumFiles = UnpackSize = 0;
+ _multiArchives = multiArchives;
_pathMode = pathMode;
_overwriteMode = overwriteMode;
+ NumFolders = NumFiles = UnpackSize = 0;
+ CrcSum = 0;
}
void Init(
- IInArchive *archiveHandler,
+ const NWildcard::CCensorNode *wildcardCensor,
+ const CArc *arc,
IFolderArchiveExtractCallback *extractCallback2,
- bool stdOutMode,
+ bool stdOutMode, bool testMode, bool crcMode,
const UString &directoryPath,
const UStringVector &removePathParts,
- const UString &itemDefaultName,
- const FILETIME &utcMTimeDefault,
- UInt32 attributesDefault,
UInt64 packSize);
- UInt64 _numErrors;
};
#endif
diff --git a/CPP/7zip/UI/Common/ArchiveName.cpp b/CPP/7zip/UI/Common/ArchiveName.cpp
index 9b9a4fe6..c3684def 100755
--- a/CPP/7zip/UI/Common/ArchiveName.cpp
+++ b/CPP/7zip/UI/Common/ArchiveName.cpp
@@ -2,12 +2,14 @@
#include "StdAfx.h"
-#include "Windows/FileFind.h"
#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+
+#include "ExtractingFilePath.h"
using namespace NWindows;
-UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)
+static UString CreateArchiveName2(const UString &srcName, bool fromPrev, bool keepName)
{
UString resultName = L"Archive";
if (fromPrev)
@@ -20,7 +22,7 @@ UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)
{
dirPrefix.Delete(dirPrefix.Length() - 1);
NFile::NFind::CFileInfoW fileInfo;
- if (NFile::NFind::FindFile(dirPrefix, fileInfo))
+ if (fileInfo.Find(dirPrefix))
resultName = fileInfo.Name;
}
}
@@ -28,8 +30,9 @@ UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)
else
{
NFile::NFind::CFileInfoW fileInfo;
- if (!NFile::NFind::FindFile(srcName, fileInfo))
- return resultName;
+ if (!fileInfo.Find(srcName))
+ // return resultName;
+ return srcName;
resultName = fileInfo.Name;
if (!fileInfo.IsDir() && !keepName)
{
@@ -44,3 +47,8 @@ UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)
}
return resultName;
}
+
+UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)
+{
+ return GetCorrectFsPath(CreateArchiveName2(srcName, fromPrev, keepName));
+}
diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
index 8f289d1b..7188bcb6 100755
--- a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
+++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
@@ -2,14 +2,15 @@
#include "StdAfx.h"
-#include "ArchiveOpenCallback.h"
-
#include "Common/StringConvert.h"
#include "Common/ComTry.h"
+
#include "Windows/PropVariant.h"
#include "../../Common/FileStreams.h"
+#include "ArchiveOpenCallback.h"
+
using namespace NWindows;
STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)
@@ -91,7 +92,7 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre
}
*inStream = NULL;
UString fullPath = _folderPrefix + name;
- if (!NFile::NFind::FindFile(fullPath, _fileInfo))
+ if (!_fileInfo.Find(fullPath))
return S_FALSE;
if (_fileInfo.IsDir())
return S_FALSE;
diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.h b/CPP/7zip/UI/Common/ArchiveOpenCallback.h
index ca445974..c6651e8f 100755
--- a/CPP/7zip/UI/Common/ArchiveOpenCallback.h
+++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.h
@@ -3,8 +3,9 @@
#ifndef __ARCHIVE_OPEN_CALLBACK_H
#define __ARCHIVE_OPEN_CALLBACK_H
-#include "Common/MyString.h"
#include "Common/MyCom.h"
+#include "Common/MyString.h"
+
#include "Windows/FileFind.h"
#ifndef _NO_CRYPTO
@@ -71,6 +72,7 @@ public:
{
_subArchiveMode = true;
_subArchiveName = name;
+ TotalSize = 0;
return S_OK;
}
@@ -86,10 +88,10 @@ public:
UInt64 TotalSize;
COpenCallbackImp(): Callback(NULL) {}
- void Init(const UString &folderPrefix, const UString &fileName)
+ void Init(const UString &folderPrefix, const UString &fileName)
{
_folderPrefix = folderPrefix;
- if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo))
+ if (!_fileInfo.Find(_folderPrefix + fileName))
throw 1;
FileNames.Clear();
_subArchiveMode = false;
diff --git a/CPP/7zip/UI/Common/CompressCall.cpp b/CPP/7zip/UI/Common/CompressCall.cpp
index 3564c950..47f89ed6 100755
--- a/CPP/7zip/UI/Common/CompressCall.cpp
+++ b/CPP/7zip/UI/Common/CompressCall.cpp
@@ -2,20 +2,20 @@
#include "StdAfx.h"
-#include "CompressCall.h"
-
-#include "Common/Random.h"
#include "Common/IntToString.h"
#include "Common/MyCom.h"
+#include "Common/Random.h"
#include "Common/StringConvert.h"
-#include "Windows/Synchronization.h"
-#include "Windows/FileMapping.h"
#include "Windows/FileDir.h"
+#include "Windows/FileMapping.h"
+#include "Windows/Synchronization.h"
#include "../FileManager/ProgramLocation.h"
#include "../FileManager/RegistryUtils.h"
+#include "CompressCall.h"
+
#ifndef _UNICODE
extern bool g_IsNT;
#endif _UNICODE
@@ -122,8 +122,8 @@ static HRESULT CreateTempEvent(const wchar_t *name,
for (;;)
{
int number = random.Generate();
- wchar_t temp[32];
- ConvertUInt64ToString((UInt32)number, temp);
+ wchar_t temp[16];
+ ConvertUInt32ToString((UInt32)number, temp);
eventName = name;
eventName += temp;
RINOK(event.CreateWithName(false, GetSystemString(eventName)));
@@ -151,8 +151,8 @@ static HRESULT CreateMap(const UStringVector &names,
for (;;)
{
int number = random.Generate();
- wchar_t temp[32];
- ConvertUInt64ToString(UInt32(number), temp);
+ wchar_t temp[16];
+ ConvertUInt32ToString(UInt32(number), temp);
mappingName = id;
mappingName += L"Mapping";
mappingName += temp;
@@ -169,8 +169,8 @@ static HRESULT CreateMap(const UStringVector &names,
params += mappingName;
params += L":";
- wchar_t string[10];
- ConvertUInt64ToString(totalSize, string);
+ wchar_t string[16];
+ ConvertUInt32ToString(totalSize, string);
params += string;
params += L":";
@@ -231,8 +231,8 @@ HRESULT CompressFiles(
for (;;)
{
int number = random.Generate();
- wchar_t temp[32];
- ConvertUInt64ToString(UInt32(number), temp);
+ wchar_t temp[16];
+ ConvertUInt32ToString(UInt32(number), temp);
mappingName = L"7zCompressMapping";
mappingName += temp;
if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL,
@@ -252,8 +252,8 @@ HRESULT CompressFiles(
params += mappingName;
params += L":";
- wchar_t string[10];
- ConvertUInt64ToString(totalSize, string);
+ wchar_t string[16];
+ ConvertUInt32ToString(totalSize, string);
params += string;
params += L":";
diff --git a/CPP/7zip/UI/Common/DirItem.h b/CPP/7zip/UI/Common/DirItem.h
index 0f289483..29cc60d9 100755
--- a/CPP/7zip/UI/Common/DirItem.h
+++ b/CPP/7zip/UI/Common/DirItem.h
@@ -58,11 +58,12 @@ struct CArcItem
UString Name;
bool IsDir;
bool SizeDefined;
+ bool MTimeDefined;
bool Censored;
UInt32 IndexInServer;
int TimeType;
- CArcItem(): IsDir(false), SizeDefined(false), Censored(false), TimeType(-1) {}
+ CArcItem(): IsDir(false), SizeDefined(false), MTimeDefined(false), Censored(false), TimeType(-1) {}
};
#endif
diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp
index b83edf2a..ba03ea35 100755
--- a/CPP/7zip/UI/Common/EnumDirItems.cpp
+++ b/CPP/7zip/UI/Common/EnumDirItems.cpp
@@ -2,12 +2,6 @@
#include "StdAfx.h"
-#include <stdio.h>
-
-#include "Common/StringConvert.h"
-#include "Common/Wildcard.h"
-#include "Common/MyCom.h"
-
#include "EnumDirItems.h"
using namespace NWindows;
@@ -122,7 +116,7 @@ void CDirItems::EnumerateDirItems2(const UString &phyPrefix, const UString &logP
const UString &filePath = filePaths[i];
NFind::CFileInfoW fi;
const UString phyPath = phyPrefix + filePath;
- if (!NFind::FindFile(phyPath, fi))
+ if (!fi.Find(phyPath))
{
errorCodes.Add(::GetLastError());
errorPaths.Add(phyPath);
@@ -218,7 +212,7 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
const UString &name = item.PathParts.Front();
const UString fullPath = phyPrefix + name;
NFind::CFileInfoW fi;
- if (!NFind::FindFile(fullPath, fi))
+ if (!fi.Find(fullPath))
{
errorCodes.Add(::GetLastError());
errorPaths.Add(fullPath);
@@ -268,7 +262,7 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
const UString fullPath = phyPrefix + nextNode.Name;
NFind::CFileInfoW fi;
- if (!NFind::FindFile(fullPath, fi))
+ if (!fi.Find(fullPath))
{
if (!nextNode.AreThereIncludeItems())
continue;
diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp
index 3ac497f4..93329091 100755
--- a/CPP/7zip/UI/Common/Extract.cpp
+++ b/CPP/7zip/UI/Common/Extract.cpp
@@ -2,55 +2,65 @@
#include "StdAfx.h"
-#include "Extract.h"
+#include <stdio.h>
-#include "Windows/Defs.h"
#include "Windows/FileDir.h"
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+
+#include "../Common/ExtractingFilePath.h"
-#include "OpenArchive.h"
+#include "Extract.h"
#include "SetProperties.h"
using namespace NWindows;
static HRESULT DecompressArchive(
- IInArchive *archive,
+ const CArc &arc,
UInt64 packSize,
const NWildcard::CCensorNode &wildcardCensor,
const CExtractOptions &options,
IExtractCallbackUI *callback,
CArchiveExtractCallback *extractCallbackSpec,
- UString &errorMessage)
+ UString &errorMessage,
+ UInt64 &stdInProcessed)
{
+ stdInProcessed = 0;
+ IInArchive *archive = arc.Archive;
CRecordVector<UInt32> realIndices;
- UInt32 numItems;
- RINOK(archive->GetNumberOfItems(&numItems));
-
- for(UInt32 i = 0; i < numItems; i++)
- {
- UString filePath;
- RINOK(GetArchiveItemPath(archive, i, options.DefaultItemName, filePath));
- bool isFolder;
- RINOK(IsArchiveItemFolder(archive, i, isFolder));
- if (!wildcardCensor.CheckPath(filePath, !isFolder))
- continue;
- realIndices.Add(i);
- }
- if (realIndices.Size() == 0)
+ if (!options.StdInMode)
{
- callback->ThereAreNoFiles();
- return S_OK;
+ UInt32 numItems;
+ RINOK(archive->GetNumberOfItems(&numItems));
+
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ UString filePath;
+ RINOK(arc.GetItemPath(i, filePath));
+ bool isFolder;
+ RINOK(IsArchiveItemFolder(archive, i, isFolder));
+ if (!wildcardCensor.CheckPath(filePath, !isFolder))
+ continue;
+ realIndices.Add(i);
+ }
+ if (realIndices.Size() == 0)
+ {
+ callback->ThereAreNoFiles();
+ return S_OK;
+ }
}
UStringVector removePathParts;
UString outDir = options.OutputDir;
- outDir.Replace(L"*", options.DefaultItemName);
+ outDir.Replace(L"*", GetCorrectFsPath(arc.DefaultName));
#ifdef _WIN32
outDir.TrimRight();
+ outDir = GetCorrectFullFsPath(outDir);
#endif
- if(!outDir.IsEmpty())
- if(!NFile::NDirectory::CreateComplexDirectory(outDir))
+ if (!outDir.IsEmpty())
+ if (!NFile::NDirectory::CreateComplexDirectory(outDir))
{
HRESULT res = ::GetLastError();
if (res == S_OK)
@@ -60,91 +70,108 @@ static HRESULT DecompressArchive(
}
extractCallbackSpec->Init(
- archive,
+ options.StdInMode ? &wildcardCensor : NULL,
+ &arc,
callback,
- options.StdOutMode,
+ options.StdOutMode, options.TestMode, options.CalcCrc,
outDir,
removePathParts,
- options.DefaultItemName,
- options.ArchiveFileInfo.MTime,
- options.ArchiveFileInfo.Attrib,
packSize);
#ifdef COMPRESS_MT
RINOK(SetProperties(archive, options.Properties));
#endif
- HRESULT result = archive->Extract(&realIndices.Front(),
- realIndices.Size(), options.TestMode? 1: 0, extractCallbackSpec);
+ HRESULT result;
+ Int32 testMode = (options.TestMode && !options.CalcCrc) ? 1: 0;
+ if (options.StdInMode)
+ {
+ result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, extractCallbackSpec);
+ NCOM::CPropVariant prop;
+ if (archive->GetArchiveProperty(kpidPhySize, &prop) == S_OK)
+ if (prop.vt == VT_UI8 || prop.vt == VT_UI4)
+ stdInProcessed = ConvertPropVariantToUInt64(prop);
+ }
+ else
+ result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallbackSpec);
return callback->ExtractResult(result);
}
HRESULT DecompressArchives(
CCodecs *codecs, const CIntVector &formatIndices,
- UStringVector &archivePaths, UStringVector &archivePathsFull,
+ UStringVector &arcPaths, UStringVector &arcPathsFull,
const NWildcard::CCensorNode &wildcardCensor,
- const CExtractOptions &optionsSpec,
+ const CExtractOptions &options,
IOpenCallbackUI *openCallback,
IExtractCallbackUI *extractCallback,
UString &errorMessage,
CDecompressStat &stat)
{
stat.Clear();
- CExtractOptions options = optionsSpec;
int i;
UInt64 totalPackSize = 0;
CRecordVector<UInt64> archiveSizes;
- for (i = 0; i < archivePaths.Size(); i++)
+
+ int numArcs = options.StdInMode ? 1 : arcPaths.Size();
+
+ for (i = 0; i < numArcs; i++)
{
- const UString &archivePath = archivePaths[i];
NFile::NFind::CFileInfoW fi;
- if (!NFile::NFind::FindFile(archivePath, fi))
- throw "there is no such archive";
- if (fi.IsDir())
- throw "can't decompress folder";
+ fi.Size = 0;
+ if (!options.StdInMode)
+ {
+ const UString &arcPath = arcPaths[i];
+ if (!fi.Find(arcPath))
+ throw "there is no such archive";
+ if (fi.IsDir())
+ throw "can't decompress folder";
+ }
archiveSizes.Add(fi.Size);
totalPackSize += fi.Size;
}
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
CMyComPtr<IArchiveExtractCallback> ec(extractCallbackSpec);
- bool multi = (archivePaths.Size() > 1);
+ bool multi = (numArcs > 1);
extractCallbackSpec->InitForMulti(multi, options.PathMode, options.OverwriteMode);
if (multi)
{
RINOK(extractCallback->SetTotal(totalPackSize));
}
- for (i = 0; i < archivePaths.Size(); i++)
+ for (i = 0; i < numArcs; i++)
{
- const UString &archivePath = archivePaths[i];
+ const UString &arcPath = arcPaths[i];
NFile::NFind::CFileInfoW fi;
- if (!NFile::NFind::FindFile(archivePath, fi))
- throw "there is no such archive";
-
- if (fi.IsDir())
- throw "there is no such archive";
-
- options.ArchiveFileInfo = fi;
+ if (options.StdInMode)
+ {
+ fi.Size = 0;
+ fi.Attrib = 0;
+ }
+ else
+ {
+ if (!fi.Find(arcPath) || fi.IsDir())
+ throw "there is no such archive";
+ }
#ifndef _NO_CRYPTO
openCallback->Open_ClearPasswordWasAskedFlag();
#endif
- RINOK(extractCallback->BeforeOpen(archivePath));
+ RINOK(extractCallback->BeforeOpen(arcPath));
CArchiveLink archiveLink;
CIntVector formatIndices2 = formatIndices;
#ifndef _SFX
if (formatIndices.IsEmpty())
{
- int pos = archivePath.ReverseFind(L'.');
+ int pos = arcPath.ReverseFind(L'.');
if (pos >= 0)
{
- UString s = archivePath.Mid(pos + 1);
+ UString s = arcPath.Mid(pos + 1);
int index = codecs->FindFormatForExtension(s);
if (index >= 0 && s == L"001")
{
- s = archivePath.Left(pos);
+ s = arcPath.Left(pos);
pos = s.ReverseFind(L'.');
if (pos >= 0)
{
@@ -159,7 +186,7 @@ HRESULT DecompressArchives(
}
}
#endif
- HRESULT result = MyOpenArchive(codecs, formatIndices2, archivePath, archiveLink, openCallback);
+ HRESULT result = archiveLink.Open2(codecs, formatIndices2, options.StdInMode, NULL, arcPath, openCallback);
if (result == E_ABORT)
return result;
@@ -168,19 +195,21 @@ HRESULT DecompressArchives(
crypted = openCallback->Open_WasPasswordAsked();
#endif
- RINOK(extractCallback->OpenResult(archivePath, result, crypted));
+ RINOK(extractCallback->OpenResult(arcPath, result, crypted));
if (result != S_OK)
continue;
+ if (!options.StdInMode)
for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
{
- int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
+ int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]);
if (index >= 0 && index > i)
{
- archivePaths.Delete(index);
- archivePathsFull.Delete(index);
+ arcPaths.Delete(index);
+ arcPathsFull.Delete(index);
totalPackSize -= archiveSizes[index];
archiveSizes.Delete(index);
+ numArcs = arcPaths.Size();
}
}
if (archiveLink.VolumePaths.Size() != 0)
@@ -198,13 +227,17 @@ HRESULT DecompressArchives(
}
#endif
- options.DefaultItemName = archiveLink.GetDefaultItemName();
- RINOK(DecompressArchive(
- archiveLink.GetArchive(),
+ CArc &arc = archiveLink.Arcs.Back();
+ arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice);
+ arc.MTime = fi.MTime;
+
+ UInt64 packProcessed;
+ RINOK(DecompressArchive(arc,
fi.Size + archiveLink.VolumesSize,
- wildcardCensor, options, extractCallback, extractCallbackSpec, errorMessage));
- extractCallbackSpec->LocalProgressSpec->InSize += fi.Size +
- archiveLink.VolumesSize;
+ wildcardCensor, options, extractCallback, extractCallbackSpec, errorMessage, packProcessed));
+ if (!options.StdInMode)
+ packProcessed = fi.Size + archiveLink.VolumesSize;
+ extractCallbackSpec->LocalProgressSpec->InSize += packProcessed;
extractCallbackSpec->LocalProgressSpec->OutSize = extractCallbackSpec->UnpackSize;
if (!errorMessage.IsEmpty())
return E_FAIL;
@@ -212,7 +245,9 @@ HRESULT DecompressArchives(
stat.NumFolders = extractCallbackSpec->NumFolders;
stat.NumFiles = extractCallbackSpec->NumFiles;
stat.UnpackSize = extractCallbackSpec->UnpackSize;
- stat.NumArchives = archivePaths.Size();
+ stat.CrcSum = extractCallbackSpec->CrcSum;
+
+ stat.NumArchives = arcPaths.Size();
stat.PackSize = extractCallbackSpec->LocalProgressSpec->InSize;
return S_OK;
}
diff --git a/CPP/7zip/UI/Common/Extract.h b/CPP/7zip/UI/Common/Extract.h
index 37add18b..442dd2b0 100755
--- a/CPP/7zip/UI/Common/Extract.h
+++ b/CPP/7zip/UI/Common/Extract.h
@@ -3,7 +3,6 @@
#ifndef __EXTRACT_H
#define __EXTRACT_H
-#include "Common/Wildcard.h"
#include "Windows/FileFind.h"
#include "../../Archive/IArchive.h"
@@ -15,17 +14,16 @@
#include "../Common/LoadCodecs.h"
-class CExtractOptions
+struct CExtractOptions
{
-public:
+ bool StdInMode;
bool StdOutMode;
+ bool YesToAll;
bool TestMode;
+ bool CalcCrc;
NExtract::NPathMode::EEnum PathMode;
-
+ NExtract::NOverwriteMode::EEnum OverwriteMode;
UString OutputDir;
- bool YesToAll;
- UString DefaultItemName;
- NWindows::NFile::NFind::CFileInfoW ArchiveFileInfo;
// bool ShowDialog;
// bool PasswordEnabled;
@@ -34,24 +32,19 @@ public:
CObjectVector<CProperty> Properties;
#endif
- NExtract::NOverwriteMode::EEnum OverwriteMode;
-
#ifdef EXTERNAL_CODECS
CCodecs *Codecs;
#endif
CExtractOptions():
+ StdInMode(false),
StdOutMode(false),
YesToAll(false),
TestMode(false),
+ CalcCrc(false),
PathMode(NExtract::NPathMode::kFullPathnames),
OverwriteMode(NExtract::NOverwriteMode::kAskBefore)
{}
-
- /*
- bool FullPathMode() const { return (ExtractMode == NExtractMode::kTest) ||
- (ExtractMode == NExtractMode::kFullPath); }
- */
};
struct CDecompressStat
@@ -61,7 +54,13 @@ struct CDecompressStat
UInt64 PackSize;
UInt64 NumFolders;
UInt64 NumFiles;
- void Clear() { NumArchives = PackSize = UnpackSize = NumFolders = NumFiles = 0; }
+ UInt32 CrcSum;
+
+ void Clear()
+ {
+ NumArchives = UnpackSize = PackSize = NumFolders = NumFiles = 0;
+ CrcSum = 0;
+ }
};
HRESULT DecompressArchives(
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
index 5de388dd..67a58372 100755
--- a/CPP/7zip/UI/Common/ExtractingFilePath.cpp
+++ b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
@@ -1,6 +1,9 @@
// ExtractingFilePath.cpp
#include "StdAfx.h"
+
+#include "Common/Wildcard.h"
+
#include "ExtractingFilePath.h"
static UString ReplaceIncorrectChars(const UString &s)
@@ -15,6 +18,8 @@ static UString ReplaceIncorrectChars(const UString &s)
res += c;
}
res.TrimRight();
+ while (!res.IsEmpty() && res[res.Length() - 1] == '.')
+ res.Delete(res.Length() - 1);
return res;
#else
return s;
@@ -95,3 +100,41 @@ void MakeCorrectPath(UStringVector &pathParts)
}
}
+UString MakePathNameFromParts(const UStringVector &parts)
+{
+ UString result;
+ for (int i = 0; i < parts.Size(); i++)
+ {
+ if (i != 0)
+ result += WCHAR_PATH_SEPARATOR;
+ result += parts[i];
+ }
+ return result;
+}
+
+UString GetCorrectFsPath(const UString &path)
+{
+ UString res = GetCorrectFileName(path);
+ #ifdef _WIN32
+ if (!IsSupportedName(res))
+ res = (UString)L"_" + res;
+ #endif
+ return res;
+}
+
+UString GetCorrectFullFsPath(const UString &path)
+{
+ UStringVector parts;
+ SplitPathToParts(path, parts);
+ for (int i = 0; i < parts.Size(); i++)
+ {
+ UString &s = parts[i];
+ #ifdef _WIN32
+ while (!s.IsEmpty() && s[s.Length() - 1] == '.')
+ s.Delete(s.Length() - 1);
+ if (!IsSupportedName(s))
+ s = (UString)L"_" + s;
+ #endif
+ }
+ return MakePathNameFromParts(parts);
+}
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.h b/CPP/7zip/UI/Common/ExtractingFilePath.h
index a86a6a9b..da28bfc2 100755
--- a/CPP/7zip/UI/Common/ExtractingFilePath.h
+++ b/CPP/7zip/UI/Common/ExtractingFilePath.h
@@ -1,10 +1,13 @@
// ExtractingFilePath.h
-#ifndef __EXTRACTINGFILEPATH_H
-#define __EXTRACTINGFILEPATH_H
+#ifndef __EXTRACTING_FILE_PATH_H
+#define __EXTRACTING_FILE_PATH_H
#include "Common/MyString.h"
+UString MakePathNameFromParts(const UStringVector &parts);
void MakeCorrectPath(UStringVector &pathParts);
+UString GetCorrectFsPath(const UString &path);
+UString GetCorrectFullFsPath(const UString &path);
#endif
diff --git a/CPP/7zip/UI/Common/LoadCodecs.cpp b/CPP/7zip/UI/Common/LoadCodecs.cpp
index 4b5639ee..dac8c4d2 100755
--- a/CPP/7zip/UI/Common/LoadCodecs.cpp
+++ b/CPP/7zip/UI/Common/LoadCodecs.cpp
@@ -69,22 +69,17 @@ static bool ReadPathFromRegistry(HKEY baseKey, CSysString &path)
CSysString GetBaseFolderPrefixFromRegistry()
{
CSysString moduleFolderPrefix = GetLibraryFolderPrefix();
- NFind::CFileInfo fi;
- if (NFind::FindFile(moduleFolderPrefix + kMainDll, fi))
- if (!fi.IsDir())
- return moduleFolderPrefix;
- if (NFind::FindFile(moduleFolderPrefix + kCodecsFolderName, fi))
- if (fi.IsDir())
- return moduleFolderPrefix;
- if (NFind::FindFile(moduleFolderPrefix + kFormatsFolderName, fi))
- if (fi.IsDir())
- return moduleFolderPrefix;
#ifdef _WIN32
- CSysString path;
- if (ReadPathFromRegistry(HKEY_CURRENT_USER, path))
- return path;
- if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path))
- return path;
+ if (!NFind::DoesFileExist(moduleFolderPrefix + kMainDll) &&
+ !NFind::DoesDirExist(moduleFolderPrefix + kCodecsFolderName) &&
+ !NFind::DoesDirExist(moduleFolderPrefix + kFormatsFolderName))
+ {
+ CSysString path;
+ if (ReadPathFromRegistry(HKEY_CURRENT_USER, path))
+ return path;
+ if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path))
+ return path;
+ }
#endif
return moduleFolderPrefix;
}
@@ -181,7 +176,7 @@ static HRESULT ReadStringProp(
#endif
-static const unsigned int kNumArcsMax = 32;
+static const unsigned int kNumArcsMax = 48;
static unsigned int g_NumArcs = 0;
static const CArcInfo *g_Arcs[kNumArcsMax];
void RegisterArc(const CArcInfo *arcInfo)
@@ -457,9 +452,7 @@ int CCodecs::FindFormatForArchiveName(const UString &arcPath) const
const CArcInfoEx &arc = Formats[i];
if (!arc.UpdateEnabled)
continue;
- // if (arc.FindExtension(ext) >= 0)
- UString mainExt = arc.GetMainExt();
- if (!mainExt.IsEmpty() && ext.CompareNoCase(mainExt) == 0)
+ if (arc.FindExtension(ext) >= 0)
return i;
}
return -1;
diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp
index 364ddff5..ec9f9a45 100755
--- a/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -2,45 +2,56 @@
#include "StdAfx.h"
-#include "OpenArchive.h"
-
#include "Common/Wildcard.h"
-#include "Windows/FileName.h"
#include "Windows/FileDir.h"
-#include "Windows/Defs.h"
#include "Windows/PropVariant.h"
#include "../../Common/FileStreams.h"
#include "../../Common/StreamUtils.h"
-#include "Common/StringConvert.h"
-
#include "DefaultName.h"
+#include "OpenArchive.h"
using namespace NWindows;
-HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result)
+// Static-SFX (for Linux) can be big.
+const UInt64 kMaxCheckStartPosition = 1 << 22;
+
+HRESULT GetArchiveItemBoolProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
{
NCOM::CPropVariant prop;
- RINOK(archive->GetProperty(index, kpidPath, &prop));
- if(prop.vt == VT_BSTR)
- result = prop.bstrVal;
- else if (prop.vt == VT_EMPTY)
- result.Empty();
- else
+ result = false;
+ RINOK(archive->GetProperty(index, propID, &prop));
+ if (prop.vt == VT_BOOL)
+ result = VARIANT_BOOLToBool(prop.boolVal);
+ else if (prop.vt != VT_EMPTY)
return E_FAIL;
return S_OK;
}
-HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result)
+HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
{
- RINOK(GetArchiveItemPath(archive, index, result));
+ return GetArchiveItemBoolProp(archive, index, kpidIsDir, result);
+}
+
+HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
+{
+ {
+ NCOM::CPropVariant prop;
+ RINOK(Archive->GetProperty(index, kpidPath, &prop));
+ if (prop.vt == VT_BSTR)
+ result = prop.bstrVal;
+ else if (prop.vt == VT_EMPTY)
+ result.Empty();
+ else
+ return E_FAIL;
+ }
if (result.IsEmpty())
{
- result = defaultName;
+ result = DefaultName;
NCOM::CPropVariant prop;
- RINOK(archive->GetProperty(index, kpidExtension, &prop));
+ RINOK(Archive->GetProperty(index, kpidExtension, &prop));
if (prop.vt == VT_BSTR)
{
result += L'.';
@@ -52,54 +63,27 @@ HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &def
return S_OK;
}
-HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
- const FILETIME &defaultFileTime, FILETIME &fileTime)
+HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const
{
NCOM::CPropVariant prop;
- RINOK(archive->GetProperty(index, kpidMTime, &prop));
+ defined = false;
+ ft.dwHighDateTime = ft.dwLowDateTime = 0;
+ RINOK(Archive->GetProperty(index, kpidMTime, &prop));
if (prop.vt == VT_FILETIME)
- fileTime = prop.filetime;
- else if (prop.vt == VT_EMPTY)
- fileTime = defaultFileTime;
- else
- return E_FAIL;
- return S_OK;
-}
-
-HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
-{
- NCOM::CPropVariant prop;
- RINOK(archive->GetProperty(index, propID, &prop));
- if(prop.vt == VT_BOOL)
- result = VARIANT_BOOLToBool(prop.boolVal);
- else if (prop.vt == VT_EMPTY)
- result = false;
- else
+ {
+ ft = prop.filetime;
+ defined = true;
+ }
+ else if (prop.vt != VT_EMPTY)
return E_FAIL;
+ else if (MTimeDefined)
+ {
+ ft = MTime;
+ defined = true;
+ }
return S_OK;
}
-HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
-{
- return IsArchiveItemProp(archive, index, kpidIsDir, result);
-}
-
-HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result)
-{
- return IsArchiveItemProp(archive, index, kpidIsAnti, result);
-}
-
-// Static-SFX (for Linux) can be big.
-const UInt64 kMaxCheckStartPosition = 1 << 22;
-
-HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName, IArchiveOpenCallback *openArchiveCallback)
-{
- CInFileStream *inStreamSpec = new CInFileStream;
- CMyComPtr<IInStream> inStream(inStreamSpec);
- inStreamSpec->Open(fileName);
- return archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback);
-}
-
#ifndef _SFX
static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
{
@@ -110,17 +94,15 @@ static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
}
#endif
-HRESULT OpenArchive(
+HRESULT CArc::OpenStream(
CCodecs *codecs,
- int arcTypeIndex,
- IInStream *inStream,
- const UString &fileName,
- IInArchive **archiveResult,
- int &formatIndex,
- UString &defaultItemName,
- IArchiveOpenCallback *openArchiveCallback)
+ int formatIndex,
+ IInStream *stream,
+ ISequentialInStream *seqStream,
+ IArchiveOpenCallback *callback)
{
- *archiveResult = NULL;
+ Archive.Release();
+ const UString fileName = ExtractFileNameFromPath(Path);
UString extension;
{
int dotPos = fileName.ReverseFind(L'.');
@@ -128,8 +110,8 @@ HRESULT OpenArchive(
extension = fileName.Mid(dotPos + 1);
}
CIntVector orderIndices;
- if (arcTypeIndex >= 0)
- orderIndices.Add(arcTypeIndex);
+ if (formatIndex >= 0)
+ orderIndices.Add(formatIndex);
else
{
@@ -141,16 +123,23 @@ HRESULT OpenArchive(
else
orderIndices.Add(i);
+ if (!stream)
+ {
+ if (numFinded != 1)
+ return E_NOTIMPL;
+ orderIndices.DeleteFrom(1);
+ }
+
#ifndef _SFX
- if (numFinded != 1)
+ if (numFinded == 0)
{
CIntVector orderIndices2;
CByteBuffer byteBuffer;
const size_t kBufferSize = (1 << 21);
byteBuffer.SetCapacity(kBufferSize);
- RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
size_t processedSize = kBufferSize;
- RINOK(ReadStream(inStream, byteBuffer, &processedSize));
+ RINOK(ReadStream(stream, byteBuffer, &processedSize));
if (processedSize == 0)
return S_FALSE;
@@ -206,24 +195,6 @@ HRESULT OpenArchive(
orderIndices2.Add(val);
}
orderIndices = orderIndices2;
-
- if (orderIndices.Size() >= 2)
- {
- int isoIndex = codecs->FindFormatForArchiveType(L"iso");
- int udfIndex = codecs->FindFormatForArchiveType(L"udf");
- int iIso = -1;
- int iUdf = -1;
- for (int i = 0; i < orderIndices.Size(); i++)
- {
- if (orderIndices[i] == isoIndex) iIso = i;
- if (orderIndices[i] == udfIndex) iUdf = i;
- }
- if (iUdf == iIso + 1)
- {
- orderIndices[iUdf] = isoIndex;
- orderIndices[iIso] = udfIndex;
- }
- }
}
else if (extension == L"000" || extension == L"001")
{
@@ -231,9 +202,9 @@ HRESULT OpenArchive(
const size_t kBufferSize = (1 << 10);
byteBuffer.SetCapacity(kBufferSize);
Byte *buffer = byteBuffer;
- RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+ RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
size_t processedSize = kBufferSize;
- RINOK(ReadStream(inStream, buffer, &processedSize));
+ RINOK(ReadStream(stream, buffer, &processedSize));
if (processedSize >= 16)
{
Byte kRarHeader[] = {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00};
@@ -252,17 +223,37 @@ HRESULT OpenArchive(
}
}
}
+ if (orderIndices.Size() >= 2)
+ {
+ int isoIndex = codecs->FindFormatForArchiveType(L"iso");
+ int udfIndex = codecs->FindFormatForArchiveType(L"udf");
+ int iIso = -1;
+ int iUdf = -1;
+ for (int i = 0; i < orderIndices.Size(); i++)
+ {
+ if (orderIndices[i] == isoIndex) iIso = i;
+ if (orderIndices[i] == udfIndex) iUdf = i;
+ }
+ if (iUdf > iIso && iIso >= 0)
+ {
+ orderIndices[iUdf] = isoIndex;
+ orderIndices[iIso] = udfIndex;
+ }
+ }
+
#endif
}
- for(int i = 0; i < orderIndices.Size(); i++)
+ for (int i = 0; i < orderIndices.Size(); i++)
{
- inStream->Seek(0, STREAM_SEEK_SET, NULL);
-
+ if (stream)
+ {
+ RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
+ }
CMyComPtr<IInArchive> archive;
- formatIndex = orderIndices[i];
- RINOK(codecs->CreateInArchive(formatIndex, archive));
+ FormatIndex = orderIndices[i];
+ RINOK(codecs->CreateInArchive(FormatIndex, archive));
if (!archive)
continue;
@@ -277,274 +268,239 @@ HRESULT OpenArchive(
}
#endif
- HRESULT result = archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback);
+ // OutputDebugStringW(codecs->Formats[FormatIndex].Name);
+
+ HRESULT result;
+ if (stream)
+ result = archive->Open(stream, &kMaxCheckStartPosition, callback);
+ else
+ {
+ CMyComPtr<IArchiveOpenSeq> openSeq;
+ archive.QueryInterface(IID_IArchiveOpenSeq, (void **)&openSeq);
+ if (!openSeq)
+ return E_NOTIMPL;
+ result = openSeq->OpenSeq(seqStream);
+ }
+
if (result == S_FALSE)
continue;
RINOK(result);
- *archiveResult = archive.Detach();
- const CArcInfoEx &format = codecs->Formats[formatIndex];
+
+ Archive = archive;
+ const CArcInfoEx &format = codecs->Formats[FormatIndex];
if (format.Exts.Size() == 0)
- {
- defaultItemName = GetDefaultName2(fileName, L"", L"");
- }
+ DefaultName = GetDefaultName2(fileName, L"", L"");
else
{
int subExtIndex = format.FindExtension(extension);
if (subExtIndex < 0)
subExtIndex = 0;
- defaultItemName = GetDefaultName2(fileName,
- format.Exts[subExtIndex].Ext,
- format.Exts[subExtIndex].AddExt);
+ const CArcExtInfo &extInfo = format.Exts[subExtIndex];
+ DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt);
}
return S_OK;
}
return S_FALSE;
}
-HRESULT OpenArchive(
+HRESULT CArc::OpenStreamOrFile(
CCodecs *codecs,
- int arcTypeIndex,
- const UString &filePath,
- IInArchive **archiveResult,
- int &formatIndex,
- UString &defaultItemName,
- IArchiveOpenCallback *openArchiveCallback)
+ int formatIndex,
+ bool stdInMode,
+ IInStream *stream,
+ IArchiveOpenCallback *callback)
{
- CInFileStream *inStreamSpec = new CInFileStream;
- CMyComPtr<IInStream> inStream(inStreamSpec);
- if (!inStreamSpec->Open(filePath))
- return GetLastError();
- return OpenArchive(codecs, arcTypeIndex, inStream, ExtractFileNameFromPath(filePath),
- archiveResult, formatIndex,
- defaultItemName, openArchiveCallback);
+ CMyComPtr<IInStream> fileStream;
+ CMyComPtr<ISequentialInStream> seqStream;
+ if (stdInMode)
+ seqStream = new CStdInFileStream;
+ else if (!stream)
+ {
+ CInFileStream *fileStreamSpec = new CInFileStream;
+ fileStream = fileStreamSpec;
+ if (!fileStreamSpec->Open(Path))
+ return GetLastError();
+ stream = fileStream;
+ }
+
+ return OpenStream(codecs, formatIndex, stream, seqStream, callback);
}
-static void MakeDefaultName(UString &name)
+HRESULT CArchiveLink::Close()
{
- int dotPos = name.ReverseFind(L'.');
- if (dotPos < 0)
- return;
- UString ext = name.Mid(dotPos + 1);
- if (ext.IsEmpty())
- return;
- for (int pos = 0; pos < ext.Length(); pos++)
- if (ext[pos] < L'0' || ext[pos] > L'9')
- return;
- name = name.Left(dotPos);
+ for (int i = Arcs.Size() - 1; i >= 0; i--)
+ {
+ RINOK(Arcs[i].Archive->Close());
+ }
+ IsOpen = false;
+ return S_OK;
}
-HRESULT OpenArchive(
+void CArchiveLink::Release()
+{
+ while (!Arcs.IsEmpty())
+ Arcs.DeleteBack();
+}
+
+HRESULT CArchiveLink::Open(
CCodecs *codecs,
const CIntVector &formatIndices,
- const UString &fileName,
- IInArchive **archive0,
- IInArchive **archive1,
- int &formatIndex0,
- int &formatIndex1,
- UString &defaultItemName0,
- UString &defaultItemName1,
- IArchiveOpenCallback *openArchiveCallback)
+ bool stdInMode,
+ IInStream *stream,
+ const UString &filePath,
+ IArchiveOpenCallback *callback)
{
- if (formatIndices.Size() >= 3)
+ Release();
+ if (formatIndices.Size() >= 32)
return E_NOTIMPL;
- int arcTypeIndex = -1;
- if (formatIndices.Size() >= 1)
- arcTypeIndex = formatIndices[formatIndices.Size() - 1];
-
- HRESULT result = OpenArchive(codecs, arcTypeIndex, fileName,
- archive0, formatIndex0, defaultItemName0, openArchiveCallback);
- RINOK(result);
+ HRESULT resSpec;
- if (formatIndices.Size() == 1)
- return S_OK;
- arcTypeIndex = -1;
- if (formatIndices.Size() >= 2)
- arcTypeIndex = formatIndices[formatIndices.Size() - 2];
-
- HRESULT resSpec = (formatIndices.Size() == 0 ? S_OK : E_NOTIMPL);
-
- CMyComPtr<IInArchiveGetStream> getStream;
- result = (*archive0)->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream);
- if (result != S_OK || !getStream)
- return resSpec;
-
- CMyComPtr<ISequentialInStream> subSeqStream;
- result = getStream->GetStream(0, &subSeqStream);
- if (result != S_OK || !subSeqStream)
- return resSpec;
-
- CMyComPtr<IInStream> subStream;
- result = subSeqStream.QueryInterface(IID_IInStream, &subStream);
- if (result != S_OK || !subStream)
- return resSpec;
-
- UInt32 numItems;
- RINOK((*archive0)->GetNumberOfItems(&numItems));
- if (numItems < 1)
- return resSpec;
-
- UString subPath;
- RINOK(GetArchiveItemPath(*archive0, 0, subPath))
- if (subPath.IsEmpty())
+ for (;;)
{
- MakeDefaultName(defaultItemName0);
- subPath = defaultItemName0;
- const CArcInfoEx &format = codecs->Formats[formatIndex0];
- if (format.Name.CompareNoCase(L"7z") == 0)
+ resSpec = S_OK;
+ int formatIndex = -1;
+ if (formatIndices.Size() >= 1)
+ {
+ if (Arcs.Size() >= formatIndices.Size())
+ break;
+ formatIndex = formatIndices[formatIndices.Size() - Arcs.Size() - 1];
+ }
+ else if (Arcs.Size() >= 32)
+ break;
+
+ if (Arcs.IsEmpty())
+ {
+ CArc arc;
+ arc.Path = filePath;
+ arc.SubfileIndex = (UInt32)(Int32)-1;
+ RINOK(arc.OpenStreamOrFile(codecs, formatIndex, stdInMode, stream, callback));
+ Arcs.Add(arc);
+ continue;
+ }
+
+ const CArc &arc = Arcs.Back();
+
+ resSpec = (formatIndices.Size() == 0 ? S_OK : E_NOTIMPL);
+
+ UInt32 mainSubfile;
{
- if (subPath.Right(3).CompareNoCase(L".7z") != 0)
- subPath += L".7z";
+ NCOM::CPropVariant prop;
+ RINOK(arc.Archive->GetArchiveProperty(kpidMainSubfile, &prop));
+ if (prop.vt == VT_UI4)
+ mainSubfile = prop.ulVal;
+ else
+ break;
+ UInt32 numItems;
+ RINOK(arc.Archive->GetNumberOfItems(&numItems));
+ if (mainSubfile >= numItems)
+ break;
}
+
+
+ CMyComPtr<IInArchiveGetStream> getStream;
+ if (arc.Archive->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream) != S_OK || !getStream)
+ break;
+
+ CMyComPtr<ISequentialInStream> subSeqStream;
+ if (getStream->GetStream(mainSubfile, &subSeqStream) != S_OK || !subSeqStream)
+ break;
+
+ CMyComPtr<IInStream> subStream;
+ if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK || !subStream)
+ break;
+
+ CArc arc2;
+ RINOK(arc.GetItemPath(mainSubfile, arc2.Path));
+
+ CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
+ callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
+ if (setSubArchiveName)
+ setSubArchiveName->SetSubArchiveName(arc2.Path);
+
+ arc2.SubfileIndex = mainSubfile;
+ HRESULT result = arc2.OpenStream(codecs, formatIndex, subStream, NULL, callback);
+ resSpec = (formatIndices.Size() == 0 ? S_OK : S_FALSE);
+ if (result == S_FALSE)
+ break;
+ RINOK(result);
+ RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined));
+ Arcs.Add(arc2);
}
- else
- subPath = ExtractFileNameFromPath(subPath);
-
- CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
- openArchiveCallback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
- if (setSubArchiveName)
- setSubArchiveName->SetSubArchiveName(subPath);
-
- result = OpenArchive(codecs, arcTypeIndex, subStream, subPath,
- archive1, formatIndex1, defaultItemName1, openArchiveCallback);
- resSpec = (formatIndices.Size() == 0 ? S_OK : S_FALSE);
- if (result != S_OK)
- return resSpec;
+ IsOpen = !Arcs.IsEmpty();
return S_OK;
}
-static void SetCallback(const UString &archiveName,
- IOpenCallbackUI *openCallbackUI,
+static void SetCallback(const UString &filePath,
+ IOpenCallbackUI *callbackUI,
IArchiveOpenCallback *reOpenCallback,
- CMyComPtr<IArchiveOpenCallback> &openCallback)
+ CMyComPtr<IArchiveOpenCallback> &callback)
{
COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
- openCallback = openCallbackSpec;
- openCallbackSpec->Callback = openCallbackUI;
+ callback = openCallbackSpec;
+ openCallbackSpec->Callback = callbackUI;
openCallbackSpec->ReOpenCallback = reOpenCallback;
UString fullName;
int fileNamePartStartIndex;
- NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
+ NFile::NDirectory::MyGetFullPathName(filePath, fullName, fileNamePartStartIndex);
openCallbackSpec->Init(
fullName.Left(fileNamePartStartIndex),
fullName.Mid(fileNamePartStartIndex));
}
-HRESULT MyOpenArchive(
- CCodecs *codecs,
- int arcTypeIndex,
- const UString &archiveName,
- IInArchive **archive, UString &defaultItemName, IOpenCallbackUI *openCallbackUI)
-{
- CMyComPtr<IArchiveOpenCallback> openCallback;
- SetCallback(archiveName, openCallbackUI, NULL, openCallback);
- int formatInfo;
- return OpenArchive(codecs, arcTypeIndex, archiveName, archive, formatInfo, defaultItemName, openCallback);
-}
-
-HRESULT MyOpenArchive(
- CCodecs *codecs,
+HRESULT CArchiveLink::Open2(CCodecs *codecs,
const CIntVector &formatIndices,
- const UString &archiveName,
- IInArchive **archive0,
- IInArchive **archive1,
- UString &defaultItemName0,
- UString &defaultItemName1,
- UStringVector &volumePaths,
- UInt64 &volumesSize,
- IOpenCallbackUI *openCallbackUI)
+ bool stdInMode,
+ IInStream *stream,
+ const UString &filePath,
+ IOpenCallbackUI *callbackUI)
{
- volumesSize = 0;
+ VolumesSize = 0;
COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
- CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
- openCallbackSpec->Callback = openCallbackUI;
+ CMyComPtr<IArchiveOpenCallback> callback = openCallbackSpec;
+ openCallbackSpec->Callback = callbackUI;
- UString fullName;
- int fileNamePartStartIndex;
- NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
- UString prefix = fullName.Left(fileNamePartStartIndex);
- UString name = fullName.Mid(fileNamePartStartIndex);
- openCallbackSpec->Init(prefix, name);
-
- int formatIndex0, formatIndex1;
- RINOK(OpenArchive(codecs, formatIndices, archiveName,
- archive0,
- archive1,
- formatIndex0,
- formatIndex1,
- defaultItemName0,
- defaultItemName1,
- openCallback));
- volumePaths.Add(prefix + name);
- for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)
- volumePaths.Add(prefix + openCallbackSpec->FileNames[i]);
- volumesSize = openCallbackSpec->TotalSize;
- return S_OK;
-}
+ UString fullName, prefix, name;
+ if (!stream && !stdInMode)
+ {
+ int fileNamePartStartIndex;
+ if (!NFile::NDirectory::MyGetFullPathName(filePath, fullName, fileNamePartStartIndex))
+ return GetLastError();
+ prefix = fullName.Left(fileNamePartStartIndex);
+ name = fullName.Mid(fileNamePartStartIndex);
+ openCallbackSpec->Init(prefix, name);
+ }
+ else
+ {
+ openCallbackSpec->SetSubArchiveName(filePath);
+ }
-HRESULT CArchiveLink::Close()
-{
- if (Archive1 != 0)
- RINOK(Archive1->Close());
- if (Archive0 != 0)
- RINOK(Archive0->Close());
- IsOpen = false;
+ RINOK(Open(codecs, formatIndices, stdInMode, stream, filePath, callback));
+ VolumePaths.Add(prefix + name);
+ for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)
+ VolumePaths.Add(prefix + openCallbackSpec->FileNames[i]);
+ VolumesSize = openCallbackSpec->TotalSize;
return S_OK;
}
-void CArchiveLink::Release()
-{
- IsOpen = false;
- Archive1.Release();
- Archive0.Release();
-}
-
-HRESULT OpenArchive(
- CCodecs *codecs,
- const CIntVector &formatIndices,
- const UString &archiveName,
- CArchiveLink &archiveLink,
- IArchiveOpenCallback *openCallback)
-{
- HRESULT res = OpenArchive(codecs, formatIndices, archiveName,
- &archiveLink.Archive0, &archiveLink.Archive1,
- archiveLink.FormatIndex0, archiveLink.FormatIndex1,
- archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
- openCallback);
- archiveLink.IsOpen = (res == S_OK);
- return res;
-}
-
-HRESULT MyOpenArchive(CCodecs *codecs,
- const CIntVector &formatIndices,
- const UString &archiveName,
- CArchiveLink &archiveLink,
- IOpenCallbackUI *openCallbackUI)
+HRESULT CArchiveLink::ReOpen(CCodecs *codecs, const UString &filePath,
+ IArchiveOpenCallback *callback)
{
- HRESULT res = MyOpenArchive(codecs, formatIndices, archiveName,
- &archiveLink.Archive0, &archiveLink.Archive1,
- archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
- archiveLink.VolumePaths,
- archiveLink.VolumesSize,
- openCallbackUI);
- archiveLink.IsOpen = (res == S_OK);
- return res;
-}
-
-HRESULT ReOpenArchive(CCodecs *codecs, CArchiveLink &archiveLink, const UString &fileName,
- IArchiveOpenCallback *openCallback)
-{
- if (archiveLink.GetNumLevels() > 1)
+ if (Arcs.Size() > 1)
return E_NOTIMPL;
- if (archiveLink.GetNumLevels() == 0)
- return MyOpenArchive(codecs, CIntVector(), fileName, archiveLink, 0);
+ if (Arcs.Size() == 0)
+ return Open2(codecs, CIntVector(), false, NULL, filePath, 0);
CMyComPtr<IArchiveOpenCallback> openCallbackNew;
- SetCallback(fileName, NULL, openCallback, openCallbackNew);
+ SetCallback(filePath, NULL, callback, openCallbackNew);
- HRESULT res = ReOpenArchive(archiveLink.GetArchive(), fileName, openCallbackNew);
- archiveLink.IsOpen = (res == S_OK);
+ CInFileStream *fileStreamSpec = new CInFileStream;
+ CMyComPtr<IInStream> stream(fileStreamSpec);
+ if (!fileStreamSpec->Open(filePath))
+ return GetLastError();
+ HRESULT res = GetArchive()->Open(stream, &kMaxCheckStartPosition, callback);
+ IsOpen = (res == S_OK);
return res;
}
diff --git a/CPP/7zip/UI/Common/OpenArchive.h b/CPP/7zip/UI/Common/OpenArchive.h
index f1b4fda7..92103623 100755
--- a/CPP/7zip/UI/Common/OpenArchive.h
+++ b/CPP/7zip/UI/Common/OpenArchive.h
@@ -1,117 +1,86 @@
// OpenArchive.h
-#ifndef __OPENARCHIVE_H
-#define __OPENARCHIVE_H
+#ifndef __OPEN_ARCHIVE_H
+#define __OPEN_ARCHIVE_H
#include "Common/MyString.h"
+
#include "Windows/FileFind.h"
#include "../../Archive/IArchive.h"
-#include "LoadCodecs.h"
+
#include "ArchiveOpenCallback.h"
+#include "LoadCodecs.h"
-HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result);
-HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result);
-HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
- const FILETIME &defaultFileTime, FILETIME &fileTime);
-HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result);
+HRESULT GetArchiveItemBoolProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result);
HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);
-HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result);
-struct ISetSubArchiveName
+struct CArc
{
- virtual void SetSubArchiveName(const wchar_t *name) = 0;
-};
-
-HRESULT OpenArchive(
+ CMyComPtr<IInArchive> Archive;
+ UString Path;
+ UString DefaultName;
+ int FormatIndex;
+ int SubfileIndex;
+ FILETIME MTime;
+ bool MTimeDefined;
+
+ CArc(): MTimeDefined(false) {}
+
+ HRESULT GetItemPath(UInt32 index, UString &result) const;
+ HRESULT GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const;
+ HRESULT IsItemAnti(UInt32 index, bool &result) const
+ { return GetArchiveItemBoolProp(Archive, index, kpidIsAnti, result); }
+
+ HRESULT OpenStream(
CCodecs *codecs,
- int arcTypeIndex,
- IInStream *inStream,
- const UString &fileName,
- IInArchive **archiveResult,
- int &formatIndex,
- UString &defaultItemName,
- IArchiveOpenCallback *openArchiveCallback);
-
-HRESULT OpenArchive(
- CCodecs *codecs,
- int arcTypeIndex,
- const UString &filePath,
- IInArchive **archive,
- int &formatIndex,
- UString &defaultItemName,
- IArchiveOpenCallback *openArchiveCallback);
+ int formatIndex,
+ IInStream *stream,
+ ISequentialInStream *seqStream,
+ IArchiveOpenCallback *callback);
-HRESULT OpenArchive(
+ HRESULT OpenStreamOrFile(
CCodecs *codecs,
- const CIntVector &formatIndices,
- const UString &filePath,
- IInArchive **archive0,
- IInArchive **archive1,
- int &formatIndex0,
- int &formatIndex1,
- UString &defaultItemName0,
- UString &defaultItemName1,
- IArchiveOpenCallback *openArchiveCallback);
-
-
-HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName, IArchiveOpenCallback *openArchiveCallback);
+ int formatIndex,
+ bool stdInMode,
+ IInStream *stream,
+ IArchiveOpenCallback *callback);
+};
struct CArchiveLink
{
- CMyComPtr<IInArchive> Archive0;
- CMyComPtr<IInArchive> Archive1;
- UString DefaultItemName0;
- UString DefaultItemName1;
-
- int FormatIndex0;
- int FormatIndex1;
-
+ CObjectVector<CArc> Arcs;
UStringVector VolumePaths;
-
- bool IsOpen;
UInt64 VolumesSize;
+ bool IsOpen;
- int GetNumLevels() const
- {
- int result = 0;
- if (Archive0)
- {
- result++;
- if (Archive1)
- result++;
- }
- return result;
- }
-
- CArchiveLink(): IsOpen(false), VolumesSize(0) {};
-
- IInArchive *GetArchive() { return Archive1 != 0 ? Archive1: Archive0; }
- UString GetDefaultItemName() { return Archive1 != 0 ? DefaultItemName1: DefaultItemName0; }
- int GetArchiverIndex() const { return Archive1 != 0 ? FormatIndex1: FormatIndex0; }
+ CArchiveLink(): VolumesSize(0), IsOpen(false) {}
HRESULT Close();
void Release();
-};
+ ~CArchiveLink() { Release(); }
+
+ IInArchive *GetArchive() const { return Arcs.Back().Archive; }
-HRESULT OpenArchive(
+ HRESULT Open(
CCodecs *codecs,
const CIntVector &formatIndices,
- const UString &archiveName,
- CArchiveLink &archiveLink,
- IArchiveOpenCallback *openCallback);
+ bool stdInMode,
+ IInStream *stream,
+ const UString &filePath,
+ IArchiveOpenCallback *callback);
-HRESULT MyOpenArchive(
+ HRESULT Open2(
CCodecs *codecs,
const CIntVector &formatIndices,
- const UString &archiveName,
- CArchiveLink &archiveLink,
- IOpenCallbackUI *openCallbackUI);
+ bool stdInMode,
+ IInStream *stream,
+ const UString &filePath,
+ IOpenCallbackUI *callbackUI);
-HRESULT ReOpenArchive(
+ HRESULT ReOpen(
CCodecs *codecs,
- CArchiveLink &archiveLink,
- const UString &fileName,
- IArchiveOpenCallback *openCallback);
+ const UString &filePath,
+ IArchiveOpenCallback *callback);
+};
#endif
-
diff --git a/CPP/7zip/UI/Common/PropIDUtils.cpp b/CPP/7zip/UI/Common/PropIDUtils.cpp
index bf11ea15..d8c0e7d6 100755
--- a/CPP/7zip/UI/Common/PropIDUtils.cpp
+++ b/CPP/7zip/UI/Common/PropIDUtils.cpp
@@ -2,26 +2,18 @@
#include "StdAfx.h"
-#include "PropIDUtils.h"
-
#include "Common/IntToString.h"
-#include "Common/StringConvert.h"
#include "Windows/FileFind.h"
#include "Windows/PropVariantConversions.h"
#include "../../PropID.h"
-using namespace NWindows;
+#include "PropIDUtils.h"
-static UString ConvertUInt32ToString(UInt32 value)
-{
- wchar_t buffer[32];
- ConvertUInt64ToString(value, buffer);
- return buffer;
-}
+using namespace NWindows;
-static void ConvertUInt32ToHex(UInt32 value, wchar_t *s)
+void ConvertUInt32ToHex(UInt32 value, wchar_t *s)
{
for (int i = 0; i < 8; i++)
{
@@ -32,7 +24,9 @@ static void ConvertUInt32ToHex(UInt32 value, wchar_t *s)
s[8] = L'\0';
}
-UString ConvertPropertyToString(const PROPVARIANT &propVariant, PROPID propID, bool full)
+#define MY_ATTR_CHAR(a, n, c) ((a )& (1 << (n))) ? c : L'-';
+
+UString ConvertPropertyToString(const PROPVARIANT &prop, PROPID propID, bool full)
{
switch(propID)
{
@@ -40,50 +34,63 @@ UString ConvertPropertyToString(const PROPVARIANT &propVariant, PROPID propID, b
case kpidATime:
case kpidMTime:
{
- if (propVariant.vt != VT_FILETIME)
- return UString(); // It is error;
+ if (prop.vt != VT_FILETIME)
+ break;
FILETIME localFileTime;
- if (propVariant.filetime.dwHighDateTime == 0 &&
- propVariant.filetime.dwLowDateTime == 0)
+ if ((prop.filetime.dwHighDateTime == 0 &&
+ prop.filetime.dwLowDateTime == 0) ||
+ !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
return UString();
- if (!::FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime))
- return UString(); // It is error;
return ConvertFileTimeToString(localFileTime, true, full);
}
case kpidCRC:
{
- if(propVariant.vt != VT_UI4)
+ if (prop.vt != VT_UI4)
break;
wchar_t temp[12];
- ConvertUInt32ToHex(propVariant.ulVal, temp);
+ ConvertUInt32ToHex(prop.ulVal, temp);
return temp;
}
case kpidAttrib:
{
- if(propVariant.vt != VT_UI4)
+ if (prop.vt != VT_UI4)
break;
- UString result;
- UInt32 attributes = propVariant.ulVal;
- if (NFile::NFind::NAttributes::IsReadOnly(attributes)) result += L'R';
- if (NFile::NFind::NAttributes::IsHidden(attributes)) result += L'H';
- if (NFile::NFind::NAttributes::IsSystem(attributes)) result += L'S';
- if (NFile::NFind::NAttributes::IsDir(attributes)) result += L'D';
- if (NFile::NFind::NAttributes::IsArchived(attributes)) result += L'A';
- if (NFile::NFind::NAttributes::IsCompressed(attributes)) result += L'C';
- if (NFile::NFind::NAttributes::IsEncrypted(attributes)) result += L'E';
- return result;
+ UString res;
+ UInt32 a = prop.ulVal;
+ if (NFile::NFind::NAttributes::IsReadOnly(a)) res += L'R';
+ if (NFile::NFind::NAttributes::IsHidden(a)) res += L'H';
+ if (NFile::NFind::NAttributes::IsSystem(a)) res += L'S';
+ if (NFile::NFind::NAttributes::IsDir(a)) res += L'D';
+ if (NFile::NFind::NAttributes::IsArchived(a)) res += L'A';
+ if (NFile::NFind::NAttributes::IsCompressed(a)) res += L'C';
+ if (NFile::NFind::NAttributes::IsEncrypted(a)) res += L'E';
+ return res;
}
- case kpidDictionarySize:
+ case kpidPosixAttrib:
{
- if(propVariant.vt != VT_UI4)
+ if (prop.vt != VT_UI4)
break;
- UInt32 size = propVariant.ulVal;
- if (size % (1 << 20) == 0)
- return ConvertUInt32ToString(size >> 20) + L"MB";
- if (size % (1 << 10) == 0)
- return ConvertUInt32ToString(size >> 10) + L"KB";
- return ConvertUInt32ToString(size);
+ UString res;
+ UInt32 a = prop.ulVal;
+ wchar_t temp[16];
+ temp[0] = MY_ATTR_CHAR(a, 14, L'd');
+ for (int i = 6; i >= 0; i -= 3)
+ {
+ temp[7 - i] = MY_ATTR_CHAR(a, i + 2, L'r');
+ temp[8 - i] = MY_ATTR_CHAR(a, i + 1, L'w');
+ temp[9 - i] = MY_ATTR_CHAR(a, i + 0, L'x');
+ }
+ temp[10] = 0;
+ res = temp;
+ a &= ~0x1FF;
+ a &= ~0xC000;
+ if (a != 0)
+ {
+ ConvertUInt32ToHex(a, temp);
+ res = UString(temp) + L' ' + res;
+ }
+ return res;
}
}
- return ConvertPropVariantToString(propVariant);
+ return ConvertPropVariantToString(prop);
}
diff --git a/CPP/7zip/UI/Common/PropIDUtils.h b/CPP/7zip/UI/Common/PropIDUtils.h
index 1d820976..ca14d091 100755
--- a/CPP/7zip/UI/Common/PropIDUtils.h
+++ b/CPP/7zip/UI/Common/PropIDUtils.h
@@ -1,10 +1,12 @@
// PropIDUtils.h
-#ifndef __PROPIDUTILS_H
-#define __PROPIDUTILS_H
+#ifndef __PROPID_UTILS_H
+#define __PROPID_UTILS_H
#include "Common/MyString.h"
+#include "Common/Types.h"
+void ConvertUInt32ToHex(UInt32 value, wchar_t *s);
UString ConvertPropertyToString(const PROPVARIANT &propVariant, PROPID propID, bool full = true);
#endif
diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp
index d8fee28b..8c8db8de 100755
--- a/CPP/7zip/UI/Common/Update.cpp
+++ b/CPP/7zip/UI/Common/Update.cpp
@@ -44,12 +44,6 @@ static const wchar_t *kTempFolderPrefix = L"7zE";
using namespace NUpdateArchive;
-static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream)
-{
- CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
- return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
-}
-
class COutMultiVolStream:
public IOutStream,
public CMyUnknownImp
@@ -111,7 +105,7 @@ HRESULT COutMultiVolStream::Close()
STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if(processedSize != NULL)
+ if (processedSize != NULL)
*processedSize = 0;
while(size > 0)
{
@@ -119,15 +113,15 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
{
CSubStreamInfo subStream;
- wchar_t temp[32];
- ConvertUInt64ToString(_streamIndex + 1, temp);
+ wchar_t temp[16];
+ ConvertUInt32ToString(_streamIndex + 1, temp);
UString res = temp;
while (res.Length() < 3)
res = UString(L'0') + res;
UString name = Prefix + res;
subStream.StreamSpec = new COutFileStream;
subStream.Stream = subStream.StreamSpec;
- if(!subStream.StreamSpec->Create(name, false))
+ if (!subStream.StreamSpec->Create(name, false))
return ::GetLastError();
{
// NSynchronization::CCriticalSectionLock lock(g_TempPathsCS);
@@ -173,7 +167,7 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
_length = _absPos;
if (_offsetPos > subStream.RealSize)
subStream.RealSize = _offsetPos;
- if(processedSize != NULL)
+ if (processedSize != NULL)
*processedSize += realProcessed;
if (subStream.Pos == volSize)
{
@@ -189,7 +183,7 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
- if(seekOrigin >= 3)
+ if (seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
switch(seekOrigin)
{
@@ -261,6 +255,7 @@ bool CUpdateOptions::Init(const CCodecs *codecs, const CIntVector &formatIndices
else
{
MethodMode.FormatIndex = codecs->FindFormatForArchiveName(arcPath);
+ // It works incorrectly for update command if archive has some non-default extension!
if (MethodMode.FormatIndex < 0)
MethodMode.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArchiveType);
}
@@ -292,7 +287,7 @@ struct CUpdateProduceCallbackImp: public IUpdateProduceCallback
const CObjectVector<CArcItem> *_arcItems;
IUpdateCallbackUI *_callback;
- CUpdateProduceCallbackImp(const CObjectVector<CArcItem> *a,
+ CUpdateProduceCallbackImp(const CObjectVector<CArcItem> *a,
IUpdateCallbackUI *callback): _arcItems(a), _callback(callback) {}
virtual HRESULT ShowDeleteFile(int arcIndex);
};
@@ -323,11 +318,11 @@ static HRESULT Compress(
IUpdateCallbackUI *callback)
{
CMyComPtr<IOutArchive> outArchive;
- if(archive != NULL)
+ if (archive != NULL)
{
CMyComPtr<IInArchive> archive2 = archive;
HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive);
- if(result != S_OK)
+ if (result != S_OK)
throw kUpdateIsNotSupoorted;
}
else
@@ -397,7 +392,7 @@ static HRESULT Compress(
{
UString resultPath;
int pos;
- if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
+ if (!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
throw 1417161;
NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
}
@@ -421,8 +416,8 @@ static HRESULT Compress(
{
if (i > 0)
{
- wchar_t s[32];
- ConvertUInt64ToString(i, s);
+ wchar_t s[16];
+ ConvertUInt32ToString(i, s);
archivePath.TempPostfix = s;
}
realPath = archivePath.GetTempPath();
@@ -499,7 +494,7 @@ static HRESULT Compress(
return E_FAIL;
}
}
- RINOK(CopyBlock(sfxStream, sfxOutStream));
+ RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL));
if (outStreamSpec)
{
RINOK(outStreamSpec->Close());
@@ -517,26 +512,22 @@ static HRESULT Compress(
}
HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
- IInArchive *archive,
- const UString &defaultItemName,
- const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+ const CArc &arc,
CObjectVector<CArcItem> &arcItems)
{
arcItems.Clear();
UInt32 numItems;
+ IInArchive *archive = arc.Archive;
RINOK(archive->GetNumberOfItems(&numItems));
arcItems.Reserve(numItems);
for (UInt32 i = 0; i < numItems; i++)
{
CArcItem ai;
- RINOK(GetArchiveItemPath(archive, i, ai.Name));
- // check it: defaultItemName !!!
- if (ai.Name.IsEmpty())
- ai.Name = defaultItemName;
+ RINOK(arc.GetItemPath(i, ai.Name));
RINOK(IsArchiveItemFolder(archive, i, ai.IsDir));
ai.Censored = censor.CheckPath(ai.Name, !ai.IsDir);
- RINOK(GetArchiveItemFileTime(archive, i, archiveFileInfo.MTime, ai.MTime));
+ RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined));
{
CPropVariant prop;
@@ -586,7 +577,7 @@ static HRESULT UpdateWithItemLists(
CUpdateArchiveCommand &command = options.Commands[i];
if (options.StdOutMode)
{
- RINOK(callback->StartArchive(0, archive != 0));
+ RINOK(callback->StartArchive(L"stdout", archive != 0));
}
else
{
@@ -684,12 +675,10 @@ HRESULT UpdateArchive(
const UString archiveName = options.ArchivePath.GetFinalPath();
- UString defaultItemName;
+ CArchiveLink archiveLink;
NFind::CFileInfoW archiveFileInfo;
- CArchiveLink archiveLink;
- IInArchive *archive = 0;
- if (NFind::FindFile(archiveName, archiveFileInfo))
+ if (archiveFileInfo.Find(archiveName))
{
if (archiveFileInfo.IsDir())
throw "there is no such archive";
@@ -698,7 +687,7 @@ HRESULT UpdateArchive(
CIntVector formatIndices;
if (options.MethodMode.FormatIndex >= 0)
formatIndices.Add(options.MethodMode.FormatIndex);
- HRESULT result = MyOpenArchive(codecs, formatIndices, archiveName, archiveLink, openCallback);
+ HRESULT result = archiveLink.Open2(codecs, formatIndices, false, NULL, archiveName, openCallback);
if (result == E_ABORT)
return result;
RINOK(callback->OpenResult(archiveName, result));
@@ -709,8 +698,10 @@ HRESULT UpdateArchive(
errorInfo.Message = L"Updating for multivolume archives is not implemented";
return E_NOTIMPL;
}
- archive = archiveLink.GetArchive();
- defaultItemName = archiveLink.GetDefaultItemName();
+
+ CArc &arc = archiveLink.Arcs.Back();
+ arc.MTimeDefined = !archiveFileInfo.IsDevice;
+ arc.MTime = archiveFileInfo.MTime;
}
else
{
@@ -777,12 +768,15 @@ HRESULT UpdateArchive(
CTempFiles tempFiles;
bool createTempFile = false;
- if(!options.StdOutMode && options.UpdateArchiveItself)
+
+ bool thereIsInArchive = archiveLink.IsOpen;
+
+ if (!options.StdOutMode && options.UpdateArchiveItself)
{
CArchivePath &ap = options.Commands[0].ArchivePath;
ap = options.ArchivePath;
// if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty())
- if ((archive != 0 || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0)
+ if ((thereIsInArchive || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0)
{
createTempFile = true;
ap.Temp = true;
@@ -807,7 +801,7 @@ HRESULT UpdateArchive(
if (i > 0 || !createTempFile)
{
const UString &path = ap.GetFinalPath();
- if (NFind::DoesFileExist(path))
+ if (NFind::DoesFileOrDirExist(path))
{
errorInfo.SystemError = 0;
errorInfo.Message = L"File already exists";
@@ -818,29 +812,30 @@ HRESULT UpdateArchive(
}
CObjectVector<CArcItem> arcItems;
- if (archive != NULL)
+ if (thereIsInArchive)
{
- RINOK(EnumerateInArchiveItems(censor,
- archive, defaultItemName, archiveFileInfo, arcItems));
+ RINOK(EnumerateInArchiveItems(censor, archiveLink.Arcs.Back(), arcItems));
}
- RINOK(UpdateWithItemLists(codecs, options, archive, arcItems, dirItems,
+ RINOK(UpdateWithItemLists(codecs, options,
+ thereIsInArchive ? archiveLink.GetArchive() : 0,
+ arcItems, dirItems,
tempFiles, errorInfo, callback));
- if (archive != NULL)
+ if (thereIsInArchive)
{
RINOK(archiveLink.Close());
archiveLink.Release();
}
tempFiles.Paths.Clear();
- if(createTempFile)
+ if (createTempFile)
{
try
{
CArchivePath &ap = options.Commands[0].ArchivePath;
const UString &tempPath = ap.GetTempPath();
- if (archive != NULL)
+ if (thereIsInArchive)
if (!NDirectory::DeleteFileAlways(archiveName))
{
errorInfo.SystemError = ::GetLastError();
@@ -887,7 +882,7 @@ HRESULT UpdateArchive(
{
CArchivePath &ap = options.Commands[i].ArchivePath;
UString arcPath;
- if(!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath))
+ if (!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath))
{
errorInfo.SystemError = ::GetLastError();
return E_FAIL;
diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp
index dcca2a1a..0f229058 100755
--- a/CPP/7zip/UI/Common/UpdateCallback.cpp
+++ b/CPP/7zip/UI/Common/UpdateCallback.cpp
@@ -2,17 +2,17 @@
#include "StdAfx.h"
-#include "UpdateCallback.h"
-
-#include "Common/StringConvert.h"
-#include "Common/IntToString.h"
-#include "Common/Defs.h"
#include "Common/ComTry.h"
+#include "Common/Defs.h"
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
#include "Windows/PropVariant.h"
#include "../../Common/FileStreams.h"
+#include "UpdateCallback.h"
+
using namespace NWindows;
CArchiveUpdateCallback::CArchiveUpdateCallback():
@@ -216,8 +216,8 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
{
COM_TRY_BEGIN
- wchar_t temp[32];
- ConvertUInt64ToString(index + 1, temp);
+ wchar_t temp[16];
+ ConvertUInt32ToString(index + 1, temp);
UString res = temp;
while (res.Length() < 2)
res = UString(L'0') + res;
@@ -240,3 +240,10 @@ STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDef
return Callback->CryptoGetTextPassword2(passwordIsDefined, password);
COM_TRY_END
}
+
+STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)
+{
+ COM_TRY_BEGIN
+ return Callback->CryptoGetTextPassword(password);
+ COM_TRY_END
+}
diff --git a/CPP/7zip/UI/Common/UpdateCallback.h b/CPP/7zip/UI/Common/UpdateCallback.h
index 2a814b37..50803f52 100755
--- a/CPP/7zip/UI/Common/UpdateCallback.h
+++ b/CPP/7zip/UI/Common/UpdateCallback.h
@@ -23,6 +23,7 @@
virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError) x; \
virtual HRESULT SetOperationResult(Int32 operationResult) x; \
virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \
+ virtual HRESULT CryptoGetTextPassword(BSTR *password) x; \
// virtual HRESULT ShowDeleteFile(const wchar_t *name) x; \
// virtual HRESULT CloseProgress() { return S_OK; };
@@ -34,13 +35,15 @@ struct IUpdateCallbackUI
class CArchiveUpdateCallback:
public IArchiveUpdateCallback2,
public ICryptoGetTextPassword2,
+ public ICryptoGetTextPassword,
public ICompressProgressInfo,
public CMyUnknownImp
{
public:
- MY_UNKNOWN_IMP3(
+ MY_UNKNOWN_IMP4(
IArchiveUpdateCallback2,
ICryptoGetTextPassword2,
+ ICryptoGetTextPassword,
ICompressProgressInfo)
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
@@ -48,6 +51,7 @@ public:
INTERFACE_IArchiveUpdateCallback2(;)
STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
+ STDMETHOD(CryptoGetTextPassword)(BSTR *password);
public:
CRecordVector<UInt64> VolumesSizes;
diff --git a/CPP/7zip/UI/Common/UpdatePair.cpp b/CPP/7zip/UI/Common/UpdatePair.cpp
index f6727cbf..a43a9e77 100755
--- a/CPP/7zip/UI/Common/UpdatePair.cpp
+++ b/CPP/7zip/UI/Common/UpdatePair.cpp
@@ -6,10 +6,11 @@
#include "Common/Defs.h"
#include "Common/Wildcard.h"
+
#include "Windows/Time.h"
-#include "UpdatePair.h"
#include "SortUtils.h"
+#include "UpdatePair.h"
using namespace NWindows;
using namespace NTime;
@@ -117,20 +118,16 @@ void GetUpdatePairInfoList(
ThrowError(kNotCensoredCollisionMessaged, dirNames[dirIndex2], ai.Name);
pair.DirIndex = dirIndex2;
pair.ArcIndex = arcIndex2;
- switch (MyCompareTime(
+ switch (ai.MTimeDefined ? MyCompareTime(
ai.TimeType != - 1 ? (NFileTimeType::EEnum)ai.TimeType : fileTimeType,
- di.MTime, ai.MTime))
+ di.MTime, ai.MTime): 0)
{
case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break;
case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break;
default:
- if (ai.SizeDefined)
- if (di.Size != ai.Size)
- pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles;
- else
- pair.State = NUpdateArchive::NPairState::kSameFiles;
- else
- pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles;
+ pair.State = (ai.SizeDefined && di.Size == ai.Size) ?
+ NUpdateArchive::NPairState::kSameFiles :
+ NUpdateArchive::NPairState::kUnknowNewerFiles;
}
dirIndex++;
arcIndex++;
diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp
index 4bba19f8..16df878f 100755
--- a/CPP/7zip/UI/Common/ZipRegistry.cpp
+++ b/CPP/7zip/UI/Common/ZipRegistry.cpp
@@ -46,7 +46,7 @@ void SaveExtractionInfo(const NExtract::CInfo &info)
for(int i = 0; i < info.Paths.Size(); i++)
{
wchar_t numberString[16];
- ConvertUInt64ToString(i, numberString);
+ ConvertUInt32ToString(i, numberString);
pathHistoryKey.SetValue(numberString, info.Paths[i]);
}
}
@@ -75,7 +75,7 @@ void ReadExtractionInfo(NExtract::CInfo &info)
for (;;)
{
wchar_t numberString[16];
- ConvertUInt64ToString(info.Paths.Size(), numberString);
+ ConvertUInt32ToString(info.Paths.Size(), numberString);
UString path;
if (pathHistoryKey.QueryValue(numberString, path) != ERROR_SUCCESS)
break;
@@ -180,7 +180,7 @@ void SaveCompressionInfo(const NCompression::CInfo &info)
for(int i = 0; i < info.HistoryArchives.Size(); i++)
{
wchar_t numberString[16];
- ConvertUInt64ToString(i, numberString);
+ ConvertUInt32ToString(i, numberString);
historyArchivesKey.SetValue(numberString, info.HistoryArchives[i]);
}
}
@@ -246,7 +246,7 @@ void ReadCompressionInfo(NCompression::CInfo &info)
for (;;)
{
wchar_t numberString[16];
- ConvertUInt64ToString(info.HistoryArchives.Size(), numberString);
+ ConvertUInt32ToString(info.HistoryArchives.Size(), numberString);
UString path;
if (historyArchivesKey.QueryValue(numberString, path) != ERROR_SUCCESS)
break;