Files
easy7zip/7zip/UI/GUI/GUI.cpp
Igor Pavlov 8c1b5c7b7e 3.13
2016-05-28 00:15:41 +01:00

362 lines
9.1 KiB
C++
Executable File

// GUI.cpp
#include "StdAfx.h"
#include <initguid.h>
#include "Common/NewHandler.h"
#include "Common/StringConvert.h"
#include "Common/CommandLineParser.h"
#include "Windows/COM.h"
#include "Windows/FileMapping.h"
#include "Windows/FileDir.h"
#include "Windows/Synchronization.h"
#include "Windows/FileName.h"
#include "../../IStream.h"
#include "../../IPassword.h"
// #include "../../Compress/Interface/CompressInterface.h"
// #include "../../FileManager/FolderInterface.h"
#include "../../FileManager/StringUtils.h"
#include "../Resource/Extract/resource.h"
#include "../Agent/Agent.h"
// #include "../Common/FolderArchiveInterface.h"
#include "../Explorer/MyMessages.h"
#include "Test.h"
#include "Extract.h"
#include "Compress.h"
using namespace NWindows;
using namespace NCommandLineParser;
HINSTANCE g_hInstance;
static const int kNumSwitches = 5;
namespace NKey {
enum Enum
{
// kHelp1 = 0,
// kHelp2,
// kDisablePercents,
kArchiveType,
// kYes,
// kPassword,
// kProperty,
kOutputDir,
// kWorkingDir,
kInclude,
// kExclude,
// kUpdate,
// kRecursed,
// kSfx,
// kOverwrite,
kEmail,
kShowDialog
// kMap
};
}
static const int kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
static const int kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
static const wchar_t *kRecursedPostCharSet = L"0-";
static const wchar_t *kOverwritePostCharSet = L"asut";
static const CSwitchForm kSwitchForms[kNumSwitches] =
{
// { L"?", NSwitchType::kSimple, false },
// { L"H", NSwitchType::kSimple, false },
// { L"BD", NSwitchType::kSimple, false },
{ L"T", NSwitchType::kUnLimitedPostString, false, 1 },
// { L"Y", NSwitchType::kSimple, false },
// { L"P", NSwitchType::kUnLimitedPostString, false, 0 },
// { L"M", NSwitchType::kUnLimitedPostString, true, 1 },
{ L"O", NSwitchType::kUnLimitedPostString, false, 1 },
// { L"W", NSwitchType::kUnLimitedPostString, false, 0 },
{ L"I", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
// { L"X", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
// { L"U", NSwitchType::kUnLimitedPostString, true, 1},
// { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet },
// { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 },
// { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet},
{ L"SEML", NSwitchType::kSimple, false },
{ L"AD", NSwitchType::kSimple, false }
// { L"MAP=", NSwitchType::kUnLimitedPostString, false, 1 }
};
static bool inline IsItWindowsNT()
{
OSVERSIONINFO versionInfo;
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
if (!::GetVersionEx(&versionInfo))
return false;
return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
static void MyMessageBoxError(const char *message)
{
::MessageBoxA(0, message, "Error", 0);
}
static wchar_t *kIncorrectCommandMessage = L"Incorrect command";
static void ErrorMessage(const wchar_t *message)
{
MessageBoxW(0, message, L"7-Zip GUI", MB_ICONERROR);
}
static bool ParseIncludeMap(const UString &switchParam, UStringVector &fileNames)
{
int splitPos = switchParam.Find(L':');
if (splitPos < 0)
{
ErrorMessage(L"Bad switch");
return false;
}
UString mappingName = switchParam.Left(splitPos);
UString switchParam2 = switchParam.Mid(splitPos + 1);
splitPos = switchParam2.Find(L':');
if (splitPos < 0)
{
ErrorMessage(L"Bad switch");
return false;
}
UString mappingSize = switchParam2.Left(splitPos);
UString eventName = switchParam2.Mid(splitPos + 1);
wchar_t *endptr;
UINT32 dataSize = wcstoul(mappingSize, &endptr, 10);
{
CFileMapping fileMapping;
if (!fileMapping.Open(FILE_MAP_READ, false,
GetSystemString(mappingName)))
{
// ShowLastErrorMessage(0);
ErrorMessage(L"Can not open mapping");
return false;
}
LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_READ, 0, dataSize);
if (data == NULL)
{
ErrorMessage(L"MapViewOfFile error");
return false;
}
try
{
const wchar_t *curData = (const wchar_t *)data;
if (*curData != 0)
{
ErrorMessage(L"Incorrect mapping data");
return false;
}
UINT32 numChars = dataSize /2;
UString name;
for (int i = 1; i < numChars; i++)
{
wchar_t c = curData[i];
if (c == L'\0')
{
fileNames.Add(name);
name.Empty();
}
else
name += c;
}
if (!name.IsEmpty())
{
ErrorMessage(L"data error");
return false;
}
}
catch(...)
{
UnmapViewOfFile(data);
throw;
}
UnmapViewOfFile(data);
}
{
NSynchronization::CEvent event;
event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName));
event.Set();
}
return true;
}
static bool ParseIncludeSwitches(CParser &parser, UStringVector &fileNames)
{
if (parser[NKey::kInclude].ThereIs)
{
for (int i = 0; i < parser[NKey::kInclude].PostStrings.Size(); i++)
{
UString switchParam = parser[NKey::kInclude].PostStrings[i];
if (switchParam.Length() < 1)
return false;
if (switchParam[0] == L'#')
{
if (!ParseIncludeMap(switchParam.Mid(1), fileNames))
return false;
}
else if (switchParam[0] == L'!')
{
fileNames.Add(switchParam.Mid(1));
}
else
{
ErrorMessage(L"Incorrect command");
return false;
}
}
}
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
for (int i = 2; i < nonSwitchStrings.Size(); i++)
{
// ErrorMessage(nonSwitchStrings[i]);
fileNames.Add(nonSwitchStrings[i]);
}
return true;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
g_hInstance = hInstance;
InitCommonControls();
#ifdef UNICODE
if (!IsItWindowsNT())
{
// g_StdOut << "This program requires Windows NT/2000/XP";
return 0;
}
#endif
// setlocale(LC_COLLATE, ".ACP");
int result = 0;
try
{
UStringVector commandStrings;
SplitCommandLine(GetCommandLineW(), commandStrings);
if (commandStrings.Size() > 0)
commandStrings.Delete(0);
CParser parser(kNumSwitches);
try
{
parser.ParseStrings(kSwitchForms, commandStrings);
}
catch(...)
{
MyMessageBox(kIncorrectCommandMessage);
return 1;
}
const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
int numNonSwitchStrings = nonSwitchStrings.Size();
if(numNonSwitchStrings < 1)
{
MyMessageBox(kIncorrectCommandMessage);
return 1;
}
UString command = nonSwitchStrings[0];
if (command == L"t")
{
if(numNonSwitchStrings < 2)
{
MyMessageBox(kIncorrectCommandMessage);
return 1;
}
UString archiveName = nonSwitchStrings[1];
HRESULT result = TestArchive(0, archiveName);
if (result == S_FALSE)
MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604);
else if (result != S_OK)
ShowErrorMessage(0, result);
}
else if (command == L"x")
{
if(numNonSwitchStrings < 2)
{
MyMessageBox(kIncorrectCommandMessage);
return 1;
}
UString archiveName = nonSwitchStrings[1];
UString outputDir;
bool outputDirDefined = parser[NKey::kOutputDir].ThereIs;
if(outputDirDefined)
outputDir = parser[NKey::kOutputDir].PostStrings[0];
else
NFile::NDirectory::MyGetCurrentDirectory(outputDir);
NFile::NName::NormalizeDirPathPrefix(outputDir);
HRESULT result = ExtractArchive(0, archiveName,
false, parser[NKey::kShowDialog].ThereIs, outputDir);
if (result == S_FALSE)
MyMessageBox(IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, 0x02000604);
else if (result != S_OK)
ShowErrorMessage(0, result);
}
else if (command == L"a")
{
if(numNonSwitchStrings < 2)
{
MyMessageBox(kIncorrectCommandMessage);
return 1;
}
const UString &archiveName = nonSwitchStrings[1];
UString mapString, emailString;
bool emailMode = parser[NKey::kEmail].ThereIs;
UStringVector fileNames;
if (!ParseIncludeSwitches(parser, fileNames))
return 1;
if (fileNames.Size() == 0)
{
ErrorMessage(L"Incorrect command: No files");
return 1;
}
UString archiveType = L"7z";;
if (parser[NKey::kArchiveType].ThereIs)
archiveType = parser[NKey::kArchiveType].PostStrings.Front();
HRESULT result = CompressArchive(archiveName, fileNames,
archiveType, emailMode, parser[NKey::kShowDialog].ThereIs);
// if (result != S_OK)
// ShowErrorMessage(result);
}
else
{
ErrorMessage(L"Use correct command");
return 0;
}
return 0;
}
catch(const CNewException &)
{
// MyMessageBoxError(kMemoryExceptionMessage);
return 1;
}
catch(...)
{
// g_StdOut << kUnknownExceptionMessage;
return 2;
}
return result;
}