aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
diff options
context:
space:
mode:
authorTetsuo Osaka <tetsugit@gmail.com>2016-10-18 15:12:28 +0200
committerTetsuo Osaka <tetsugit@gmail.com>2017-04-18 10:07:58 +0200
commitf955a79a9fffb09826cf7547f70d08c3798a2f50 (patch)
tree7ba3acdf7ba22cb749ffd9e6a868630e5a8382f2 /CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
parent462f68aa279e25fda265a87c6d3c4da3318314f8 (diff)
downloadlzma-f955a79a9fffb09826cf7547f70d08c3798a2f50.tar.gz
Rebase LZMA SDK on 16.04 stable
This was downloaded from http://www.7-zip.org/a/lzma1604.7z The bin folder was excluded like in previous updates All files were deleted and replaced with those from the SDK. The embedded projects Tukaani, xz-embedded and android build files where not touched. The changelog since the 9.38 beta is: 16.04 2016-10-04 ------------------------- - The bug was fixed in DllSecur.c. 16.03 2016-09-28 ------------------------- - SFX modules now use some protection against DLL preloading attack. - Some bugs in 7z code were fixed. 16.02 2016-05-21 ------------------------- - The BUG in 16.00 - 16.01 was fixed: Split Handler (SplitHandler.cpp) returned incorrect total size value (kpidSize) for split archives. 16.01 2016-05-19 ------------------------- - Some internal changes to reduce the number of compiler warnings. 16.00 2016-05-10 ------------------------- - Some bugs were fixed. 15.12 2015-11-19 ------------------------- - The BUG in C version of 7z decoder was fixed: 7zDec.c : SzDecodeLzma2() 7z decoder could mistakenly report about decoding error for some 7z archives that use LZMA2 compression method. The probability to get that mistaken decoding error report was about one error per 16384 solid blocks for solid blocks larger than 16 KB (compressed size). - The BUG (in 9.26-15.11) in C version of 7z decoder was fixed: 7zArcIn.c : SzReadHeader2() 7z decoder worked incorrectly for 7z archives that contain empty solid blocks, that can be placed to 7z archive, if some file is unavailable for reading during archive creation. 15.09 beta 2015-10-16 ------------------------- - The BUG in LZMA / LZMA2 encoding code was fixed. The BUG in LzFind.c::MatchFinder_ReadBlock() function. If input data size is larger than (4 GiB - dictionary_size), the following code worked incorrectly: - LZMA : LzmaEnc_MemEncode(), LzmaEncode() : LZMA encoding functions for compressing from memory to memory. That BUG is not related to LZMA encoder version that works via streams. - LZMA2 : multi-threaded version of LZMA2 encoder worked incorrectly, if default value of chunk size (CLzma2EncProps::blockSize) is changed to value larger than (4 GiB - dictionary_size). Change-Id: I6b3974015c605fba3c0d4d897fab5a166174f441
Diffstat (limited to 'CPP/7zip/UI/Console/ExtractCallbackConsole.cpp')
-rw-r--r--CPP/7zip/UI/Console/ExtractCallbackConsole.cpp781
1 files changed, 581 insertions, 200 deletions
diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
index 0c6f806..cc82770 100644
--- a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
@@ -2,12 +2,6 @@
#include "StdAfx.h"
-// #undef sprintf
-
-#include "ConsoleClose.h"
-#include "ExtractCallbackConsole.h"
-#include "UserInputUtils.h"
-
#include "../../../Common/IntToString.h"
#include "../../../Common/Wildcard.h"
@@ -17,25 +11,146 @@
#include "../../../Windows/ErrorMsg.h"
#include "../../../Windows/PropVariantConv.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 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";
@@ -49,8 +164,9 @@ 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";
-static const char *k_ErrorFlagsMessages[] =
+static const char * const k_ErrorFlagsMessages[] =
{
"Is not archive"
, "Headers Error"
@@ -65,31 +181,72 @@ static const char *k_ErrorFlagsMessages[] =
, "CRC Error"
};
+STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64 size)
+{
+ MT_LOCK
+
+ if (NeedPercents())
+ {
+ _percent.Total = size;
+ _percent.Print();
+ }
+ return CheckBreak2();
+}
-STDMETHODIMP CExtractCallbackConsole::SetTotal(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();
}
-STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *)
+static const char *kTab = " ";
+
+static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size)
{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- return S_OK;
+ *_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 << endl <<
- "already exists. Overwrite with" << endl <<
- newName;
+ MT_LOCK
- NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream);
+ 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(_so);
switch (overwriteAnswer)
{
@@ -101,86 +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: s = kExtractString; break;
case NArchive::NExtract::NAskMode::kTest: s = kTestString; break;
- case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; break;
- default: s = ""; // return E_FAIL;
+ case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; requiredLevel = 2; break;
+ default: s = "???"; requiredLevel = 2;
};
- (*OutStream) << s << 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;
- NumFileErrorsInCurrent++;
+ MT_LOCK
+
+ RINOK(CheckBreak2());
+
+ NumFileErrors_in_Current++;
NumFileErrors++;
- return S_OK;
+
+ ClosePercentsAndFlush();
+ if (_se)
+ {
+ *_se << kError << message << endl;
+ _se->Flush();
+ }
+
+ return CheckBreak2();
}
-STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted)
+void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest)
{
- switch (operationResult)
+ 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 opRes, Int32 encrypted)
+{
+ MT_LOCK
+
+ if (opRes == NArchive::NExtract::NOperationResult::kOK)
{
- case NArchive::NExtract::NOperationResult::kOK:
- break;
- default:
+ if (NeedPercents())
{
- NumFileErrorsInCurrent++;
- NumFileErrors++;
- (*OutStream) << " : ";
- const char *s = NULL;
- switch (operationResult)
- {
- 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;
- }
- if (s)
- (*OutStream) << "Error : " << s;
- else
- {
- char temp[16];
- ConvertUInt32ToString(operationResult, temp);
- (*OutStream) << "Error #" << temp;
- }
+ _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)
@@ -192,55 +455,39 @@ 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)
{
+ RINOK(CheckBreak2());
+
NumTryArcs++;
- ThereIsErrorInCurrent = false;
- ThereIsWarningInCurrent = false;
- NumFileErrorsInCurrent = 0;
- (*OutStream) << endl << kProcessing << name << endl;
- return S_OK;
-}
+ ThereIsError_in_Current = false;
+ ThereIsWarning_in_Current = false;
+ NumFileErrors_in_Current = 0;
+
+ ClosePercents_for_so();
+ if (_so)
+ *_so << endl << (testMode ? kTesting : kExtracting) << name << endl;
-HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT result, bool encrypted)
-{
- (*OutStream) << endl;
- if (result != S_OK)
- {
- (*OutStream) << "Error: ";
- if (result == S_FALSE)
- {
- (*OutStream) << (encrypted ?
- "Can not open encrypted archive. Wrong password?" :
- "Can not open file as archive");
- }
- else
- {
- if (result == E_OUTOFMEMORY)
- (*OutStream) << "Can't allocate required memory";
- else
- (*OutStream) << NError::MyFormatMessage(result);
- }
- (*OutStream) << endl;
- NumCantOpenArcs++;
- ThereIsErrorInCurrent = true;
- }
+ if (NeedPercents())
+ _percent.Command = "Open";
return S_OK;
}
-AString GetOpenArcErrorMessage(UInt32 errorFlags)
+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)
{
AString s;
+
for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsMessages); i++)
{
UInt32 f = (1 << i);
@@ -248,10 +495,11 @@ AString GetOpenArcErrorMessage(UInt32 errorFlags)
continue;
const char *m = k_ErrorFlagsMessages[i];
if (!s.IsEmpty())
- s += '\n';
+ s.Add_LF();
s += m;
errorFlags &= ~f;
}
+
if (errorFlags != 0)
{
char sz[16];
@@ -259,125 +507,258 @@ AString GetOpenArcErrorMessage(UInt32 errorFlags)
sz[1] = 'x';
ConvertUInt32ToHex(errorFlags, sz + 2);
if (!s.IsEmpty())
- s += '\n';
+ 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");
+}
-HRESULT CExtractCallbackConsole::SetError(int level, const wchar_t *name,
- UInt32 errorFlags, const wchar_t *errors,
- UInt32 warningFlags, const wchar_t *warnings)
+void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc)
{
- if (level != 0)
+ const CArcErrorInfo &er = arc.ErrorInfo;
+
+ UString s = L"WARNING:\n";
+ s += arc.Path;
+ if (arc.FormatIndex == er.ErrorFormatIndex)
{
- (*OutStream) << name << endl;
+ s.Add_LF();
+ s.AddAscii("The archive is open with offset");
}
-
- if (errorFlags != 0)
+ else
{
- (*OutStream) << "Errors: ";
- (*OutStream) << endl;
- (*OutStream) << GetOpenArcErrorMessage(errorFlags);
- (*OutStream) << endl;
- NumOpenArcErrors++;
- ThereIsErrorInCurrent = true;
+ 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 (errors && wcslen(errors) != 0)
+ if (NeedPercents())
{
- (*OutStream) << "Errors: ";
- (*OutStream) << endl;
- (*OutStream) << errors;
- (*OutStream) << endl;
- NumOpenArcErrors++;
- ThereIsErrorInCurrent = true;
+ _percent.Files = 0;
+ _percent.Command.Empty();
+ _percent.FileName.Empty();
}
- if (warningFlags != 0)
+
+ ClosePercentsAndFlush();
+
+ FOR_VECTOR (level, arcLink.Arcs)
{
- (*OutStream) << "Warnings: ";
- (*OutStream) << endl;
- (*OutStream) << GetOpenArcErrorMessage(warningFlags);
- (*OutStream) << endl;
- NumOpenArcWarnings++;
- ThereIsWarningInCurrent = true;
- }
+ 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);
+ 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();
+ }
+ }
+
+ 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);
+ 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 (warnings && wcslen(warnings) != 0)
+
+ if (er.ErrorFormatIndex >= 0)
+ {
+ if (_so)
+ {
+ Print_ErrorFormatIndex_Warning(_so, codecs, arc);
+ if (NeedFlush)
+ _so->Flush();
+ }
+ ThereIsWarning_in_Current = true;
+ }
+ }
+
+ if (result == S_OK)
{
- (*OutStream) << "Warnings: ";
- (*OutStream) << endl;
- (*OutStream) << warnings;
- (*OutStream) << endl;
- NumOpenArcWarnings++;
- ThereIsWarningInCurrent = true;
+ if (_so)
+ {
+ RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink));
+ *_so << endl;
+ }
}
-
- (*OutStream) << endl;
- return S_OK;
+ 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
+ {
+ if (result == E_OUTOFMEMORY)
+ *_se << "Can't allocate required memory";
+ else
+ *_se << NError::MyFormatMessage(result);
+ *_se << endl;
+ }
+ _se->Flush();
+ }
+ }
+
+
+ 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)
{
- if (result == S_OK)
+ MT_LOCK
+
+ if (NeedPercents())
{
- (*OutStream) << endl;
+ _percent.ClosePrint(true);
+ _percent.Command.Empty();
+ _percent.FileName.Empty();
+ }
- if (NumFileErrorsInCurrent == 0 && !ThereIsErrorInCurrent)
+ if (_so)
+ _so->Flush();
+
+ if (result == S_OK)
+ {
+ if (NumFileErrors_in_Current == 0 && !ThereIsError_in_Current)
{
- if (ThereIsWarningInCurrent)
+ if (ThereIsWarning_in_Current)
NumArcsWithWarnings++;
else
NumOkArcs++;
- (*OutStream) << kEverythingIsOk << endl;
+ if (_so)
+ *_so << kEverythingIsOk << endl;
}
else
{
NumArcsWithError++;
- if (NumFileErrorsInCurrent != 0)
- (*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrent << endl;
+ if (_so)
+ {
+ *_so << endl;
+ if (NumFileErrors_in_Current != 0)
+ *_so << "Sub items Errors: " << NumFileErrors_in_Current << endl;
+ }
}
- return S_OK;
+ if (_so && NeedFlush)
+ _so->Flush();
}
-
- NumArcsWithError++;
- if (result == E_ABORT || result == ERROR_DISK_FULL)
- return result;
- (*OutStream) << endl << kError;
- if (result == E_OUTOFMEMORY)
- (*OutStream) << kMemoryExceptionMessage;
else
- (*OutStream) << NError::MyFormatMessage(result);
- (*OutStream) << endl;
- return S_OK;
-}
-
-HRESULT CExtractCallbackConsole::OpenTypeWarning(const wchar_t *name, const wchar_t *okType, const wchar_t *errorType)
-{
- UString s = L"Warning:\n";
- if (wcscmp(okType, errorType) == 0)
{
- s += L"The archive is open with offset";
- }
- else
- {
- s += name;
- s += L"\nCan not open the file as [";
- s += errorType;
- s += L"] archive\n";
- s += L"The file is open as [";
- s += okType;
- s += L"] archive";
+ 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();
+ }
}
- (*OutStream) << s << endl << endl;
- ThereIsWarningInCurrent = true;
- return S_OK;
+
+ return CheckBreak2();
}