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