5 #include "Common/IntToString.h"
\r
6 #include "Common/MyCom.h"
\r
7 #include "Common/Random.h"
\r
8 #include "Common/StringConvert.h"
\r
10 #include "Windows/FileDir.h"
\r
11 #include "Windows/FileMapping.h"
\r
12 #include "Windows/Process.h"
\r
13 #include "Windows/Synchronization.h"
\r
15 #include "../FileManager/ProgramLocation.h"
\r
16 #include "../FileManager/RegistryUtils.h"
\r
18 #include "CompressCall.h"
\r
20 using namespace NWindows;
\r
22 #define MY_TRY_BEGIN try {
\r
23 #define MY_TRY_FINISH } \
\r
24 catch(...) { ErrorMessageHRESULT(E_FAIL); return E_FAIL; }
\r
26 static LPCWSTR kShowDialogSwitch = L" -ad";
\r
27 static LPCWSTR kEmailSwitch = L" -seml.";
\r
28 static LPCWSTR kIncludeSwitch = L" -i";
\r
29 static LPCWSTR kArchiveTypeSwitch = L" -t";
\r
30 static LPCWSTR kArcIncludeSwitches = L" -an -ai";
\r
31 static LPCWSTR kStopSwitchParsing = L" --";
\r
32 static LPCWSTR kLargePagesDisable = L" -slp-";
\r
34 UString GetQuotedString(const UString &s)
\r
36 return UString(L'\"') + s + UString(L'\"');
\r
38 static void ErrorMessage(LPCWSTR message)
\r
40 MessageBoxW(g_HWND, message, L"7-Zip", MB_ICONERROR | MB_OK);
\r
43 static void ErrorMessageHRESULT(HRESULT res, LPCWSTR s = NULL)
\r
45 UString s2 = HResultToMessage(res);
\r
54 static HRESULT MyCreateProcess(LPCWSTR imageName, const UString ¶ms,
\r
55 LPCWSTR curDir, bool waitFinish,
\r
56 NSynchronization::CBaseEvent *event)
\r
59 WRes res = process.Create(imageName, params, curDir);
\r
62 ErrorMessageHRESULT(res, imageName);
\r
67 else if (event != NULL)
\r
69 HANDLE handles[] = { process, *event };
\r
70 ::WaitForMultipleObjects(sizeof(handles) / sizeof(handles[0]), handles, FALSE, INFINITE);
\r
75 static void AddLagePagesSwitch(UString ¶ms)
\r
77 if (!ReadLockMemoryEnable())
\r
78 params += kLargePagesDisable;
\r
81 static UString Get7zGuiPath()
\r
84 GetProgramFolderPath(path);
\r
85 return path + L"7zG.exe";
\r
88 class CRandNameGenerator
\r
92 CRandNameGenerator() { _random.Init(); }
\r
93 UString GenerateName()
\r
96 ConvertUInt32ToString((UInt32)_random.Generate(), temp);
\r
101 static HRESULT CreateMap(const UStringVector &names,
\r
102 CFileMapping &fileMapping, NSynchronization::CManualResetEvent &event,
\r
105 UInt32 totalSize = 1;
\r
106 for (int i = 0; i < names.Size(); i++)
\r
107 totalSize += (names[i].Length() + 1);
\r
108 totalSize *= sizeof(wchar_t);
\r
110 CRandNameGenerator random;
\r
112 UString mappingName;
\r
115 mappingName = L"7zMap" + random.GenerateName();
\r
117 WRes res = fileMapping.Create(PAGE_READWRITE, totalSize, GetSystemString(mappingName));
\r
118 if (fileMapping.IsCreated() && res == 0)
\r
120 if (res != ERROR_ALREADY_EXISTS)
\r
122 fileMapping.Close();
\r
128 eventName = L"7zEvent" + random.GenerateName();
\r
129 WRes res = event.CreateWithName(false, GetSystemString(eventName));
\r
130 if (event.IsCreated() && res == 0)
\r
132 if (res != ERROR_ALREADY_EXISTS)
\r
138 params += mappingName;
\r
141 ConvertUInt32ToString(totalSize, temp);
\r
145 params += eventName;
\r
147 LPVOID data = fileMapping.Map(FILE_MAP_WRITE, 0, totalSize);
\r
150 CFileUnmapper unmapper(data);
\r
152 wchar_t *cur = (wchar_t *)data;
\r
154 for (int i = 0; i < names.Size(); i++)
\r
156 const UString &s = names[i];
\r
157 int len = s.Length() + 1;
\r
158 memcpy(cur, (const wchar_t *)s, len * sizeof(wchar_t));
\r
165 HRESULT CompressFiles(
\r
166 const UString &arcPathPrefix,
\r
167 const UString &arcName,
\r
168 const UString &arcType,
\r
169 const UStringVector &names,
\r
170 bool email, bool showDialog, bool waitFinish)
\r
173 UString params = L'a';
\r
175 CFileMapping fileMapping;
\r
176 NSynchronization::CManualResetEvent event;
\r
177 params += kIncludeSwitch;
\r
178 RINOK(CreateMap(names, fileMapping, event, params));
\r
180 if (!arcType.IsEmpty())
\r
182 params += kArchiveTypeSwitch;
\r
187 params += kEmailSwitch;
\r
190 params += kShowDialogSwitch;
\r
192 AddLagePagesSwitch(params);
\r
194 params += kStopSwitchParsing;
\r
197 params += GetQuotedString(
\r
203 return MyCreateProcess(Get7zGuiPath(), params,
\r
204 (arcPathPrefix.IsEmpty()? 0: (LPCWSTR)arcPathPrefix), waitFinish, &event);
\r
208 static HRESULT ExtractGroupCommand(const UStringVector &arcPaths, UString ¶ms)
\r
210 AddLagePagesSwitch(params);
\r
211 params += kArcIncludeSwitches;
\r
212 CFileMapping fileMapping;
\r
213 NSynchronization::CManualResetEvent event;
\r
214 RINOK(CreateMap(arcPaths, fileMapping, event, params));
\r
215 return MyCreateProcess(Get7zGuiPath(), params, 0, false, &event);
\r
218 HRESULT ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog)
\r
221 UString params = L'x';
\r
222 if (!outFolder.IsEmpty())
\r
225 params += GetQuotedString(outFolder);
\r
228 params += kShowDialogSwitch;
\r
229 return ExtractGroupCommand(arcPaths, params);
\r
233 HRESULT TestArchives(const UStringVector &arcPaths)
\r
236 UString params = L't';
\r
237 return ExtractGroupCommand(arcPaths, params);
\r
241 HRESULT Benchmark()
\r
244 return MyCreateProcess(Get7zGuiPath(), L'b', 0, false, NULL);
\r