PhysicsFS 2.0.3 imported.

This commit is contained in:
King_DuckZ 2014-02-12 23:59:58 +01:00
parent bcc0937726
commit 993311d151
459 changed files with 87785 additions and 0 deletions

View file

@ -0,0 +1,63 @@
// ConsoleClose.cpp
#include "StdAfx.h"
#include "ConsoleClose.h"
static int g_BreakCounter = 0;
static const int kBreakAbortThreshold = 2;
namespace NConsoleClose {
static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
{
if (ctrlType == CTRL_LOGOFF_EVENT)
{
// printf("\nCTRL_LOGOFF_EVENT\n");
return TRUE;
}
g_BreakCounter++;
if (g_BreakCounter < kBreakAbortThreshold)
return TRUE;
return FALSE;
/*
switch(ctrlType)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
if (g_BreakCounter < kBreakAbortThreshold)
return TRUE;
}
return FALSE;
*/
}
bool TestBreakSignal()
{
/*
if (g_BreakCounter > 0)
return true;
*/
return (g_BreakCounter > 0);
}
void CheckCtrlBreak()
{
if (TestBreakSignal())
throw CCtrlBreakException();
}
CCtrlHandlerSetter::CCtrlHandlerSetter()
{
if(!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
throw "SetConsoleCtrlHandler fails";
}
CCtrlHandlerSetter::~CCtrlHandlerSetter()
{
if(!SetConsoleCtrlHandler(HandlerRoutine, FALSE))
throw "SetConsoleCtrlHandler fails";
}
}

View file

@ -0,0 +1,24 @@
// ConsoleCloseUtils.h
#ifndef __CONSOLECLOSEUTILS_H
#define __CONSOLECLOSEUTILS_H
namespace NConsoleClose {
bool TestBreakSignal();
class CCtrlHandlerSetter
{
public:
CCtrlHandlerSetter();
virtual ~CCtrlHandlerSetter();
};
class CCtrlBreakException
{};
void CheckCtrlBreak();
}
#endif

View file

@ -0,0 +1,235 @@
// ExtractCallbackConsole.h
#include "StdAfx.h"
#include "ExtractCallbackConsole.h"
#include "UserInputUtils.h"
#include "ConsoleClose.h"
#include "Common/Wildcard.h"
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
#include "Windows/Time.h"
#include "Windows/Defs.h"
#include "Windows/PropVariant.h"
#include "Windows/Error.h"
#include "Windows/PropVariantConversions.h"
#include "../../Common/FilePathAutoRename.h"
#include "../Common/ExtractingFilePath.h"
using namespace NWindows;
using namespace NFile;
using namespace NDirectory;
static const char *kTestingString = "Testing ";
static const char *kExtractingString = "Extracting ";
static const char *kSkippingString = "Skipping ";
// 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 *kEverythingIsOk = "Everything is Ok";
static const char *kNoFiles = "No files to process";
static const char *kUnsupportedMethod = "Unsupported Method";
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";
STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64)
{
if (NConsoleClose::TestBreakSignal())
return E_ABORT;
return S_OK;
}
STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *)
{
if (NConsoleClose::TestBreakSignal())
return E_ABORT;
return S_OK;
}
STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
const wchar_t *existName, const FILETIME *, const UInt64 *,
const wchar_t *newName, const FILETIME *, const UInt64 *,
Int32 *answer)
{
(*OutStream) << "file " << existName <<
"\nalready exists. Overwrite with " << endl;
(*OutStream) << newName;
NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream);
switch(overwriteAnswer)
{
case NUserAnswerMode::kQuit:
return E_ABORT;
case NUserAnswerMode::kNo:
*answer = NOverwriteAnswer::kNo;
break;
case NUserAnswerMode::kNoAll:
*answer = NOverwriteAnswer::kNoToAll;
break;
case NUserAnswerMode::kYesAll:
*answer = NOverwriteAnswer::kYesToAll;
break;
case NUserAnswerMode::kYes:
*answer = NOverwriteAnswer::kYes;
break;
case NUserAnswerMode::kAutoRename:
*answer = NOverwriteAnswer::kAutoRename;
break;
default:
return E_FAIL;
}
return S_OK;
}
STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, bool /* isFolder */, Int32 askExtractMode, const UInt64 *position)
{
switch (askExtractMode)
{
case NArchive::NExtract::NAskMode::kExtract:
(*OutStream) << kExtractingString;
break;
case NArchive::NExtract::NAskMode::kTest:
(*OutStream) << kTestingString;
break;
case NArchive::NExtract::NAskMode::kSkip:
(*OutStream) << kSkippingString;
break;
};
(*OutStream) << name;
if (position != 0)
(*OutStream) << " <" << *position << ">";
return S_OK;
}
STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message)
{
(*OutStream) << message << endl;
NumFileErrorsInCurrentArchive++;
NumFileErrors++;
return S_OK;
}
STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted)
{
switch(operationResult)
{
case NArchive::NExtract::NOperationResult::kOK:
break;
default:
{
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;
}
}
}
(*OutStream) << endl;
return S_OK;
}
STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)
{
if (!PasswordIsDefined)
{
Password = GetPassword(OutStream);
PasswordIsDefined = true;
}
CMyComBSTR tempName(Password);
*password = tempName.Detach();
return S_OK;
}
HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name)
{
NumArchives++;
NumFileErrorsInCurrentArchive = 0;
(*OutStream) << endl << kProcessing << name << endl;
return S_OK;
}
HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT result, bool encrypted)
{
(*OutStream) << endl;
if (result != S_OK)
{
(*OutStream) << "Error: ";
if (encrypted)
(*OutStream) << "Can not open encrypted archive. Wrong password?";
else
(*OutStream) << "Can not open file as archive";
(*OutStream) << endl;
NumArchiveErrors++;
}
return S_OK;
}
HRESULT CExtractCallbackConsole::ThereAreNoFiles()
{
(*OutStream) << endl << kNoFiles << endl;
return S_OK;
}
HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)
{
if (result == S_OK)
{
(*OutStream) << endl;
if (NumFileErrorsInCurrentArchive == 0)
(*OutStream) << kEverythingIsOk << endl;
else
{
NumArchiveErrors++;
(*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl;
}
}
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
{
UString message;
NError::MyFormatMessage(result, message);
(*OutStream) << message;
}
(*OutStream) << endl;
return S_OK;
}
HRESULT CExtractCallbackConsole::SetPassword(const UString &password)
{
PasswordIsDefined = true;
Password = password;
return S_OK;
}

View file

@ -0,0 +1,65 @@
// ExtractCallbackConsole.h
#ifndef __EXTRACTCALLBACKCONSOLE_H
#define __EXTRACTCALLBACKCONSOLE_H
#include "Common/MyString.h"
#include "Common/StdOutStream.h"
#include "../../Common/FileStreams.h"
#include "../../IPassword.h"
#include "../../Archive/IArchive.h"
#include "../Common/ArchiveExtractCallback.h"
class CExtractCallbackConsole:
public IExtractCallbackUI,
public ICryptoGetTextPassword,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP2(IFolderArchiveExtractCallback, ICryptoGetTextPassword)
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);
// ICryptoGetTextPassword
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
HRESULT BeforeOpen(const wchar_t *name);
HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted);
HRESULT ThereAreNoFiles();
HRESULT ExtractResult(HRESULT result);
HRESULT SetPassword(const UString &password);
public:
bool PasswordIsDefined;
UString Password;
UInt64 NumArchives;
UInt64 NumArchiveErrors;
UInt64 NumFileErrors;
UInt64 NumFileErrorsInCurrentArchive;
CStdOutStream *OutStream;
void Init()
{
NumArchives = 0;
NumArchiveErrors = 0;
NumFileErrors = 0;
NumFileErrorsInCurrentArchive = 0;
}
};
#endif

