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