Home | History | Annotate | Download | only in SFXWin
      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 
     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 *kUnknownExceptionMessage = L"ERROR: Unknown Error!";
     69 
     70 void ErrorMessageForHRESULT(HRESULT res)
     71 {
     72   ShowErrorMessage(HResultToMessage(res));
     73 }
     74 
     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 
    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