View file

@ -0,0 +1,579 @@
// List.cpp
#include "StdAfx.h"
#include "List.h"
#include "ConsoleClose.h"
#include "Common/StringConvert.h"
#include "Common/StdOutStream.h"
#include "Common/IntToString.h"
#include "Common/MyCom.h"
#include "Windows/PropVariant.h"
#include "Windows/Defs.h"
#include "Windows/PropVariantConversions.h"
#include "Windows/FileDir.h"
#include "../../Archive/IArchive.h"
#include "../Common/PropIDUtils.h"
#include "../Common/OpenArchive.h"
#include "OpenCallbackConsole.h"
using namespace NWindows;
struct CPropIdToName
{
PROPID PropID;
const wchar_t *Name;
};
static CPropIdToName kPropIdToName[] =
{
{ kpidPath, L"Path" },
{ kpidName, L"Name" },
{ kpidIsFolder, L"Folder" },
{ kpidSize, L"Size" },
{ kpidPackedSize, L"Packed Size" },
{ kpidAttributes, L"Attributes" },
{ kpidCreationTime, L"Created" },
{ kpidLastAccessTime, L"Accessed" },
{ kpidLastWriteTime, 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" },
{ kpidNumSubFolders, 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" }
};
static const char kEmptyAttributeChar = '.';
static const char kDirectoryAttributeChar = 'D';
static const char kReadonlyAttributeChar = 'R';
static const char kHiddenAttributeChar = 'H';
static const char kSystemAttributeChar = 'S';
static const char kArchiveAttributeChar = 'A';
static const char *kListing = "Listing archive: ";
static const wchar_t *kFilesMessage = L"files";
static const wchar_t *kDirsMessage = L"folders";
static void GetAttributesString(DWORD wa, bool directory, char *s)
{
s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ?
kDirectoryAttributeChar: kEmptyAttributeChar;
s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0)?
kReadonlyAttributeChar: kEmptyAttributeChar;
s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ?
kHiddenAttributeChar: kEmptyAttributeChar;
s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ?
kSystemAttributeChar: kEmptyAttributeChar;
s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ?
kArchiveAttributeChar: kEmptyAttributeChar;
s[5] = '\0';
}
enum EAdjustment
{
kLeft,
kCenter,
kRight
};
struct CFieldInfo
{
PROPID PropID;
UString Name;
EAdjustment TitleAdjustment;
EAdjustment TextAdjustment;
int PrefixSpacesWidth;
int Width;
};
struct CFieldInfoInit
{
PROPID PropID;
const wchar_t *Name;
EAdjustment TitleAdjustment;
EAdjustment TextAdjustment;
int PrefixSpacesWidth;
int Width;
};
CFieldInfoInit kStandardFieldTable[] =
{
{ kpidLastWriteTime, L" Date Time", kLeft, kLeft, 0, 19 },
{ kpidAttributes, L"Attr", kRight, kCenter, 1, 5 },
{ kpidSize, L"Size", kRight, kRight, 1, 12 },
{ kpidPackedSize, L"Compressed", kRight, kRight, 1, 12 },
{ kpidPath, L"Name", kLeft, kLeft, 2, 24 }
};
void PrintSpaces(int numSpaces)
{
for (int i = 0; i < numSpaces; i++)
g_StdOut << ' ';
}
void PrintString(EAdjustment adjustment, int width, const UString &textString)
{
const int numSpaces = width - textString.Length();
int numLeftSpaces = 0;
switch (adjustment)
{
case kLeft:
numLeftSpaces = 0;
break;
case kCenter:
numLeftSpaces = numSpaces / 2;
break;
case kRight:
numLeftSpaces = numSpaces;
break;
}
PrintSpaces(numLeftSpaces);
g_StdOut << textString;
PrintSpaces(numSpaces - numLeftSpaces);
}
class CFieldPrinter
{
CObjectVector<CFieldInfo> _fields;
public:
void Clear() { _fields.Clear(); }
void Init(const CFieldInfoInit *standardFieldTable, int numItems);
HRESULT Init(IInArchive *archive);
void PrintTitle();
void PrintTitleLines();
HRESULT PrintItemInfo(IInArchive *archive,
const UString &defaultItemName,
const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
UInt32 index,
bool techMode);
HRESULT PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs,
const UInt64 *size, const UInt64 *compressedSize);
};
void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems)
{
Clear();
for (int 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);
}
}
static UString GetPropName(PROPID propID, BSTR name)
{
for (int i = 0; i < sizeof(kPropIdToName) / sizeof(kPropIdToName[0]); i++)
{
const CPropIdToName &propIdToName = kPropIdToName[i];
if (propIdToName.PropID == propID)
return propIdToName.Name;
}
if (name)
return name;
return L"?";
}
HRESULT CFieldPrinter::Init(IInArchive *archive)
{
Clear();
UInt32 numProps;
RINOK(archive->GetNumberOfProperties(&numProps));
for (UInt32 i = 0; i < numProps; i++)
{
CMyComBSTR name;
PROPID propID;
VARTYPE vt;
RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt));
CFieldInfo fieldInfo;
fieldInfo.PropID = propID;
fieldInfo.Name = GetPropName(propID, name);
_fields.Add(fieldInfo);
}
return S_OK;
}
void CFieldPrinter::PrintTitle()
{
for (int i = 0; i < _fields.Size(); i++)
{
const CFieldInfo &fieldInfo = _fields[i];
PrintSpaces(fieldInfo.PrefixSpacesWidth);
PrintString(fieldInfo.TitleAdjustment,
((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name);
}
}
void CFieldPrinter::PrintTitleLines()
{
for (int i = 0; i < _fields.Size(); i++)
{
const CFieldInfo &fieldInfo = _fields[i];
PrintSpaces(fieldInfo.PrefixSpacesWidth);
for (int i = 0; i < fieldInfo.Width; i++)
g_StdOut << '-';
}
}
BOOL IsFileTimeZero(CONST FILETIME *lpFileTime)
{
return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0);
}
static const char *kEmptyTimeString = " ";
void PrintTime(const NCOM::CPropVariant &propVariant)
{
if (propVariant.vt != VT_FILETIME)
throw "incorrect item";
if (IsFileTimeZero(&propVariant.filetime))
g_StdOut << kEmptyTimeString;
else
{
FILETIME localFileTime;
if (!FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime))
throw "FileTimeToLocalFileTime error";
char s[32];
if (ConvertFileTimeToString(localFileTime, s, true, true))
g_StdOut << s;
else
g_StdOut << kEmptyTimeString;
}
}
HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive,
const UString &defaultItemName,
const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
UInt32 index,
bool techMode)
{
/*
if (techMode)
{
g_StdOut << "Index = ";
g_StdOut << (UInt64)index;
g_StdOut << endl;
}
*/
for (int i = 0; i < _fields.Size(); i++)
{
const CFieldInfo &fieldInfo = _fields[i];
if (!techMode)
PrintSpaces(fieldInfo.PrefixSpacesWidth);
NCOM::CPropVariant propVariant;
RINOK(archive->GetProperty(index, fieldInfo.PropID, &propVariant));
if (techMode)
{
g_StdOut << fieldInfo.Name << " = ";
}
int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width;
if (propVariant.vt == VT_EMPTY)
{
switch(fieldInfo.PropID)
{
case kpidPath:
propVariant = defaultItemName;
break;
case kpidLastWriteTime:
propVariant = archiveFileInfo.LastWriteTime;
break;
default:
if (techMode)
g_StdOut << endl;
else
PrintSpaces(width);
continue;
}
}
if (fieldInfo.PropID == kpidLastWriteTime)
{
PrintTime(propVariant);
}
else if (fieldInfo.PropID == kpidAttributes)
{
if (propVariant.vt != VT_UI4)
throw "incorrect item";
UInt32 attributes = propVariant.ulVal;
bool isFolder;
RINOK(IsArchiveItemFolder(archive, index, isFolder));
char s[8];
GetAttributesString(attributes, isFolder, s);
g_StdOut << s;
}
else if (propVariant.vt == VT_BSTR)
{
if (techMode)
g_StdOut << propVariant.bstrVal;
else
PrintString(fieldInfo.TextAdjustment, width, propVariant.bstrVal);
}
else
{
UString s = ConvertPropertyToString(propVariant, fieldInfo.PropID);
s.Replace(wchar_t(0xA), L' ');
s.Replace(wchar_t(0xD), L' ');
if (techMode)
g_StdOut << s;
else
PrintString(fieldInfo.TextAdjustment, width, s);
}
if (techMode)
g_StdOut << endl;
}
return S_OK;
}
void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value)
{
wchar_t textString[32] = { 0 };
if (value != NULL)
ConvertUInt64ToString(*value, textString);
PrintString(adjustment, width, textString);
}
HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs,
const UInt64 *size, const UInt64 *compressedSize)
{
for (int i = 0; i < _fields.Size(); i++)
{
const CFieldInfo &fieldInfo = _fields[i];
PrintSpaces(fieldInfo.PrefixSpacesWidth);
NCOM::CPropVariant propVariant;
if (fieldInfo.PropID == kpidSize)
PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, size);
else if (fieldInfo.PropID == kpidPackedSize)
PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, compressedSize);
else if (fieldInfo.PropID == kpidPath)
{
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);
}
else
PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L"");
}
return S_OK;
}
bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value)
{
NCOM::CPropVariant propVariant;
if (archive->GetProperty(index, propID, &propVariant) != S_OK)
throw "GetPropertyValue error";
if (propVariant.vt == VT_EMPTY)
return false;
value = ConvertPropVariantToUInt64(propVariant);
return true;
}
HRESULT ListArchives(
CCodecs *codecs,
UStringVector &archivePaths, UStringVector &archivePathsFull,
const NWildcard::CCensorNode &wildcardCensor,
bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password, UInt64 &numErrors)
{
numErrors = 0;
CFieldPrinter fieldPrinter;
if (!techMode)
fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));
UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;
UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;
for (int i = 0; i < archivePaths.Size(); i++)
{
const UString &archiveName = archivePaths[i];
NFile::NFind::CFileInfoW archiveFileInfo;
if (!NFile::NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory())
{
g_StdOut << endl << "Error: " << archiveName << " is not archive" << endl;
numErrors++;
continue;
}
if (archiveFileInfo.IsDirectory())
{
g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;
numErrors++;
continue;
}
CArchiveLink archiveLink;
COpenCallbackConsole openCallback;
openCallback.OutStream = &g_StdOut;
openCallback.PasswordIsDefined = passwordEnabled;
openCallback.Password = password;
HRESULT result = MyOpenArchive(codecs, archiveName, archiveLink, &openCallback);
if (result != S_OK)
{
g_StdOut << endl << "Error: " << archiveName << " is not supported archive" << endl;
numErrors++;
continue;
}
for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
{
int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
if (index >= 0 && index > i)
{
archivePaths.Delete(index);
archivePathsFull.Delete(index);
}
}
IInArchive *archive = archiveLink.GetArchive();
const UString defaultItemName = archiveLink.GetDefaultItemName();
if (enableHeaders)
{
g_StdOut << endl << kListing << archiveName << endl << endl;
UInt32 numProps;
if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK)
{
for (UInt32 i = 0; i < numProps; i++)
{
CMyComBSTR name;
PROPID propID;
VARTYPE vt;
if (archive->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK)
continue;
NCOM::CPropVariant prop;
if (archive->GetArchiveProperty(propID, &prop) != S_OK)
continue;
UString s = ConvertPropertyToString(prop, propID);
if (!s.IsEmpty())
g_StdOut << GetPropName(propID, name) << " = " << s << endl;
}
}
if (techMode)
g_StdOut << "----------\n";
if (numProps > 0)
g_StdOut << endl;
}
if (enableHeaders && !techMode)
{
fieldPrinter.PrintTitle();
g_StdOut << endl;
fieldPrinter.PrintTitleLines();
g_StdOut << endl;
}
if (techMode)
{
RINOK(fieldPrinter.Init(archive));
}
UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0;
UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;
UInt32 numItems;
RINOK(archive->GetNumberOfItems(&numItems));
for(UInt32 i = 0; i < numItems; i++)
{
if (NConsoleClose::TestBreakSignal())
return E_ABORT;
UString filePath;
RINOK(GetArchiveItemPath(archive, i, defaultItemName, filePath));
bool isFolder;
RINOK(IsArchiveItemFolder(archive, i, isFolder));
if (!wildcardCensor.CheckPath(filePath, !isFolder))
continue;
fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i, techMode);
UInt64 packSize, unpackSize;
if (!GetUInt64Value(archive, i, kpidSize, unpackSize))
unpackSize = 0;
else
totalUnPackSizePointer = &totalUnPackSize;
if (!GetUInt64Value(archive, i, kpidPackedSize, packSize))
packSize = 0;
else
totalPackSizePointer = &totalPackSize;
g_StdOut << endl;
if (isFolder)
numDirs++;
else
numFiles++;
totalPackSize += packSize;
totalUnPackSize += unpackSize;
}
if (enableHeaders && !techMode)
{
fieldPrinter.PrintTitleLines();
g_StdOut << endl;
fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer);
g_StdOut << endl;
}
if (totalPackSizePointer != 0)
{
totalPackSizePointer2 = &totalPackSize2;
totalPackSize2 += totalPackSize;
}
if (totalUnPackSizePointer != 0)
{
totalUnPackSizePointer2 = &totalUnPackSize2;
totalUnPackSize2 += totalUnPackSize;
}
numFiles2 += numFiles;
numDirs2 += numDirs;
}
if (enableHeaders && !techMode && archivePaths.Size() > 1)
{
g_StdOut << endl;
fieldPrinter.PrintTitleLines();
g_StdOut << endl;
fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2);
g_StdOut << endl;
g_StdOut << "Archives: " << archivePaths.Size() << endl;
}
return S_OK;
}

