SfxWin.cpp revision f955a79a9fffb09826cf7547f70d08c3798a2f50
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
33using namespace NWindows;
34using namespace NFile;
35using namespace NDir;
36
37HINSTANCE g_hInstance;
38
39#ifndef UNDER_CE
40
41DWORD g_ComCtl32Version;
42
43static 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
66bool g_LVN_ITEMACTIVATE_Support = true;
67
68static const wchar_t *kUnknownExceptionMessage = L"ERROR: Unknown Error!";
69
70void ErrorMessageForHRESULT(HRESULT res)
71{
72  ShowErrorMessage(HResultToMessage(res));
73}
74
75int 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
211int 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