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
29using namespace NWindows;
30using namespace NFile;
31using namespace NDir;
32
33HINSTANCE g_hInstance;
34
35#ifndef UNDER_CE
36
37DWORD g_ComCtl32Version;
38
39static 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
62bool g_LVN_ITEMACTIVATE_Support = true;
63
64static const wchar_t *kUnknownExceptionMessage = L"ERROR: Unknown Error!";
65
66void ErrorMessageForHRESULT(HRESULT res)
67{
68  ShowErrorMessage(HResultToMessage(res));
69}
70
71int 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
207int 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