summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp')
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp766
1 files changed, 653 insertions, 113 deletions
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();
}