1 // GUI.cpp
2
3 #include "StdAfx.h"
4
5 #ifdef _WIN32
6 #include "../../../../C/DllSecur.h"
7 #endif
8
9 #include "../../../Common/MyWindows.h"
10
11 #include <Shlwapi.h>
12
13 #include "../../../Common/MyInitGuid.h"
14
15 #include "../../../Common/CommandLineParser.h"
16 #include "../../../Common/MyException.h"
17 #include "../../../Common/StringConvert.h"
18
19 #include "../../../Windows/FileDir.h"
20 #include "../../../Windows/NtCheck.h"
21
22 #include "../Common/ArchiveCommandLine.h"
23 #include "../Common/ExitCode.h"
24
25 #include "../FileManager/StringUtils.h"
26 #include "../FileManager/MyWindowsNew.h"
27
28 #include "BenchmarkDialog.h"
29 #include "ExtractGUI.h"
30 #include "HashGUI.h"
31 #include "UpdateGUI.h"
32
33 #include "ExtractRes.h"
34
35 using namespace NWindows;
36
37 #ifdef EXTERNAL_CODECS
38 const CExternalCodecs *g_ExternalCodecs_Ptr;
39 #endif
40
41 extern
42 HINSTANCE g_hInstance;
43 HINSTANCE g_hInstance;
44
45 #ifndef UNDER_CE
46
47 extern
48 DWORD g_ComCtl32Version;
49 DWORD g_ComCtl32Version;
50
GetDllVersion(LPCTSTR dllName)51 static DWORD GetDllVersion(LPCTSTR dllName)
52 {
53 DWORD dwVersion = 0;
54 HINSTANCE hinstDll = LoadLibrary(dllName);
55 if (hinstDll)
56 {
57 DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)(void *)GetProcAddress(hinstDll, "DllGetVersion");
58 if (pDllGetVersion)
59 {
60 DLLVERSIONINFO dvi;
61 ZeroMemory(&dvi, sizeof(dvi));
62 dvi.cbSize = sizeof(dvi);
63 HRESULT hr = (*pDllGetVersion)(&dvi);
64 if (SUCCEEDED(hr))
65 dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion);
66 }
67 FreeLibrary(hinstDll);
68 }
69 return dwVersion;
70 }
71
72 #endif
73
74 extern
75 bool g_LVN_ITEMACTIVATE_Support;
76 bool g_LVN_ITEMACTIVATE_Support = true;
77
ErrorMessage(LPCWSTR message)78 static void ErrorMessage(LPCWSTR message)
79 {
80 MessageBoxW(NULL, message, L"7-Zip", MB_ICONERROR | MB_OK);
81 }
82
ErrorMessage(const char * s)83 static void ErrorMessage(const char *s)
84 {
85 ErrorMessage(GetUnicodeString(s));
86 }
87
ErrorLangMessage(UINT resourceID)88 static void ErrorLangMessage(UINT resourceID)
89 {
90 ErrorMessage(LangString(resourceID));
91 }
92
93 static const char * const kNoFormats = "7-Zip cannot find the code that works with archives.";
94
ShowMemErrorMessage()95 static int ShowMemErrorMessage()
96 {
97 ErrorLangMessage(IDS_MEM_ERROR);
98 return NExitCode::kMemoryError;
99 }
100
ShowSysErrorMessage(DWORD errorCode)101 static int ShowSysErrorMessage(DWORD errorCode)
102 {
103 if ((HRESULT)errorCode == E_OUTOFMEMORY)
104 return ShowMemErrorMessage();
105 ErrorMessage(HResultToMessage(errorCode));
106 return NExitCode::kFatalError;
107 }
108
ThrowException_if_Error(HRESULT res)109 static void ThrowException_if_Error(HRESULT res)
110 {
111 if (res != S_OK)
112 throw CSystemException(res);
113 }
114
Main2()115 static int Main2()
116 {
117 UStringVector commandStrings;
118 NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
119
120 #ifndef UNDER_CE
121 if (commandStrings.Size() > 0)
122 commandStrings.Delete(0);
123 #endif
124 if (commandStrings.Size() == 0)
125 {
126 MessageBoxW(0, L"Specify command", L"7-Zip", 0);
127 return 0;
128 }
129
130 CArcCmdLineOptions options;
131 CArcCmdLineParser parser;
132
133 parser.Parse1(commandStrings, options);
134 parser.Parse2(options);
135
136 CREATE_CODECS_OBJECT
137
138 codecs->CaseSensitiveChange = options.CaseSensitiveChange;
139 codecs->CaseSensitive = options.CaseSensitive;
140 ThrowException_if_Error(codecs->Load());
141 Codecs_AddHashArcHandler(codecs);
142
143 #ifdef EXTERNAL_CODECS
144 {
145 g_ExternalCodecs_Ptr = &__externalCodecs;
146 UString s;
147 codecs->GetCodecsErrorMessage(s);
148 if (!s.IsEmpty())
149 {
150 MessageBoxW(0, s, L"7-Zip", MB_ICONERROR);
151 }
152
153 }
154 #endif
155
156 const bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
157
158 if (codecs->Formats.Size() == 0 &&
159 (isExtractGroupCommand
160
161 || options.Command.IsFromUpdateGroup()))
162 {
163 #ifdef EXTERNAL_CODECS
164 if (!codecs->MainDll_ErrorPath.IsEmpty())
165 {
166 UString s ("7-Zip cannot load module: ");
167 s += fs2us(codecs->MainDll_ErrorPath);
168 throw s;
169 }
170 #endif
171 throw kNoFormats;
172 }
173
174 CObjectVector<COpenType> formatIndices;
175 if (!ParseOpenTypes(*codecs, options.ArcType, formatIndices))
176 {
177 ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE);
178 return NExitCode::kFatalError;
179 }
180
181 CIntVector excludedFormats;
182 FOR_VECTOR (k, options.ExcludedArcTypes)
183 {
184 CIntVector tempIndices;
185 if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices)
186 || tempIndices.Size() != 1)
187 {
188 ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE);
189 return NExitCode::kFatalError;
190 }
191 excludedFormats.AddToUniqueSorted(tempIndices[0]);
192 // excludedFormats.Sort();
193 }
194
195 #ifdef EXTERNAL_CODECS
196 if (isExtractGroupCommand
197 || options.Command.IsFromUpdateGroup()
198 || options.Command.CommandType == NCommandType::kHash
199 || options.Command.CommandType == NCommandType::kBenchmark)
200 ThrowException_if_Error(__externalCodecs.Load());
201 #endif
202
203 if (options.Command.CommandType == NCommandType::kBenchmark)
204 {
205 HRESULT res = Benchmark(
206 EXTERNAL_CODECS_VARS_L
207 options.Properties,
208 options.NumIterations_Defined ?
209 options.NumIterations :
210 k_NumBenchIterations_Default);
211 /*
212 if (res == S_FALSE)
213 {
214 stdStream << "\nDecoding Error\n";
215 return NExitCode::kFatalError;
216 }
217 */
218 ThrowException_if_Error(res);
219 }
220 else if (isExtractGroupCommand)
221 {
222 UStringVector ArchivePathsSorted;
223 UStringVector ArchivePathsFullSorted;
224
225 CExtractCallbackImp *ecs = new CExtractCallbackImp;
226 CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
227
228 #ifndef _NO_CRYPTO
229 ecs->PasswordIsDefined = options.PasswordEnabled;
230 ecs->Password = options.Password;
231 #endif
232
233 ecs->Init();
234
235 CExtractOptions eo;
236 (CExtractOptionsBase &)eo = options.ExtractOptions;
237 eo.StdInMode = options.StdInMode;
238 eo.StdOutMode = options.StdOutMode;
239 eo.YesToAll = options.YesToAll;
240 eo.TestMode = options.Command.IsTestCommand();
241
242 #ifndef _SFX
243 eo.Properties = options.Properties;
244 #endif
245
246 bool messageWasDisplayed = false;
247
248 #ifndef _SFX
249 CHashBundle hb;
250 CHashBundle *hb_ptr = NULL;
251
252 if (!options.HashMethods.IsEmpty())
253 {
254 hb_ptr = &hb;
255 ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods));
256 }
257 #endif
258
259 {
260 CDirItemsStat st;
261 HRESULT hresultMain = EnumerateDirItemsAndSort(
262 options.arcCensor,
263 NWildcard::k_RelatPath,
264 UString(), // addPathPrefix
265 ArchivePathsSorted,
266 ArchivePathsFullSorted,
267 st,
268 NULL // &scan: change it!!!!
269 );
270 if (hresultMain != S_OK)
271 {
272 /*
273 if (hresultMain != E_ABORT && messageWasDisplayed)
274 return NExitCode::kFatalError;
275 */
276 throw CSystemException(hresultMain);
277 }
278 }
279
280 ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1);
281
282 HRESULT result = ExtractGUI(
283 // EXTERNAL_CODECS_VARS_L
284 codecs,
285 formatIndices, excludedFormats,
286 ArchivePathsSorted,
287 ArchivePathsFullSorted,
288 options.Censor.Pairs.Front().Head,
289 eo,
290 #ifndef _SFX
291 hb_ptr,
292 #endif
293 options.ShowDialog, messageWasDisplayed, ecs);
294 if (result != S_OK)
295 {
296 if (result != E_ABORT && messageWasDisplayed)
297 return NExitCode::kFatalError;
298 throw CSystemException(result);
299 }
300 if (!ecs->IsOK())
301 return NExitCode::kFatalError;
302 }
303 else if (options.Command.IsFromUpdateGroup())
304 {
305 #ifndef _NO_CRYPTO
306 bool passwordIsDefined = options.PasswordEnabled && !options.Password.IsEmpty();
307 #endif
308
309 CUpdateCallbackGUI callback;
310 // callback.EnablePercents = options.EnablePercents;
311
312 #ifndef _NO_CRYPTO
313 callback.PasswordIsDefined = passwordIsDefined;
314 callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();
315 callback.Password = options.Password;
316 #endif
317
318 // callback.StdOutMode = options.UpdateOptions.StdOutMode;
319 callback.Init();
320
321 if (!options.UpdateOptions.InitFormatIndex(codecs, formatIndices, options.ArchiveName) ||
322 !options.UpdateOptions.SetArcPath(codecs, options.ArchiveName))
323 {
324 ErrorLangMessage(IDS_UPDATE_NOT_SUPPORTED);
325 return NExitCode::kFatalError;
326 }
327 bool messageWasDisplayed = false;
328 HRESULT result = UpdateGUI(
329 codecs, formatIndices,
330 options.ArchiveName,
331 options.Censor,
332 options.UpdateOptions,
333 options.ShowDialog,
334 messageWasDisplayed,
335 &callback);
336
337 if (result != S_OK)
338 {
339 if (result != E_ABORT && messageWasDisplayed)
340 return NExitCode::kFatalError;
341 throw CSystemException(result);
342 }
343 if (callback.FailedFiles.Size() > 0)
344 {
345 if (!messageWasDisplayed)
346 throw CSystemException(E_FAIL);
347 return NExitCode::kWarning;
348 }
349 }
350 else if (options.Command.CommandType == NCommandType::kHash)
351 {
352 bool messageWasDisplayed = false;
353 HRESULT result = HashCalcGUI(EXTERNAL_CODECS_VARS_L
354 options.Censor, options.HashOptions, messageWasDisplayed);
355
356 if (result != S_OK)
357 {
358 if (result != E_ABORT && messageWasDisplayed)
359 return NExitCode::kFatalError;
360 throw CSystemException(result);
361 }
362 /*
363 if (callback.FailedFiles.Size() > 0)
364 {
365 if (!messageWasDisplayed)
366 throw CSystemException(E_FAIL);
367 return NExitCode::kWarning;
368 }
369 */
370 }
371 else
372 {
373 throw "Unsupported command";
374 }
375 return 0;
376 }
377
378 #if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
379 #define NT_CHECK_FAIL_ACTION ErrorMessage("Unsupported Windows version"); return NExitCode::kFatalError;
380 #endif
381
WinMain(HINSTANCE hInstance,HINSTANCE,LPWSTR,int)382 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
383 #ifdef UNDER_CE
384 LPWSTR
385 #else
386 LPSTR
387 #endif
388 /* lpCmdLine */, int /* nCmdShow */)
389 {
390 g_hInstance = hInstance;
391
392 #ifdef _WIN32
393 NT_CHECK
394 #endif
395
396 InitCommonControls();
397
398 #ifndef UNDER_CE
399 g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll"));
400 g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4));
401 #endif
402
403 // OleInitialize is required for ProgressBar in TaskBar.
404 #ifndef UNDER_CE
405 OleInitialize(NULL);
406 #endif
407
408 LoadLangOneTime();
409
410 // setlocale(LC_COLLATE, ".ACP");
411 try
412 {
413 #ifdef _WIN32
414 My_SetDefaultDllDirectories();
415 #endif
416
417 return Main2();
418 }
419 catch(const CNewException &)
420 {
421 return ShowMemErrorMessage();
422 }
423 catch(const CMessagePathException &e)
424 {
425 ErrorMessage(e);
426 return NExitCode::kUserError;
427 }
428 catch(const CSystemException &systemError)
429 {
430 if (systemError.ErrorCode == E_ABORT)
431 return NExitCode::kUserBreak;
432 return ShowSysErrorMessage(systemError.ErrorCode);
433 }
434 catch(const UString &s)
435 {
436 ErrorMessage(s);
437 return NExitCode::kFatalError;
438 }
439 catch(const AString &s)
440 {
441 ErrorMessage(s);
442 return NExitCode::kFatalError;
443 }
444 catch(const wchar_t *s)
445 {
446 ErrorMessage(s);
447 return NExitCode::kFatalError;
448 }
449 catch(const char *s)
450 {
451 ErrorMessage(s);
452 return NExitCode::kFatalError;
453 }
454 catch(int v)
455 {
456 AString e ("Error: ");
457 e.Add_UInt32(v);
458 ErrorMessage(e);
459 return NExitCode::kFatalError;
460 }
461 catch(...)
462 {
463 ErrorMessage("Unknown error");
464 return NExitCode::kFatalError;
465 }
466 }
467