View file

@ -0,0 +1,16 @@
// List.h
#ifndef __LIST_H
#define __LIST_H
#include "Common/Wildcard.h"
#include "../Common/LoadCodecs.h"
HRESULT ListArchives(
CCodecs *codecs,
UStringVector &archivePaths, UStringVector &archivePathsFull,
const NWildcard::CCensorNode &wildcardCensor,
bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password, UInt64 &errors);
#endif

View file

@ -0,0 +1,563 @@
// Main.cpp
#include "StdAfx.h"
#include "Common/MyInitGuid.h"
#include "Common/CommandLineParser.h"
#include "Common/MyException.h"
#include "Common/IntToString.h"
#include "Common/StdOutStream.h"
#include "Common/StringConvert.h"
#include "Common/StringToInt.h"
#include "Windows/FileDir.h"
#include "Windows/FileName.h"
#include "Windows/Defs.h"
#include "Windows/Error.h"
#ifdef _WIN32
#include "Windows/MemoryLock.h"
#endif
#include "../../IPassword.h"
#include "../../ICoder.h"
#include "../Common/UpdateAction.h"
#include "../Common/Update.h"
#include "../Common/Extract.h"
#include "../Common/ArchiveCommandLine.h"
#include "../Common/ExitCode.h"
#ifdef EXTERNAL_CODECS
#include "../Common/LoadCodecs.h"
#endif
#include "../../Compress/LZMA_Alone/LzmaBenchCon.h"
#include "List.h"
#include "OpenCallbackConsole.h"
#include "ExtractCallbackConsole.h"
#include "UpdateCallbackConsole.h"
#include "../../MyVersion.h"
#if defined( _WIN32) && defined( _7ZIP_LARGE_PAGES)
extern "C"
{
#include "../../../../C/Alloc.h"
}
#endif
using namespace NWindows;
using namespace NFile;
using namespace NCommandLineParser;
HINSTANCE g_hInstance = 0;
extern CStdOutStream *g_StdStream;
static const char *kCopyrightString = "\n7-Zip"
#ifndef EXTERNAL_CODECS
" (A)"
#endif
#ifdef _WIN64
" [64]"
#endif
" " MY_VERSION_COPYRIGHT_DATE "\n";
static const char *kHelpString =
"\nUsage: 7z"
#ifdef _NO_CRYPTO
"r"
#else
#ifndef EXTERNAL_CODECS
"a"
#endif
#endif
" <command> [<switches>...] <archive_name> [<file_names>...]\n"
" [<@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"
"<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"
" -p{Password}: set Password\n"
" -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"
" -v{Size}[b|k|m|g]: Create volumes\n"
" -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\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
static const char *kEverythingIsOk = "Everything is Ok";
static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError
static const wchar_t *kDefaultSfxModule = L"7zCon.sfx";
static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code)
{
s << message << endl;
throw code;
}
static void PrintHelpAndExit(CStdOutStream &s) // yyy
{
s << kHelpString;
ShowMessageAndThrowException(s, kUserErrorMessage, NExitCode::kUserError);
}
#ifndef _WIN32
static void GetArguments(int numArguments, const char *arguments[], UStringVector &parts)
{
parts.Clear();
for(int i = 0; i < numArguments; i++)
{
UString s = MultiByteToUnicodeString(arguments[i]);
parts.Add(s);
}
}
#endif
static void ShowCopyrightAndHelp(CStdOutStream &s, bool needHelp)
{
s << kCopyrightString;
// s << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << "\n";
if (needHelp)
s << kHelpString;
}
#ifdef EXTERNAL_CODECS
static void PrintString(CStdOutStream &stdStream, const AString &s, int size)
{
int len = s.Length();
stdStream << s;
for (int i = len; i < size; i++)
stdStream << ' ';
}
#endif
static void PrintString(CStdOutStream &stdStream, const UString &s, int size)
{
int len = s.Length();
stdStream << s;
for (int i = len; i < size; i++)
stdStream << ' ';
}
static inline char GetHex(Byte value)
{
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
}
int Main2(
#ifndef _WIN32
int numArguments, const char *arguments[]
#endif
)
{
#ifdef _WIN32
SetFileApisToOEM();
#endif
UStringVector commandStrings;
#ifdef _WIN32
NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
#else
GetArguments(numArguments, arguments, commandStrings);
#endif
if(commandStrings.Size() == 1)
{
ShowCopyrightAndHelp(g_StdOut, true);
return 0;
}
commandStrings.Delete(0);
CArchiveCommandLineOptions options;
CArchiveCommandLineParser parser;
parser.Parse1(commandStrings, options);
if(options.HelpMode)
{
ShowCopyrightAndHelp(g_StdOut, true);
return 0;
}
#if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
if (options.LargePages)
{
SetLargePageSize();
NSecurity::EnableLockMemoryPrivilege();
}
#endif
CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut;
g_StdStream = &stdStream;
if (options.EnableHeaders)
ShowCopyrightAndHelp(stdStream, false);
parser.Parse2(options);
CCodecs *codecs = new CCodecs;
CMyComPtr<
#ifdef EXTERNAL_CODECS
ICompressCodecsInfo
#else
IUnknown
#endif
> compressCodecsInfo = codecs;
HRESULT result = codecs->Load();
if (result != S_OK)
throw CSystemException(result);
bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
if (options.Command.CommandType == NCommandType::kInfo)
{
stdStream << endl << "Formats:" << endl;
int i;
for (i = 0; i < codecs->Formats.Size(); i++)
{
const CArcInfoEx &arc = codecs->Formats[i];
#ifdef EXTERNAL_CODECS
if (arc.LibIndex >= 0)
{
char s[32];
ConvertUInt64ToString(arc.LibIndex, s);
PrintString(stdStream, s, 2);
}
else
#endif
stdStream << " ";
stdStream << ' ';
stdStream << (char)(arc.UpdateEnabled ? 'C' : ' ');
stdStream << (char)(arc.KeepName ? 'K' : ' ');
stdStream << " ";
PrintString(stdStream, arc.Name, 6);
stdStream << " ";
UString s;
for (int t = 0; t < arc.Exts.Size(); t++)
{
const CArcExtInfo &ext = arc.Exts[t];
s += ext.Ext;
if (!ext.AddExt.IsEmpty())
{
s += L" (";
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++)
{
Byte b = sig[j];
if (b > 0x20 && b < 0x80)
{
stdStream << (char)b;
}
else
{
stdStream << GetHex((Byte)((b >> 4) & 0xF));
stdStream << GetHex((Byte)(b & 0xF));
}
stdStream << ' ';
}
stdStream << endl;
}
stdStream << endl << "Codecs:" << endl;
#ifdef EXTERNAL_CODECS
UINT32 numMethods;
if (codecs->GetNumberOfMethods(&numMethods) == S_OK)
for (UInt32 j = 0; j < numMethods; j++)
{
int libIndex = codecs->GetCodecLibIndex(j);
if (libIndex >= 0)
{
char s[32];
ConvertUInt64ToString(libIndex, s);
PrintString(stdStream, s, 2);
}
else
stdStream << " ";
stdStream << ' ';
stdStream << (char)(codecs->GetCodecEncoderIsAssigned(j) ? 'C' : ' ');
UInt64 id;
stdStream << " ";
HRESULT res = codecs->GetCodecId(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";
*/
}
#endif
return S_OK;
}
else if (options.Command.CommandType == NCommandType::kBenchmark)
{
if (options.Method.CompareNoCase(L"CRC") == 0)
{
HRESULT res = CrcBenchCon((FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);
if (res != S_OK)
{
if (res == S_FALSE)
{
stdStream << "\nCRC Error\n";
return NExitCode::kFatalError;
}
throw CSystemException(res);
}
}
else
{
HRESULT res = LzmaBenchCon(
#ifdef EXTERNAL_LZMA
codecs,
#endif
(FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);
if (res != S_OK)
{
if (res == S_FALSE)
{
stdStream << "\nDecoding Error\n";
return NExitCode::kFatalError;
}
throw CSystemException(res);
}
}
}
else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
{
if(isExtractGroupCommand)
{
CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
ecs->OutStream = &stdStream;
ecs->PasswordIsDefined = options.PasswordEnabled;
ecs->Password = options.Password;
ecs->Init();
COpenCallbackConsole openCallback;
openCallback.OutStream = &stdStream;
openCallback.PasswordIsDefined = options.PasswordEnabled;
openCallback.Password = options.Password;
CExtractOptions eo;
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;
#ifdef COMPRESS_MT
eo.Properties = options.ExtractProperties;
#endif
UString errorMessage;
CDecompressStat stat;
HRESULT result = DecompressArchives(
codecs,
options.ArchivePathsSorted,
options.ArchivePathsFullSorted,
options.WildcardCensor.Pairs.Front().Head,
eo, &openCallback, ecs, errorMessage, stat);
if (!errorMessage.IsEmpty())
{
stdStream << endl << "Error: " << errorMessage;
if (result == S_OK)
result = E_FAIL;
}
stdStream << endl;
if (ecs->NumArchives > 1)
stdStream << "Archives: " << ecs->NumArchives << endl;
if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)
{
if (ecs->NumArchives > 1)
{
stdStream << endl;
if (ecs->NumArchiveErrors != 0)
stdStream << "Archive Errors: " << ecs->NumArchiveErrors << endl;
if (ecs->NumFileErrors != 0)
stdStream << "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;
}
else
{
UInt64 numErrors = 0;
HRESULT result = ListArchives(
codecs,
options.ArchivePathsSorted,
options.ArchivePathsFullSorted,
options.WildcardCensor.Pairs.Front().Head,
options.EnableHeaders,
options.TechMode,
options.PasswordEnabled,
options.Password, numErrors);
if (numErrors > 0)
{
g_StdOut << endl << "Errors: " << numErrors;
return NExitCode::kFatalError;
}
if (result != S_OK)
throw CSystemException(result);
}
}
else if(options.Command.IsFromUpdateGroup())
{
UString workingDir;
CUpdateOptions &uo = options.UpdateOptions;
if (uo.SfxMode && uo.SfxModule.IsEmpty())
uo.SfxModule = kDefaultSfxModule;
bool passwordIsDefined =
options.PasswordEnabled && !options.Password.IsEmpty();
COpenCallbackConsole openCallback;
openCallback.OutStream = &stdStream;
openCallback.PasswordIsDefined = passwordIsDefined;
openCallback.Password = options.Password;
CUpdateCallbackConsole callback;
callback.EnablePercents = options.EnablePercents;
callback.PasswordIsDefined = passwordIsDefined;
callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();
callback.Password = options.Password;
callback.StdOutMode = uo.StdOutMode;
callback.Init(&stdStream);
CUpdateErrorInfo errorInfo;
if (!uo.Init(codecs, options.ArchiveName, options.ArcType))
throw "Unsupported archive type";
HRESULT result = UpdateArchive(codecs,
options.WildcardCensor, uo,
errorInfo, &openCallback, &callback);
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;
}
if (result != S_OK)
{
UString message;
if (!errorInfo.Message.IsEmpty())
{
message += errorInfo.Message;
message += L"\n";
}
if (!errorInfo.FileName.IsEmpty())
{
message += errorInfo.FileName;
message += L"\n";
}
if (!errorInfo.FileName2.IsEmpty())
{
message += 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;
}
else
PrintHelpAndExit(stdStream);
return 0;
}

View file

@ -0,0 +1,161 @@
// MainAr.cpp
#include "StdAfx.h"
// #include <locale.h>
#include "Windows/Error.h"
#include "Common/StdOutStream.h"
#include "Common/NewHandler.h"
#include "Common/MyException.h"
#include "Common/StringConvert.h"
#include "../Common/ExitCode.h"
#include "../Common/ArchiveCommandLine.h"
#include "ConsoleClose.h"
using namespace NWindows;
CStdOutStream *g_StdStream = 0;
#ifdef _WIN32
#ifndef _UNICODE
bool g_IsNT = false;
#endif
#if !defined(_UNICODE) || !defined(_WIN64)
static inline bool IsItWindowsNT()
{
OSVERSIONINFO versionInfo;
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
if (!::GetVersionEx(&versionInfo))
return false;
return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
#endif
#endif
extern int Main2(
#ifndef _WIN32
int numArguments, const char *arguments[]
#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 *kInternalExceptionMessage = "\n\nInternal Error #";
int
#ifdef _MSC_VER
__cdecl
#endif
main
(
#ifndef _WIN32
int numArguments, const char *arguments[]
#endif
)
{
g_StdStream = &g_StdOut;
#ifdef _WIN32
#ifdef _UNICODE
#ifndef _WIN64
if (!IsItWindowsNT())
{
(*g_StdStream) << "This program requires Windows NT/2000/XP/2003/Vista";
return NExitCode::kFatalError;
}
#endif
#else
g_IsNT = IsItWindowsNT();
#endif
#endif
// setlocale(LC_COLLATE, ".OCP");
NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter;
int res = 0;
try
{
res = Main2(
#ifndef _WIN32
numArguments, arguments
#endif
);
}
catch(const CNewException &)
{
(*g_StdStream) << kMemoryExceptionMessage;
return (NExitCode::kMemoryError);
}
catch(const NConsoleClose::CCtrlBreakException &)
{
(*g_StdStream) << endl << kUserBreak;
return (NExitCode::kUserBreak);
}
catch(const CArchiveCommandLineException &e)
{
(*g_StdStream) << kExceptionErrorMessage << e << endl;
return (NExitCode::kUserError);
}
catch(const CSystemException &systemError)
{
if (systemError.ErrorCode == E_OUTOFMEMORY)
{
(*g_StdStream) << kMemoryExceptionMessage;
return (NExitCode::kMemoryError);
}
if (systemError.ErrorCode == E_ABORT)
{
(*g_StdStream) << endl << kUserBreak;
return (NExitCode::kUserBreak);
}
UString message;
NError::MyFormatMessage(systemError.ErrorCode, message);
(*g_StdStream) << endl << endl << "System error:" << endl <<
message << endl;
return (NExitCode::kFatalError);
}
catch(NExitCode::EEnum &exitCode)
{
(*g_StdStream) << 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;
return (NExitCode::kFatalError);
}
catch(const AString &s)
{
(*g_StdStream) << kExceptionErrorMessage << s << endl;
return (NExitCode::kFatalError);
}
catch(const char *s)
{
(*g_StdStream) << kExceptionErrorMessage << s << endl;
return (NExitCode::kFatalError);
}
catch(int t)
{
(*g_StdStream) << kInternalExceptionMessage << t << endl;
return (NExitCode::kFatalError);
}
catch(...)
{
(*g_StdStream) << kUnknownExceptionMessage;
return (NExitCode::kFatalError);
}
return res;
}

View file

@ -0,0 +1,58 @@
// OpenCallbackConsole.cpp
#include "StdAfx.h"
#include "OpenCallbackConsole.h"
#include "ConsoleClose.h"
#include "UserInputUtils.h"
HRESULT COpenCallbackConsole::CheckBreak()
{
if (NConsoleClose::TestBreakSignal())
return E_ABORT;
return S_OK;
}
HRESULT COpenCallbackConsole::SetTotal(const UInt64 *, const UInt64 *)
{
return CheckBreak();
}
HRESULT COpenCallbackConsole::SetCompleted(const UInt64 *, const UInt64 *)
{
return CheckBreak();
}
HRESULT COpenCallbackConsole::CryptoGetTextPassword(BSTR *password)
{
PasswordWasAsked = true;
RINOK(CheckBreak());
if (!PasswordIsDefined)
{
Password = GetPassword(OutStream);
PasswordIsDefined = true;
}
CMyComBSTR temp(Password);
*password = temp.Detach();
return S_OK;
}
HRESULT COpenCallbackConsole::GetPasswordIfAny(UString &password)
{
if (PasswordIsDefined)
password = Password;
return S_OK;
}
bool COpenCallbackConsole::WasPasswordAsked()
{
return PasswordWasAsked;
}
void COpenCallbackConsole::ClearPasswordWasAskedFlag()
{
PasswordWasAsked = false;
}

View file

@ -0,0 +1,27 @@
// OpenCallbackConsole.h
#ifndef __OPENCALLBACKCONSOLE_H
#define __OPENCALLBACKCONSOLE_H
#include "Common/StdOutStream.h"
#include "../Common/ArchiveOpenCallback.h"
class COpenCallbackConsole: public IOpenCallbackUI
{
public:
HRESULT CheckBreak();
HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes);
HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes);
HRESULT CryptoGetTextPassword(BSTR *password);
HRESULT GetPasswordIfAny(UString &password);
bool WasPasswordAsked();
void ClearPasswordWasAskedFlag();
CStdOutStream *OutStream;
bool PasswordIsDefined;
UString Password;
bool PasswordWasAsked;
COpenCallbackConsole(): PasswordIsDefined(false), PasswordWasAsked(false) {}
};
#endif

View file

@ -0,0 +1,90 @@
// PercentPrinter.cpp
#include "StdAfx.h"
#include "Common/IntToString.h"
#include "Common/MyString.h"
#include "PercentPrinter.h"
const int kPaddingSize = 2;
const int kPercentsSize = 4;
const int kMaxExtraSize = kPaddingSize + 32 + kPercentsSize;
static void ClearPrev(char *p, int num)
{
int 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;
}
void CPercentPrinter::PrintString(const char *s)
{
ClosePrint();
(*OutStream) << s;
}
void CPercentPrinter::PrintString(const wchar_t *s)
{
ClosePrint();
(*OutStream) << s;
}
void CPercentPrinter::PrintNewLine()
{
ClosePrint();
(*OutStream) << "\n";
}
void CPercentPrinter::RePrintRatio()
{
char s[32];
ConvertUInt64ToString(((m_Total == 0) ? 0 : (m_CurValue * 100 / m_Total)), s);
int size = (int)strlen(s);
s[size++] = '%';
s[size] = '\0';
int extraSize = kPaddingSize + MyMax(size, kPercentsSize);
if (extraSize < m_NumExtraChars)
extraSize = m_NumExtraChars;
char fullString[kMaxExtraSize * 3];
char *p = fullString;
int i;
if (m_NumExtraChars == 0)
{
for (i = 0; i < extraSize; i++)
*p++ = ' ';
m_NumExtraChars = extraSize;
}
for (i = 0; i < m_NumExtraChars; i++)
*p++ = '\b';
m_NumExtraChars = extraSize;
for (; size < m_NumExtraChars; size++)
*p++ = ' ';
MyStringCopy(p, s);
(*OutStream) << fullString;
OutStream->Flush();
m_PrevValue = m_CurValue;
}
void CPercentPrinter::PrintRatio()
{
if (m_CurValue < m_PrevValue + m_MinStepSize &&
m_CurValue + m_MinStepSize > m_PrevValue && m_NumExtraChars != 0)
return;
RePrintRatio();
}

View file

@ -0,0 +1,31 @@
// PercentPrinter.h
#ifndef __PERCENTPRINTER_H
#define __PERCENTPRINTER_H
#include "Common/Types.h"
#include "Common/StdOutStream.h"
class CPercentPrinter
{
UInt64 m_MinStepSize;
UInt64 m_PrevValue;
UInt64 m_CurValue;
UInt64 m_Total;
int m_NumExtraChars;
public:
CStdOutStream *OutStream;
CPercentPrinter(UInt64 minStepSize = 1): m_MinStepSize(minStepSize),
m_PrevValue(0), m_CurValue(0), m_Total(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();
};
#endif

View file

@ -0,0 +1,3 @@
// StdAfx.cpp
#include "StdAfx.h"

View file

@ -0,0 +1,9 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/MyWindows.h"
#include "../../../Common/NewHandler.h"
#endif

View file

@ -0,0 +1,208 @@
// UpdateCallbackConsole.cpp
#include "StdAfx.h"
#include "UpdateCallbackConsole.h"
#include "Windows/Error.h"
#ifdef COMPRESS_MT
#include "Windows/Synchronization.h"
#endif
#include "ConsoleClose.h"
#include "UserInputUtils.h"
using namespace NWindows;
#ifdef COMPRESS_MT
static NSynchronization::CCriticalSection g_CriticalSection;
#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
#else
#define MT_LOCK
#endif
static const wchar_t *kEmptyFileAlias = L"[Content]";
static const char *kCreatingArchiveMessage = "Creating archive ";
static const char *kUpdatingArchiveMessage = "Updating archive ";
static const char *kScanningMessage = "Scanning";
HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result)
{
(*OutStream) << endl;
if (result != S_OK)
(*OutStream) << "Error: " << name << " is not supported archive" << endl;
return S_OK;
}
HRESULT CUpdateCallbackConsole::StartScanning()
{
(*OutStream) << kScanningMessage;
return S_OK;
}
HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError)
{
CantFindFiles.Add(name);
CantFindCodes.Add(systemError);
// m_PercentPrinter.ClosePrint();
if (!m_WarningsMode)
{
(*OutStream) << endl << endl;
m_PercentPrinter.PrintNewLine();
m_WarningsMode = true;
}
m_PercentPrinter.PrintString(name);
m_PercentPrinter.PrintString(": WARNING: ");
m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
m_PercentPrinter.PrintNewLine();
return S_OK;
}
HRESULT CUpdateCallbackConsole::FinishScanning()
{
(*OutStream) << endl << 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;
return S_OK;
}
HRESULT CUpdateCallbackConsole::FinishArchive()
{
(*OutStream) << endl;
return S_OK;
}
HRESULT CUpdateCallbackConsole::CheckBreak()
{
if (NConsoleClose::TestBreakSignal())
return E_ABORT;
return S_OK;
}
HRESULT CUpdateCallbackConsole::Finilize()
{
MT_LOCK
if (m_NeedBeClosed)
{
if (EnablePercents)
{
m_PercentPrinter.ClosePrint();
}
if (!StdOutMode && m_NeedNewLine)
{
m_PercentPrinter.PrintNewLine();
m_NeedNewLine = false;
}
m_NeedBeClosed = false;
}
return S_OK;
}
HRESULT CUpdateCallbackConsole::SetNumFiles(UInt64 /* numFiles */)
{
return S_OK;
}
HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size)
{
MT_LOCK
if (EnablePercents)
m_PercentPrinter.SetTotal(size);
return S_OK;
}
HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue)
{
MT_LOCK
if (completeValue != NULL)
{
if (EnablePercents)
{
m_PercentPrinter.SetRatio(*completeValue);
m_PercentPrinter.PrintRatio();
m_NeedBeClosed = true;
}
}
if (NConsoleClose::TestBreakSignal())
return E_ABORT;
return S_OK;
}
HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 * /* outSize */)
{
/*
if (NConsoleClose::TestBreakSignal())
return E_ABORT;
*/
return S_OK;
}
HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti)
{
MT_LOCK
if (StdOutMode)
return S_OK;
if(isAnti)
m_PercentPrinter.PrintString("Anti item ");
else
m_PercentPrinter.PrintString("Compressing ");
if (name[0] == 0)
name = kEmptyFileAlias;
m_PercentPrinter.PrintString(name);
if (EnablePercents)
m_PercentPrinter.RePrintRatio();
return S_OK;
}
HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError)
{
MT_LOCK
FailedCodes.Add(systemError);
FailedFiles.Add(name);
// if (systemError == ERROR_SHARING_VIOLATION)
{
m_PercentPrinter.ClosePrint();
m_PercentPrinter.PrintNewLine();
m_PercentPrinter.PrintString("WARNING: ");
m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
return S_FALSE;
}
// return systemError;
}
HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 )
{
m_NeedBeClosed = true;
m_NeedNewLine = true;
return S_OK;
}
HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
{
if (!PasswordIsDefined)
{
if (AskPassword)
{
Password = GetPassword(OutStream);
PasswordIsDefined = true;
}
}
*passwordIsDefined = BoolToInt(PasswordIsDefined);
CMyComBSTR tempName(Password);
*password = tempName.Detach();
return S_OK;
}

