Source code
Revision control
Copy as Markdown
Other Tools
// UpdateCallbackConsole.cpp↩
↩
#include "StdAfx.h"↩
↩
#include "../../../Common/IntToString.h"↩
↩
#include "../../../Windows/ErrorMsg.h"↩
↩
#ifndef _7ZIP_ST↩
#include "../../../Windows/Synchronization.h"↩
#endif↩
↩
#include "ConsoleClose.h"↩
#include "UserInputUtils.h"↩
#include "UpdateCallbackConsole.h"↩
↩
using namespace NWindows;↩
↩
#ifndef _7ZIP_ST↩
static NSynchronization::CCriticalSection g_CriticalSection;↩
#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection);↩
#else↩
#define MT_LOCK↩
#endif↩
↩
static const wchar_t * const kEmptyFileAlias = L"[Content]";↩
↩
static const char * const kOpenArchiveMessage = "Open archive: ";↩
static const char * const kCreatingArchiveMessage = "Creating archive: ";↩
static const char * const kUpdatingArchiveMessage = "Updating archive: ";↩
static const char * const kScanningMessage = "Scanning the drive:";↩
↩
static const char * const kError = "ERROR: ";↩
static const char * const 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 CCodecs *codecs, const CArchiveLink &arcLink,↩
const wchar_t *name, HRESULT result)↩
{↩
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;↩
_se->NormalizePrint_wstr(name);↩
*_se << endl;↩
HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink);↩
RINOK(res);↩
_se->Flush();↩
}↩
}↩
↩
return S_OK;↩
}↩
↩
HRESULT CUpdateCallbackConsole::StartScanning()↩
{↩
if (_so)↩
*_so << kScanningMessage << endl;↩
_percent.Command = "Scan ";↩
return S_OK;↩
}↩
↩
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();↩
}↩
↩
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;↩
_se->NormalizePrint_UString(fs2us(path));↩
*_se << 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);↩
void Print_DirItemsStat2(AString &s, const CDirItemsStat2 &st);↩
↩
HRESULT CUpdateCallbackConsole::FinishScanning(const CDirItemsStat &st)↩
{↩
if (NeedPercents())↩
{↩
_percent.ClosePrint(true);↩
_percent.ClearCurState();↩
}↩
↩
if (_so)↩
{↩
AString s;↩
Print_DirItemsStat(s, st);↩
*_so << s << endl << endl;↩
}↩
return S_OK;↩
}↩
↩
static const char * const k_StdOut_ArcName = "StdOut";↩
↩
HRESULT CUpdateCallbackConsole::StartOpenArchive(const wchar_t *name)↩
{↩
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 (_so)↩
{↩
*_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage);↩
if (name)↩
_so->NormalizePrint_wstr(name);↩
else↩
*_so << k_StdOut_ArcName;↩
*_so << endl << endl;↩
}↩
return S_OK;↩
}↩
↩
HRESULT CUpdateCallbackConsole::FinishArchive(const CFinishArchiveStat &st)↩
{↩
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::WriteSfx(const wchar_t *name, UInt64 size)↩
{↩
if (_so)↩
{↩
*_so << "Write SFX: ";↩
*_so << name;↩
AString s (" : ");↩
PrintSize_bytes_Smart(s, size);↩
*_so << s << endl;↩
}↩
return S_OK;↩
}↩
↩
↩
HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */)↩
{↩
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->Normalize_UString(_tempU);↩
_so->PrintUString(_tempU, _tempA);↩
*_so << endl;↩
if (NeedFlush)↩
_so->Flush();↩
}↩
}↩
}↩
↩
if (!DeleteMessageWasShown)↩
{↩
if (NeedPercents())↩
{↩
_percent.ClearCurState();↩
}↩
DeleteMessageWasShown = true;↩
}↩
else↩
{↩
_percent.Files++;↩
}↩
↩
if (NeedPercents())↩
{↩
// if (!FullLog)↩
{↩
_percent.Command = "Removing";↩
_percent.FileName = fs2us(path);↩
}↩
_percent.Print();↩
}↩
↩
return S_OK;↩
}↩
↩
↩
HRESULT CUpdateCallbackConsole::FinishDeletingAfterArchiving()↩
{↩
ClosePercents2();↩
if (_so && DeleteMessageWasShown)↩
*_so << endl;↩
return S_OK;↩
}↩
↩
HRESULT CUpdateCallbackConsole::CheckBreak()↩
{↩
return CheckBreak2();↩
}↩
↩
/*↩
HRESULT CUpdateCallbackConsole::Finalize()↩
{↩
// MT_LOCK↩
return S_OK;↩
}↩
*/↩
↩
↩
void static PrintToDoStat(CStdOutStream *_so, const CDirItemsStat2 &stat, const char *name)↩
{↩
AString s;↩
Print_DirItemsStat2(s, stat);↩
*_so << name << ": " << s << endl;↩
}↩
↩
HRESULT CUpdateCallbackConsole::SetNumItems(const CArcToDoStat &stat)↩
{↩
if (_so)↩
{↩
ClosePercents_for_so();↩
if (!stat.DeleteData.IsEmpty())↩
{↩
*_so << endl;↩
PrintToDoStat(_so, stat.DeleteData, "Delete data from archive");↩
}↩
if (!stat.OldData.IsEmpty())↩
PrintToDoStat(_so, stat.OldData, "Keep old data in archive");↩
// if (!stat.NewData.IsEmpty())↩
{↩
PrintToDoStat(_so, stat.NewData, "Add new data to archive");↩
}↩
*_so << endl;↩
}↩
return S_OK;↩
}↩
↩
HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size)↩
{↩
MT_LOCK↩
if (NeedPercents())↩
{↩
_percent.Total = size;↩
_percent.Print();↩
}↩
return S_OK;↩
}↩
↩
HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue)↩
{↩
MT_LOCK↩
if (completeValue)↩
{↩
if (NeedPercents())↩
{↩
_percent.Completed = *completeValue;↩
_percent.Print();↩
}↩
}↩
return CheckBreak2();↩
}↩
↩
HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 * /* outSize */)↩
{↩
return CheckBreak2();↩
}↩
↩
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->Normalize_UString(_tempU);↩
}↩
_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 (!name || name[0] == 0)↩
name = kEmptyFileAlias;↩
↩
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::SetOperationResult(Int32)↩
{↩
MT_LOCK↩
_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)↩
{↩
ClosePercents2();↩
↩
if (_se)↩
{↩
if (_so)↩
_so->Flush();↩
↩
AString s;↩
SetExtractErrorMessage(opRes, isEncrypted, s);↩
*_se << s << " : " << endl;↩
_se->NormalizePrint_wstr(name);↩
*_se << 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 PrintProgress(name, s, LogLevel >= requiredLevel);↩
}↩
↩
/*↩
HRESULT CUpdateCallbackConsole::SetPassword(const UString &↩
#ifndef _NO_CRYPTO↩
password↩
#endif↩
)↩
{↩
#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↩
↩
*passwordIsDefined = false;↩
return S_OK;↩
↩
#else↩
↩
if (!PasswordIsDefined)↩
{↩
if (AskPassword)↩
{↩
RINOK(GetPassword_HRESULT(_so, Password));↩
PasswordIsDefined = true;↩
}↩
}↩
*passwordIsDefined = BoolToInt(PasswordIsDefined);↩
return StringToBstr(Password, password);↩
↩
#endif↩
↩
COM_TRY_END↩
}↩
↩
HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password)↩
{↩
COM_TRY_BEGIN↩
↩
*password = NULL;↩
↩
#ifdef _NO_CRYPTO↩
↩
return E_NOTIMPL;↩
↩
#else↩
↩
if (!PasswordIsDefined)↩
{↩
{↩
RINOK(GetPassword_HRESULT(_so, Password))↩
PasswordIsDefined = true;↩
}↩
}↩
return StringToBstr(Password, password);↩
↩
#endif↩
COM_TRY_END↩
}↩
↩
HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool /* isDir */)↩
{↩
if (StdOutMode)↩
return S_OK;↩
↩
if (LogLevel > 7)↩
{↩
if (!name || name[0] == 0)↩
name = kEmptyFileAlias;↩
return PrintProgress(name, "D", true);↩
}↩
return S_OK;↩
}↩