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
45 #ifndef UNDER_CE
46
47 static
48 DWORD g_ComCtl32Version;
49
GetDllVersion(LPCTSTR dllName)50 static DWORD GetDllVersion(LPCTSTR dllName)
51 {
52 DWORD dwVersion = 0;
53 const HINSTANCE hinstDll = LoadLibrary(dllName);
54 if (hinstDll)
55 {
56 const
57 DLLGETVERSIONPROC func_DllGetVersion = Z7_GET_PROC_ADDRESS(
58 DLLGETVERSIONPROC, hinstDll, "DllGetVersion");
59 if (func_DllGetVersion)
60 {
61 DLLVERSIONINFO dvi;
62 ZeroMemory(&dvi, sizeof(dvi));
63 dvi.cbSize = sizeof(dvi);
64 const HRESULT hr = func_DllGetVersion(&dvi);
65 if (SUCCEEDED(hr))
66 dwVersion = (DWORD)MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion);
67 }
68 FreeLibrary(hinstDll);
69 }
70 return dwVersion;
71 }
72
73 #endif
74
75 extern
76 bool g_LVN_ITEMACTIVATE_Support;
77 bool g_LVN_ITEMACTIVATE_Support = true;
78
79 static const wchar_t * const kUnknownExceptionMessage = L"ERROR: Unknown Error!";
80
ErrorMessageForHRESULT(HRESULT res)81 static void ErrorMessageForHRESULT(HRESULT res)
82 {
83 ShowErrorMessage(HResultToMessage(res));
84 }
85
WinMain2()86 static int APIENTRY WinMain2()
87 {
88 // OleInitialize is required for ProgressBar in TaskBar.
89 #ifndef UNDER_CE
90 OleInitialize(NULL);
91 #endif
92
93 #ifndef UNDER_CE
94 g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll"));
95 g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4));
96 #endif
97
98 UString password;
99 bool assumeYes = false;
100 bool outputFolderDefined = false;
101 FString outputFolder;
102 UStringVector commandStrings;
103 NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
104
105 #ifndef UNDER_CE
106 if (commandStrings.Size() > 0)
107 commandStrings.Delete(0);
108 #endif
109
110 FOR_VECTOR (i, commandStrings)
111 {
112 const UString &s = commandStrings[i];
113 if (s.Len() > 1 && s[0] == '-')
114 {
115 const wchar_t c = MyCharLower_Ascii(s[1]);
116 if (c == 'y')
117 {
118 assumeYes = true;
119 if (s.Len() != 2)
120 {
121 ShowErrorMessage(L"Bad command");
122 return 1;
123 }
124 }
125 else if (c == 'o')
126 {
127 outputFolder = us2fs(s.Ptr(2));
128 NName::NormalizeDirPathPrefix(outputFolder);
129 outputFolderDefined = !outputFolder.IsEmpty();
130 }
131 else if (c == 'p')
132 {
133 password = s.Ptr(2);
134 }
135 }
136 }
137
138 FString path;
139 NDLL::MyGetModuleFileName(path);
140
141 FString fullPath;
142 if (!MyGetFullPathName(path, fullPath))
143 {
144 ShowErrorMessage(L"Error 1329484");
145 return 1;
146 }
147
148 CCodecs *codecs = new CCodecs;
149 CMyComPtr<IUnknown> compressCodecsInfo = codecs;
150 HRESULT result = codecs->Load();
151 if (result != S_OK)
152 {
153 ErrorMessageForHRESULT(result);
154 return 1;
155 }
156
157 // COpenCallbackGUI openCallback;
158
159 // openCallback.PasswordIsDefined = !password.IsEmpty();
160 // openCallback.Password = password;
161
162 CExtractCallbackImp *ecs = new CExtractCallbackImp;
163 CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
164 ecs->Init();
165
166 #ifndef Z7_NO_CRYPTO
167 ecs->PasswordIsDefined = !password.IsEmpty();
168 ecs->Password = password;
169 #endif
170
171 CExtractOptions eo;
172
173 FString dirPrefix;
174 if (!GetOnlyDirPrefix(path, dirPrefix))
175 {
176 ShowErrorMessage(L"Error 1329485");
177 return 1;
178 }
179
180 eo.OutputDir = outputFolderDefined ? outputFolder : dirPrefix;
181 eo.YesToAll = assumeYes;
182 eo.OverwriteMode = assumeYes ?
183 NExtract::NOverwriteMode::kOverwrite :
184 NExtract::NOverwriteMode::kAsk;
185 eo.PathMode = NExtract::NPathMode::kFullPaths;
186 eo.TestMode = false;
187
188 UStringVector v1, v2;
189 v1.Add(fs2us(fullPath));
190 v2.Add(fs2us(fullPath));
191 NWildcard::CCensorNode wildcardCensor;
192 wildcardCensor.Add_Wildcard();
193
194 bool messageWasDisplayed = false;
195 result = ExtractGUI(codecs,
196 CObjectVector<COpenType>(), CIntVector(),
197 v1, v2,
198 wildcardCensor, eo, (assumeYes ? false: true), messageWasDisplayed, ecs);
199
200 if (result == S_OK)
201 {
202 if (!ecs->IsOK())
203 return NExitCode::kFatalError;
204 return 0;
205 }
206 if (result == E_ABORT)
207 return NExitCode::kUserBreak;
208 if (!messageWasDisplayed)
209 {
210 if (result == S_FALSE)
211 ShowErrorMessage(L"Error in archive");
212 else
213 ErrorMessageForHRESULT(result);
214 }
215 if (result == E_OUTOFMEMORY)
216 return NExitCode::kMemoryError;
217 return NExitCode::kFatalError;
218 }
219
220 #if defined(_WIN32) && defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
221 #define NT_CHECK_FAIL_ACTION ShowErrorMessage(L"Unsupported Windows version"); return NExitCode::kFatalError;
222 #endif
223
WinMain(HINSTANCE hInstance,HINSTANCE,LPWSTR,int)224 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
225 #ifdef UNDER_CE
226 LPWSTR
227 #else
228 LPSTR
229 #endif
230 /* lpCmdLine */, int /* nCmdShow */)
231 {
232 g_hInstance = (HINSTANCE)hInstance;
233
234 NT_CHECK
235
236 try
237 {
238 #ifdef _WIN32
239 LoadSecurityDlls();
240 #endif
241
242 return WinMain2();
243 }
244 catch(const CNewException &)
245 {
246 ErrorMessageForHRESULT(E_OUTOFMEMORY);
247 return NExitCode::kMemoryError;
248 }
249 catch(...)
250 {
251 ShowErrorMessage(kUnknownExceptionMessage);
252 return NExitCode::kFatalError;
253 }
254 }
255