View file

@ -0,0 +1,58 @@
// UpdateCallbackConsole.h
#ifndef __UPDATECALLBACKCONSOLE_H
#define __UPDATECALLBACKCONSOLE_H
#include "Common/MyString.h"
#include "Common/StdOutStream.h"
#include "PercentPrinter.h"
#include "../Common/Update.h"
class CUpdateCallbackConsole: public IUpdateCallbackUI2
{
CPercentPrinter m_PercentPrinter;
bool m_NeedBeClosed;
bool m_NeedNewLine;
bool m_WarningsMode;
CStdOutStream *OutStream;
public:
bool EnablePercents;
bool StdOutMode;
bool PasswordIsDefined;
UString Password;
bool AskPassword;
CUpdateCallbackConsole():
m_PercentPrinter(1 << 16),
PasswordIsDefined(false),
AskPassword(false),
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;
}
INTERFACE_IUpdateCallbackUI2(;)
UStringVector FailedFiles;
CRecordVector<HRESULT> FailedCodes;
UStringVector CantFindFiles;
CRecordVector<HRESULT> CantFindCodes;
};
#endif

View file

@ -0,0 +1,58 @@
// UserInputUtils.cpp
#include "StdAfx.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 kAutoRename = 'U';
static const char kQuit = 'Q';
static const char *kFirstQuestionMessage = "?\n";
static const char *kHelpQuestionMessage =
"(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename / (Q)uit? ";
// return true if pressed Quite;
// in: anAll
// out: anAll, anYes;
NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
{
(*outStream) << kFirstQuestionMessage;
for(;;)
{
(*outStream) << kHelpQuestionMessage;
AString scannedString = g_StdIn.ScanStringUntilNewLine();
scannedString.Trim();
if(!scannedString.IsEmpty())
switch(::MyCharUpper(scannedString[0]))
{
case kYes:
return NUserAnswerMode::kYes;
case kNo:
return NUserAnswerMode::kNo;
case kYesAll:
return NUserAnswerMode::kYesAll;
case kNoAll:
return NUserAnswerMode::kNoAll;
case kAutoRename:
return NUserAnswerMode::kAutoRename;
case kQuit:
return NUserAnswerMode::kQuit;
}
}
}
UString GetPassword(CStdOutStream *outStream)
{
(*outStream) << "\nEnter password:";
outStream->Flush();
AString oemPassword = g_StdIn.ScanStringUntilNewLine();
return MultiByteToUnicodeString(oemPassword, CP_OEMCP);
}

View file

@ -0,0 +1,24 @@
// UserInputUtils.h
#ifndef __USERINPUTUTILS_H
#define __USERINPUTUTILS_H
#include "Common/StdOutStream.h"
namespace NUserAnswerMode {
enum EEnum
{
kYes,
kNo,
kYesAll,
kNoAll,
kAutoRename,
kQuit
};
}
NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream);
UString GetPassword(CStdOutStream *outStream);
#endif

View file

@ -0,0 +1 @@
#include <winresrc.h>