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