Home | History | Annotate | Download | only in SFXWin
      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 
     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 
     66 void ErrorMessageForHRESULT(HRESULT res)
     67 {
     68   ShowErrorMessage(HResultToMessage(res));
     69 }
     70 
     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 
    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