xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/GUI/GUI.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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