xref: /aosp_15_r20/external/lzma/CPP/7zip/Bundles/SFXWin/SfxWin.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // Main.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../Common/MyWindows.h"
6 
7 #if defined(__MINGW32__) || defined(__MINGW64__)
8 #include <shlwapi.h>
9 #else
10 #include <Shlwapi.h>
11 #endif
12 
13 #include "../../../../C/DllSecur.h"
14 
15 #include "../../../Common/MyInitGuid.h"
16 
17 #include "../../../Common/CommandLineParser.h"
18 #include "../../../Common/StringConvert.h"
19 
20 #include "../../../Windows/DLL.h"
21 #include "../../../Windows/ErrorMsg.h"
22 #include "../../../Windows/FileDir.h"
23 #include "../../../Windows/FileName.h"
24 #include "../../../Windows/NtCheck.h"
25 #include "../../../Windows/ResourceString.h"
26 
27 #include "../../ICoder.h"
28 #include "../../IPassword.h"
29 #include "../../Archive/IArchive.h"
30 #include "../../UI/Common/Extract.h"
31 #include "../../UI/Common/ExitCode.h"
32 #include "../../UI/Explorer/MyMessages.h"
33 #include "../../UI/FileManager/MyWindowsNew.h"
34 #include "../../UI/GUI/ExtractGUI.h"
35 #include "../../UI/GUI/ExtractRes.h"
36 
37 using namespace NWindows;
38 using namespace NFile;
39 using namespace NDir;
40 
41 extern
42 HINSTANCE g_hInstance;
43 HINSTANCE g_hInstance;
44 extern
45 bool g_DisableUserQuestions;
46 bool g_DisableUserQuestions;
47 
48 #ifndef UNDER_CE
49 
50 #if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // win2000
51 #define Z7_USE_DYN_ComCtl32Version
52 #endif
53 
54 #ifdef Z7_USE_DYN_ComCtl32Version
55 Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
56 
GetDllVersion(LPCTSTR dllName)57 static DWORD GetDllVersion(LPCTSTR dllName)
58 {
59   DWORD dwVersion = 0;
60   const HINSTANCE hinstDll = LoadLibrary(dllName);
61   if (hinstDll)
62   {
63     const
64     DLLGETVERSIONPROC func_DllGetVersion = Z7_GET_PROC_ADDRESS(
65     DLLGETVERSIONPROC, hinstDll, "DllGetVersion");
66     if (func_DllGetVersion)
67     {
68       DLLVERSIONINFO dvi;
69       ZeroMemory(&dvi, sizeof(dvi));
70       dvi.cbSize = sizeof(dvi);
71       const HRESULT hr = func_DllGetVersion(&dvi);
72       if (SUCCEEDED(hr))
73         dwVersion = (DWORD)MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion);
74     }
75     FreeLibrary(hinstDll);
76   }
77   return dwVersion;
78 }
79 
80 #endif
81 #endif
82 
83 extern
84 bool g_LVN_ITEMACTIVATE_Support;
85 bool g_LVN_ITEMACTIVATE_Support = true;
86 
87 static const wchar_t * const kUnknownExceptionMessage = L"ERROR: Unknown Error!";
88 
ErrorMessageForHRESULT(HRESULT res)89 static void ErrorMessageForHRESULT(HRESULT res)
90 {
91   ShowErrorMessage(HResultToMessage(res));
92 }
93 
WinMain2()94 static int APIENTRY WinMain2()
95 {
96   // OleInitialize is required for ProgressBar in TaskBar.
97 #ifndef UNDER_CE
98   OleInitialize(NULL);
99 #endif
100 
101 #ifndef UNDER_CE
102 #ifdef Z7_USE_DYN_ComCtl32Version
103   {
104     const DWORD g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll"));
105     g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4));
106   }
107 #endif
108 #endif
109 
110   UString password;
111   bool assumeYes = false;
112   bool outputFolderDefined = false;
113   FString outputFolder;
114   UStringVector commandStrings;
115   NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
116 
117   #ifndef UNDER_CE
118   if (commandStrings.Size() > 0)
119     commandStrings.Delete(0);
120   #endif
121 
122   FOR_VECTOR (i, commandStrings)
123   {
124     const UString &s = commandStrings[i];
125     if (s.Len() > 1 && s[0] == '-')
126     {
127       const wchar_t c = MyCharLower_Ascii(s[1]);
128       if (c == 'y')
129       {
130         assumeYes = true;
131         if (s.Len() != 2)
132         {
133           ShowErrorMessage(L"Bad command");
134           return 1;
135         }
136       }
137       else if (c == 'o')
138       {
139         outputFolder = us2fs(s.Ptr(2));
140         NName::NormalizeDirPathPrefix(outputFolder);
141         outputFolderDefined = !outputFolder.IsEmpty();
142       }
143       else if (c == 'p')
144       {
145         password = s.Ptr(2);
146       }
147     }
148   }
149 
150   g_DisableUserQuestions = assumeYes;
151 
152   FString path;
153   NDLL::MyGetModuleFileName(path);
154 
155   FString fullPath;
156   if (!MyGetFullPathName(path, fullPath))
157   {
158     ShowErrorMessage(L"Error 1329484");
159     return 1;
160   }
161 
162   CCodecs *codecs = new CCodecs;
163   CMyComPtr<IUnknown> compressCodecsInfo = codecs;
164   HRESULT result = codecs->Load();
165   if (result != S_OK)
166   {
167     ErrorMessageForHRESULT(result);
168     return 1;
169   }
170 
171   // COpenCallbackGUI openCallback;
172 
173   // openCallback.PasswordIsDefined = !password.IsEmpty();
174   // openCallback.Password = password;
175 
176   CExtractCallbackImp *ecs = new CExtractCallbackImp;
177   CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
178   ecs->Init();
179 
180   #ifndef Z7_NO_CRYPTO
181   ecs->PasswordIsDefined = !password.IsEmpty();
182   ecs->Password = password;
183   #endif
184 
185   CExtractOptions eo;
186 
187   FString dirPrefix;
188   if (!GetOnlyDirPrefix(path, dirPrefix))
189   {
190     ShowErrorMessage(L"Error 1329485");
191     return 1;
192   }
193 
194   eo.OutputDir = outputFolderDefined ? outputFolder : dirPrefix;
195   eo.YesToAll = assumeYes;
196   eo.OverwriteMode = assumeYes ?
197       NExtract::NOverwriteMode::kOverwrite :
198       NExtract::NOverwriteMode::kAsk;
199   eo.PathMode = NExtract::NPathMode::kFullPaths;
200   eo.TestMode = false;
201 
202   UStringVector v1, v2;
203   v1.Add(fs2us(fullPath));
204   v2.Add(fs2us(fullPath));
205   NWildcard::CCensorNode wildcardCensor;
206   wildcardCensor.Add_Wildcard();
207 
208   bool messageWasDisplayed = false;
209   result = ExtractGUI(codecs,
210       CObjectVector<COpenType>(), CIntVector(),
211       v1, v2,
212       wildcardCensor, eo, (assumeYes ? false: true), messageWasDisplayed, ecs);
213 
214   if (result == S_OK)
215   {
216     if (!ecs->IsOK())
217       return NExitCode::kFatalError;
218     return 0;
219   }
220   if (result == E_ABORT)
221     return NExitCode::kUserBreak;
222   if (!messageWasDisplayed)
223   {
224     if (result == S_FALSE)
225       ShowErrorMessage(L"Error in archive");
226     else
227       ErrorMessageForHRESULT(result);
228   }
229   if (result == E_OUTOFMEMORY)
230     return NExitCode::kMemoryError;
231   return NExitCode::kFatalError;
232 }
233 
234 #if defined(_WIN32) && defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
235 #define NT_CHECK_FAIL_ACTION ShowErrorMessage(L"Unsupported Windows version"); return NExitCode::kFatalError;
236 #endif
237 
WinMain(HINSTANCE hInstance,HINSTANCE,LPWSTR,int)238 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
239   #ifdef UNDER_CE
240   LPWSTR
241   #else
242   LPSTR
243   #endif
244   /* lpCmdLine */, int /* nCmdShow */)
245 {
246   g_hInstance = (HINSTANCE)hInstance;
247 
248   NT_CHECK
249 
250   try
251   {
252     #ifdef _WIN32
253     LoadSecurityDlls();
254     #endif
255 
256     return WinMain2();
257   }
258   catch(const CNewException &)
259   {
260     ErrorMessageForHRESULT(E_OUTOFMEMORY);
261     return NExitCode::kMemoryError;
262   }
263   catch(...)
264   {
265     ShowErrorMessage(kUnknownExceptionMessage);
266     return NExitCode::kFatalError;
267   }
268 }
269