summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/win/CPP/7zip/UI/Common/CompressCall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/UI/Common/CompressCall.cpp')
-rw-r--r--src/libs/7zip/win/CPP/7zip/UI/Common/CompressCall.cpp246
1 files changed, 246 insertions, 0 deletions
diff --git a/src/libs/7zip/win/CPP/7zip/UI/Common/CompressCall.cpp b/src/libs/7zip/win/CPP/7zip/UI/Common/CompressCall.cpp
new file mode 100644
index 000000000..c2685f798
--- /dev/null
+++ b/src/libs/7zip/win/CPP/7zip/UI/Common/CompressCall.cpp
@@ -0,0 +1,246 @@
+// CompressCall.cpp
+
+#include "StdAfx.h"
+
+#include "Common/IntToString.h"
+#include "Common/MyCom.h"
+#include "Common/Random.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileMapping.h"
+#include "Windows/Process.h"
+#include "Windows/Synchronization.h"
+
+#include "../FileManager/ProgramLocation.h"
+#include "../FileManager/RegistryUtils.h"
+
+#include "CompressCall.h"
+
+using namespace NWindows;
+
+#define MY_TRY_BEGIN try {
+#define MY_TRY_FINISH } \
+ catch(...) { ErrorMessageHRESULT(E_FAIL); return E_FAIL; }
+
+static LPCWSTR kShowDialogSwitch = L" -ad";
+static LPCWSTR kEmailSwitch = L" -seml.";
+static LPCWSTR kIncludeSwitch = L" -i";
+static LPCWSTR kArchiveTypeSwitch = L" -t";
+static LPCWSTR kArcIncludeSwitches = L" -an -ai";
+static LPCWSTR kStopSwitchParsing = L" --";
+static LPCWSTR kLargePagesDisable = L" -slp-";
+
+UString GetQuotedString(const UString &s)
+{
+ return UString(L'\"') + s + UString(L'\"');
+}
+static void ErrorMessage(LPCWSTR message)
+{
+ MessageBoxW(g_HWND, message, L"7-Zip", MB_ICONERROR | MB_OK);
+}
+
+static void ErrorMessageHRESULT(HRESULT res, LPCWSTR s = NULL)
+{
+ UString s2 = HResultToMessage(res);
+ if (s)
+ {
+ s2 += L'\n';
+ s2 += s;
+ }
+ ErrorMessage(s2);
+}
+
+static HRESULT MyCreateProcess(LPCWSTR imageName, const UString &params,
+ LPCWSTR curDir, bool waitFinish,
+ NSynchronization::CBaseEvent *event)
+{
+ CProcess process;
+ WRes res = process.Create(imageName, params, curDir);
+ if (res != 0)
+ {
+ ErrorMessageHRESULT(res, imageName);
+ return res;
+ }
+ if (waitFinish)
+ process.Wait();
+ else if (event != NULL)
+ {
+ HANDLE handles[] = { process, *event };
+ ::WaitForMultipleObjects(sizeof(handles) / sizeof(handles[0]), handles, FALSE, INFINITE);
+ }
+ return S_OK;
+}
+
+static void AddLagePagesSwitch(UString &params)
+{
+ if (!ReadLockMemoryEnable())
+ params += kLargePagesDisable;
+}
+
+static UString Get7zGuiPath()
+{
+ UString path;
+ GetProgramFolderPath(path);
+ return path + L"7zG.exe";
+}
+
+class CRandNameGenerator
+{
+ CRandom _random;
+public:
+ CRandNameGenerator() { _random.Init(); }
+ UString GenerateName()
+ {
+ wchar_t temp[16];
+ ConvertUInt32ToString((UInt32)_random.Generate(), temp);
+ return temp;
+ }
+};
+
+static HRESULT CreateMap(const UStringVector &names,
+ CFileMapping &fileMapping, NSynchronization::CManualResetEvent &event,
+ UString &params)
+{
+ UInt32 totalSize = 1;
+ for (int i = 0; i < names.Size(); i++)
+ totalSize += (names[i].Length() + 1);
+ totalSize *= sizeof(wchar_t);
+
+ CRandNameGenerator random;
+
+ UString mappingName;
+ for (;;)
+ {
+ mappingName = L"7zMap" + random.GenerateName();
+
+ WRes res = fileMapping.Create(PAGE_READWRITE, totalSize, GetSystemString(mappingName));
+ if (fileMapping.IsCreated() && res == 0)
+ break;
+ if (res != ERROR_ALREADY_EXISTS)
+ return res;
+ fileMapping.Close();
+ }
+
+ UString eventName;
+ for (;;)
+ {
+ eventName = L"7zEvent" + random.GenerateName();
+ WRes res = event.CreateWithName(false, GetSystemString(eventName));
+ if (event.IsCreated() && res == 0)
+ break;
+ if (res != ERROR_ALREADY_EXISTS)
+ return res;
+ event.Close();
+ }
+
+ params += L'#';
+ params += mappingName;
+ params += L':';
+ wchar_t temp[16];
+ ConvertUInt32ToString(totalSize, temp);
+ params += temp;
+
+ params += L':';
+ params += eventName;
+
+ LPVOID data = fileMapping.Map(FILE_MAP_WRITE, 0, totalSize);
+ if (data == NULL)
+ return E_FAIL;
+ CFileUnmapper unmapper(data);
+ {
+ wchar_t *cur = (wchar_t *)data;
+ *cur++ = 0;
+ for (int i = 0; i < names.Size(); i++)
+ {
+ const UString &s = names[i];
+ int len = s.Length() + 1;
+ memcpy(cur, (const wchar_t *)s, len * sizeof(wchar_t));
+ cur += len;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CompressFiles(
+ const UString &arcPathPrefix,
+ const UString &arcName,
+ const UString &arcType,
+ const UStringVector &names,
+ bool email, bool showDialog, bool waitFinish)
+{
+ MY_TRY_BEGIN
+ UString params = L'a';
+
+ CFileMapping fileMapping;
+ NSynchronization::CManualResetEvent event;
+ params += kIncludeSwitch;
+ RINOK(CreateMap(names, fileMapping, event, params));
+
+ if (!arcType.IsEmpty())
+ {
+ params += kArchiveTypeSwitch;
+ params += arcType;
+ }
+
+ if (email)
+ params += kEmailSwitch;
+
+ if (showDialog)
+ params += kShowDialogSwitch;
+
+ AddLagePagesSwitch(params);
+
+ params += kStopSwitchParsing;
+ params += L' ';
+
+ params += GetQuotedString(
+ #ifdef UNDER_CE
+ arcPathPrefix +
+ #endif
+ arcName);
+
+ return MyCreateProcess(Get7zGuiPath(), params,
+ (arcPathPrefix.IsEmpty()? 0: (LPCWSTR)arcPathPrefix), waitFinish, &event);
+ MY_TRY_FINISH
+}
+
+static HRESULT ExtractGroupCommand(const UStringVector &arcPaths, UString &params)
+{
+ AddLagePagesSwitch(params);
+ params += kArcIncludeSwitches;
+ CFileMapping fileMapping;
+ NSynchronization::CManualResetEvent event;
+ RINOK(CreateMap(arcPaths, fileMapping, event, params));
+ return MyCreateProcess(Get7zGuiPath(), params, 0, false, &event);
+}
+
+HRESULT ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog)
+{
+ MY_TRY_BEGIN
+ UString params = L'x';
+ if (!outFolder.IsEmpty())
+ {
+ params += L" -o";
+ params += GetQuotedString(outFolder);
+ }
+ if (showDialog)
+ params += kShowDialogSwitch;
+ return ExtractGroupCommand(arcPaths, params);
+ MY_TRY_FINISH
+}
+
+HRESULT TestArchives(const UStringVector &arcPaths)
+{
+ MY_TRY_BEGIN
+ UString params = L't';
+ return ExtractGroupCommand(arcPaths, params);
+ MY_TRY_FINISH
+}
+
+HRESULT Benchmark()
+{
+ MY_TRY_BEGIN
+ return MyCreateProcess(Get7zGuiPath(), L'b', 0, false, NULL);
+ MY_TRY_FINISH
+}