diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/UI/Console')
23 files changed, 4207 insertions, 1262 deletions
diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp index d0e432226a6..a7c9e6762c8 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.cpp @@ -23,7 +23,7 @@ void CPrintBenchCallback::Print(const char *s) void CPrintBenchCallback::NewLine() { - Print("\n"); + fputc('\n', _file); } HRESULT CPrintBenchCallback::CheckBreak() @@ -32,11 +32,10 @@ HRESULT CPrintBenchCallback::CheckBreak() } HRESULT BenchCon(DECL_EXTERNAL_CODECS_LOC_VARS - const CObjectVector<CProperty> props, UInt32 numIterations, FILE *f) + const CObjectVector<CProperty> &props, UInt32 numIterations, FILE *f) { CPrintBenchCallback callback; callback._file = f; - callback.NewLine(); return Bench(EXTERNAL_CODECS_LOC_VARS &callback, NULL, props, numIterations, true); } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h b/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h index 739721864bb..c9da1de399c 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/BenchCon.h @@ -9,6 +9,6 @@ #include "../../UI/Common/Property.h" HRESULT BenchCon(DECL_EXTERNAL_CODECS_LOC_VARS - const CObjectVector<CProperty> props, UInt32 numIterations, FILE *f); + const CObjectVector<CProperty> &props, UInt32 numIterations, FILE *f); #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/Console.mak b/3rdparty/lzma/CPP/7zip/UI/Console/Console.mak new file mode 100644 index 00000000000..05a07e5ad8a --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/Console/Console.mak @@ -0,0 +1,36 @@ +CONSOLE_OBJS = \ + $O\BenchCon.obj \ + $O\ConsoleClose.obj \ + $O\ExtractCallbackConsole.obj \ + $O\HashCon.obj \ + $O\List.obj \ + $O\Main.obj \ + $O\MainAr.obj \ + $O\OpenCallbackConsole.obj \ + $O\PercentPrinter.obj \ + $O\UpdateCallbackConsole.obj \ + $O\UserInputUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveCommandLine.obj \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\Bench.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\HashCalc.obj \ + $O\LoadCodecs.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SetProperties.obj \ + $O\SortUtils.obj \ + $O\TempFiles.obj \ + $O\Update.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + +# diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp index 5acae942dd8..734981886d0 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp @@ -4,11 +4,15 @@ #include "ConsoleClose.h" -static int g_BreakCounter = 0; -static const int kBreakAbortThreshold = 2; +#if !defined(UNDER_CE) && defined(_WIN32) +#include "../../../Common/MyWindows.h" +#endif namespace NConsoleClose { +unsigned g_BreakCounter = 0; +static const unsigned kBreakAbortThreshold = 2; + #if !defined(UNDER_CE) && defined(_WIN32) static BOOL WINAPI HandlerRoutine(DWORD ctrlType) { @@ -23,7 +27,7 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType) return TRUE; return FALSE; /* - switch(ctrlType) + switch (ctrlType) { case CTRL_C_EVENT: case CTRL_BREAK_EVENT: @@ -35,29 +39,18 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType) } #endif -bool TestBreakSignal() -{ - #ifdef UNDER_CE - return false; - #else - /* - if (g_BreakCounter > 0) - return true; - */ - return (g_BreakCounter > 0); - #endif -} - +/* void CheckCtrlBreak() { if (TestBreakSignal()) throw CCtrlBreakException(); } +*/ CCtrlHandlerSetter::CCtrlHandlerSetter() { #if !defined(UNDER_CE) && defined(_WIN32) - if(!SetConsoleCtrlHandler(HandlerRoutine, TRUE)) + if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE)) throw "SetConsoleCtrlHandler fails"; #endif } @@ -65,7 +58,7 @@ CCtrlHandlerSetter::CCtrlHandlerSetter() CCtrlHandlerSetter::~CCtrlHandlerSetter() { #if !defined(UNDER_CE) && defined(_WIN32) - if(!SetConsoleCtrlHandler(HandlerRoutine, FALSE)) + if (!SetConsoleCtrlHandler(HandlerRoutine, FALSE)) throw "SetConsoleCtrlHandler fails"; #endif } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h b/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h index 9019c4ce2bd..11c1631ca71 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/ConsoleClose.h @@ -1,11 +1,20 @@ -// ConsoleCloseUtils.h +// ConsoleClose.h -#ifndef __CONSOLECLOSEUTILS_H -#define __CONSOLECLOSEUTILS_H +#ifndef __CONSOLE_CLOSE_H +#define __CONSOLE_CLOSE_H namespace NConsoleClose { -bool TestBreakSignal(); +extern unsigned g_BreakCounter; + +inline bool TestBreakSignal() +{ + #ifdef UNDER_CE + return false; + #else + return (g_BreakCounter != 0); + #endif +} class CCtrlHandlerSetter { @@ -17,7 +26,7 @@ public: class CCtrlBreakException {}; -void CheckCtrlBreak(); +// void CheckCtrlBreak(); } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp index af379861737..8dac7fbc3e9 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp @@ -1,40 +1,156 @@ -// ExtractCallbackConsole.h +// ExtractCallbackConsole.cpp #include "StdAfx.h" -#include "ExtractCallbackConsole.h" -#include "UserInputUtils.h" -#include "ConsoleClose.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/Wildcard.h" -#include "Common/Wildcard.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/TimeUtils.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/PropVariantConv.h" -#include "Windows/FileDir.h" -#include "Windows/FileFind.h" -#include "Windows/Time.h" -#include "Windows/Defs.h" -#include "Windows/PropVariant.h" -#include "Windows/Error.h" -#include "Windows/PropVariantConversions.h" +#ifndef _7ZIP_ST +#include "../../../Windows/Synchronization.h" +#endif #include "../../Common/FilePathAutoRename.h" #include "../Common/ExtractingFilePath.h" +#include "ConsoleClose.h" +#include "ExtractCallbackConsole.h" +#include "UserInputUtils.h" + using namespace NWindows; using namespace NFile; -using namespace NDirectory; +using namespace NDir; -static const char *kTestString = "Testing "; -static const char *kExtractString = "Extracting "; -static const char *kSkipString = "Skipping "; +static HRESULT CheckBreak2() +{ + return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; +} + +static const char *kError = "ERROR: "; + + +void CExtractScanConsole::StartScanning() +{ + if (NeedPercents()) + _percent.Command = "Scan"; +} + +HRESULT CExtractScanConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */) +{ + if (NeedPercents()) + { + _percent.Files = st.NumDirs + st.NumFiles; + _percent.Completed = st.GetTotalBytes(); + _percent.FileName = fs2us(path); + _percent.Print(); + } + + return CheckBreak2(); +} + +HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError) +{ + ClosePercentsAndFlush(); + + if (_se) + { + *_se << endl << kError << NError::MyFormatMessage(systemError) << endl << + fs2us(path) << endl << endl; + _se->Flush(); + } + return HRESULT_FROM_WIN32(systemError); +} + + +void Print_UInt64_and_String(AString &s, UInt64 val, const char *name) +{ + char temp[32]; + ConvertUInt64ToString(val, temp); + s += temp; + s.Add_Space(); + s += name; +} + +void PrintSize_bytes_Smart(AString &s, UInt64 val) +{ + Print_UInt64_and_String(s, val, "bytes"); + + if (val == 0) + return; + + unsigned numBits = 10; + char c = 'K'; + char temp[4] = { 'K', 'i', 'B', 0 }; + if (val >= ((UInt64)10 << 30)) { numBits = 30; c = 'G'; } + else if (val >= ((UInt64)10 << 20)) { numBits = 20; c = 'M'; } + temp[0] = c; + s += " ("; + Print_UInt64_and_String(s, ((val + ((UInt64)1 << numBits) - 1) >> numBits), temp); + s += ')'; +} + +void Print_DirItemsStat(AString &s, const CDirItemsStat &st) +{ + if (st.NumDirs != 0) + { + Print_UInt64_and_String(s, st.NumDirs, st.NumDirs == 1 ? "folder" : "folders"); + s += ", "; + } + Print_UInt64_and_String(s, st.NumFiles, st.NumFiles == 1 ? "file" : "files"); + s += ", "; + PrintSize_bytes_Smart(s, st.FilesSize); + if (st.NumAltStreams != 0) + { + s.Add_LF(); + Print_UInt64_and_String(s, st.NumAltStreams, "alternate streams"); + s += ", "; + PrintSize_bytes_Smart(s, st.AltStreamsSize); + } +} + +void CExtractScanConsole::PrintStat(const CDirItemsStat &st) +{ + if (_so) + { + AString s; + Print_DirItemsStat(s, st); + *_so << s << endl; + } +} + + + + + + + +#ifndef _7ZIP_ST +static NSynchronization::CCriticalSection g_CriticalSection; +#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); +#else +#define MT_LOCK +#endif + + +static const char *kTestString = "T"; +static const char *kExtractString = "-"; +static const char *kSkipString = "."; // static const char *kCantAutoRename = "can not create file with auto name\n"; // static const char *kCantRenameFile = "can not rename existing file\n"; // static const char *kCantDeleteOutputFile = "can not delete output file "; -static const char *kError = "ERROR: "; + static const char *kMemoryExceptionMessage = "Can't allocate required memory!"; -static const char *kProcessing = "Processing archive: "; +static const char *kExtracting = "Extracting archive: "; +static const char *kTesting = "Testing archive: "; + static const char *kEverythingIsOk = "Everything is Ok"; static const char *kNoFiles = "No files to process"; @@ -43,34 +159,96 @@ static const char *kCrcFailed = "CRC Failed"; static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?"; static const char *kDataError = "Data Error"; static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?"; -static const char *kUnknownError = "Unknown Error"; +static const char *kUnavailableData = "Unavailable data"; +static const char *kUnexpectedEnd = "Unexpected end of data"; +static const char *kDataAfterEnd = "There are some data after the end of the payload data"; +static const char *kIsNotArc = "Is not archive"; +static const char *kHeadersError = "Headers Error"; +static const char *kWrongPassword = "Wrong password"; -STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64) +static const char * const k_ErrorFlagsMessages[] = { - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - return S_OK; + "Is not archive" + , "Headers Error" + , "Headers Error in encrypted archive. Wrong password?" + , "Unavailable start of archive" + , "Unconfirmed start of archive" + , "Unexpected end of archive" + , "There are data after the end of archive" + , "Unsupported method" + , "Unsupported feature" + , "Data Error" + , "CRC Error" +}; + +STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64 size) +{ + MT_LOCK + + if (NeedPercents()) + { + _percent.Total = size; + _percent.Print(); + } + return CheckBreak2(); } -STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *) +STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue) { - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - return S_OK; + MT_LOCK + + if (NeedPercents()) + { + if (completeValue) + _percent.Completed = *completeValue; + _percent.Print(); + } + return CheckBreak2(); +} + +static const char *kTab = " "; + +static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size) +{ + *_so << kTab << "Path: " << path << endl; + if (size) + { + AString s; + PrintSize_bytes_Smart(s, *size); + *_so << kTab << "Size: " << s << endl; + } + if (ft) + { + char temp[64]; + FILETIME locTime; + if (FileTimeToLocalFileTime(ft, &locTime)) + if (ConvertFileTimeToString(locTime, temp, true, true)) + *_so << kTab << "Modified: " << temp << endl; + } } STDMETHODIMP CExtractCallbackConsole::AskOverwrite( - const wchar_t *existName, const FILETIME *, const UInt64 *, - const wchar_t *newName, const FILETIME *, const UInt64 *, + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, Int32 *answer) { - (*OutStream) << "file " << existName << - "\nalready exists. Overwrite with " << endl; - (*OutStream) << newName; + MT_LOCK + + RINOK(CheckBreak2()); + + ClosePercentsAndFlush(); + + if (_so) + { + *_so << endl << "Would you like to replace the existing file:\n"; + PrintFileInfo(_so, existName, existTime, existSize); + *_so << "with the file from archive:\n"; + PrintFileInfo(_so, newName, newTime, newSize); + } - NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream); + NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(_so); - switch(overwriteAnswer) + switch (overwriteAnswer) { case NUserAnswerMode::kQuit: return E_ABORT; case NUserAnswerMode::kNo: *answer = NOverwriteAnswer::kNo; break; @@ -80,62 +258,192 @@ STDMETHODIMP CExtractCallbackConsole::AskOverwrite( case NUserAnswerMode::kAutoRenameAll: *answer = NOverwriteAnswer::kAutoRename; break; default: return E_FAIL; } - return S_OK; + + if (_so) + { + *_so << endl; + if (NeedFlush) + _so->Flush(); + } + + return CheckBreak2(); } -STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, bool /* isFolder */, Int32 askExtractMode, const UInt64 *position) +STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 /* isFolder */, Int32 askExtractMode, const UInt64 *position) { + MT_LOCK + + _currentName = name; + + const char *s; + unsigned requiredLevel = 1; + switch (askExtractMode) { - case NArchive::NExtract::NAskMode::kExtract: (*OutStream) << kExtractString; break; - case NArchive::NExtract::NAskMode::kTest: (*OutStream) << kTestString; break; - case NArchive::NExtract::NAskMode::kSkip: (*OutStream) << kSkipString; break; + case NArchive::NExtract::NAskMode::kExtract: s = kExtractString; break; + case NArchive::NExtract::NAskMode::kTest: s = kTestString; break; + case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; requiredLevel = 2; break; + default: s = "???"; requiredLevel = 2; }; - (*OutStream) << name; - if (position != 0) - (*OutStream) << " <" << *position << ">"; - return S_OK; + + bool show2 = (LogLevel >= requiredLevel && _so); + + if (show2) + { + ClosePercents_for_so(); + + _tempA = s; + if (name) + _tempA.Add_Space(); + *_so << _tempA; + + _tempU.Empty(); + if (name) + _tempU = name; + _so->PrintUString(_tempU, _tempA); + if (position) + *_so << " <" << *position << ">"; + *_so << endl; + + if (NeedFlush) + _so->Flush(); + } + + if (NeedPercents()) + { + if (PercentsNameLevel >= 1) + { + _percent.FileName.Empty(); + _percent.Command.Empty(); + if (PercentsNameLevel > 1 || !show2) + { + _percent.Command = s; + if (name) + _percent.FileName = name; + } + } + _percent.Print(); + } + + return CheckBreak2(); } STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message) { - (*OutStream) << message << endl; - NumFileErrorsInCurrentArchive++; + MT_LOCK + + RINOK(CheckBreak2()); + + NumFileErrors_in_Current++; NumFileErrors++; - return S_OK; + + ClosePercentsAndFlush(); + if (_se) + { + *_se << kError << message << endl; + _se->Flush(); + } + + return CheckBreak2(); +} + +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest) +{ + dest.Empty(); + const char *s = NULL; + + switch (opRes) + { + case NArchive::NExtract::NOperationResult::kUnsupportedMethod: + s = kUnsupportedMethod; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + s = (encrypted ? kCrcFailedEncrypted : kCrcFailed); + break; + case NArchive::NExtract::NOperationResult::kDataError: + s = (encrypted ? kDataErrorEncrypted : kDataError); + break; + case NArchive::NExtract::NOperationResult::kUnavailable: + s = kUnavailableData; + break; + case NArchive::NExtract::NOperationResult::kUnexpectedEnd: + s = kUnexpectedEnd; + break; + case NArchive::NExtract::NOperationResult::kDataAfterEnd: + s = kDataAfterEnd; + break; + case NArchive::NExtract::NOperationResult::kIsNotArc: + s = kIsNotArc; + break; + case NArchive::NExtract::NOperationResult::kHeadersError: + s = kHeadersError; + break; + case NArchive::NExtract::NOperationResult::kWrongPassword: + s = kWrongPassword; + break; + } + + dest += kError; + if (s) + dest += s; + else + { + char temp[16]; + ConvertUInt32ToString(opRes, temp); + dest += "Error #"; + dest += temp; + } } -STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted) +STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encrypted) { - switch(operationResult) + MT_LOCK + + if (opRes == NArchive::NExtract::NOperationResult::kOK) { - case NArchive::NExtract::NOperationResult::kOK: - break; - default: + if (NeedPercents()) { - NumFileErrorsInCurrentArchive++; - NumFileErrors++; - (*OutStream) << " "; - switch(operationResult) - { - case NArchive::NExtract::NOperationResult::kUnSupportedMethod: - (*OutStream) << kUnsupportedMethod; - break; - case NArchive::NExtract::NOperationResult::kCRCError: - (*OutStream) << (encrypted ? kCrcFailedEncrypted: kCrcFailed); - break; - case NArchive::NExtract::NOperationResult::kDataError: - (*OutStream) << (encrypted ? kDataErrorEncrypted : kDataError); - break; - default: - (*OutStream) << kUnknownError; - } + _percent.Command.Empty(); + _percent.FileName.Empty(); + _percent.Files++; } } - (*OutStream) << endl; - return S_OK; + else + { + NumFileErrors_in_Current++; + NumFileErrors++; + + if (_se) + { + ClosePercentsAndFlush(); + + AString s; + SetExtractErrorMessage(opRes, encrypted, s); + + *_se << s; + if (!_currentName.IsEmpty()) + *_se << " : " << _currentName; + *_se << endl; + _se->Flush(); + } + } + + return CheckBreak2(); +} + +STDMETHODIMP CExtractCallbackConsole::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name) +{ + if (opRes != NArchive::NExtract::NOperationResult::kOK) + { + _currentName = name; + return SetOperationResult(opRes, encrypted); + } + + return CheckBreak2(); } + + #ifndef _NO_CRYPTO HRESULT CExtractCallbackConsole::SetPassword(const UString &password) @@ -147,78 +455,310 @@ HRESULT CExtractCallbackConsole::SetPassword(const UString &password) STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password) { - if (!PasswordIsDefined) - { - Password = GetPassword(OutStream); - PasswordIsDefined = true; - } - return StringToBstr(Password, password); + COM_TRY_BEGIN + MT_LOCK + return Open_CryptoGetTextPassword(password); + COM_TRY_END } #endif -HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name) +HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name, bool testMode) { - NumArchives++; - NumFileErrorsInCurrentArchive = 0; - (*OutStream) << endl << kProcessing << name << endl; + RINOK(CheckBreak2()); + + NumTryArcs++; + ThereIsError_in_Current = false; + ThereIsWarning_in_Current = false; + NumFileErrors_in_Current = 0; + + ClosePercents_for_so(); + if (_so) + *_so << endl << (testMode ? kTesting : kExtracting) << name << endl; + + if (NeedPercents()) + _percent.Command = "Open"; return S_OK; } -HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT result, bool encrypted) +HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); +HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); + +static AString GetOpenArcErrorMessage(UInt32 errorFlags) { - (*OutStream) << endl; - if (result != S_OK) + AString s; + + for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsMessages); i++) + { + UInt32 f = (1 << i); + if ((errorFlags & f) == 0) + continue; + const char *m = k_ErrorFlagsMessages[i]; + if (!s.IsEmpty()) + s.Add_LF(); + s += m; + errorFlags &= ~f; + } + + if (errorFlags != 0) { - (*OutStream) << "Error: "; - if (result == S_FALSE) + char sz[16]; + sz[0] = '0'; + sz[1] = 'x'; + ConvertUInt32ToHex(errorFlags, sz + 2); + if (!s.IsEmpty()) + s.Add_LF(); + s += sz; + } + + return s; +} + +void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags) +{ + if (errorFlags == 0) + return; + so << s << endl << GetOpenArcErrorMessage(errorFlags) << endl; +} + +void Add_Messsage_Pre_ArcType(UString &s, const char *pre, const wchar_t *arcType) +{ + s.Add_LF(); + s.AddAscii(pre); + s.AddAscii(" as ["); + s += arcType; + s.AddAscii("] archive"); +} + +void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc) +{ + const CArcErrorInfo &er = arc.ErrorInfo; + + UString s = L"WARNING:\n"; + s += arc.Path; + if (arc.FormatIndex == er.ErrorFormatIndex) + { + s.Add_LF(); + s.AddAscii("The archive is open with offset"); + } + else + { + Add_Messsage_Pre_ArcType(s, "Can not open the file", codecs->GetFormatNamePtr(er.ErrorFormatIndex)); + Add_Messsage_Pre_ArcType(s, "The file is open", codecs->GetFormatNamePtr(arc.FormatIndex)); + } + + *_so << s << endl << endl; +} + + +HRESULT CExtractCallbackConsole::OpenResult( + const CCodecs *codecs, const CArchiveLink &arcLink, + const wchar_t *name, HRESULT result) +{ + ClosePercents(); + + if (NeedPercents()) + { + _percent.Files = 0; + _percent.Command.Empty(); + _percent.FileName.Empty(); + } + + + ClosePercentsAndFlush(); + + FOR_VECTOR (level, arcLink.Arcs) + { + const CArc &arc = arcLink.Arcs[level]; + const CArcErrorInfo &er = arc.ErrorInfo; + + UInt32 errorFlags = er.GetErrorFlags(); + + if (errorFlags != 0 || !er.ErrorMessage.IsEmpty()) { - (*OutStream) << (encrypted ? - "Can not open encrypted archive. Wrong password?" : - "Can not open file as archive"); + if (_se) + { + *_se << endl; + if (level != 0) + *_se << arc.Path << endl; + } + + if (errorFlags != 0) + { + if (_se) + PrintErrorFlags(*_se, "ERRORS:", errorFlags); + NumOpenArcErrors++; + ThereIsError_in_Current = true; + } + + if (!er.ErrorMessage.IsEmpty()) + { + if (_se) + *_se << "ERRORS:" << endl << er.ErrorMessage << endl; + NumOpenArcErrors++; + ThereIsError_in_Current = true; + } + + if (_se) + { + *_se << endl; + _se->Flush(); + } } - else + + UInt32 warningFlags = er.GetWarningFlags(); + + if (warningFlags != 0 || !er.WarningMessage.IsEmpty()) { - if (result == E_OUTOFMEMORY) - (*OutStream) << "Can't allocate required memory"; + if (_so) + { + *_so << endl; + if (level != 0) + *_so << arc.Path << endl; + } + + if (warningFlags != 0) + { + if (_so) + PrintErrorFlags(*_so, "WARNINGS:", warningFlags); + NumOpenArcWarnings++; + ThereIsWarning_in_Current = true; + } + + if (!er.WarningMessage.IsEmpty()) + { + if (_so) + *_so << "WARNINGS:" << endl << er.WarningMessage << endl; + NumOpenArcWarnings++; + ThereIsWarning_in_Current = true; + } + + if (_so) + { + *_so << endl; + if (NeedFlush) + _so->Flush(); + } + } + + + if (er.ErrorFormatIndex >= 0) + { + if (_so) + { + Print_ErrorFormatIndex_Warning(_so, codecs, arc); + if (NeedFlush) + _so->Flush(); + } + ThereIsWarning_in_Current = true; + } + } + + if (result == S_OK) + { + if (_so) + { + RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)); + *_so << endl; + } + } + else + { + NumCantOpenArcs++; + if (_so) + _so->Flush(); + if (_se) + { + *_se << kError << name << endl; + HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); + RINOK(res); + if (result == S_FALSE) + { + } else - (*OutStream) << NError::MyFormatMessageW(result); + { + if (result == E_OUTOFMEMORY) + *_se << "Can't allocate required memory"; + else + *_se << NError::MyFormatMessage(result); + *_se << endl; + } + _se->Flush(); } - (*OutStream) << endl; - NumArchiveErrors++; } - return S_OK; + + + return CheckBreak2(); } HRESULT CExtractCallbackConsole::ThereAreNoFiles() { - (*OutStream) << endl << kNoFiles << endl; - return S_OK; + ClosePercents_for_so(); + + if (_so) + { + *_so << endl << kNoFiles << endl; + if (NeedFlush) + _so->Flush(); + } + return CheckBreak2(); } HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result) { + MT_LOCK + + if (NeedPercents()) + { + _percent.ClosePrint(true); + _percent.Command.Empty(); + _percent.FileName.Empty(); + } + + if (_so) + _so->Flush(); + if (result == S_OK) { - (*OutStream) << endl; - if (NumFileErrorsInCurrentArchive == 0) - (*OutStream) << kEverythingIsOk << endl; + if (NumFileErrors_in_Current == 0 && !ThereIsError_in_Current) + { + if (ThereIsWarning_in_Current) + NumArcsWithWarnings++; + else + NumOkArcs++; + if (_so) + *_so << kEverythingIsOk << endl; + } else { - NumArchiveErrors++; - (*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl; + NumArcsWithError++; + if (_so) + { + *_so << endl; + if (NumFileErrors_in_Current != 0) + *_so << "Sub items Errors: " << NumFileErrors_in_Current << endl; + } } + if (_so && NeedFlush) + _so->Flush(); } - if (result == S_OK) - return result; - NumArchiveErrors++; - if (result == E_ABORT || result == ERROR_DISK_FULL) - return result; - (*OutStream) << endl << kError; - if (result == E_OUTOFMEMORY) - (*OutStream) << kMemoryExceptionMessage; else - (*OutStream) << NError::MyFormatMessageW(result); - (*OutStream) << endl; - return S_OK; + { + NumArcsWithError++; + if (result == E_ABORT || result == ERROR_DISK_FULL) + return result; + + if (_se) + { + *_se << endl << kError; + if (result == E_OUTOFMEMORY) + *_se << kMemoryExceptionMessage; + else + *_se << NError::MyFormatMessage(result); + *_se << endl; + _se->Flush(); + } + } + + return CheckBreak2(); } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h b/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h index e42ca6f403b..dc659521e03 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h @@ -1,24 +1,95 @@ // ExtractCallbackConsole.h -#ifndef __EXTRACTCALLBACKCONSOLE_H -#define __EXTRACTCALLBACKCONSOLE_H +#ifndef __EXTRACT_CALLBACK_CONSOLE_H +#define __EXTRACT_CALLBACK_CONSOLE_H + +#include "../../../Common/StdOutStream.h" -#include "Common/MyString.h" -#include "Common/StdOutStream.h" -#include "../../Common/FileStreams.h" #include "../../IPassword.h" + #include "../../Archive/IArchive.h" + #include "../Common/ArchiveExtractCallback.h" +#include "PercentPrinter.h" + +#include "OpenCallbackConsole.h" + +class CExtractScanConsole: public IDirItemsCallback +{ + CStdOutStream *_so; + CStdOutStream *_se; + CPercentPrinter _percent; + + bool NeedPercents() const { return _percent._so != NULL; } + + void ClosePercentsAndFlush() + { + if (NeedPercents()) + _percent.ClosePrint(true); + if (_so) + _so->Flush(); + } + +public: + void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) + { + _so = outStream; + _se = errorStream; + _percent._so = percentStream; + } + + void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } + + void StartScanning(); + + INTERFACE_IDirItemsCallback(;) + + void CloseScanning() + { + if (NeedPercents()) + _percent.ClosePrint(true); + } + + void PrintStat(const CDirItemsStat &st); +}; + + + + class CExtractCallbackConsole: public IExtractCallbackUI, + // public IArchiveExtractCallbackMessage, + public IFolderArchiveExtractCallback2, #ifndef _NO_CRYPTO public ICryptoGetTextPassword, #endif + public COpenCallbackConsole, public CMyUnknownImp { + AString _tempA; + UString _tempU; + + UString _currentName; + + void ClosePercents_for_so() + { + if (NeedPercents() && _so == _percent._so) + _percent.ClosePrint(false); + } + + void ClosePercentsAndFlush() + { + if (NeedPercents()) + _percent.ClosePrint(true); + if (_so) + _so->Flush(); + } + public: MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback) + // MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage) + MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback2) #ifndef _NO_CRYPTO MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) #endif @@ -28,46 +99,66 @@ public: STDMETHOD(SetTotal)(UInt64 total); STDMETHOD(SetCompleted)(const UInt64 *completeValue); - // IFolderArchiveExtractCallback - STDMETHOD(AskOverwrite)( - const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, - const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, - Int32 *answer); - STDMETHOD (PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position); - - STDMETHOD(MessageError)(const wchar_t *message); - STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted); + INTERFACE_IFolderArchiveExtractCallback(;) - HRESULT BeforeOpen(const wchar_t *name); - HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted); - HRESULT ThereAreNoFiles(); - HRESULT ExtractResult(HRESULT result); + INTERFACE_IExtractCallbackUI(;) + // INTERFACE_IArchiveExtractCallbackMessage(;) + INTERFACE_IFolderArchiveExtractCallback2(;) - #ifndef _NO_CRYPTO - HRESULT SetPassword(const UString &password); - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - bool PasswordIsDefined; - UString Password; + STDMETHOD(CryptoGetTextPassword)(BSTR *password); #endif - UInt64 NumArchives; - UInt64 NumArchiveErrors; + UInt64 NumTryArcs; + + bool ThereIsError_in_Current; + bool ThereIsWarning_in_Current; + + UInt64 NumOkArcs; + UInt64 NumCantOpenArcs; + UInt64 NumArcsWithError; + UInt64 NumArcsWithWarnings; + + UInt64 NumOpenArcErrors; + UInt64 NumOpenArcWarnings; + UInt64 NumFileErrors; - UInt64 NumFileErrorsInCurrentArchive; + UInt64 NumFileErrors_in_Current; + + bool NeedFlush; + unsigned PercentsNameLevel; + unsigned LogLevel; - CStdOutStream *OutStream; + CExtractCallbackConsole(): + NeedFlush(false), + PercentsNameLevel(1), + LogLevel(0) + {} - void Init() + void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } + + void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) { - NumArchives = 0; - NumArchiveErrors = 0; + COpenCallbackConsole::Init(outStream, errorStream, percentStream); + + NumTryArcs = 0; + + ThereIsError_in_Current = false; + ThereIsWarning_in_Current = false; + + NumOkArcs = 0; + NumCantOpenArcs = 0; + NumArcsWithError = 0; + NumArcsWithWarnings = 0; + + NumOpenArcErrors = 0; + NumOpenArcWarnings = 0; + NumFileErrors = 0; - NumFileErrorsInCurrentArchive = 0; + NumFileErrors_in_Current = 0; } - }; #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.cpp new file mode 100644 index 00000000000..a71e4b50d21 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.cpp @@ -0,0 +1,367 @@ +// HashCon.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "ConsoleClose.h" +#include "HashCon.h" + +static const wchar_t *kEmptyFileAlias = L"[Content]"; + +static const char *kScanningMessage = "Scanning"; + +static HRESULT CheckBreak2() +{ + return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; +} + +HRESULT CHashCallbackConsole::CheckBreak() +{ + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::StartScanning() +{ + if (PrintHeaders && _so) + *_so << kScanningMessage << endl; + if (NeedPercents()) + { + _percent.ClearCurState(); + _percent.Command = "Scan"; + } + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */) +{ + if (NeedPercents()) + { + _percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams; + _percent.Completed = st.GetTotalBytes(); + _percent.FileName = fs2us(path); + _percent.Print(); + } + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::ScanError(const FString &path, DWORD systemError) +{ + return ScanError_Base(path, systemError); +} + +void Print_DirItemsStat(AString &s, const CDirItemsStat &st); + +HRESULT CHashCallbackConsole::FinishScanning(const CDirItemsStat &st) +{ + if (NeedPercents()) + { + _percent.ClosePrint(true); + _percent.ClearCurState(); + } + if (PrintHeaders && _so) + { + Print_DirItemsStat(_s, st); + *_so << _s << endl << endl; + } + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::SetNumFiles(UInt64 /* numFiles */) +{ + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::SetTotal(UInt64 size) +{ + if (NeedPercents()) + { + _percent.Total = size; + _percent.Print(); + } + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::SetCompleted(const UInt64 *completeValue) +{ + if (completeValue && NeedPercents()) + { + _percent.Completed = *completeValue; + _percent.Print(); + } + return CheckBreak2(); +} + +static void AddMinuses(AString &s, unsigned num) +{ + for (unsigned i = 0; i < num; i++) + s += '-'; +} + +static void AddSpaces_if_Positive(AString &s, int num) +{ + for (int i = 0; i < num; i++) + s.Add_Space(); +} + +static void SetSpacesAndNul(char *s, unsigned num) +{ + for (unsigned i = 0; i < num; i++) + s[i] = ' '; + s[num] = 0; +} + +static const unsigned kSizeField_Len = 13; +static const unsigned kNameField_Len = 12; + +static const unsigned kHashColumnWidth_Min = 4 * 2; + +static unsigned GetColumnWidth(unsigned digestSize) +{ + unsigned width = digestSize * 2; + return width < kHashColumnWidth_Min ? kHashColumnWidth_Min: width; +} + +void CHashCallbackConsole::PrintSeparatorLine(const CObjectVector<CHasherState> &hashers) +{ + _s.Empty(); + + for (unsigned i = 0; i < hashers.Size(); i++) + { + if (i != 0) + _s.Add_Space(); + const CHasherState &h = hashers[i]; + AddMinuses(_s, GetColumnWidth(h.DigestSize)); + } + + if (PrintSize) + { + _s.Add_Space(); + AddMinuses(_s, kSizeField_Len); + } + + if (PrintName) + { + AddSpacesBeforeName(); + AddMinuses(_s, kNameField_Len); + } + + *_so << _s << endl; +} + +HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb) +{ + if (PrintHeaders && _so) + { + _s.Empty(); + ClosePercents_for_so(); + + FOR_VECTOR (i, hb.Hashers) + { + if (i != 0) + _s.Add_Space(); + const CHasherState &h = hb.Hashers[i]; + _s += h.Name; + AddSpaces_if_Positive(_s, (int)GetColumnWidth(h.DigestSize) - (int)h.Name.Len()); + } + + if (PrintSize) + { + _s.Add_Space(); + const AString s2 = "Size"; + AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len()); + _s += s2; + } + + if (PrintName) + { + AddSpacesBeforeName(); + _s += "Name"; + } + + *_so << _s << endl; + PrintSeparatorLine(hb.Hashers); + } + + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::OpenFileError(const FString &path, DWORD systemError) +{ + return OpenFileError_Base(path, systemError); +} + +HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool /* isFolder */) +{ + _fileName = name; + + if (NeedPercents()) + { + if (PrintNameInPercents) + { + _percent.FileName.Empty(); + if (name) + _percent.FileName = name; + } + _percent.Print(); + } + return CheckBreak2(); +} + +void CHashCallbackConsole::PrintResultLine(UInt64 fileSize, + const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash) +{ + ClosePercents_for_so(); + + _s.Empty(); + + FOR_VECTOR (i, hashers) + { + const CHasherState &h = hashers[i]; + char s[k_HashCalc_DigestSize_Max * 2 + 64]; + s[0] = 0; + if (showHash) + AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize); + SetSpacesAndNul(s + strlen(s), (int)GetColumnWidth(h.DigestSize) - (int)strlen(s)); + if (i != 0) + _s.Add_Space(); + _s += s; + } + + if (PrintSize) + { + _s.Add_Space(); + + char s[kSizeField_Len + 32]; + char *p = s; + + if (showHash) + { + p = s + kSizeField_Len; + ConvertUInt64ToString(fileSize, p); + int numSpaces = kSizeField_Len - (int)strlen(p); + if (numSpaces > 0) + { + p -= (unsigned)numSpaces; + for (unsigned i = 0; i < (unsigned)numSpaces; i++) + p[i] = ' '; + } + } + else + SetSpacesAndNul(s, kSizeField_Len); + + _s += p; + } + + if (PrintName) + AddSpacesBeforeName(); + + *_so << _s; +} + +HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) +{ + if (_so) + { + PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash); + if (PrintName) + { + if (_fileName.IsEmpty()) + *_so << kEmptyFileAlias; + else + *_so << _fileName; + } + *_so << endl; + } + + if (NeedPercents()) + { + _percent.Files++; + _percent.Print(); + } + + return CheckBreak2(); +} + +static const char *k_DigestTitles[] = +{ + " : " + , " for data: " + , " for data and names: " + , " for streams and names: " +}; + +static void PrintSum(CStdOutStream &so, const CHasherState &h, unsigned digestIndex) +{ + so << h.Name; + + { + AString temp; + AddSpaces_if_Positive(temp, 6 - (int)h.Name.Len()); + so << temp; + } + + so << k_DigestTitles[digestIndex]; + + char s[k_HashCalc_DigestSize_Max * 2 + 64]; + s[0] = 0; + AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize); + so << s << endl; +} + +void PrintHashStat(CStdOutStream &so, const CHashBundle &hb) +{ + FOR_VECTOR (i, hb.Hashers) + { + const CHasherState &h = hb.Hashers[i]; + PrintSum(so, h, k_HashCalc_Index_DataSum); + if (hb.NumFiles != 1 || hb.NumDirs != 0) + PrintSum(so, h, k_HashCalc_Index_NamesSum); + if (hb.NumAltStreams != 0) + PrintSum(so, h, k_HashCalc_Index_StreamsSum); + so << endl; + } +} + +void CHashCallbackConsole::PrintProperty(const char *name, UInt64 value) +{ + char s[32]; + s[0] = ':'; + s[1] = ' '; + ConvertUInt64ToString(value, s + 2); + *_so << name << s << endl; +} + +HRESULT CHashCallbackConsole::AfterLastFile(const CHashBundle &hb) +{ + ClosePercents2(); + + if (PrintHeaders && _so) + { + PrintSeparatorLine(hb.Hashers); + + PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true); + + *_so << endl << endl; + + if (hb.NumFiles != 1 || hb.NumDirs != 0) + { + if (hb.NumDirs != 0) + PrintProperty("Folders", hb.NumDirs); + PrintProperty("Files", hb.NumFiles); + } + + PrintProperty("Size", hb.FilesSize); + + if (hb.NumAltStreams != 0) + { + PrintProperty("Alternate streams", hb.NumAltStreams); + PrintProperty("Alternate streams size", hb.AltStreamsSize); + } + + *_so << endl; + PrintHashStat(*_so, hb); + } + + return S_OK; +} diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.h b/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.h new file mode 100644 index 00000000000..5b30b69a058 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/Console/HashCon.h @@ -0,0 +1,48 @@ +// HashCon.h + +#ifndef __HASH_CON_H +#define __HASH_CON_H + +#include "../Common/HashCalc.h" + +#include "UpdateCallbackConsole.h" + +class CHashCallbackConsole: public IHashCallbackUI, public CCallbackConsoleBase +{ + UString _fileName; + AString _s; + + void AddSpacesBeforeName() + { + _s.Add_Space(); + _s.Add_Space(); + } + + void PrintSeparatorLine(const CObjectVector<CHasherState> &hashers); + void PrintResultLine(UInt64 fileSize, + const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash); + void PrintProperty(const char *name, UInt64 value); + +public: + bool PrintNameInPercents; + + bool PrintHeaders; + + bool PrintSize; + bool PrintName; + + CHashCallbackConsole(): + PrintNameInPercents(true), + PrintHeaders(false), + PrintSize(true), + PrintName(true) + {} + + ~CHashCallbackConsole() { } + + INTERFACE_IHashCallbackUI(;) +}; + +void PrintHashStat(CStdOutStream &so, const CHashBundle &hb); + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/List.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/List.cpp index 7de2379ad11..e70f1b67ed2 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/List.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/List.cpp @@ -2,17 +2,16 @@ #include "StdAfx.h" -#include "Common/IntToString.h" -#include "Common/MyCom.h" -#include "Common/StdOutStream.h" -#include "Common/StringConvert.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/MyCom.h" +#include "../../../Common/StdOutStream.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/UTFConvert.h" -#include "Windows/Error.h" -#include "Windows/FileDir.h" -#include "Windows/PropVariant.h" -#include "Windows/PropVariantConversions.h" - -#include "../../Archive/IArchive.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/PropVariantConv.h" #include "../Common/OpenArchive.h" #include "../Common/PropIDUtils.h" @@ -22,88 +21,137 @@ #include "OpenCallbackConsole.h" using namespace NWindows; +using namespace NCOM; -struct CPropIdToName -{ - PROPID PropID; - const wchar_t *Name; -}; +extern CStdOutStream *g_StdStream; +extern CStdOutStream *g_ErrStream; -static const CPropIdToName kPropIdToName[] = -{ - { kpidPath, L"Path" }, - { kpidName, L"Name" }, - { kpidIsDir, L"Folder" }, - { kpidSize, L"Size" }, - { kpidPackSize, L"Packed Size" }, - { kpidAttrib, L"Attributes" }, - { kpidCTime, L"Created" }, - { kpidATime, L"Accessed" }, - { kpidMTime, L"Modified" }, - { kpidSolid, L"Solid" }, - { kpidCommented, L"Commented" }, - { kpidEncrypted, L"Encrypted" }, - { kpidSplitBefore, L"Split Before" }, - { kpidSplitAfter, L"Split After" }, - { kpidDictionarySize, L"Dictionary Size" }, - { kpidCRC, L"CRC" }, - { kpidType, L"Type" }, - { kpidIsAnti, L"Anti" }, - { kpidMethod, L"Method" }, - { kpidHostOS, L"Host OS" }, - { kpidFileSystem, L"File System" }, - { kpidUser, L"User" }, - { kpidGroup, L"Group" }, - { kpidBlock, L"Block" }, - { kpidComment, L"Comment" }, - { kpidPosition, L"Position" }, - { kpidPrefix, L"Prefix" }, - { kpidNumSubDirs, L"Folders" }, - { kpidNumSubFiles, L"Files" }, - { kpidUnpackVer, L"Version" }, - { kpidVolume, L"Volume" }, - { kpidIsVolume, L"Multivolume" }, - { kpidOffset, L"Offset" }, - { kpidLinks, L"Links" }, - { kpidNumBlocks, L"Blocks" }, - { kpidNumVolumes, L"Volumes" }, - - { kpidBit64, L"64-bit" }, - { kpidBigEndian, L"Big-endian" }, - { kpidCpu, L"CPU" }, - { kpidPhySize, L"Physical Size" }, - { kpidHeadersSize, L"Headers Size" }, - { kpidChecksum, L"Checksum" }, - { kpidCharacts, L"Characteristics" }, - { kpidVa, L"Virtual Address" }, - { kpidId, L"ID" }, - { kpidShortName, L"Short Name" }, - { kpidCreatorApp, L"Creator Application"}, - { kpidSectorSize, L"Sector Size" }, - { kpidPosixAttrib, L"Mode" }, - { kpidLink, L"Link" }, - { kpidError, L"Error" }, - - { kpidTotalSize, L"Total Size" }, - { kpidFreeSpace, L"Free Space" }, - { kpidClusterSize, L"Cluster Size" }, - { kpidVolumeName, L"Label" } +static const char * const kPropIdToName[] = +{ + "0" + , "1" + , "2" + , "Path" + , "Name" + , "Extension" + , "Folder" + , "Size" + , "Packed Size" + , "Attributes" + , "Created" + , "Accessed" + , "Modified" + , "Solid" + , "Commented" + , "Encrypted" + , "Split Before" + , "Split After" + , "Dictionary Size" + , "CRC" + , "Type" + , "Anti" + , "Method" + , "Host OS" + , "File System" + , "User" + , "Group" + , "Block" + , "Comment" + , "Position" + , "Path Prefix" + , "Folders" + , "Files" + , "Version" + , "Volume" + , "Multivolume" + , "Offset" + , "Links" + , "Blocks" + , "Volumes" + , "Time Type" + , "64-bit" + , "Big-endian" + , "CPU" + , "Physical Size" + , "Headers Size" + , "Checksum" + , "Characteristics" + , "Virtual Address" + , "ID" + , "Short Name" + , "Creator Application" + , "Sector Size" + , "Mode" + , "Symbolic Link" + , "Error" + , "Total Size" + , "Free Space" + , "Cluster Size" + , "Label" + , "Local Name" + , "Provider" + , "NT Security" + , "Alternate Stream" + , "Aux" + , "Deleted" + , "Tree" + , "SHA-1" + , "SHA-256" + , "Error Type" + , "Errors" + , "Errors" + , "Warnings" + , "Warning" + , "Streams" + , "Alternate Streams" + , "Alternate Streams Size" + , "Virtual Size" + , "Unpack Size" + , "Total Physical Size" + , "Volume Index" + , "SubType" + , "Short Comment" + , "Code Page" + , "Is not archive type" + , "Physical Size can't be detected" + , "Zeros Tail Is Allowed" + , "Tail Size" + , "Embedded Stub Size" + , "Link" + , "Hard Link" + , "iNode" + , "Stream ID" + , "Read-only" + , "Out Name" + , "Copy Link" }; static const char kEmptyAttribChar = '.'; static const char *kListing = "Listing archive: "; -static const wchar_t *kFilesMessage = L"files"; -static const wchar_t *kDirsMessage = L"folders"; -static void GetAttribString(DWORD wa, bool isDir, char *s) +static const char *kString_Files = "files"; +static const char *kString_Dirs = "folders"; +static const char *kString_AltStreams = "alternate streams"; +static const char *kString_Streams = "streams"; + +static const char *kError = "ERROR: "; + +static void GetAttribString(UInt32 wa, bool isDir, bool allAttribs, char *s) { - s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : kEmptyAttribChar; - s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar; - s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar; - s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar; - s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar; - s[5] = '\0'; + if (isDir) + wa |= FILE_ATTRIBUTE_DIRECTORY; + if (allAttribs) + { + ConvertWinAttribToString(s, wa); + return; + } + s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0) ? 'D': kEmptyAttribChar; + s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar; + s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar; + s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar; + s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar; + s[5] = 0; } enum EAdjustment @@ -116,108 +164,294 @@ enum EAdjustment struct CFieldInfo { PROPID PropID; - UString Name; + bool IsRawProp; + UString NameU; + AString NameA; EAdjustment TitleAdjustment; EAdjustment TextAdjustment; - int PrefixSpacesWidth; - int Width; + unsigned PrefixSpacesWidth; + unsigned Width; }; struct CFieldInfoInit { PROPID PropID; - const wchar_t *Name; + const char *Name; EAdjustment TitleAdjustment; EAdjustment TextAdjustment; - int PrefixSpacesWidth; - int Width; + unsigned PrefixSpacesWidth; + unsigned Width; }; -static CFieldInfoInit kStandardFieldTable[] = +static const CFieldInfoInit kStandardFieldTable[] = { - { kpidMTime, L" Date Time", kLeft, kLeft, 0, 19 }, - { kpidAttrib, L"Attr", kRight, kCenter, 1, 5 }, - { kpidSize, L"Size", kRight, kRight, 1, 12 }, - { kpidPackSize, L"Compressed", kRight, kRight, 1, 12 }, - { kpidPath, L"Name", kLeft, kLeft, 2, 24 } + { kpidMTime, " Date Time", kLeft, kLeft, 0, 19 }, + { kpidAttrib, "Attr", kRight, kCenter, 1, 5 }, + { kpidSize, "Size", kRight, kRight, 1, 12 }, + { kpidPackSize, "Compressed", kRight, kRight, 1, 12 }, + { kpidPath, "Name", kLeft, kLeft, 2, 24 } }; -static void PrintSpaces(int numSpaces) +const unsigned kNumSpacesMax = 32; // it must be larger than max CFieldInfoInit.Width +static const char *g_Spaces = +" " ; + +static void PrintSpaces(unsigned numSpaces) { - for (int i = 0; i < numSpaces; i++) - g_StdOut << ' '; + if (numSpaces > 0 && numSpaces <= kNumSpacesMax) + g_StdOut << g_Spaces + (kNumSpacesMax - numSpaces); } -static void PrintString(EAdjustment adjustment, int width, const UString &textString) +static void PrintSpacesToString(char *dest, unsigned numSpaces) { - const int numSpaces = width - textString.Length(); - int numLeftSpaces = 0; - switch (adjustment) + unsigned i; + for (i = 0; i < numSpaces; i++) + dest[i] = ' '; + dest[i] = 0; +} + +// extern int g_CodePage; + +static void PrintUString(EAdjustment adj, unsigned width, const UString &s, AString &temp) +{ + /* + // we don't need multibyte align. + int codePage = g_CodePage; + if (codePage == -1) + codePage = CP_OEMCP; + if (codePage == CP_UTF8) + ConvertUnicodeToUTF8(s, temp); + else + UnicodeStringToMultiByte2(temp, s, (UINT)codePage); + */ + + unsigned numSpaces = 0; + + if (width > s.Len()) { - case kLeft: - numLeftSpaces = 0; - break; - case kCenter: - numLeftSpaces = numSpaces / 2; - break; - case kRight: - numLeftSpaces = numSpaces; - break; + numSpaces = width - s.Len(); + unsigned numLeftSpaces = 0; + switch (adj) + { + case kLeft: numLeftSpaces = 0; break; + case kCenter: numLeftSpaces = numSpaces / 2; break; + case kRight: numLeftSpaces = numSpaces; break; + } + PrintSpaces(numLeftSpaces); + numSpaces -= numLeftSpaces; } - PrintSpaces(numLeftSpaces); - g_StdOut << textString; - PrintSpaces(numSpaces - numLeftSpaces); + + g_StdOut.PrintUString(s, temp); + PrintSpaces(numSpaces); } +static void PrintString(EAdjustment adj, unsigned width, const char *s) +{ + unsigned numSpaces = 0; + unsigned len = (unsigned)strlen(s); + + if (width > len) + { + numSpaces = width - len; + unsigned numLeftSpaces = 0; + switch (adj) + { + case kLeft: numLeftSpaces = 0; break; + case kCenter: numLeftSpaces = numSpaces / 2; break; + case kRight: numLeftSpaces = numSpaces; break; + } + PrintSpaces(numLeftSpaces); + numSpaces -= numLeftSpaces; + } + + g_StdOut << s; + PrintSpaces(numSpaces); +} + +static void PrintStringToString(char *dest, EAdjustment adj, unsigned width, const char *textString) +{ + unsigned numSpaces = 0; + unsigned len = (unsigned)strlen(textString); + + if (width > len) + { + numSpaces = width - len; + unsigned numLeftSpaces = 0; + switch (adj) + { + case kLeft: numLeftSpaces = 0; break; + case kCenter: numLeftSpaces = numSpaces / 2; break; + case kRight: numLeftSpaces = numSpaces; break; + } + PrintSpacesToString(dest, numLeftSpaces); + dest += numLeftSpaces; + numSpaces -= numLeftSpaces; + } + + memcpy(dest, textString, len); + dest += len; + PrintSpacesToString(dest, numSpaces); +} + +struct CListUInt64Def +{ + UInt64 Val; + bool Def; + + CListUInt64Def(): Val(0), Def(false) {} + void Add(UInt64 v) { Val += v; Def = true; } + void Add(const CListUInt64Def &v) { if (v.Def) Add(v.Val); } +}; + +struct CListFileTimeDef +{ + FILETIME Val; + bool Def; + + CListFileTimeDef(): Def(false) { Val.dwLowDateTime = 0; Val.dwHighDateTime = 0; } + void Update(const CListFileTimeDef &t) + { + if (t.Def && (!Def || CompareFileTime(&Val, &t.Val) < 0)) + { + Val = t.Val; + Def = true; + } + } +}; + +struct CListStat +{ + CListUInt64Def Size; + CListUInt64Def PackSize; + CListFileTimeDef MTime; + UInt64 NumFiles; + + CListStat(): NumFiles(0) {} + void Update(const CListStat &st) + { + Size.Add(st.Size); + PackSize.Add(st.PackSize); + MTime.Update(st.MTime); + NumFiles += st.NumFiles; + } + void SetSizeDefIfNoFiles() { if (NumFiles == 0) Size.Def = true; } +}; + +struct CListStat2 +{ + CListStat MainFiles; + CListStat AltStreams; + UInt64 NumDirs; + + CListStat2(): NumDirs(0) {} + + void Update(const CListStat2 &st) + { + MainFiles.Update(st.MainFiles); + AltStreams.Update(st.AltStreams); + NumDirs += st.NumDirs; + } + const UInt64 GetNumStreams() const { return MainFiles.NumFiles + AltStreams.NumFiles; } + CListStat &GetStat(bool altStreamsMode) { return altStreamsMode ? AltStreams : MainFiles; } +}; + class CFieldPrinter { CObjectVector<CFieldInfo> _fields; + + void AddProp(const wchar_t *name, PROPID propID, bool isRawProp); public: - void Clear() { _fields.Clear(); } - void Init(const CFieldInfoInit *standardFieldTable, int numItems); - HRESULT Init(IInArchive *archive); + const CArc *Arc; + bool TechMode; + UString FilePath; + AString TempAString; + UString TempWString; + bool IsDir; + + AString LinesString; + + void Clear() { _fields.Clear(); LinesString.Empty(); } + void Init(const CFieldInfoInit *standardFieldTable, unsigned numItems); + + HRESULT AddMainProps(IInArchive *archive); + HRESULT AddRawProps(IArchiveGetRawProps *getRawProps); + void PrintTitle(); void PrintTitleLines(); - HRESULT PrintItemInfo(const CArc &arc, UInt32 index, bool techMode); - HRESULT PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs, - const UInt64 *size, const UInt64 *compressedSize); + HRESULT PrintItemInfo(UInt32 index, const CListStat &st); + void PrintSum(const CListStat &st, UInt64 numDirs, const char *str); + void PrintSum(const CListStat2 &stat2); }; -void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems) +void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, unsigned numItems) { Clear(); - for (int i = 0; i < numItems; i++) + for (unsigned i = 0; i < numItems; i++) { - CFieldInfo fieldInfo; - const CFieldInfoInit &fieldInfoInit = standardFieldTable[i]; - fieldInfo.PropID = fieldInfoInit.PropID; - fieldInfo.Name = fieldInfoInit.Name; - fieldInfo.TitleAdjustment = fieldInfoInit.TitleAdjustment; - fieldInfo.TextAdjustment = fieldInfoInit.TextAdjustment; - fieldInfo.PrefixSpacesWidth = fieldInfoInit.PrefixSpacesWidth; - fieldInfo.Width = fieldInfoInit.Width; - _fields.Add(fieldInfo); + CFieldInfo &f = _fields.AddNew(); + const CFieldInfoInit &fii = standardFieldTable[i]; + f.PropID = fii.PropID; + f.IsRawProp = false; + f.NameA = fii.Name; + f.TitleAdjustment = fii.TitleAdjustment; + f.TextAdjustment = fii.TextAdjustment; + f.PrefixSpacesWidth = fii.PrefixSpacesWidth; + f.Width = fii.Width; + + unsigned k; + for (k = 0; k < fii.PrefixSpacesWidth; k++) + LinesString.Add_Space(); + for (k = 0; k < fii.Width; k++) + LinesString += '-'; } } -static UString GetPropName(PROPID propID, BSTR name) +static void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UString &nameU) { - for (int i = 0; i < sizeof(kPropIdToName) / sizeof(kPropIdToName[0]); i++) + if (propID < ARRAY_SIZE(kPropIdToName)) { - const CPropIdToName &propIdToName = kPropIdToName[i]; - if (propIdToName.PropID == propID) - return propIdToName.Name; + nameA = kPropIdToName[propID]; + return; } if (name) - return name; - wchar_t s[16]; - ConvertUInt32ToString(propID, s); - return s; + nameU = name; + else + { + char s[16]; + ConvertUInt32ToString(propID, s); + nameA = s; + } } -HRESULT CFieldPrinter::Init(IInArchive *archive) +void CFieldPrinter::AddProp(const wchar_t *name, PROPID propID, bool isRawProp) +{ + CFieldInfo f; + f.PropID = propID; + f.IsRawProp = isRawProp; + GetPropName(propID, name, f.NameA, f.NameU); + f.NameU.AddAscii(" = "); + if (!f.NameA.IsEmpty()) + f.NameA += " = "; + else + { + const UString &s = f.NameU; + AString sA; + unsigned i; + for (i = 0; i < s.Len(); i++) + { + wchar_t c = s[i]; + if (c >= 0x80) + break; + sA += (char)c; + } + if (i == s.Len()) + f.NameA = sA; + } + _fields.Add(f); +} + +HRESULT CFieldPrinter::AddMainProps(IInArchive *archive) { - Clear(); UInt32 numProps; RINOK(archive->GetNumberOfProperties(&numProps)); for (UInt32 i = 0; i < numProps; i++) @@ -226,64 +460,80 @@ HRESULT CFieldPrinter::Init(IInArchive *archive) PROPID propID; VARTYPE vt; RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt)); - CFieldInfo fieldInfo; - fieldInfo.PropID = propID; - fieldInfo.Name = GetPropName(propID, name); - _fields.Add(fieldInfo); + AddProp(name, propID, false); } return S_OK; } -void CFieldPrinter::PrintTitle() +HRESULT CFieldPrinter::AddRawProps(IArchiveGetRawProps *getRawProps) { - for (int i = 0; i < _fields.Size(); i++) + UInt32 numProps; + RINOK(getRawProps->GetNumRawProps(&numProps)); + for (UInt32 i = 0; i < numProps; i++) { - const CFieldInfo &fieldInfo = _fields[i]; - PrintSpaces(fieldInfo.PrefixSpacesWidth); - PrintString(fieldInfo.TitleAdjustment, - ((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name); + CMyComBSTR name; + PROPID propID; + RINOK(getRawProps->GetRawPropInfo(i, &name, &propID)); + AddProp(name, propID, true); } + return S_OK; } -void CFieldPrinter::PrintTitleLines() +void CFieldPrinter::PrintTitle() { - for (int i = 0; i < _fields.Size(); i++) + FOR_VECTOR (i, _fields) { - const CFieldInfo &fieldInfo = _fields[i]; - PrintSpaces(fieldInfo.PrefixSpacesWidth); - for (int i = 0; i < fieldInfo.Width; i++) - g_StdOut << '-'; + const CFieldInfo &f = _fields[i]; + PrintSpaces(f.PrefixSpacesWidth); + PrintString(f.TitleAdjustment, ((f.PropID == kpidPath) ? 0: f.Width), f.NameA); } } +void CFieldPrinter::PrintTitleLines() +{ + g_StdOut << LinesString; +} -static BOOL IsFileTimeZero(CONST FILETIME *lpFileTime) +static void PrintTime(char *dest, const FILETIME *ft) { - return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0); + *dest = 0; + if (ft->dwLowDateTime == 0 && ft->dwHighDateTime == 0) + return; + FILETIME locTime; + if (!FileTimeToLocalFileTime(ft, &locTime)) + throw 20121211; + ConvertFileTimeToString(locTime, dest, true, true); } -static const char *kEmptyTimeString = " "; -static void PrintTime(const NCOM::CPropVariant &prop) +#ifndef _SFX + +static inline char GetHex(Byte value) { - if (prop.vt != VT_FILETIME) - throw "incorrect item"; - if (IsFileTimeZero(&prop.filetime)) - g_StdOut << kEmptyTimeString; - else + return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); +} + +static void HexToString(char *dest, const Byte *data, UInt32 size) +{ + for (UInt32 i = 0; i < size; i++) { - FILETIME localFileTime; - if (!FileTimeToLocalFileTime(&prop.filetime, &localFileTime)) - throw "FileTimeToLocalFileTime error"; - char s[32]; - if (ConvertFileTimeToString(localFileTime, s, true, true)) - g_StdOut << s; - else - g_StdOut << kEmptyTimeString; + Byte b = data[i]; + dest[0] = GetHex((Byte)((b >> 4) & 0xF)); + dest[1] = GetHex((Byte)(b & 0xF)); + dest += 2; } + *dest = 0; } -HRESULT CFieldPrinter::PrintItemInfo(const CArc &arc, UInt32 index, bool techMode) +#endif + +#define MY_ENDL endl + +HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) { + char temp[128]; + size_t tempPos = 0; + + bool techMode = this->TechMode; /* if (techMode) { @@ -292,165 +542,502 @@ HRESULT CFieldPrinter::PrintItemInfo(const CArc &arc, UInt32 index, bool techMod g_StdOut << endl; } */ - for (int i = 0; i < _fields.Size(); i++) + FOR_VECTOR (i, _fields) { - const CFieldInfo &fieldInfo = _fields[i]; - if (!techMode) - PrintSpaces(fieldInfo.PrefixSpacesWidth); + const CFieldInfo &f = _fields[i]; - NCOM::CPropVariant prop; - if (fieldInfo.PropID == kpidPath) - { - UString s; - RINOK(arc.GetItemPath(index, s)); - prop = s; - } - else + if (!techMode) { - RINOK(arc.Archive->GetProperty(index, fieldInfo.PropID, &prop)); + PrintSpacesToString(temp + tempPos, f.PrefixSpacesWidth); + tempPos += f.PrefixSpacesWidth; } + if (techMode) { - g_StdOut << fieldInfo.Name << " = "; - } - int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width; - if (fieldInfo.PropID == kpidAttrib && (prop.vt == VT_EMPTY || prop.vt == VT_UI4)) - { - UInt32 attrib = (prop.vt == VT_EMPTY) ? 0 : prop.ulVal; - bool isFolder; - RINOK(IsArchiveItemFolder(arc.Archive, index, isFolder)); - char s[8]; - GetAttribString(attrib, isFolder, s); - g_StdOut << s; + if (!f.NameA.IsEmpty()) + g_StdOut << f.NameA; + else + g_StdOut << f.NameU; } - else if (prop.vt == VT_EMPTY) + + if (f.PropID == kpidPath) { if (!techMode) - PrintSpaces(width); - } - else if (fieldInfo.PropID == kpidMTime) - { - PrintTime(prop); + g_StdOut << temp; + g_StdOut.PrintUString(FilePath, TempAString); + if (techMode) + g_StdOut << MY_ENDL; + continue; } - else if (prop.vt == VT_BSTR) + + const unsigned width = f.Width; + + if (f.IsRawProp) { - if (techMode) - g_StdOut << prop.bstrVal; - else - PrintString(fieldInfo.TextAdjustment, width, prop.bstrVal); + #ifndef _SFX + + const void *data; + UInt32 dataSize; + UInt32 propType; + RINOK(Arc->GetRawProps->GetRawProp(index, f.PropID, &data, &dataSize, &propType)); + + if (dataSize != 0) + { + bool needPrint = true; + + if (f.PropID == kpidNtSecure) + { + if (propType != NPropDataType::kRaw) + return E_FAIL; + #ifndef _SFX + ConvertNtSecureToString((const Byte *)data, dataSize, TempAString); + g_StdOut << TempAString; + needPrint = false; + #endif + } + else if (f.PropID == kpidNtReparse) + { + UString s; + if (ConvertNtReparseToString((const Byte *)data, dataSize, s)) + { + needPrint = false; + g_StdOut.PrintUString(s, TempAString); + } + } + + if (needPrint) + { + if (propType != NPropDataType::kRaw) + return E_FAIL; + + const UInt32 kMaxDataSize = 64; + + if (dataSize > kMaxDataSize) + { + g_StdOut << "data:"; + g_StdOut << dataSize; + } + else + { + char hexStr[kMaxDataSize * 2 + 4]; + HexToString(hexStr, (const Byte *)data, dataSize); + g_StdOut << hexStr; + } + } + } + + #endif } else { - UString s = ConvertPropertyToString(prop, fieldInfo.PropID); - s.Replace(wchar_t(0xA), L' '); - s.Replace(wchar_t(0xD), L' '); - - if (techMode) - g_StdOut << s; + CPropVariant prop; + switch (f.PropID) + { + case kpidSize: if (st.Size.Def) prop = st.Size.Val; break; + case kpidPackSize: if (st.PackSize.Def) prop = st.PackSize.Val; break; + case kpidMTime: if (st.MTime.Def) prop = st.MTime.Val; break; + default: + RINOK(Arc->Archive->GetProperty(index, f.PropID, &prop)); + } + if (f.PropID == kpidAttrib && (prop.vt == VT_EMPTY || prop.vt == VT_UI4)) + { + GetAttribString((prop.vt == VT_EMPTY) ? 0 : prop.ulVal, IsDir, techMode, temp + tempPos); + if (techMode) + g_StdOut << temp + tempPos; + else + tempPos += strlen(temp + tempPos); + } + else if (prop.vt == VT_EMPTY) + { + if (!techMode) + { + PrintSpacesToString(temp + tempPos, width); + tempPos += width; + } + } + else if (prop.vt == VT_FILETIME) + { + PrintTime(temp + tempPos, &prop.filetime); + if (techMode) + g_StdOut << temp + tempPos; + else + { + size_t len = strlen(temp + tempPos); + tempPos += len; + if (len < (unsigned)f.Width) + { + len = f.Width - len; + PrintSpacesToString(temp + tempPos, (unsigned)len); + tempPos += len; + } + } + } + else if (prop.vt == VT_BSTR) + { + TempWString.SetFromBstr(prop.bstrVal); + if (techMode) + { + // replace CR/LF here. + g_StdOut.PrintUString(TempWString, TempAString); + } + else + PrintUString(f.TextAdjustment, width, TempWString, TempAString); + } else - PrintString(fieldInfo.TextAdjustment, width, s); + { + char s[64]; + ConvertPropertyToShortString(s, prop, f.PropID); + if (techMode) + g_StdOut << s; + else + { + PrintStringToString(temp + tempPos, f.TextAdjustment, width, s); + tempPos += strlen(temp + tempPos); + } + } } if (techMode) - g_StdOut << endl; + g_StdOut << MY_ENDL; } + g_StdOut << MY_ENDL; return S_OK; } -static void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value) +static void PrintNumber(EAdjustment adj, unsigned width, const CListUInt64Def &value) { - wchar_t textString[32] = { 0 }; - if (value != NULL) - ConvertUInt64ToString(*value, textString); - PrintString(adjustment, width, textString); + char s[32]; + s[0] = 0; + if (value.Def) + ConvertUInt64ToString(value.Val, s); + PrintString(adj, width, s); } +void Print_UInt64_and_String(AString &s, UInt64 val, const char *name); -HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs, - const UInt64 *size, const UInt64 *compressedSize) +void CFieldPrinter::PrintSum(const CListStat &st, UInt64 numDirs, const char *str) { - for (int i = 0; i < _fields.Size(); i++) + FOR_VECTOR (i, _fields) { - const CFieldInfo &fieldInfo = _fields[i]; - PrintSpaces(fieldInfo.PrefixSpacesWidth); - NCOM::CPropVariant prop; - if (fieldInfo.PropID == kpidSize) - PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, size); - else if (fieldInfo.PropID == kpidPackSize) - PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, compressedSize); - else if (fieldInfo.PropID == kpidPath) + const CFieldInfo &f = _fields[i]; + PrintSpaces(f.PrefixSpacesWidth); + if (f.PropID == kpidSize) + PrintNumber(f.TextAdjustment, f.Width, st.Size); + else if (f.PropID == kpidPackSize) + PrintNumber(f.TextAdjustment, f.Width, st.PackSize); + else if (f.PropID == kpidMTime) { - wchar_t textString[32]; - ConvertUInt64ToString(numFiles, textString); - UString temp = textString; - temp += L" "; - temp += kFilesMessage; - temp += L", "; - ConvertUInt64ToString(numDirs, textString); - temp += textString; - temp += L" "; - temp += kDirsMessage; - PrintString(fieldInfo.TextAdjustment, 0, temp); + char s[64]; + s[0] = 0; + if (st.MTime.Def) + PrintTime(s, &st.MTime.Val); + PrintString(f.TextAdjustment, f.Width, s); } + else if (f.PropID == kpidPath) + { + AString s; + Print_UInt64_and_String(s, st.NumFiles, str); + if (numDirs != 0) + { + s += ", "; + Print_UInt64_and_String(s, numDirs, kString_Dirs); + } + PrintString(f.TextAdjustment, 0, s); + } + else + PrintString(f.TextAdjustment, f.Width, ""); + } + g_StdOut << endl; +} + +void CFieldPrinter::PrintSum(const CListStat2 &stat2) +{ + PrintSum(stat2.MainFiles, stat2.NumDirs, kString_Files); + if (stat2.AltStreams.NumFiles != 0) + { + PrintSum(stat2.AltStreams, 0, kString_AltStreams);; + CListStat st = stat2.MainFiles; + st.Update(stat2.AltStreams); + PrintSum(st, 0, kString_Streams); + } +} + +static HRESULT GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, CListUInt64Def &value) +{ + value.Val = 0; + value.Def = false; + CPropVariant prop; + RINOK(archive->GetProperty(index, propID, &prop)); + value.Def = ConvertPropVariantToUInt64(prop, value.Val); + return S_OK; +} + +static HRESULT GetItemMTime(IInArchive *archive, UInt32 index, CListFileTimeDef &t) +{ + t.Val.dwLowDateTime = 0; + t.Val.dwHighDateTime = 0; + t.Def = false; + CPropVariant prop; + RINOK(archive->GetProperty(index, kpidMTime, &prop)); + if (prop.vt == VT_FILETIME) + { + t.Val = prop.filetime; + t.Def = true; + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + +static void PrintPropNameAndNumber(CStdOutStream &so, const char *name, UInt64 val) +{ + so << name << ": " << val << endl; +} + +static void PrintPropName_and_Eq(CStdOutStream &so, PROPID propID) +{ + const char *s; + char temp[16]; + if (propID < ARRAY_SIZE(kPropIdToName)) + s = kPropIdToName[propID]; + else + { + ConvertUInt32ToString(propID, temp); + s = temp; + } + so << s << " = "; +} + +static void PrintPropNameAndNumber(CStdOutStream &so, PROPID propID, UInt64 val) +{ + PrintPropName_and_Eq(so, propID); + so << val << endl; +} + +static void PrintPropNameAndNumber_Signed(CStdOutStream &so, PROPID propID, Int64 val) +{ + PrintPropName_and_Eq(so, propID); + so << val << endl; +} + +static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val) +{ + so << name << " = " << val << endl; +} + + +static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *name, const CPropVariant &prop) +{ + UString s; + ConvertPropertyToString(s, prop, propID); + if (!s.IsEmpty()) + { + AString nameA; + UString nameU; + GetPropName(propID, name, nameA, nameU); + if (!nameA.IsEmpty()) + PrintPropPair(so, nameA, s); else - PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L""); + so << nameU << " = " << s << endl; } +} + +static HRESULT PrintArcProp(CStdOutStream &so, IInArchive *archive, PROPID propID, const wchar_t *name) +{ + CPropVariant prop; + RINOK(archive->GetArchiveProperty(propID, &prop)); + PrintPropertyPair2(so, propID, name, prop); return S_OK; } -bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value) +static void PrintArcTypeError(CStdOutStream &so, const UString &type, bool isWarning) { - NCOM::CPropVariant prop; - if (archive->GetProperty(index, propID, &prop) != S_OK) - throw "GetPropertyValue error"; - if (prop.vt == VT_EMPTY) - return false; - value = ConvertPropVariantToUInt64(prop); - return true; + so << "Open " << (isWarning ? "WARNING" : "ERROR") + << ": Can not open the file as [" + << type + << "] archive" + << endl; } -static void PrintPropPair(const wchar_t *name, const wchar_t *value) +int Find_FileName_InSortedVector(const UStringVector &fileName, const UString& name); + +void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags); + +static void ErrorInfo_Print(CStdOutStream &so, const CArcErrorInfo &er) { - g_StdOut << name << " = " << value << endl; + PrintErrorFlags(so, "ERRORS:", er.GetErrorFlags()); + if (!er.ErrorMessage.IsEmpty()) + PrintPropPair(so, "ERROR", er.ErrorMessage); + + PrintErrorFlags(so, "WARNINGS:", er.GetWarningFlags()); + if (!er.WarningMessage.IsEmpty()) + PrintPropPair(so, "WARNING", er.WarningMessage); } -HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices, +HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink) +{ + FOR_VECTOR (r, arcLink.Arcs) + { + const CArc &arc = arcLink.Arcs[r]; + const CArcErrorInfo &er = arc.ErrorInfo; + + so << "--\n"; + PrintPropPair(so, "Path", arc.Path); + if (er.ErrorFormatIndex >= 0) + { + if (er.ErrorFormatIndex == arc.FormatIndex) + so << "Warning: The archive is open with offset" << endl; + else + PrintArcTypeError(so, codecs->GetFormatNamePtr(er.ErrorFormatIndex), true); + } + PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex)); + + ErrorInfo_Print(so, er); + + Int64 offset = arc.GetGlobalOffset(); + if (offset != 0) + PrintPropNameAndNumber_Signed(so, kpidOffset, offset); + IInArchive *archive = arc.Archive; + RINOK(PrintArcProp(so, archive, kpidPhySize, NULL)); + if (er.TailSize != 0) + PrintPropNameAndNumber(so, kpidTailSize, er.TailSize); + UInt32 numProps; + RINOK(archive->GetNumberOfArchiveProperties(&numProps)); + + { + for (UInt32 j = 0; j < numProps; j++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt)); + RINOK(PrintArcProp(so, archive, propID, name)); + } + } + + if (r != arcLink.Arcs.Size() - 1) + { + UInt32 numProps; + so << "----\n"; + if (archive->GetNumberOfProperties(&numProps) == S_OK) + { + UInt32 mainIndex = arcLink.Arcs[r + 1].SubfileIndex; + for (UInt32 j = 0; j < numProps; j++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt)); + CPropVariant prop; + RINOK(archive->GetProperty(mainIndex, propID, &prop)); + PrintPropertyPair2(so, propID, name, prop); + } + } + } + } + return S_OK; +} + +HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink) +{ + #ifndef _NO_CRYPTO + if (arcLink.PasswordWasAsked) + so << "Can not open encrypted archive. Wrong password?"; + else + #endif + { + if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) + { + so << arcLink.NonOpen_ArcPath << endl; + PrintArcTypeError(so, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); + } + else + so << "Can not open the file as archive"; + } + + so << endl; + so << endl; + ErrorInfo_Print(so, arcLink.NonOpen_ErrorInfo); + + return S_OK; +} + +bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item); + +HRESULT ListArchives(CCodecs *codecs, + const CObjectVector<COpenType> &types, + const CIntVector &excludedFormats, bool stdInMode, UStringVector &arcPaths, UStringVector &arcPathsFull, + bool processAltStreams, bool showAltStreams, const NWildcard::CCensorNode &wildcardCensor, bool enableHeaders, bool techMode, #ifndef _NO_CRYPTO bool &passwordEnabled, UString &password, #endif - UInt64 &numErrors) + #ifndef _SFX + const CObjectVector<CProperty> *props, + #endif + UInt64 &numErrors, + UInt64 &numWarnings) { + bool allFilesAreAllowed = wildcardCensor.AreAllAllowed(); + numErrors = 0; - CFieldPrinter fieldPrinter; + numWarnings = 0; + + CFieldPrinter fp; if (!techMode) - fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0])); + fp.Init(kStandardFieldTable, ARRAY_SIZE(kStandardFieldTable)); - UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0; - UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0; - int numArcs = /* stdInMode ? 1 : */ arcPaths.Size(); - for (int i = 0; i < numArcs; i++) + CListStat2 stat2total; + + CBoolArr skipArcs(arcPaths.Size()); + unsigned arcIndex; + for (arcIndex = 0; arcIndex < arcPaths.Size(); arcIndex++) + skipArcs[arcIndex] = false; + UInt64 numVolumes = 0; + UInt64 numArcs = 0; + UInt64 totalArcSizes = 0; + + HRESULT lastError = 0; + + for (arcIndex = 0; arcIndex < arcPaths.Size(); arcIndex++) { - const UString &archiveName = arcPaths[i]; + if (skipArcs[arcIndex]) + continue; + const UString &arcPath = arcPaths[arcIndex]; UInt64 arcPackSize = 0; + if (!stdInMode) { NFile::NFind::CFileInfo fi; - if (!fi.Find(us2fs(archiveName)) || fi.IsDir()) + if (!fi.Find(us2fs(arcPath))) { - g_StdOut << endl << "Error: " << archiveName << " is not file" << endl; + DWORD errorCode = GetLastError(); + if (errorCode == 0) + errorCode = ERROR_FILE_NOT_FOUND; + lastError = HRESULT_FROM_WIN32(lastError);; + g_StdOut.Flush(); + *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << + endl << arcPath << endl << endl; + numErrors++; + continue; + } + if (fi.IsDir()) + { + g_StdOut.Flush(); + *g_ErrStream << endl << kError << arcPath << " is not a file" << endl << endl; numErrors++; continue; } arcPackSize = fi.Size; + totalArcSizes += arcPackSize; } - CArchiveLink archiveLink; + CArchiveLink arcLink; COpenCallbackConsole openCallback; - openCallback.OutStream = &g_StdOut; + openCallback.Init(&g_StdOut, g_ErrStream, NULL); #ifndef _NO_CRYPTO @@ -459,95 +1046,97 @@ HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices, #endif - HRESULT result = archiveLink.Open2(codecs, formatIndices, stdInMode, NULL, archiveName, &openCallback); + /* + CObjectVector<COptionalOpenProperties> optPropsVector; + COptionalOpenProperties &optProps = optPropsVector.AddNew(); + optProps.Props = *props; + */ + + COpenOptions options; + #ifndef _SFX + options.props = props; + #endif + options.codecs = codecs; + options.types = &types; + options.excludedFormats = &excludedFormats; + options.stdInMode = stdInMode; + options.stream = NULL; + options.filePath = arcPath; + + if (enableHeaders) + { + g_StdOut << endl << kListing << arcPath << endl << endl; + } + + HRESULT result = arcLink.Open3(options, &openCallback); + if (result != S_OK) { if (result == E_ABORT) return result; - g_StdOut << endl << "Error: " << archiveName << ": "; + g_StdOut.Flush(); + *g_ErrStream << endl << kError << arcPath << " : "; if (result == S_FALSE) { - #ifndef _NO_CRYPTO - if (openCallback.Open_WasPasswordAsked()) - g_StdOut << "Can not open encrypted archive. Wrong password?"; - else - #endif - g_StdOut << "Can not open file as archive"; + Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink); } - else if (result == E_OUTOFMEMORY) - g_StdOut << "Can't allocate required memory"; else - g_StdOut << NError::MyFormatMessageW(result); - g_StdOut << endl; + { + lastError = result; + *g_ErrStream << "opening : "; + if (result == E_OUTOFMEMORY) + *g_ErrStream << "Can't allocate required memory"; + else + *g_ErrStream << NError::MyFormatMessage(result); + } + *g_ErrStream << endl; numErrors++; continue; } + + { + if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) + numErrors++; + + FOR_VECTOR (r, arcLink.Arcs) + { + const CArcErrorInfo &arc = arcLink.Arcs[r].ErrorInfo; + if (!arc.WarningMessage.IsEmpty()) + numWarnings++; + if (arc.AreThereWarnings()) + numWarnings++; + if (arc.ErrorFormatIndex >= 0) + numWarnings++; + if (arc.AreThereErrors()) + { + numErrors++; + // break; + } + if (!arc.ErrorMessage.IsEmpty()) + numErrors++; + } + } + + numArcs++; + numVolumes++; if (!stdInMode) - for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) { - int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]); - if (index >= 0 && index > i) + numVolumes += arcLink.VolumePaths.Size(); + totalArcSizes += arcLink.VolumesSize; + FOR_VECTOR (v, arcLink.VolumePaths) { - arcPaths.Delete(index); - arcPathsFull.Delete(index); - numArcs = arcPaths.Size(); + int index = Find_FileName_InSortedVector(arcPathsFull, arcLink.VolumePaths[v]); + if (index >= 0 && (unsigned)index > arcIndex) + skipArcs[(unsigned)index] = true; } } + if (enableHeaders) { - g_StdOut << endl << kListing << archiveName << endl << endl; + RINOK(Print_OpenArchive_Props(g_StdOut, codecs, arcLink)); - for (int i = 0; i < archiveLink.Arcs.Size(); i++) - { - const CArc &arc = archiveLink.Arcs[i]; - - g_StdOut << "--\n"; - PrintPropPair(L"Path", arc.Path); - PrintPropPair(L"Type", codecs->Formats[arc.FormatIndex].Name); - if (!arc.ErrorMessage.IsEmpty()) - PrintPropPair(L"Error", arc.ErrorMessage); - UInt32 numProps; - IInArchive *archive = arc.Archive; - if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK) - { - for (UInt32 j = 0; j < numProps; j++) - { - CMyComBSTR name; - PROPID propID; - VARTYPE vt; - RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt)); - NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(propID, &prop)); - UString s = ConvertPropertyToString(prop, propID); - if (!s.IsEmpty()) - PrintPropPair(GetPropName(propID, name), s); - } - } - if (i != archiveLink.Arcs.Size() - 1) - { - UInt32 numProps; - g_StdOut << "----\n"; - if (archive->GetNumberOfProperties(&numProps) == S_OK) - { - UInt32 mainIndex = archiveLink.Arcs[i + 1].SubfileIndex; - for (UInt32 j = 0; j < numProps; j++) - { - CMyComBSTR name; - PROPID propID; - VARTYPE vt; - RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt)); - NCOM::CPropVariant prop; - RINOK(archive->GetProperty(mainIndex, propID, &prop)); - UString s = ConvertPropertyToString(prop, propID); - if (!s.IsEmpty()) - PrintPropPair(GetPropName(propID, name), s); - } - } - } - - } g_StdOut << endl; if (techMode) g_StdOut << "----------\n"; @@ -555,100 +1144,148 @@ HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices, if (enableHeaders && !techMode) { - fieldPrinter.PrintTitle(); + fp.PrintTitle(); g_StdOut << endl; - fieldPrinter.PrintTitleLines(); + fp.PrintTitleLines(); g_StdOut << endl; } - const CArc &arc = archiveLink.Arcs.Back(); + const CArc &arc = arcLink.Arcs.Back(); + fp.Arc = &arc; + fp.TechMode = techMode; IInArchive *archive = arc.Archive; if (techMode) { - RINOK(fieldPrinter.Init(archive)); + fp.Clear(); + RINOK(fp.AddMainProps(archive)); + if (arc.GetRawProps) + { + RINOK(fp.AddRawProps(arc.GetRawProps)); + } } - UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0; - UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0; + + CListStat2 stat2; + UInt32 numItems; RINOK(archive->GetNumberOfItems(&numItems)); + + CReadArcItem item; + UStringVector pathParts; + for (UInt32 i = 0; i < numItems; i++) { if (NConsoleClose::TestBreakSignal()) return E_ABORT; - UString filePath; - HRESULT res = arc.GetItemPath(i, filePath); + HRESULT res = arc.GetItemPath2(i, fp.FilePath); + if (stdInMode && res == E_INVALIDARG) break; RINOK(res); - bool isFolder; - RINOK(IsArchiveItemFolder(archive, i, isFolder)); - if (!wildcardCensor.CheckPath(filePath, !isFolder)) - continue; - - fieldPrinter.PrintItemInfo(arc, i, techMode); + if (arc.Ask_Aux) + { + bool isAux; + RINOK(Archive_IsItem_Aux(archive, i, isAux)); + if (isAux) + continue; + } + + bool isAltStream = false; + if (arc.Ask_AltStream) + { + RINOK(Archive_IsItem_AltStream(archive, i, isAltStream)); + if (isAltStream && !processAltStreams) + continue; + } + + RINOK(Archive_IsItem_Dir(archive, i, fp.IsDir)); + + if (!allFilesAreAllowed) + { + if (isAltStream) + { + RINOK(arc.GetItem(i, item)); + if (!CensorNode_CheckPath(wildcardCensor, item)) + continue; + } + else + { + SplitPathToParts(fp.FilePath, pathParts);; + bool include; + if (!wildcardCensor.CheckPathVect(pathParts, !fp.IsDir, include)) + continue; + if (!include) + continue; + } + } - UInt64 packSize, unpackSize; - if (!GetUInt64Value(archive, i, kpidSize, unpackSize)) - unpackSize = 0; - else - totalUnPackSizePointer = &totalUnPackSize; - if (!GetUInt64Value(archive, i, kpidPackSize, packSize)) - packSize = 0; - else - totalPackSizePointer = &totalPackSize; + CListStat st; - g_StdOut << endl; + RINOK(GetUInt64Value(archive, i, kpidSize, st.Size)); + RINOK(GetUInt64Value(archive, i, kpidPackSize, st.PackSize)); + RINOK(GetItemMTime(archive, i, st.MTime)); - if (isFolder) - numDirs++; + if (fp.IsDir) + stat2.NumDirs++; else - numFiles++; - totalPackSize += packSize; - totalUnPackSize += unpackSize; - } + st.NumFiles = 1; + stat2.GetStat(isAltStream).Update(st); - if (!stdInMode && totalPackSizePointer == 0) - { - if (archiveLink.VolumePaths.Size() != 0) - arcPackSize += archiveLink.VolumesSize; - totalPackSize = (numFiles == 0) ? 0 : arcPackSize; - totalPackSizePointer = &totalPackSize; + if (isAltStream && !showAltStreams) + continue; + RINOK(fp.PrintItemInfo(i, st)); } - if (totalUnPackSizePointer == 0 && numFiles == 0) + + UInt64 numStreams = stat2.GetNumStreams(); + if (!stdInMode + && !stat2.MainFiles.PackSize.Def + && !stat2.AltStreams.PackSize.Def) { - totalUnPackSize = 0; - totalUnPackSizePointer = &totalUnPackSize; + if (arcLink.VolumePaths.Size() != 0) + arcPackSize += arcLink.VolumesSize; + stat2.MainFiles.PackSize.Add((numStreams == 0) ? 0 : arcPackSize); } + + stat2.MainFiles.SetSizeDefIfNoFiles(); + stat2.AltStreams.SetSizeDefIfNoFiles(); + if (enableHeaders && !techMode) { - fieldPrinter.PrintTitleLines(); + fp.PrintTitleLines(); g_StdOut << endl; - fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer); - g_StdOut << endl; - } - if (totalPackSizePointer != 0) - { - totalPackSizePointer2 = &totalPackSize2; - totalPackSize2 += totalPackSize; + fp.PrintSum(stat2); } - if (totalUnPackSizePointer != 0) + + if (enableHeaders) { - totalUnPackSizePointer2 = &totalUnPackSize2; - totalUnPackSize2 += totalUnPackSize; + if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) + { + g_StdOut << "----------\n"; + PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath); + PrintArcTypeError(g_StdOut, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); + } } - numFiles2 += numFiles; - numDirs2 += numDirs; + + stat2total.Update(stat2); + + g_StdOut.Flush(); } - if (enableHeaders && !techMode && numArcs > 1) + + if (enableHeaders && !techMode && (arcPaths.Size() > 1 || numVolumes > 1)) { g_StdOut << endl; - fieldPrinter.PrintTitleLines(); + fp.PrintTitleLines(); g_StdOut << endl; - fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2); + fp.PrintSum(stat2total); g_StdOut << endl; - g_StdOut << "Archives: " << numArcs << endl; + PrintPropNameAndNumber(g_StdOut, "Archives", numArcs); + PrintPropNameAndNumber(g_StdOut, "Volumes", numVolumes); + PrintPropNameAndNumber(g_StdOut, "Total archives size", totalArcSizes); } + + if (numErrors == 1 && lastError != 0) + return lastError; + return S_OK; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/List.h b/3rdparty/lzma/CPP/7zip/UI/Console/List.h index 97d9fb15ab3..462c4710375 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/List.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/List.h @@ -3,18 +3,25 @@ #ifndef __LIST_H #define __LIST_H -#include "Common/Wildcard.h" +#include "../../../Common/Wildcard.h" + #include "../Common/LoadCodecs.h" -HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices, +HRESULT ListArchives(CCodecs *codecs, + const CObjectVector<COpenType> &types, + const CIntVector &excludedFormats, bool stdInMode, UStringVector &archivePaths, UStringVector &archivePathsFull, + bool processAltStreams, bool showAltStreams, const NWildcard::CCensorNode &wildcardCensor, bool enableHeaders, bool techMode, #ifndef _NO_CRYPTO bool &passwordEnabled, UString &password, #endif - UInt64 &errors); + #ifndef _SFX + const CObjectVector<CProperty> *props, + #endif + UInt64 &errors, + UInt64 &numWarnings); #endif - diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp index f5a703979eb..50652555de7 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/Main.cpp @@ -2,42 +2,55 @@ #include "StdAfx.h" -#if defined( _WIN32) && defined( _7ZIP_LARGE_PAGES) +#include "../../../Common/MyWindows.h" + +#ifdef _WIN32 +#include <Psapi.h> +#endif + +#include "../../../../C/CpuArch.h" + +#if defined( _7ZIP_LARGE_PAGES) #include "../../../../C/Alloc.h" #endif -#include "Common/MyInitGuid.h" +#include "../../../Common/MyInitGuid.h" -#include "Common/CommandLineParser.h" -#include "Common/IntToString.h" -#include "Common/MyException.h" -#include "Common/StdOutStream.h" -#include "Common/StringConvert.h" -#include "Common/StringToInt.h" +#include "../../../Common/CommandLineParser.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/MyException.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" +#include "../../../Common/UTFConvert.h" + +#include "../../../Windows/ErrorMsg.h" -#include "Windows/Error.h" #ifdef _WIN32 -#include "Windows/MemoryLock.h" +#include "../../../Windows/MemoryLock.h" #endif +#include "../../../Windows/TimeUtils.h" + #include "../Common/ArchiveCommandLine.h" #include "../Common/ExitCode.h" #include "../Common/Extract.h" + #ifdef EXTERNAL_CODECS #include "../Common/LoadCodecs.h" #endif +#include "../../Common/RegisterCodec.h" + #include "BenchCon.h" +#include "ConsoleClose.h" #include "ExtractCallbackConsole.h" #include "List.h" #include "OpenCallbackConsole.h" #include "UpdateCallbackConsole.h" -#if !defined(EXTERNAL_CODECS) && defined(_NO_CRYPTO) -#define IT_IS_REDUCED_VERSION -#endif +#include "HashCon.h" -#ifdef IT_IS_REDUCED_VERSION +#ifdef PROG_VARIANT_R #include "../../../../C/7zVersion.h" #else #include "../../MyVersion.h" @@ -50,27 +63,37 @@ using namespace NCommandLineParser; #ifdef _WIN32 HINSTANCE g_hInstance = 0; #endif + extern CStdOutStream *g_StdStream; +extern CStdOutStream *g_ErrStream; + +extern unsigned g_NumCodecs; +extern const CCodecInfo *g_Codecs[]; + +extern unsigned g_NumHashers; +extern const CHasherInfo *g_Hashers[]; static const char *kCopyrightString = "\n7-Zip" #ifndef EXTERNAL_CODECS -#ifdef IT_IS_REDUCED_VERSION +#ifdef PROG_VARIANT_R " (r)" #else " (a)" #endif #endif -#ifdef _WIN64 +#ifdef MY_CPU_64BIT " [64]" +#elif defined MY_CPU_32BIT +" [32]" #endif -" " MY_VERSION_COPYRIGHT_DATE "\n"; +" " MY_VERSION_COPYRIGHT_DATE "\n\n"; static const char *kHelpString = - "\nUsage: 7z" + "Usage: 7z" #ifndef EXTERNAL_CODECS -#ifdef IT_IS_REDUCED_VERSION +#ifdef PROG_VARIANT_R "r" #else "a" @@ -80,42 +103,65 @@ static const char *kHelpString = " [<@listfiles...>]\n" "\n" "<Commands>\n" - " a: Add files to archive\n" - " b: Benchmark\n" - " d: Delete files from archive\n" - " e: Extract files from archive (without using directory names)\n" - " l: List contents of archive\n" -// " l[a|t][f]: List contents of archive\n" -// " a - with Additional fields\n" -// " t - with all fields\n" -// " f - with Full pathnames\n" - " t: Test integrity of archive\n" - " u: Update files to archive\n" - " x: eXtract files with full paths\n" + " a : Add files to archive\n" + " b : Benchmark\n" + " d : Delete files from archive\n" + " e : Extract files from archive (without using directory names)\n" + " h : Calculate hash values for files\n" + " i : Show information about supported formats\n" + " l : List contents of archive\n" + " rn : Rename files in archive\n" + " t : Test integrity of archive\n" + " u : Update files to archive\n" + " x : eXtract files with full paths\n" + "\n" "<Switches>\n" - " -ai[r[-|0]]{@listfile|!wildcard}: Include archives\n" - " -ax[r[-|0]]{@listfile|!wildcard}: eXclude archives\n" - " -bd: Disable percentage indicator\n" - " -i[r[-|0]]{@listfile|!wildcard}: Include filenames\n" - " -m{Parameters}: set compression Method\n" - " -o{Directory}: set Output directory\n" + " -- : Stop switches parsing\n" + " -ai[r[-|0]]{@listfile|!wildcard} : Include archives\n" + " -ax[r[-|0]]{@listfile|!wildcard} : eXclude archives\n" + " -ao{a|s|t|u} : set Overwrite mode\n" + " -an : disable archive_name field\n" + " -bb[0-3] : set output log level\n" + " -bd : disable progress indicator\n" + " -bs{o|e|p}{0|1|2} : set output stream for output/error/progress line\n" + " -bt : show execution time statistics\n" + " -i[r[-|0]]{@listfile|!wildcard} : Include filenames\n" + " -m{Parameters} : set compression Method\n" + " -mmt[N] : set number of CPU threads\n" + " -o{Directory} : set Output directory\n" #ifndef _NO_CRYPTO - " -p{Password}: set Password\n" + " -p{Password} : set Password\n" #endif - " -r[-|0]: Recurse subdirectories\n" - " -scs{UTF-8 | WIN | DOS}: set charset for list files\n" - " -sfx[{name}]: Create SFX archive\n" - " -si[{name}]: read data from stdin\n" - " -slt: show technical information for l (List) command\n" - " -so: write data to stdout\n" - " -ssc[-]: set sensitive case mode\n" - " -ssw: compress shared files\n" - " -t{Type}: Set type of archive\n" - " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n" - " -v{Size}[b|k|m|g]: Create volumes\n" - " -w[{path}]: assign Work directory. Empty path means a temporary directory\n" - " -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n" - " -y: assume Yes on all queries\n"; + " -r[-|0] : Recurse subdirectories\n" + " -sa{a|e|s} : set Archive name mode\n" + " -scc{UTF-8|WIN|DOS} : set charset for for console input/output\n" + " -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n" + " -scrc[CRC32|CRC64|SHA1|SHA256|*] : set hash function for x, e, h commands\n" + " -sdel : delete files after compression\n" + " -seml[.] : send archive by email\n" + " -sfx[{name}] : Create SFX archive\n" + " -si[{name}] : read data from stdin\n" + " -slp : set Large Pages mode\n" + " -slt : show technical information for l (List) command\n" + " -snh : store hard links as links\n" + " -snl : store symbolic links as links\n" + " -sni : store NT security information\n" + " -sns[-] : store NTFS alternate streams\n" + " -so : write data to stdout\n" + " -spd : disable wildcard matching for file names\n" + " -spe : eliminate duplication of root folder for extract command\n" + " -spf : use fully qualified file paths\n" + " -ssc[-] : set sensitive case mode\n" + " -ssw : compress shared files\n" + " -stl : set archive timestamp from the most recently modified file\n" + " -stm{HexMask} : set CPU thread affinity mask (hexadecimal number)\n" + " -stx{Type} : exclude archive type\n" + " -t{Type} : Set type of archive\n" + " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options\n" + " -v{Size}[b|k|m|g] : Create volumes\n" + " -w[{path}] : assign Work directory. Empty path means a temporary directory\n" + " -x[r[-|0]]{@listfile|!wildcard} : eXclude filenames\n" + " -y : assume Yes on all queries\n"; // --------------------------- // exception messages @@ -124,21 +170,17 @@ static const char *kEverythingIsOk = "Everything is Ok"; static const char *kUserErrorMessage = "Incorrect command line"; static const char *kNoFormats = "7-Zip cannot find the code that works with archives."; static const char *kUnsupportedArcTypeMessage = "Unsupported archive type"; +// static const char *kUnsupportedUpdateArcType = "Can't create archive for that type"; static CFSTR kDefaultSfxModule = FTEXT("7zCon.sfx"); -static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code) +static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code) { - s << message << endl; + if (g_ErrStream) + *g_ErrStream << endl << "ERROR: " << message << endl; throw code; } -static void PrintHelpAndExit(CStdOutStream &s) -{ - s << kHelpString; - ShowMessageAndThrowException(s, kUserErrorMessage, NExitCode::kUserError); -} - #ifndef _WIN32 static void GetArguments(int numArgs, const char *args[], UStringVector &parts) { @@ -151,48 +193,295 @@ static void GetArguments(int numArgs, const char *args[], UStringVector &parts) } #endif -static void ShowCopyrightAndHelp(CStdOutStream &s, bool needHelp) +static void ShowCopyrightAndHelp(CStdOutStream *so, bool needHelp) { - s << kCopyrightString; - // s << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << "\n"; + if (!so) + return; + *so << kCopyrightString; + // *so << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << endl; if (needHelp) - s << kHelpString; + *so << kHelpString; } -#ifdef EXTERNAL_CODECS -static void PrintString(CStdOutStream &stdStream, const AString &s, int size) + +static void PrintStringRight(CStdOutStream &so, const AString &s, unsigned size) +{ + unsigned len = s.Len(); + for (unsigned i = len; i < size; i++) + so << ' '; + so << s; +} + +static void PrintUInt32(CStdOutStream &so, UInt32 val, unsigned size) +{ + char s[16]; + ConvertUInt32ToString(val, s); + PrintStringRight(so, s, size); +} + +static void PrintLibIndex(CStdOutStream &so, int libIndex) +{ + if (libIndex >= 0) + PrintUInt32(so, libIndex, 2); + else + so << " "; + so << ' '; +} + +static void PrintString(CStdOutStream &so, const UString &s, unsigned size) +{ + unsigned len = s.Len(); + so << s; + for (unsigned i = len; i < size; i++) + so << ' '; +} + +static inline char GetHex(unsigned val) +{ + return (char)((val < 10) ? ('0' + val) : ('A' + (val - 10))); +} + +static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so) +{ + FOR_VECTOR(i, pc.Paths) + { + so << pc.Paths[i] << " : "; + so << NError::MyFormatMessage(pc.Codes[i]) << endl; + } + so << "----------------" << endl; +} + +static int WarningsCheck(HRESULT result, const CCallbackConsoleBase &callback, + const CUpdateErrorInfo &errorInfo, + CStdOutStream *so, + CStdOutStream *se, + bool showHeaders) +{ + int exitCode = NExitCode::kSuccess; + + if (callback.ScanErrors.Paths.Size() != 0) + { + if (se) + { + *se << endl; + *se << "Scan WARNINGS for files and folders:" << endl << endl; + PrintWarningsPaths(callback.ScanErrors, *se); + *se << "Scan WARNINGS: " << callback.ScanErrors.Paths.Size(); + *se << endl; + } + exitCode = NExitCode::kWarning; + } + + if (result != S_OK || errorInfo.ThereIsError()) + { + if (se) + { + UString message; + if (!errorInfo.Message.IsEmpty()) + { + message.AddAscii(errorInfo.Message); + message.Add_LF(); + } + { + FOR_VECTOR(i, errorInfo.FileNames) + { + message += fs2us(errorInfo.FileNames[i]); + message.Add_LF(); + } + } + if (errorInfo.SystemError != 0) + { + message += NError::MyFormatMessage(errorInfo.SystemError); + message.Add_LF(); + } + if (!message.IsEmpty()) + *se << L"\nError:\n" << message; + } + + // we will work with (result) later + // throw CSystemException(result); + return NExitCode::kFatalError; + } + + unsigned numErrors = callback.FailedFiles.Paths.Size(); + if (numErrors == 0) + { + if (showHeaders) + if (callback.ScanErrors.Paths.Size() == 0) + if (so) + { + if (se) + se->Flush(); + *so << kEverythingIsOk << endl; + } + } + else + { + if (se) + { + *se << endl; + *se << "WARNINGS for files:" << endl << endl; + PrintWarningsPaths(callback.FailedFiles, *se); + *se << "WARNING: Cannot open " << numErrors << " file"; + if (numErrors > 1) + *se << 's'; + *se << endl; + } + exitCode = NExitCode::kWarning; + } + + return exitCode; +} + +static void ThrowException_if_Error(HRESULT res) +{ + if (res != S_OK) + throw CSystemException(res); +} + + +static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ') +{ + char temp[64]; + char *p = temp + 32; + ConvertUInt64ToString(val, p); + unsigned len = MyStringLen(p); + for (; len < numDigits; len++) + *--p = c; + *g_StdStream << p; +} + +static void PrintTime(const char *s, UInt64 val, UInt64 total) +{ + *g_StdStream << endl << s << " Time ="; + const UInt32 kFreq = 10000000; + UInt64 sec = val / kFreq; + PrintNum(sec, 6); + *g_StdStream << '.'; + UInt32 ms = (UInt32)(val - (sec * kFreq)) / (kFreq / 1000); + PrintNum(ms, 3, '0'); + + while (val > ((UInt64)1 << 56)) + { + val >>= 1; + total >>= 1; + } + + UInt64 percent = 0; + if (total != 0) + percent = val * 100 / total; + *g_StdStream << " ="; + PrintNum(percent, 5); + *g_StdStream << '%'; +} + +#ifndef UNDER_CE + +#define SHIFT_SIZE_VALUE(x, num) (((x) + (1 << (num)) - 1) >> (num)) + +static void PrintMemUsage(const char *s, UInt64 val) { - int len = s.Length(); - stdStream << s; - for (int i = len; i < size; i++) - stdStream << ' '; + *g_StdStream << " " << s << " Memory ="; + PrintNum(SHIFT_SIZE_VALUE(val, 20), 7); + *g_StdStream << " MB"; } + +EXTERN_C_BEGIN +typedef BOOL (WINAPI *Func_GetProcessMemoryInfo)(HANDLE Process, + PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb); +EXTERN_C_END + #endif -static void PrintString(CStdOutStream &stdStream, const UString &s, int size) +static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; } + +static void PrintStat() { - int len = s.Length(); - stdStream << s; - for (int i = len; i < size; i++) - stdStream << ' '; + FILETIME creationTimeFT, exitTimeFT, kernelTimeFT, userTimeFT; + if (! + #ifdef UNDER_CE + ::GetThreadTimes(::GetCurrentThread() + #else + // NT 3.5 + ::GetProcessTimes(::GetCurrentProcess() + #endif + , &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT)) + return; + FILETIME curTimeFT; + NTime::GetCurUtcFileTime(curTimeFT); + + #ifndef UNDER_CE + + PROCESS_MEMORY_COUNTERS m; + memset(&m, 0, sizeof(m)); + BOOL memDefined = FALSE; + { + /* NT 4.0: GetProcessMemoryInfo() in Psapi.dll + Win7: new function K32GetProcessMemoryInfo() in kernel32.dll + It's faster to call kernel32.dll code than Psapi.dll code + GetProcessMemoryInfo() requires Psapi.lib + Psapi.lib in SDK7+ can link to K32GetProcessMemoryInfo in kernel32.dll + The program with K32GetProcessMemoryInfo will not work on systems before Win7 + // memDefined = GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); + */ + + Func_GetProcessMemoryInfo my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo) + ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "K32GetProcessMemoryInfo"); + if (!my_GetProcessMemoryInfo) + { + HMODULE lib = LoadLibraryW(L"Psapi.dll"); + if (lib) + my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)::GetProcAddress(lib, "GetProcessMemoryInfo"); + } + if (my_GetProcessMemoryInfo) + memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); + // FreeLibrary(lib); + } + + #endif + + UInt64 curTime = GetTime64(curTimeFT); + UInt64 creationTime = GetTime64(creationTimeFT); + UInt64 kernelTime = GetTime64(kernelTimeFT); + UInt64 userTime = GetTime64(userTimeFT); + + UInt64 totalTime = curTime - creationTime; + + PrintTime("Kernel ", kernelTime, totalTime); + PrintTime("User ", userTime, totalTime); + + PrintTime("Process", kernelTime + userTime, totalTime); + #ifndef UNDER_CE + if (memDefined) PrintMemUsage("Virtual ", m.PeakPagefileUsage); + #endif + + PrintTime("Global ", totalTime, totalTime); + #ifndef UNDER_CE + if (memDefined) PrintMemUsage("Physical", m.PeakWorkingSetSize); + #endif + + *g_StdStream << endl; } -static inline char GetHex(Byte value) +static void PrintHexId(CStdOutStream &so, UInt64 id) { - return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); + char s[32]; + ConvertUInt64ToHex(id, s); + PrintStringRight(so, s, 8); } int Main2( #ifndef _WIN32 - int numArgs, const char *args[] + int numArgs, char *args[] #endif ) { #if defined(_WIN32) && !defined(UNDER_CE) SetFileApisToOEM(); #endif - + UStringVector commandStrings; + #ifdef _WIN32 NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); #else @@ -201,89 +490,185 @@ int Main2( if (commandStrings.Size() == 1) { - ShowCopyrightAndHelp(g_StdOut, true); + ShowCopyrightAndHelp(g_StdStream, true); return 0; } + commandStrings.Delete(0); - CArchiveCommandLineOptions options; + CArcCmdLineOptions options; - CArchiveCommandLineParser parser; + CArcCmdLineParser parser; parser.Parse1(commandStrings, options); + + if (options.Number_for_Out != k_OutStream_stdout) + g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL); + + if (options.Number_for_Errors != k_OutStream_stderr) + g_ErrStream = (options.Number_for_Errors == k_OutStream_stdout ? &g_StdOut : NULL); + + CStdOutStream *percentsStream = NULL; + if (options.Number_for_Percents != k_OutStream_disabled) + percentsStream = (options.Number_for_Percents == k_OutStream_stderr) ? &g_StdErr : &g_StdOut;; + if (options.HelpMode) { - ShowCopyrightAndHelp(g_StdOut, true); + ShowCopyrightAndHelp(g_StdStream, true); return 0; } - #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES) + #if defined(_WIN32) && !defined(UNDER_CE) + NSecurity::EnablePrivilege_SymLink(); + #endif + + #ifdef _7ZIP_LARGE_PAGES if (options.LargePages) { SetLargePageSize(); - NSecurity::EnableLockMemoryPrivilege(); + #if defined(_WIN32) && !defined(UNDER_CE) + NSecurity::EnablePrivilege_LockMemory(); + #endif } #endif - CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut; - g_StdStream = &stdStream; - if (options.EnableHeaders) - ShowCopyrightAndHelp(stdStream, false); + ShowCopyrightAndHelp(g_StdStream, false); parser.Parse2(options); - CCodecs *codecs = new CCodecs; - CMyComPtr< - #ifdef EXTERNAL_CODECS - ICompressCodecsInfo + unsigned percentsNameLevel = 1; + if (options.LogLevel == 0 || options.Number_for_Percents != options.Number_for_Out) + percentsNameLevel = 2; + + unsigned consoleWidth = 80; + + if (percentsStream) + { + #ifdef _WIN32 + + #if !defined(UNDER_CE) + CONSOLE_SCREEN_BUFFER_INFO consoleInfo; + if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo)) + consoleWidth = consoleInfo.dwSize.X; + #endif + #else - IUnknown + + struct winsize w; + if (ioctl(0, TIOCGWINSZ, &w) == ) + consoleWidth = w.ws_col; + #endif - > compressCodecsInfo = codecs; - HRESULT result = codecs->Load(); - if (result != S_OK) - throw CSystemException(result); + } + + CREATE_CODECS_OBJECT + + codecs->CaseSensitiveChange = options.CaseSensitiveChange; + codecs->CaseSensitive = options.CaseSensitive; + ThrowException_if_Error(codecs->Load()); bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); if (codecs->Formats.Size() == 0 && - (isExtractGroupCommand || - options.Command.CommandType == NCommandType::kList || - options.Command.IsFromUpdateGroup())) + (isExtractGroupCommand + || options.Command.CommandType == NCommandType::kList + || options.Command.IsFromUpdateGroup())) + { + #ifdef EXTERNAL_CODECS + if (!codecs->MainDll_ErrorPath.IsEmpty()) + { + UString s = L"Can't load module "; + s += fs2us(codecs->MainDll_ErrorPath); + throw s; + } + #endif + throw kNoFormats; + } - CIntVector formatIndices; - if (!codecs->FindFormatForArchiveType(options.ArcType, formatIndices)) + CObjectVector<COpenType> types; + if (!ParseOpenTypes(*codecs, options.ArcType, types)) throw kUnsupportedArcTypeMessage; + CIntVector excludedFormats; + FOR_VECTOR (k, options.ExcludedArcTypes) + { + CIntVector tempIndices; + if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices) + || tempIndices.Size() != 1) + throw kUnsupportedArcTypeMessage; + excludedFormats.AddToUniqueSorted(tempIndices[0]); + // excludedFormats.Sort(); + } + + + #ifdef EXTERNAL_CODECS + if (isExtractGroupCommand + || options.Command.CommandType == NCommandType::kHash + || options.Command.CommandType == NCommandType::kBenchmark) + ThrowException_if_Error(__externalCodecs.Load()); + #endif + + int retCode = NExitCode::kSuccess; + HRESULT hresultMain = S_OK; + + // bool showStat = options.ShowTime; + + /* + if (!options.EnableHeaders || + options.TechMode) + showStat = false; + */ + + if (options.Command.CommandType == NCommandType::kInfo) { - stdStream << endl << "Formats:" << endl; - int i; + CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); + unsigned i; + + #ifdef EXTERNAL_CODECS + so << endl << "Libs:" << endl; + for (i = 0; i < codecs->Libs.Size(); i++) + { + PrintLibIndex(so, i); + so << ' ' << codecs->Libs[i].Path << endl; + } + #endif + + so << endl << "Formats:" << endl; + + const char *kArcFlags = "KSNFMGOPBELH"; + const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags); + for (i = 0; i < codecs->Formats.Size(); i++) { const CArcInfoEx &arc = codecs->Formats[i]; + #ifdef EXTERNAL_CODECS - if (arc.LibIndex >= 0) + PrintLibIndex(so, arc.LibIndex); + #else + so << " "; + #endif + + so << (char)(arc.UpdateEnabled ? 'C' : ' '); + + for (unsigned b = 0; b < kNumArcFlags; b++) { - char s[16]; - ConvertUInt32ToString(arc.LibIndex, s); - PrintString(stdStream, s, 2); + so << (char) + ((arc.Flags & ((UInt32)1 << b)) != 0 ? kArcFlags[b] : ' '); } - else - #endif - stdStream << " "; - stdStream << ' '; - stdStream << (char)(arc.UpdateEnabled ? 'C' : ' '); - stdStream << (char)(arc.KeepName ? 'K' : ' '); - stdStream << " "; - PrintString(stdStream, arc.Name, 6); - stdStream << " "; + + so << ' '; + PrintString(so, arc.Name, 8); + so << ' '; UString s; - for (int t = 0; t < arc.Exts.Size(); t++) + + FOR_VECTOR (t, arc.Exts) { + if (t != 0) + s.Add_Space(); const CArcExtInfo &ext = arc.Exts[t]; s += ext.Ext; if (!ext.AddExt.IsEmpty()) @@ -292,199 +677,381 @@ int Main2( s += ext.AddExt; s += L')'; } - s += L' '; } - PrintString(stdStream, s, 14); - stdStream << " "; - const CByteBuffer &sig = arc.StartSignature; - for (size_t j = 0; j < sig.GetCapacity(); j++) + + PrintString(so, s, 13); + so << ' '; + + if (arc.SignatureOffset != 0) + so << "offset=" << arc.SignatureOffset << ' '; + + FOR_VECTOR(si, arc.Signatures) { - Byte b = sig[j]; - if (b > 0x20 && b < 0x80) - { - stdStream << (char)b; - } - else + if (si != 0) + so << " || "; + + const CByteBuffer &sig = arc.Signatures[si]; + + for (size_t j = 0; j < sig.Size(); j++) { - stdStream << GetHex((Byte)((b >> 4) & 0xF)); - stdStream << GetHex((Byte)(b & 0xF)); + if (j != 0) + so << ' '; + Byte b = sig[j]; + if (b > 0x20 && b < 0x80) + { + so << (char)b; + } + else + { + so << GetHex((b >> 4) & 0xF); + so << GetHex(b & 0xF); + } } - stdStream << ' '; } - stdStream << endl; + so << endl; + } + + so << endl << "Codecs:" << endl; // << "Lib ID Name" << endl; + + for (i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &cod = *g_Codecs[i]; + + PrintLibIndex(so, -1); + + if (cod.NumStreams == 1) + so << ' '; + else + so << cod.NumStreams; + + so << (char)(cod.CreateEncoder ? 'E' : ' '); + so << (char)(cod.CreateDecoder ? 'D' : ' '); + + so << ' '; + PrintHexId(so, cod.Id); + so << ' ' << cod.Name << endl; } - stdStream << endl << "Codecs:" << endl; + #ifdef EXTERNAL_CODECS + UInt32 numMethods; - if (codecs->GetNumberOfMethods(&numMethods) == S_OK) + if (codecs->GetNumMethods(&numMethods) == S_OK) for (UInt32 j = 0; j < numMethods; j++) { - int libIndex = codecs->GetCodecLibIndex(j); - if (libIndex >= 0) - { - char s[16]; - ConvertUInt32ToString(libIndex, s); - PrintString(stdStream, s, 2); - } + PrintLibIndex(so, codecs->GetCodec_LibIndex(j)); + + UInt32 numStreams = codecs->GetCodec_NumStreams(j); + if (numStreams == 1) + so << ' '; else - stdStream << " "; - stdStream << ' '; - stdStream << (char)(codecs->GetCodecEncoderIsAssigned(j) ? 'C' : ' '); + so << numStreams; + + so << (char)(codecs->GetCodec_EncoderIsAssigned(j) ? 'E' : ' '); + so << (char)(codecs->GetCodec_DecoderIsAssigned(j) ? 'D' : ' '); + + so << ' '; UInt64 id; - stdStream << " "; - HRESULT res = codecs->GetCodecId(j, id); + HRESULT res = codecs->GetCodec_Id(j, id); if (res != S_OK) id = (UInt64)(Int64)-1; - char s[32]; - ConvertUInt64ToString(id, s, 16); - PrintString(stdStream, s, 8); - stdStream << " "; - PrintString(stdStream, codecs->GetCodecName(j), 11); - stdStream << endl; - /* - if (res != S_OK) - throw "incorrect Codec ID"; - */ + PrintHexId(so, id); + so << ' ' << codecs->GetCodec_Name(j) << endl; } + #endif - return S_OK; + + + so << endl << "Hashers:" << endl; // << " L Size ID Name" << endl; + + for (i = 0; i < g_NumHashers; i++) + { + const CHasherInfo &codec = *g_Hashers[i]; + PrintLibIndex(so, -1); + PrintUInt32(so, codec.DigestSize, 4); + so << ' '; + PrintHexId(so, codec.Id); + so << ' ' << codec.Name << endl; + } + + #ifdef EXTERNAL_CODECS + + numMethods = codecs->GetNumHashers(); + for (UInt32 j = 0; j < numMethods; j++) + { + PrintLibIndex(so, codecs->GetHasherLibIndex(j)); + PrintUInt32(so, codecs->GetHasherDigestSize(j), 4); + so << ' '; + PrintHexId(so, codecs->GetHasherId(j)); + so << ' ' << codecs->GetHasherName(j) << endl; + } + + #endif + } else if (options.Command.CommandType == NCommandType::kBenchmark) { + CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); + hresultMain = BenchCon(EXTERNAL_CODECS_VARS_L + options.Properties, options.NumIterations, (FILE *)so); + if (hresultMain == S_FALSE) { - HRESULT res; - #ifdef EXTERNAL_CODECS - CObjectVector<CCodecInfoEx> externalCodecs; - res = LoadExternalCodecs(compressCodecsInfo, externalCodecs); - if (res != S_OK) - throw CSystemException(res); - #endif - res = BenchCon( - #ifdef EXTERNAL_CODECS - compressCodecsInfo, &externalCodecs, - #endif - options.Properties, options.NumIterations, (FILE *)stdStream); - if (res != S_OK) + if (g_ErrStream) + *g_ErrStream << "\nDecoding ERROR\n"; + retCode = NExitCode::kFatalError; + hresultMain = S_OK; + } + } + else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList) + { + UStringVector ArchivePathsSorted; + UStringVector ArchivePathsFullSorted; + + if (options.StdInMode) + { + ArchivePathsSorted.Add(options.ArcName_for_StdInMode); + ArchivePathsFullSorted.Add(options.ArcName_for_StdInMode); + } + else + { + CExtractScanConsole scan; + + scan.Init(options.EnableHeaders ? g_StdStream : NULL, g_ErrStream, percentsStream); + scan.SetWindowWidth(consoleWidth); + + if (g_StdStream && options.EnableHeaders) + *g_StdStream << "Scanning the drive for archives:" << endl; + + CDirItemsStat st; + + scan.StartScanning(); + + hresultMain = EnumerateDirItemsAndSort( + options.arcCensor, + NWildcard::k_RelatPath, + UString(), // addPathPrefix + ArchivePathsSorted, + ArchivePathsFullSorted, + st, + &scan); + + scan.CloseScanning(); + + if (hresultMain == S_OK) { - if (res == S_FALSE) + if (options.EnableHeaders) + scan.PrintStat(st); + } + else + { + /* + if (res != E_ABORT) { - stdStream << "\nDecoding Error\n"; - return NExitCode::kFatalError; + throw CSystemException(res); + // errorInfo.Message = "Scanning error"; } - throw CSystemException(res); + return res; + */ } } - } - else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList) - { + + if (hresultMain == S_OK) if (isExtractGroupCommand) { CExtractCallbackConsole *ecs = new CExtractCallbackConsole; CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs; - ecs->OutStream = &stdStream; - #ifndef _NO_CRYPTO ecs->PasswordIsDefined = options.PasswordEnabled; ecs->Password = options.Password; #endif - ecs->Init(); + ecs->Init(g_StdStream, g_ErrStream, percentsStream); + ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1); + ecs->LogLevel = options.LogLevel; + ecs->PercentsNameLevel = percentsNameLevel; + + if (percentsStream) + ecs->SetWindowWidth(consoleWidth); + + /* COpenCallbackConsole openCallback; - openCallback.OutStream = &stdStream; + openCallback.Init(g_StdStream, g_ErrStream); #ifndef _NO_CRYPTO openCallback.PasswordIsDefined = options.PasswordEnabled; openCallback.Password = options.Password; #endif + */ CExtractOptions eo; + (CExtractOptionsBase &)eo = options.ExtractOptions; + eo.StdInMode = options.StdInMode; eo.StdOutMode = options.StdOutMode; - eo.PathMode = options.Command.GetPathMode(); - eo.TestMode = options.Command.IsTestMode(); - eo.OverwriteMode = options.OverwriteMode; - eo.OutputDir = options.OutputDir; eo.YesToAll = options.YesToAll; - eo.CalcCrc = options.CalcCrc; - #if !defined(_7ZIP_ST) && !defined(_SFX) + eo.TestMode = options.Command.IsTestCommand(); + + #ifndef _SFX eo.Properties = options.Properties; #endif + UString errorMessage; CDecompressStat stat; - HRESULT result = DecompressArchives( + CHashBundle hb; + IHashCalc *hashCalc = NULL; + + if (!options.HashMethods.IsEmpty()) + { + hashCalc = &hb; + ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods)); + hb.Init(); + } + + hresultMain = Extract( codecs, - formatIndices, - options.ArchivePathsSorted, - options.ArchivePathsFullSorted, - options.WildcardCensor.Pairs.Front().Head, - eo, &openCallback, ecs, errorMessage, stat); + types, + excludedFormats, + ArchivePathsSorted, + ArchivePathsFullSorted, + options.Censor.Pairs.Front().Head, + eo, ecs, ecs, hashCalc, errorMessage, stat); + + ecs->ClosePercents(); + if (!errorMessage.IsEmpty()) { - stdStream << endl << "Error: " << errorMessage; - if (result == S_OK) - result = E_FAIL; + if (g_ErrStream) + *g_ErrStream << endl << "ERROR:" << endl << errorMessage << endl; + if (hresultMain == S_OK) + hresultMain = E_FAIL; } - stdStream << endl; - if (ecs->NumArchives > 1) - stdStream << "Archives: " << ecs->NumArchives << endl; - if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0) + CStdOutStream *so = g_StdStream; + + bool isError = false; + + if (so) + { + *so << endl; + + if (ecs->NumTryArcs > 1) + { + *so << "Archives: " << ecs->NumTryArcs << endl; + *so << "OK archives: " << ecs->NumOkArcs << endl; + } + } + + if (ecs->NumCantOpenArcs != 0) + { + isError = true; + if (so) + *so << "Can't open as archive: " << ecs->NumCantOpenArcs << endl; + } + + if (ecs->NumArcsWithError != 0) + { + isError = true; + if (so) + *so << "Archives with Errors: " << ecs->NumArcsWithError << endl; + } + + if (so) { - if (ecs->NumArchives > 1) + if (ecs->NumArcsWithWarnings != 0) + *so << "Archives with Warnings: " << ecs->NumArcsWithWarnings << endl; + + if (ecs->NumOpenArcWarnings != 0) { - stdStream << endl; - if (ecs->NumArchiveErrors != 0) - stdStream << "Archive Errors: " << ecs->NumArchiveErrors << endl; + *so << endl; + if (ecs->NumOpenArcWarnings != 0) + *so << "Warnings: " << ecs->NumOpenArcWarnings << endl; + } + } + + if (ecs->NumOpenArcErrors != 0) + { + isError = true; + if (so) + { + *so << endl; + if (ecs->NumOpenArcErrors != 0) + *so << "Open Errors: " << ecs->NumOpenArcErrors << endl; + } + } + + if (isError) + retCode = NExitCode::kFatalError; + + if (so) + if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0) + { + // if (ecs->NumArchives > 1) + { + *so << endl; if (ecs->NumFileErrors != 0) - stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl; + *so << "Sub items Errors: " << ecs->NumFileErrors << endl; } - if (result != S_OK) - throw CSystemException(result); - return NExitCode::kFatalError; } - if (result != S_OK) - throw CSystemException(result); - if (stat.NumFolders != 0) - stdStream << "Folders: " << stat.NumFolders << endl; - if (stat.NumFiles != 1 || stat.NumFolders != 0) - stdStream << "Files: " << stat.NumFiles << endl; - stdStream - << "Size: " << stat.UnpackSize << endl - << "Compressed: " << stat.PackSize << endl; - if (options.CalcCrc) + else if (hresultMain == S_OK) { - char s[16]; - ConvertUInt32ToHexWithZeros(stat.CrcSum, s); - stdStream << "CRC: " << s << endl; + if (stat.NumFolders != 0) + *so << "Folders: " << stat.NumFolders << endl; + if (stat.NumFiles != 1 || stat.NumFolders != 0 || stat.NumAltStreams != 0) + *so << "Files: " << stat.NumFiles << endl; + if (stat.NumAltStreams != 0) + { + *so << "Alternate Streams: " << stat.NumAltStreams << endl; + *so << "Alternate Streams Size: " << stat.AltStreams_UnpackSize << endl; + } + + *so + << "Size: " << stat.UnpackSize << endl + << "Compressed: " << stat.PackSize << endl; + if (hashCalc) + { + *so << endl; + PrintHashStat(*so, hb); + } } } else { UInt64 numErrors = 0; - HRESULT result = ListArchives( + UInt64 numWarnings = 0; + + // options.ExtractNtOptions.StoreAltStreams = true, if -sns[-] is not definmed + + hresultMain = ListArchives( codecs, - formatIndices, + types, + excludedFormats, options.StdInMode, - options.ArchivePathsSorted, - options.ArchivePathsFullSorted, - options.WildcardCensor.Pairs.Front().Head, + ArchivePathsSorted, + ArchivePathsFullSorted, + options.ExtractOptions.NtOptions.AltStreams.Val, + options.AltStreams.Val, // we don't want to show AltStreams by default + options.Censor.Pairs.Front().Head, options.EnableHeaders, options.TechMode, #ifndef _NO_CRYPTO options.PasswordEnabled, options.Password, #endif - numErrors); + &options.Properties, + numErrors, numWarnings); + + if (options.EnableHeaders) + if (numWarnings > 0) + g_StdOut << endl << "Warnings: " << numWarnings << endl; + if (numErrors > 0) { - g_StdOut << endl << "Errors: " << numErrors << endl; - return NExitCode::kFatalError; + if (options.EnableHeaders) + g_StdOut << endl << "Errors: " << numErrors << endl; + retCode = NExitCode::kFatalError; } - if (result != S_OK) - throw CSystemException(result); } } else if (options.Command.IsFromUpdateGroup()) @@ -494,105 +1061,86 @@ int Main2( uo.SfxModule = kDefaultSfxModule; COpenCallbackConsole openCallback; - openCallback.OutStream = &stdStream; + openCallback.Init(g_StdStream, g_ErrStream, percentsStream); #ifndef _NO_CRYPTO bool passwordIsDefined = - options.PasswordEnabled && !options.Password.IsEmpty(); + (options.PasswordEnabled && !options.Password.IsEmpty()); openCallback.PasswordIsDefined = passwordIsDefined; openCallback.Password = options.Password; #endif CUpdateCallbackConsole callback; - callback.EnablePercents = options.EnablePercents; + callback.LogLevel = options.LogLevel; + callback.PercentsNameLevel = percentsNameLevel; + + if (percentsStream) + callback.SetWindowWidth(consoleWidth); #ifndef _NO_CRYPTO callback.PasswordIsDefined = passwordIsDefined; - callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty(); + callback.AskPassword = (options.PasswordEnabled && options.Password.IsEmpty()); callback.Password = options.Password; #endif + callback.StdOutMode = uo.StdOutMode; - callback.Init(&stdStream); + callback.Init( + // NULL, + g_StdStream, g_ErrStream, percentsStream); CUpdateErrorInfo errorInfo; - if (!uo.Init(codecs, formatIndices, options.ArchiveName)) - throw kUnsupportedArcTypeMessage; - HRESULT result = UpdateArchive(codecs, - options.WildcardCensor, uo, - errorInfo, &openCallback, &callback); + /* + if (!uo.Init(codecs, types, options.ArchiveName)) + throw kUnsupportedUpdateArcType; + */ + hresultMain = UpdateArchive(codecs, + types, + options.ArchiveName, + options.Censor, + uo, + errorInfo, &openCallback, &callback, true); - int exitCode = NExitCode::kSuccess; - if (callback.CantFindFiles.Size() > 0) - { - stdStream << endl; - stdStream << "WARNINGS for files:" << endl << endl; - int numErrors = callback.CantFindFiles.Size(); - for (int i = 0; i < numErrors; i++) - { - stdStream << callback.CantFindFiles[i] << " : "; - stdStream << NError::MyFormatMessageW(callback.CantFindCodes[i]) << endl; - } - stdStream << "----------------" << endl; - stdStream << "WARNING: Cannot find " << numErrors << " file"; - if (numErrors > 1) - stdStream << "s"; - stdStream << endl; - exitCode = NExitCode::kWarning; - } + callback.ClosePercents2(); - if (result != S_OK) - { - UString message; - if (!errorInfo.Message.IsEmpty()) - { - message += errorInfo.Message; - message += L"\n"; - } - if (!errorInfo.FileName.IsEmpty()) - { - message += fs2us(errorInfo.FileName); - message += L"\n"; - } - if (!errorInfo.FileName2.IsEmpty()) - { - message += fs2us(errorInfo.FileName2); - message += L"\n"; - } - if (errorInfo.SystemError != 0) - { - message += NError::MyFormatMessageW(errorInfo.SystemError); - message += L"\n"; - } - if (!message.IsEmpty()) - stdStream << L"\nError:\n" << message; - throw CSystemException(result); - } - int numErrors = callback.FailedFiles.Size(); - if (numErrors == 0) - { - if (callback.CantFindFiles.Size() == 0) - stdStream << kEverythingIsOk << endl; - } - else - { - stdStream << endl; - stdStream << "WARNINGS for files:" << endl << endl; - for (int i = 0; i < numErrors; i++) - { - stdStream << callback.FailedFiles[i] << " : "; - stdStream << NError::MyFormatMessageW(callback.FailedCodes[i]) << endl; - } - stdStream << "----------------" << endl; - stdStream << "WARNING: Cannot open " << numErrors << " file"; - if (numErrors > 1) - stdStream << "s"; - stdStream << endl; - exitCode = NExitCode::kWarning; - } - return exitCode; + CStdOutStream *se = g_StdStream; + if (!se) + se = g_ErrStream; + + retCode = WarningsCheck(hresultMain, callback, errorInfo, + g_StdStream, se, + true // options.EnableHeaders + ); + } + else if (options.Command.CommandType == NCommandType::kHash) + { + const CHashOptions &uo = options.HashOptions; + + CHashCallbackConsole callback; + if (percentsStream) + callback.SetWindowWidth(consoleWidth); + + callback.Init(g_StdStream, g_ErrStream, percentsStream); + callback.PrintHeaders = options.EnableHeaders; + + AString errorInfoString; + hresultMain = HashCalc(EXTERNAL_CODECS_VARS_L + options.Censor, uo, + errorInfoString, &callback); + CUpdateErrorInfo errorInfo; + errorInfo.Message = errorInfoString; + CStdOutStream *se = g_StdStream; + if (!se) + se = g_ErrStream; + retCode = WarningsCheck(hresultMain, callback, errorInfo, g_StdStream, se, options.EnableHeaders); } else - PrintHelpAndExit(stdStream); - return 0; + ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError); + + if (options.ShowTime && g_StdStream) + PrintStat(); + + ThrowException_if_Error(hresultMain); + + return retCode; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp index 25f4bd0df44..d30a96e4be2 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/MainAr.cpp @@ -2,11 +2,11 @@ #include "StdAfx.h" -#include "Common/MyException.h" -#include "Common/StdOutStream.h" +#include "../../../Common/MyException.h" +#include "../../../Common/StdOutStream.h" -#include "Windows/Error.h" -#include "Windows/NtCheck.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/NtCheck.h" #include "../Common/ArchiveCommandLine.h" #include "../Common/ExitCode.h" @@ -15,35 +15,52 @@ using namespace NWindows; -CStdOutStream *g_StdStream = 0; +CStdOutStream *g_StdStream = NULL; +CStdOutStream *g_ErrStream = NULL; extern int Main2( #ifndef _WIN32 - int numArgs, const char *args[] + int numArgs, char *args[] #endif ); -static const char *kExceptionErrorMessage = "\n\nError:\n"; -static const char *kUserBreak = "\nBreak signaled\n"; -static const char *kMemoryExceptionMessage = "\n\nERROR: Can't allocate required memory!\n"; -static const char *kUnknownExceptionMessage = "\n\nUnknown Error\n"; +static const char *kException_CmdLine_Error_Message = "Command Line Error:"; +static const char *kExceptionErrorMessage = "ERROR:"; +static const char *kUserBreakMessage = "Break signaled"; +static const char *kMemoryExceptionMessage = "ERROR: Can't allocate required memory!"; +static const char *kUnknownExceptionMessage = "Unknown Error"; static const char *kInternalExceptionMessage = "\n\nInternal Error #"; -#define NT_CHECK_FAIL_ACTION (*g_StdStream) << "Unsupported Windows version"; return NExitCode::kFatalError; +static void FlushStreams() +{ + if (g_StdStream) + g_StdStream->Flush(); +} + +static void PrintError(const char *message) +{ + FlushStreams(); + if (g_ErrStream) + *g_ErrStream << "\n\n" << message << endl; +} + +#define NT_CHECK_FAIL_ACTION *g_StdStream << "Unsupported Windows version"; return NExitCode::kFatalError; int MY_CDECL main ( #ifndef _WIN32 - int numArgs, const char *args[] + int numArgs, char *args[] #endif ) { + g_ErrStream = &g_StdErr; g_StdStream = &g_StdOut; NT_CHECK NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; int res = 0; + try { res = Main2( @@ -54,71 +71,97 @@ int MY_CDECL main } catch(const CNewException &) { - (*g_StdStream) << kMemoryExceptionMessage; + PrintError(kMemoryExceptionMessage); return (NExitCode::kMemoryError); } catch(const NConsoleClose::CCtrlBreakException &) { - (*g_StdStream) << endl << kUserBreak; + PrintError(kUserBreakMessage); return (NExitCode::kUserBreak); } - catch(const CArchiveCommandLineException &e) + catch(const CArcCmdLineException &e) { - (*g_StdStream) << kExceptionErrorMessage << e << endl; + PrintError(kException_CmdLine_Error_Message); + if (g_ErrStream) + *g_ErrStream << e << endl; return (NExitCode::kUserError); } catch(const CSystemException &systemError) { if (systemError.ErrorCode == E_OUTOFMEMORY) { - (*g_StdStream) << kMemoryExceptionMessage; + PrintError(kMemoryExceptionMessage); return (NExitCode::kMemoryError); } if (systemError.ErrorCode == E_ABORT) { - (*g_StdStream) << endl << kUserBreak; + PrintError(kUserBreakMessage); return (NExitCode::kUserBreak); } - (*g_StdStream) << endl << endl << "System error:" << endl << - NError::MyFormatMessageW(systemError.ErrorCode) << endl; + if (g_ErrStream) + { + PrintError("System ERROR:"); + *g_ErrStream << NError::MyFormatMessage(systemError.ErrorCode) << endl; + } return (NExitCode::kFatalError); } catch(NExitCode::EEnum &exitCode) { - (*g_StdStream) << kInternalExceptionMessage << exitCode << endl; + FlushStreams(); + if (g_ErrStream) + *g_ErrStream << kInternalExceptionMessage << exitCode << endl; return (exitCode); } - /* - catch(const NExitCode::CMultipleErrors &multipleErrors) - { - (*g_StdStream) << endl << multipleErrors.NumErrors << " errors" << endl; - return (NExitCode::kFatalError); - } - */ catch(const UString &s) { - (*g_StdStream) << kExceptionErrorMessage << s << endl; + if (g_ErrStream) + { + PrintError(kExceptionErrorMessage); + *g_ErrStream << s << endl; + } return (NExitCode::kFatalError); } catch(const AString &s) { - (*g_StdStream) << kExceptionErrorMessage << s << endl; + if (g_ErrStream) + { + PrintError(kExceptionErrorMessage); + *g_ErrStream << s << endl; + } return (NExitCode::kFatalError); } catch(const char *s) { - (*g_StdStream) << kExceptionErrorMessage << s << endl; + if (g_ErrStream) + { + PrintError(kExceptionErrorMessage); + *g_ErrStream << s << endl; + } return (NExitCode::kFatalError); } - catch(int t) + catch(const wchar_t *s) { - (*g_StdStream) << kInternalExceptionMessage << t << endl; + if (g_ErrStream) + { + PrintError(kExceptionErrorMessage); + *g_ErrStream << s << endl; + } return (NExitCode::kFatalError); } + catch(int t) + { + if (g_ErrStream) + { + FlushStreams(); + *g_ErrStream << kInternalExceptionMessage << t << endl; + return (NExitCode::kFatalError); + } + } catch(...) { - (*g_StdStream) << kUnknownExceptionMessage; + PrintError(kUnknownExceptionMessage); return (NExitCode::kFatalError); } - return res; + + return res; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp index 7dba2ad5d9b..9d25a729ca0 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp @@ -7,41 +7,93 @@ #include "ConsoleClose.h" #include "UserInputUtils.h" +static HRESULT CheckBreak2() +{ + return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; +} + HRESULT COpenCallbackConsole::Open_CheckBreak() { - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - return S_OK; + return CheckBreak2(); } -HRESULT COpenCallbackConsole::Open_SetTotal(const UInt64 *, const UInt64 *) +HRESULT COpenCallbackConsole::Open_SetTotal(const UInt64 *files, const UInt64 *bytes) { - return Open_CheckBreak(); + if (!MultiArcMode && NeedPercents()) + { + if (files) + { + _totalFilesDefined = true; + // _totalFiles = *files; + _percent.Total = *files; + } + else + _totalFilesDefined = false; + + if (bytes) + { + _totalBytesDefined = true; + // _totalBytes = *bytes; + if (!files) + _percent.Total = *bytes; + } + else + _totalBytesDefined = false; + } + + return CheckBreak2(); } -HRESULT COpenCallbackConsole::Open_SetCompleted(const UInt64 *, const UInt64 *) +HRESULT COpenCallbackConsole::Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) { - return Open_CheckBreak(); + if (!MultiArcMode && NeedPercents()) + { + if (files) + { + _percent.Files = *files; + if (_totalFilesDefined) + _percent.Completed = *files; + } + + if (bytes) + { + if (!_totalFilesDefined) + _percent.Completed = *bytes; + } + _percent.Print(); + } + + return CheckBreak2(); } - + +HRESULT COpenCallbackConsole::Open_Finished() +{ + ClosePercents(); + return S_OK; +} + + #ifndef _NO_CRYPTO HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password) { - PasswordWasAsked = true; - RINOK(Open_CheckBreak()); + *password = NULL; + RINOK(CheckBreak2()); + if (!PasswordIsDefined) { - Password = GetPassword(OutStream); + ClosePercents(); + Password = GetPassword(_so); PasswordIsDefined = true; } return StringToBstr(Password, password); } -HRESULT COpenCallbackConsole::Open_GetPasswordIfAny(UString &password) +/* +HRESULT COpenCallbackConsole::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) { - if (PasswordIsDefined) - password = Password; + passwordIsDefined = PasswordIsDefined; + password = Password; return S_OK; } @@ -50,9 +102,10 @@ bool COpenCallbackConsole::Open_WasPasswordAsked() return PasswordWasAsked; } -void COpenCallbackConsole::Open_ClearPasswordWasAskedFlag() +void COpenCallbackConsole::Open_Clear_PasswordWasAsked_Flag () { PasswordWasAsked = false; } +*/ #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h b/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h index c002e6a726f..0dd4e1d1c82 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h @@ -1,23 +1,64 @@ // OpenCallbackConsole.h -#ifndef __OPENCALLBACKCONSOLE_H -#define __OPENCALLBACKCONSOLE_H +#ifndef __OPEN_CALLBACK_CONSOLE_H +#define __OPEN_CALLBACK_CONSOLE_H + +#include "../../../Common/StdOutStream.h" -#include "Common/StdOutStream.h" #include "../Common/ArchiveOpenCallback.h" +#include "PercentPrinter.h" + class COpenCallbackConsole: public IOpenCallbackUI { +protected: + CPercentPrinter _percent; + + CStdOutStream *_so; + CStdOutStream *_se; + + bool _totalFilesDefined; + bool _totalBytesDefined; + // UInt64 _totalFiles; + // UInt64 _totalBytes; + + bool NeedPercents() const { return _percent._so != NULL; } + public: - INTERFACE_IOpenCallbackUI(;) + + bool MultiArcMode; + + void ClosePercents() + { + if (NeedPercents()) + _percent.ClosePrint(true); + } + + COpenCallbackConsole(): + _totalFilesDefined(false), + _totalBytesDefined(false), + MultiArcMode(false) + + #ifndef _NO_CRYPTO + , PasswordIsDefined(false) + // , PasswordWasAsked(false) + #endif + + {} - CStdOutStream *OutStream; + void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) + { + _so = outStream; + _se = errorStream; + _percent._so = percentStream; + } + INTERFACE_IOpenCallbackUI(;) + #ifndef _NO_CRYPTO bool PasswordIsDefined; - bool PasswordWasAsked; + // bool PasswordWasAsked; UString Password; - COpenCallbackConsole(): PasswordIsDefined(false), PasswordWasAsked(false) {} #endif }; diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp index 786db1bcebb..e3e8d599811 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp @@ -2,101 +2,180 @@ #include "StdAfx.h" -#include "Common/IntToString.h" -#include "Common/MyString.h" +#include "../../../Common/IntToString.h" #include "PercentPrinter.h" -static const unsigned kPaddingSize = 2; static const unsigned kPercentsSize = 4; -static const unsigned kMaxExtraSize = kPaddingSize + 32 + kPercentsSize; -static void ClearPrev(char *p, unsigned num) +CPercentPrinter::~CPercentPrinter() { - unsigned i; - for (i = 0; i < num; i++) *p++ = '\b'; - for (i = 0; i < num; i++) *p++ = ' '; - for (i = 0; i < num; i++) *p++ = '\b'; - *p = '\0'; -} - -void CPercentPrinter::ClosePrint() -{ - if (m_NumExtraChars == 0) - return; - char s[kMaxExtraSize * 3 + 1]; - ClearPrev(s, m_NumExtraChars); - (*OutStream) << s; - m_NumExtraChars = 0; + ClosePrint(false); } -void CPercentPrinter::PrintString(const char *s) +void CPercentPrinterState::ClearCurState() { - ClosePrint(); - (*OutStream) << s; + Completed = 0; + Total = ((UInt64)(Int64)-1); + Files = 0; + Command.Empty(); + FileName.Empty(); } -void CPercentPrinter::PrintString(const wchar_t *s) +void CPercentPrinter::ClosePrint(bool needFlush) { - ClosePrint(); - (*OutStream) << s; -} + unsigned num = _printedString.Len(); + if (num != 0) + { -void CPercentPrinter::PrintNewLine() -{ - ClosePrint(); - (*OutStream) << "\n"; + unsigned i; + + /* '\r' in old MAC OS means "new line". + So we can't use '\r' in some systems */ + + #ifdef _WIN32 + char *start = _temp.GetBuf(num + 2); + char *p = start; + *p++ = '\r'; + for (i = 0; i < num; i++) *p++ = ' '; + *p++ = '\r'; + #else + char *start = _temp.GetBuf(num * 3); + char *p = start; + for (i = 0; i < num; i++) *p++ = '\b'; + for (i = 0; i < num; i++) *p++ = ' '; + for (i = 0; i < num; i++) *p++ = '\b'; + #endif + + *p = 0; + _temp.ReleaseBuf_SetLen((unsigned)(p - start)); + *_so << _temp; + } + if (needFlush) + _so->Flush(); + _printedString.Empty(); } -void CPercentPrinter::RePrintRatio() +void CPercentPrinter::GetPercents() { char s[32]; unsigned size; { char c = '%'; - UInt64 value = 0; - if (m_Total == (UInt64)(Int64)-1) + UInt64 val = 0; + if (Total == (UInt64)(Int64)-1) { - value = m_CurValue >> 20; + val = Completed >> 20; c = 'M'; } - else if (m_Total != 0) - value = m_CurValue * 100 / m_Total; - ConvertUInt64ToString(value, s); + else if (Total != 0) + val = Completed * 100 / Total; + ConvertUInt64ToString(val, s); size = (unsigned)strlen(s); s[size++] = c; - s[size] = '\0'; + s[size] = 0; } - unsigned extraSize = kPaddingSize + MyMax(size, kPercentsSize); - if (extraSize < m_NumExtraChars) - extraSize = m_NumExtraChars; - - char fullString[kMaxExtraSize * 3]; - char *p = fullString; - unsigned i; - if (m_NumExtraChars == 0) + while (size < kPercentsSize) { - for (i = 0; i < extraSize; i++) - *p++ = ' '; - m_NumExtraChars = extraSize; + _s += ' '; + size++; } - for (i = 0; i < m_NumExtraChars; i++) - *p++ = '\b'; - m_NumExtraChars = extraSize; - for (; size < extraSize; size++) - *p++ = ' '; - MyStringCopy(p, s); - (*OutStream) << fullString; - OutStream->Flush(); - m_PrevValue = m_CurValue; + _s += s; } -void CPercentPrinter::PrintRatio() +void CPercentPrinter::Print() { - if (m_CurValue < m_PrevValue + m_MinStepSize && - m_CurValue + m_MinStepSize > m_PrevValue && m_NumExtraChars != 0) + DWORD tick = 0; + if (_tickStep != 0) + tick = GetTickCount(); + + bool onlyPercentsChanged = false; + + if (!_printedString.IsEmpty()) + { + if (_tickStep != 0 && (UInt32)(tick - _prevTick) < _tickStep) + return; + + CPercentPrinterState &st = *this; + if (_printedState.Command == st.Command + && _printedState.FileName == st.FileName + && _printedState.Files == st.Files) + { + if (_printedState.Total == st.Total + && _printedState.Completed == st.Completed) + return; + onlyPercentsChanged = true; + } + } + + _s.Empty(); + + GetPercents(); + + if (onlyPercentsChanged && _s == _printedPercents) return; - RePrintRatio(); + + _printedPercents = _s; + + if (Files != 0) + { + char s[32]; + ConvertUInt64ToString(Files, s); + // unsigned size = (unsigned)strlen(s); + // for (; size < 3; size++) _s += ' '; + _s += ' '; + _s += s; + // _s += "f"; + } + + + if (!Command.IsEmpty()) + { + _s += ' '; + _s += Command; + } + + if (!FileName.IsEmpty() && _s.Len() < MaxLen) + { + _s += ' '; + + StdOut_Convert_UString_to_AString(FileName, _temp); + _temp.Replace('\n', ' '); + if (_s.Len() + _temp.Len() > MaxLen) + { + unsigned len = FileName.Len(); + for (; len != 0;) + { + unsigned delta = len / 8; + if (delta == 0) + delta = 1; + len -= delta; + _tempU = FileName; + _tempU.Delete(len / 2, FileName.Len() - len); + _tempU.Insert(len / 2, L" . "); + StdOut_Convert_UString_to_AString(_tempU, _temp); + if (_s.Len() + _temp.Len() <= MaxLen) + break; + } + if (len == 0) + _temp.Empty(); + } + _s += _temp; + } + + if (_printedString != _s) + { + ClosePrint(false); + *_so << _s; + if (NeedFlush) + _so->Flush(); + _printedString = _s; + } + + _printedState = *this; + + if (_tickStep != 0) + _prevTick = tick; } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h b/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h index d970cc4b94f..95290b37e9c 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.h @@ -3,28 +3,60 @@ #ifndef __PERCENT_PRINTER_H #define __PERCENT_PRINTER_H -#include "Common/StdOutStream.h" +#include "../../../Common/StdOutStream.h" -class CPercentPrinter +struct CPercentPrinterState { - UInt64 m_MinStepSize; - UInt64 m_PrevValue; - UInt64 m_CurValue; - UInt64 m_Total; - unsigned m_NumExtraChars; + UInt64 Completed; + UInt64 Total; + + UInt64 Files; + + AString Command; + UString FileName; + + void ClearCurState(); + + CPercentPrinterState(): + Completed(0), + Total((UInt64)(Int64)-1), + Files(0) + {} +}; + +class CPercentPrinter: public CPercentPrinterState +{ + UInt32 _tickStep; + DWORD _prevTick; + + AString _s; + + AString _printedString; + AString _temp; + UString _tempU; + + CPercentPrinterState _printedState; + AString _printedPercents; + + void GetPercents(); + public: - CStdOutStream *OutStream; - - CPercentPrinter(UInt64 minStepSize = 1): m_MinStepSize(minStepSize), - m_PrevValue(0), m_CurValue(0), m_Total((UInt64)(Int64)-1), m_NumExtraChars(0) {} - void SetTotal(UInt64 total) { m_Total = total; m_PrevValue = 0; } - void SetRatio(UInt64 doneValue) { m_CurValue = doneValue; } - void PrintString(const char *s); - void PrintString(const wchar_t *s); - void PrintNewLine(); - void ClosePrint(); - void RePrintRatio(); - void PrintRatio(); + CStdOutStream *_so; + + bool NeedFlush; + unsigned MaxLen; + + CPercentPrinter(UInt32 tickStep = 200): + _tickStep(tickStep), + _prevTick(0), + NeedFlush(true), + MaxLen(80 - 1) + {} + + ~CPercentPrinter(); + + void ClosePrint(bool needFlush); + void Print(); }; #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h b/3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h index 2e4be10b291..2854ff3e935 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/StdAfx.h @@ -3,7 +3,6 @@ #ifndef __STDAFX_H #define __STDAFX_H -#include "../../../Common/MyWindows.h" -#include "../../../Common/NewHandler.h" +#include "../../../Common/Common.h" #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp index 7f337319714..f4f2d10210d 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp @@ -2,15 +2,17 @@ #include "StdAfx.h" -#include "UpdateCallbackConsole.h" +#include "../../../Common/IntToString.h" + +#include "../../../Windows/ErrorMsg.h" -#include "Windows/Error.h" #ifndef _7ZIP_ST -#include "Windows/Synchronization.h" +#include "../../../Windows/Synchronization.h" #endif #include "ConsoleClose.h" #include "UserInputUtils.h" +#include "UpdateCallbackConsole.h" using namespace NWindows; @@ -23,179 +25,590 @@ static NSynchronization::CCriticalSection g_CriticalSection; static const wchar_t *kEmptyFileAlias = L"[Content]"; -static const char *kCreatingArchiveMessage = "Creating archive "; -static const char *kUpdatingArchiveMessage = "Updating archive "; -static const char *kScanningMessage = "Scanning"; +static const char *kOpenArchiveMessage = "Open archive: "; +static const char *kCreatingArchiveMessage = "Creating archive: "; +static const char *kUpdatingArchiveMessage = "Updating archive: "; +static const char *kScanningMessage = "Scanning the drive:"; + +static const char *kError = "ERROR: "; +static const char *kWarning = "WARNING: "; + +static HRESULT CheckBreak2() +{ + return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; +} + +HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); +HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); + +void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags); +void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc); -HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result) +HRESULT CUpdateCallbackConsole::OpenResult( + const CCodecs *codecs, const CArchiveLink &arcLink, + const wchar_t *name, HRESULT result) { - (*OutStream) << endl; - if (result != S_OK) - (*OutStream) << "Error: " << name << " is not supported archive" << endl; + ClosePercents2(); + + FOR_VECTOR (level, arcLink.Arcs) + { + const CArc &arc = arcLink.Arcs[level]; + const CArcErrorInfo &er = arc.ErrorInfo; + + UInt32 errorFlags = er.GetErrorFlags(); + + if (errorFlags != 0 || !er.ErrorMessage.IsEmpty()) + { + if (_se) + { + *_se << endl; + if (level != 0) + *_se << arc.Path << endl; + } + + if (errorFlags != 0) + { + if (_se) + PrintErrorFlags(*_se, "ERRORS:", errorFlags); + } + + if (!er.ErrorMessage.IsEmpty()) + { + if (_se) + *_se << "ERRORS:" << endl << er.ErrorMessage << endl; + } + + if (_se) + { + *_se << endl; + _se->Flush(); + } + } + + UInt32 warningFlags = er.GetWarningFlags(); + + if (warningFlags != 0 || !er.WarningMessage.IsEmpty()) + { + if (_so) + { + *_so << endl; + if (level != 0) + *_so << arc.Path << endl; + } + + if (warningFlags != 0) + { + if (_so) + PrintErrorFlags(*_so, "WARNINGS:", warningFlags); + } + + if (!er.WarningMessage.IsEmpty()) + { + if (_so) + *_so << "WARNINGS:" << endl << er.WarningMessage << endl; + } + + if (_so) + { + *_so << endl; + if (NeedFlush) + _so->Flush(); + } + } + + + if (er.ErrorFormatIndex >= 0) + { + if (_so) + { + Print_ErrorFormatIndex_Warning(_so, codecs, arc); + if (NeedFlush) + _so->Flush(); + } + } + } + + if (result == S_OK) + { + if (_so) + { + RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)); + *_so << endl; + } + } + else + { + if (_so) + _so->Flush(); + if (_se) + { + *_se << kError << name << endl; + HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); + RINOK(res); + _se->Flush(); + } + } + return S_OK; } HRESULT CUpdateCallbackConsole::StartScanning() { - (*OutStream) << kScanningMessage; + if (_so) + *_so << kScanningMessage << endl; + _percent.Command = "Scan "; return S_OK; } -HRESULT CUpdateCallbackConsole::ScanProgress(UInt64 /* numFolders */, UInt64 /* numFiles */, const wchar_t * /* path */) +HRESULT CUpdateCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */) { + if (NeedPercents()) + { + _percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams; + _percent.Completed = st.GetTotalBytes(); + _percent.FileName = fs2us(path); + _percent.Print(); + } + return CheckBreak(); } -HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError) +void CCallbackConsoleBase::CommonError(const FString &path, DWORD systemError, bool isWarning) +{ + ClosePercents2(); + + if (_se) + { + if (_so) + _so->Flush(); + + *_se << endl << (isWarning ? kWarning : kError) + << NError::MyFormatMessage(systemError) + << endl << fs2us(path) << endl << endl; + _se->Flush(); + } +} + + +HRESULT CCallbackConsoleBase::ScanError_Base(const FString &path, DWORD systemError) +{ + MT_LOCK + + ScanErrors.AddError(path, systemError); + CommonError(path, systemError, true); + + return S_OK; +} + +HRESULT CCallbackConsoleBase::OpenFileError_Base(const FString &path, DWORD systemError) +{ + MT_LOCK + FailedFiles.AddError(path, systemError); + /* + if (systemError == ERROR_SHARING_VIOLATION) + { + */ + CommonError(path, systemError, true); + return S_FALSE; + /* + } + return systemError; + */ +} + +HRESULT CCallbackConsoleBase::ReadingFileError_Base(const FString &path, DWORD systemError) +{ + MT_LOCK + CommonError(path, systemError, false); + return HRESULT_FROM_WIN32(systemError); +} + +HRESULT CUpdateCallbackConsole::ScanError(const FString &path, DWORD systemError) +{ + return ScanError_Base(path, systemError); +} + + +static void PrintPropPair(AString &s, const char *name, UInt64 val) +{ + char temp[32]; + ConvertUInt64ToString(val, temp); + s += name; + s += ": "; + s += temp; +} + +void PrintSize_bytes_Smart(AString &s, UInt64 val); +void Print_DirItemsStat(AString &s, const CDirItemsStat &st); + +HRESULT CUpdateCallbackConsole::FinishScanning(const CDirItemsStat &st) { - CantFindFiles.Add(name); - CantFindCodes.Add(systemError); - // m_PercentPrinter.ClosePrint(); - if (!m_WarningsMode) + if (NeedPercents()) + { + _percent.ClosePrint(true); + _percent.ClearCurState(); + } + + if (_so) { - (*OutStream) << endl << endl; - m_PercentPrinter.PrintNewLine(); - m_WarningsMode = true; + AString s; + Print_DirItemsStat(s, st); + *_so << s << endl << endl; } - m_PercentPrinter.PrintString(name); - m_PercentPrinter.PrintString(": WARNING: "); - m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError)); - m_PercentPrinter.PrintNewLine(); return S_OK; } -HRESULT CUpdateCallbackConsole::FinishScanning() +static const char *k_StdOut_ArcName = "StdOut"; + +HRESULT CUpdateCallbackConsole::StartOpenArchive(const wchar_t *name) { - (*OutStream) << endl << endl; + if (_so) + { + *_so << kOpenArchiveMessage; + if (name) + *_so << name; + else + *_so << k_StdOut_ArcName; + *_so << endl; + } return S_OK; } HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating) { - if(updating) - (*OutStream) << kUpdatingArchiveMessage; - else - (*OutStream) << kCreatingArchiveMessage; - if (name != 0) - (*OutStream) << name; - else - (*OutStream) << "StdOut"; - (*OutStream) << endl << endl; + if (_so) + { + *_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage); + if (name != 0) + *_so << name; + else + *_so << k_StdOut_ArcName; + *_so << endl << endl; + } return S_OK; } -HRESULT CUpdateCallbackConsole::FinishArchive() +HRESULT CUpdateCallbackConsole::FinishArchive(const CFinishArchiveStat &st) { - (*OutStream) << endl; + ClosePercents2(); + + if (_so) + { + AString s; + // Print_UInt64_and_String(s, _percent.Files == 1 ? "file" : "files", _percent.Files); + PrintPropPair(s, "Files read from disk", _percent.Files); + s.Add_LF(); + s += "Archive size: "; + PrintSize_bytes_Smart(s, st.OutArcFileSize); + s.Add_LF(); + *_so << endl; + *_so << s; + // *_so << endl; + } + return S_OK; } -HRESULT CUpdateCallbackConsole::CheckBreak() +HRESULT CUpdateCallbackConsole::WriteSfx(const wchar_t *name, UInt64 size) { - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; + if (_so) + { + *_so << "Write SFX: "; + *_so << name; + AString s = " : "; + PrintSize_bytes_Smart(s, size); + *_so << s << endl; + } return S_OK; } -HRESULT CUpdateCallbackConsole::Finilize() + +HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */) { - MT_LOCK - if (m_NeedBeClosed) + if (LogLevel > 0 && _so) + { + ClosePercents_for_so(); + + if (!DeleteMessageWasShown) + { + if (_so) + *_so << endl << ": Removing files after including to archive" << endl; + } + + { + { + _tempA = "Removing"; + _tempA.Add_Space(); + *_so << _tempA; + _tempU = fs2us(path); + _so->PrintUString(_tempU, _tempA); + *_so << endl; + if (NeedFlush) + _so->Flush(); + } + } + } + + if (!DeleteMessageWasShown) { - if (EnablePercents) + if (NeedPercents()) { - m_PercentPrinter.ClosePrint(); + _percent.ClearCurState(); } - if (!StdOutMode && m_NeedNewLine) + DeleteMessageWasShown = true; + } + else + { + _percent.Files++; + } + + if (NeedPercents()) + { + // if (!FullLog) { - m_PercentPrinter.PrintNewLine(); - m_NeedNewLine = false; + _percent.Command = "Removing"; + _percent.FileName = fs2us(path); } - m_NeedBeClosed = false; + _percent.Print(); } + + return S_OK; +} + + +HRESULT CUpdateCallbackConsole::FinishDeletingAfterArchiving() +{ + ClosePercents2(); + if (_so && DeleteMessageWasShown) + *_so << endl; return S_OK; } -HRESULT CUpdateCallbackConsole::SetNumFiles(UInt64 /* numFiles */) +HRESULT CUpdateCallbackConsole::CheckBreak() +{ + return CheckBreak2(); +} + +/* +HRESULT CUpdateCallbackConsole::Finalize() +{ + // MT_LOCK + return S_OK; +} +*/ + +HRESULT CUpdateCallbackConsole::SetNumItems(UInt64 numItems) { + if (_so) + { + ClosePercents_for_so(); + AString s; + PrintPropPair(s, "Items to compress", numItems); + *_so << s << endl << endl; + } return S_OK; } HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size) { MT_LOCK - if (EnablePercents) - m_PercentPrinter.SetTotal(size); + if (NeedPercents()) + { + _percent.Total = size; + _percent.Print(); + } return S_OK; } HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue) { MT_LOCK - if (completeValue != NULL) + if (completeValue) { - if (EnablePercents) + if (NeedPercents()) { - m_PercentPrinter.SetRatio(*completeValue); - m_PercentPrinter.PrintRatio(); - m_NeedBeClosed = true; + _percent.Completed = *completeValue; + _percent.Print(); } } - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - return S_OK; + return CheckBreak2(); } HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 * /* outSize */) { - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - return S_OK; + return CheckBreak2(); } -HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti) +HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *command, bool showInLog) { MT_LOCK + + bool show2 = (showInLog && _so); + + if (show2) + { + ClosePercents_for_so(); + + _tempA = command; + if (name) + _tempA.Add_Space(); + *_so << _tempA; + + _tempU.Empty(); + if (name) + _tempU = name; + _so->PrintUString(_tempU, _tempA); + *_so << endl; + if (NeedFlush) + _so->Flush(); + } + + if (NeedPercents()) + { + if (PercentsNameLevel >= 1) + { + _percent.FileName.Empty(); + _percent.Command.Empty(); + if (PercentsNameLevel > 1 || !show2) + { + _percent.Command = command; + if (name) + _percent.FileName = name; + } + } + _percent.Print(); + } + + return CheckBreak2(); +} + +HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool /* isDir */, bool isAnti, UInt32 mode) +{ if (StdOutMode) return S_OK; - if(isAnti) - m_PercentPrinter.PrintString("Anti item "); - else - m_PercentPrinter.PrintString("Compressing "); - if (name[0] == 0) + + if (!name || name[0] == 0) name = kEmptyFileAlias; - m_PercentPrinter.PrintString(name); - if (EnablePercents) - m_PercentPrinter.RePrintRatio(); - return S_OK; + + unsigned requiredLevel = 1; + + const char *s; + if (mode == NUpdateNotifyOp::kAdd || + mode == NUpdateNotifyOp::kUpdate) + { + if (isAnti) + s = "Anti"; + else if (mode == NUpdateNotifyOp::kAdd) + s = "+"; + else + s = "U"; + } + else + { + requiredLevel = 3; + if (mode == NUpdateNotifyOp::kAnalyze) + s = "A"; + else + s = "Reading"; + } + + return PrintProgress(name, s, LogLevel >= requiredLevel); +} + +HRESULT CUpdateCallbackConsole::OpenFileError(const FString &path, DWORD systemError) +{ + return OpenFileError_Base(path, systemError); +} + +HRESULT CUpdateCallbackConsole::ReadingFileError(const FString &path, DWORD systemError) +{ + return ReadingFileError_Base(path, systemError); } -HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError) +HRESULT CUpdateCallbackConsole::SetOperationResult(Int32) { MT_LOCK - FailedCodes.Add(systemError); - FailedFiles.Add(name); - // if (systemError == ERROR_SHARING_VIOLATION) + _percent.Files++; + return S_OK; +} + +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest); + +HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) +{ + // if (StdOutMode) return S_OK; + + if (opRes != NArchive::NExtract::NOperationResult::kOK) { - m_PercentPrinter.ClosePrint(); - m_PercentPrinter.PrintNewLine(); - m_PercentPrinter.PrintString("WARNING: "); - m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError)); - return S_FALSE; + ClosePercents2(); + + if (_se) + { + if (_so) + _so->Flush(); + + AString s; + SetExtractErrorMessage(opRes, isEncrypted, s); + *_se << s << " : " << endl << name << endl << endl; + _se->Flush(); + } + return S_OK; + } + return S_OK; +} + + +HRESULT CUpdateCallbackConsole::ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool /* isDir */) +{ + // if (StdOutMode) return S_OK; + + char temp[16]; + const char *s; + + unsigned requiredLevel = 1; + + switch (op) + { + case NUpdateNotifyOp::kAdd: s = "+"; break; + case NUpdateNotifyOp::kUpdate: s = "U"; break; + case NUpdateNotifyOp::kAnalyze: s = "A"; requiredLevel = 3; break; + case NUpdateNotifyOp::kReplicate: s = "="; requiredLevel = 3; break; + case NUpdateNotifyOp::kRepack: s = "R"; requiredLevel = 2; break; + case NUpdateNotifyOp::kSkip: s = "."; requiredLevel = 2; break; + case NUpdateNotifyOp::kDelete: s = "D"; requiredLevel = 3; break; + case NUpdateNotifyOp::kHeader: s = "Header creation"; requiredLevel = 100; break; + default: + { + temp[0] = 'o'; + temp[1] = 'p'; + ConvertUInt64ToString(op, temp + 2); + s = temp; + } } - // return systemError; + + return PrintProgress(name, s, LogLevel >= requiredLevel); } -HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 ) +/* +HRESULT CUpdateCallbackConsole::SetPassword(const UString & + #ifndef _NO_CRYPTO + password + #endif + ) { - m_NeedBeClosed = true; - m_NeedNewLine = true; + #ifndef _NO_CRYPTO + PasswordIsDefined = true; + Password = password; + #endif return S_OK; } +*/ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) { + COM_TRY_BEGIN + *password = NULL; #ifdef _NO_CRYPTO @@ -209,7 +622,7 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, { if (AskPassword) { - Password = GetPassword(OutStream); + Password = GetPassword(_so); PasswordIsDefined = true; } } @@ -217,10 +630,14 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, return StringToBstr(Password, password); #endif + + COM_TRY_END } HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password) { + COM_TRY_BEGIN + *password = NULL; #ifdef _NO_CRYPTO @@ -232,30 +649,26 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password) if (!PasswordIsDefined) { { - Password = GetPassword(OutStream); + Password = GetPassword(_so); PasswordIsDefined = true; } } return StringToBstr(Password, password); #endif + COM_TRY_END } -/* -HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name) +HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool /* isDir */) { - // MT_LOCK if (StdOutMode) return S_OK; - RINOK(Finilize()); - m_PercentPrinter.PrintString("Deleting "); - if (name[0] == 0) - name = kEmptyFileAlias; - m_PercentPrinter.PrintString(name); - if (EnablePercents) - m_PercentPrinter.RePrintRatio(); - m_NeedBeClosed = true; - m_NeedNewLine = true; + + if (LogLevel > 7) + { + if (!name || name[0] == 0) + name = kEmptyFileAlias; + return PrintProgress(name, "D", true); + } return S_OK; } -*/ diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h b/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h index 5ffe3eb7ae4..ba8614ebaa3 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h @@ -3,60 +3,122 @@ #ifndef __UPDATE_CALLBACK_CONSOLE_H #define __UPDATE_CALLBACK_CONSOLE_H -#include "Common/StdOutStream.h" +#include "../../../Common/StdOutStream.h" #include "../Common/Update.h" #include "PercentPrinter.h" -class CUpdateCallbackConsole: public IUpdateCallbackUI2 +struct CErrorPathCodes { - CPercentPrinter m_PercentPrinter; - bool m_NeedBeClosed; - bool m_NeedNewLine; + FStringVector Paths; + CRecordVector<DWORD> Codes; - bool m_WarningsMode; + void AddError(const FString &path, DWORD systemError) + { + Paths.Add(path); + Codes.Add(systemError); + } + void Clear() + { + Paths.Clear(); + Codes.Clear(); + } +}; + +class CCallbackConsoleBase +{ +protected: + CPercentPrinter _percent; + + CStdOutStream *_so; + CStdOutStream *_se; + + void CommonError(const FString &path, DWORD systemError, bool isWarning); + + HRESULT ScanError_Base(const FString &path, DWORD systemError); + HRESULT OpenFileError_Base(const FString &name, DWORD systemError); + HRESULT ReadingFileError_Base(const FString &name, DWORD systemError); - CStdOutStream *OutStream; public: - bool EnablePercents; + bool NeedPercents() const { return _percent._so != NULL; }; + bool StdOutMode; + bool NeedFlush; + unsigned PercentsNameLevel; + unsigned LogLevel; + + AString _tempA; + UString _tempU; + + CCallbackConsoleBase(): + StdOutMode(false), + NeedFlush(false), + PercentsNameLevel(1), + LogLevel(0) + {} + + void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } + + void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) + { + FailedFiles.Clear(); + + _so = outStream; + _se = errorStream; + _percent._so = percentStream; + } + + void ClosePercents2() + { + if (NeedPercents()) + _percent.ClosePrint(true); + } + + void ClosePercents_for_so() + { + if (NeedPercents() && _so == _percent._so) + _percent.ClosePrint(false); + } + + + CErrorPathCodes FailedFiles; + CErrorPathCodes ScanErrors; + + HRESULT PrintProgress(const wchar_t *name, const char *command, bool showInLog); + +}; + +class CUpdateCallbackConsole: public IUpdateCallbackUI2, public CCallbackConsoleBase +{ + // void PrintPropPair(const char *name, const wchar_t *val); + +public: #ifndef _NO_CRYPTO bool PasswordIsDefined; UString Password; bool AskPassword; #endif - CUpdateCallbackConsole(): - m_PercentPrinter(1 << 16), + bool DeleteMessageWasShown; + + CUpdateCallbackConsole() + : DeleteMessageWasShown(false) #ifndef _NO_CRYPTO - PasswordIsDefined(false), - AskPassword(false), + , PasswordIsDefined(false) + , AskPassword(false) #endif - StdOutMode(false), - EnablePercents(true), - m_WarningsMode(false) {} - ~CUpdateCallbackConsole() { Finilize(); } + /* void Init(CStdOutStream *outStream) { - m_NeedBeClosed = false; - m_NeedNewLine = false; - FailedFiles.Clear(); - FailedCodes.Clear(); - OutStream = outStream; - m_PercentPrinter.OutStream = outStream; + CCallbackConsoleBase::Init(outStream); } - + */ + // ~CUpdateCallbackConsole() { if (NeedPercents()) _percent.ClosePrint(); } INTERFACE_IUpdateCallbackUI2(;) - - UStringVector FailedFiles; - CRecordVector<HRESULT> FailedCodes; - - UStringVector CantFindFiles; - CRecordVector<HRESULT> CantFindCodes; }; #endif diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp b/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp index 754680090bc..c7f830ff999 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp @@ -2,19 +2,19 @@ #include "StdAfx.h" -#include "Common/StdInStream.h" -#include "Common/StringConvert.h" +#include "../../../Common/StdInStream.h" +#include "../../../Common/StringConvert.h" #include "UserInputUtils.h" -static const char kYes = 'Y'; -static const char kNo = 'N'; -static const char kYesAll = 'A'; -static const char kNoAll = 'S'; -static const char kAutoRenameAll = 'U'; -static const char kQuit = 'Q'; +static const char kYes = 'y'; +static const char kNo = 'n'; +static const char kYesAll = 'a'; +static const char kNoAll = 's'; +static const char kAutoRenameAll = 'u'; +static const char kQuit = 'q'; -static const char *kFirstQuestionMessage = "?\n"; +static const char *kFirstQuestionMessage = "? "; static const char *kHelpQuestionMessage = "(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? "; @@ -22,33 +22,26 @@ static const char *kHelpQuestionMessage = NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream) { - (*outStream) << kFirstQuestionMessage; + if (outStream) + *outStream << kFirstQuestionMessage; for (;;) { - (*outStream) << kHelpQuestionMessage; - outStream->Flush(); + if (outStream) + { + *outStream << kHelpQuestionMessage; + outStream->Flush(); + } AString scannedString = g_StdIn.ScanStringUntilNewLine(); scannedString.Trim(); if (!scannedString.IsEmpty()) - switch( - ::MyCharUpper( - #ifdef UNDER_CE - (wchar_t) - #endif - scannedString[0])) + switch (::MyCharLower_Ascii(scannedString[0])) { - case kYes: - return NUserAnswerMode::kYes; - case kNo: - return NUserAnswerMode::kNo; - case kYesAll: - return NUserAnswerMode::kYesAll; - case kNoAll: - return NUserAnswerMode::kNoAll; - case kAutoRenameAll: - return NUserAnswerMode::kAutoRenameAll; - case kQuit: - return NUserAnswerMode::kQuit; + case kYes: return NUserAnswerMode::kYes; + case kNo: return NUserAnswerMode::kNo; + case kYesAll: return NUserAnswerMode::kYesAll; + case kNoAll: return NUserAnswerMode::kNoAll; + case kAutoRenameAll: return NUserAnswerMode::kAutoRenameAll; + case kQuit: return NUserAnswerMode::kQuit; } } } @@ -61,14 +54,18 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream) UString GetPassword(CStdOutStream *outStream) { - (*outStream) << "\nEnter password" + if (outStream) + { + *outStream << "\nEnter password" #ifdef MY_DISABLE_ECHO " (will not be echoed)" #endif ":"; - outStream->Flush(); + outStream->Flush(); + } #ifdef MY_DISABLE_ECHO + HANDLE console = GetStdHandle(STD_INPUT_HANDLE); bool wasChanged = false; DWORD mode = 0; @@ -78,10 +75,16 @@ UString GetPassword(CStdOutStream *outStream) UString res = g_StdIn.ScanUStringUntilNewLine(); if (wasChanged) SetConsoleMode(console, mode); - (*outStream) << "\n"; - outStream->Flush(); + if (outStream) + { + *outStream << endl; + outStream->Flush(); + } return res; + #else + return g_StdIn.ScanUStringUntilNewLine(); + #endif } diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h b/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h index 8b5232b3fc2..16f045803e4 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h +++ b/3rdparty/lzma/CPP/7zip/UI/Console/UserInputUtils.h @@ -1,9 +1,9 @@ // UserInputUtils.h -#ifndef __USERINPUTUTILS_H -#define __USERINPUTUTILS_H +#ifndef __USER_INPUT_UTILS_H +#define __USER_INPUT_UTILS_H -#include "Common/StdOutStream.h" +#include "../../../Common/StdOutStream.h" namespace NUserAnswerMode { diff --git a/3rdparty/lzma/CPP/7zip/UI/Console/makefile b/3rdparty/lzma/CPP/7zip/UI/Console/makefile index f100f63589e..98ad91c2440 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Console/makefile +++ b/3rdparty/lzma/CPP/7zip/UI/Console/makefile @@ -1,25 +1,12 @@ PROG = 7z.exe MY_CONSOLE = 1 -CFLAGS = $(CFLAGS) -I ../../../ \ +CFLAGS = $(CFLAGS) \ -DEXTERNAL_CODECS \ !IFNDEF UNDER_CE CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE !ENDIF - -CONSOLE_OBJS = \ - $O\ConsoleClose.obj \ - $O\ExtractCallbackConsole.obj \ - $O\List.obj \ - $O\BenchCon.obj \ - $O\Main.obj \ - $O\MainAr.obj \ - $O\OpenCallbackConsole.obj \ - $O\PercentPrinter.obj \ - $O\UpdateCallbackConsole.obj \ - $O\UserInputUtils.obj \ - COMMON_OBJS = \ $O\CommandLineParser.obj \ $O\CRC.obj \ @@ -37,88 +24,46 @@ COMMON_OBJS = \ WIN_OBJS = \ $O\DLL.obj \ - $O\Error.obj \ + $O\ErrorMsg.obj \ $O\FileDir.obj \ $O\FileFind.obj \ $O\FileIO.obj \ + $O\FileLink.obj \ $O\FileName.obj \ + $O\FileSystem.obj \ $O\MemoryLock.obj \ $O\PropVariant.obj \ - $O\PropVariantConversions.obj \ + $O\PropVariantConv.obj \ $O\Registry.obj \ $O\System.obj \ - $O\Time.obj \ + $O\TimeUtils.obj \ 7ZIP_COMMON_OBJS = \ $O\CreateCoder.obj \ $O\FilePathAutoRename.obj \ $O\FileStreams.obj \ $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ $O\MethodProps.obj \ $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamObjects.obj \ $O\StreamUtils.obj \ - -UI_COMMON_OBJS = \ - $O\ArchiveCommandLine.obj \ - $O\ArchiveExtractCallback.obj \ - $O\ArchiveOpenCallback.obj \ - $O\DefaultName.obj \ - $O\EnumDirItems.obj \ - $O\Extract.obj \ - $O\ExtractingFilePath.obj \ - $O\Bench.obj \ - $O\LoadCodecs.obj \ - $O\OpenArchive.obj \ - $O\PropIDUtils.obj \ - $O\SetProperties.obj \ - $O\SortUtils.obj \ - $O\TempFiles.obj \ - $O\Update.obj \ - $O\UpdateAction.obj \ - $O\UpdateCallback.obj \ - $O\UpdatePair.obj \ - $O\UpdateProduce.obj \ + $O\UniqBlocks.obj \ AR_COMMON_OBJS = \ $O\OutStreamWithCRC.obj \ +COMPRESS_OBJS = \ + $O\CopyCoder.obj \ + C_OBJS = \ $O\Alloc.obj \ $O\CpuArch.obj \ + $O\Sort.obj \ $O\Threads.obj \ !include "../../Crc.mak" +!include "Console.mak" -OBJS = \ - $O\StdAfx.obj \ - $(CONSOLE_OBJS) \ - $(COMMON_OBJS) \ - $(WIN_OBJS) \ - $(7ZIP_COMMON_OBJS) \ - $(UI_COMMON_OBJS) \ - $(AR_COMMON_OBJS) \ - $O\CopyCoder.obj \ - $(C_OBJS) \ - $(ASM_OBJS) \ - $O\resource.res - -!include "../../../Build.mak" - -$(CONSOLE_OBJS): $(*B).cpp - $(COMPL) -$(COMMON_OBJS): ../../../Common/$(*B).cpp - $(COMPL) -$(WIN_OBJS): ../../../Windows/$(*B).cpp - $(COMPL) -$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp - $(COMPL) -$(UI_COMMON_OBJS): ../Common/$(*B).cpp - $(COMPL) -$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp - $(COMPL) -$O\CopyCoder.obj: ../../Compress/$(*B).cpp - $(COMPL) -$(C_OBJS): ../../../../C/$(*B).c - $(COMPL_O2) - -!include "../../Asm.mak" +!include "../../7zip.mak" |