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