1cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky// Main.cpp
2cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
3cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "StdAfx.h"
4cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
5cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Common/MyInitGuid.h"
6cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
7cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Common/CommandLineParser.h"
8cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Common/StringConvert.h"
9cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Common/TextConfig.h"
10cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
11cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/DLL.h"
12cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/ErrorMsg.h"
13cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/FileDir.h"
14cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/FileFind.h"
15cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/FileIO.h"
16cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/FileName.h"
17cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/NtCheck.h"
18cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/ResourceString.h"
19cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
20cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../UI/Explorer/MyMessages.h"
21cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
22cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "ExtractEngine.h"
23cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
24cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "resource.h"
25cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
26cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyusing namespace NWindows;
27cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyusing namespace NFile;
28cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyusing namespace NDir;
29cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
30cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHINSTANCE g_hInstance;
31cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
32cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic CFSTR kTempDirPrefix = FTEXT("7zS");
33cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
34cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define _SHELL_EXECUTE
35cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
36cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic bool ReadDataString(CFSTR fileName, LPCSTR startID,
37cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    LPCSTR endID, AString &stringResult)
38cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
39cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  stringResult.Empty();
40cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  NIO::CInFile inFile;
41cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!inFile.Open(fileName))
42cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
43cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const int kBufferSize = (1 << 12);
44cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
45cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  Byte buffer[kBufferSize];
46cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int signatureStartSize = MyStringLen(startID);
47cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int signatureEndSize = MyStringLen(endID);
48cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
49cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 numBytesPrev = 0;
50cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool writeMode = false;
51cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 posTotal = 0;
52cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (;;)
53cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
54cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (posTotal > (1 << 20))
55cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return (stringResult.IsEmpty());
56cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 numReadBytes = kBufferSize - numBytesPrev;
57cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 processedSize;
58cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!inFile.Read(buffer + numBytesPrev, numReadBytes, processedSize))
59cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return false;
60cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (processedSize == 0)
61cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return true;
62cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 numBytesInBuffer = numBytesPrev + processedSize;
63cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 pos = 0;
64cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (;;)
65cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
66cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (writeMode)
67cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
68cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (pos > numBytesInBuffer - signatureEndSize)
69cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          break;
70cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (memcmp(buffer + pos, endID, signatureEndSize) == 0)
71cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          return true;
72cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        char b = buffer[pos];
73cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (b == 0)
74cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          return false;
75cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        stringResult += b;
76cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        pos++;
77cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
78cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      else
79cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
80cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (pos > numBytesInBuffer - signatureStartSize)
81cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          break;
82cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (memcmp(buffer + pos, startID, signatureStartSize) == 0)
83cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
84cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          writeMode = true;
85cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          pos += signatureStartSize;
86cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
87cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        else
88cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          pos++;
89cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
90cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
91cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    numBytesPrev = numBytesInBuffer - pos;
92cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    posTotal += pos;
93cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    memmove(buffer, buffer + pos, numBytesPrev);
94cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
95cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
96cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
97cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic char kStartID[] = ",!@Install@!UTF-8!";
98cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic char kEndID[] = ",!@InstallEnd@!";
99cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
100cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyclass CInstallIDInit
101cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
102cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckypublic:
103cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CInstallIDInit()
104cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
105cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    kStartID[0] = ';';
106cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    kEndID[0] = ';';
107cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  };
108cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} g_CInstallIDInit;
109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
110cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
111cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define NT_CHECK_FAIL_ACTION ShowErrorMessage(L"Unsupported Windows version"); return 1;
112cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
113cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic void ShowErrorMessageSpec(const UString &name)
114cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
115cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString message = NError::MyFormatMessage(::GetLastError());
116cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int pos = message.Find(L"%1");
117cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (pos >= 0)
118cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
119cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    message.Delete(pos, 2);
120cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    message.Insert(pos, name);
121cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
122cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ShowErrorMessage(NULL, message);
123cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
124cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
125cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyint APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
126cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    #ifdef UNDER_CE
127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    LPWSTR
128cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    #else
129cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    LPSTR
130cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    #endif
131cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    /* lpCmdLine */,int /* nCmdShow */)
132cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
133cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  g_hInstance = (HINSTANCE)hInstance;
134cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
135cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  NT_CHECK
136cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
137cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // InitCommonControls();
138cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
139cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString archiveName, switches;
140cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #ifdef _SHELL_EXECUTE
141cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString executeFile, executeParameters;
142cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #endif
143cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches);
144cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
145cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  FString fullPath;
146cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  NDLL::MyGetModuleFileName(fullPath);
147cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
148cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  switches.Trim();
149cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool assumeYes = false;
150cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (MyStringCompareNoCase_N(switches, L"-y", 2) == 0)
151cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
152cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    assumeYes = true;
153cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    switches = switches.Ptr(2);
154cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    switches.Trim();
155cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
156cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
157cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  AString config;
158cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!ReadDataString(fullPath, kStartID, kEndID, config))
159cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
160cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!assumeYes)
161cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ShowErrorMessage(L"Can't load config info");
162cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return 1;
163cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
164cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
165cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString dirPrefix = L"." WSTRING_PATH_SEPARATOR;
166cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UString appLaunched;
167cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool showProgress = true;
168cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!config.IsEmpty())
169cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
170cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CObjectVector<CTextConfigPair> pairs;
171cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!GetTextConfig(config, pairs))
172cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
173cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!assumeYes)
174cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ShowErrorMessage(L"Config failed");
175cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return 1;
176cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
177cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UString friendlyName = GetTextConfigValue(pairs, L"Title");
178cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UString installPrompt = GetTextConfigValue(pairs, L"BeginPrompt");
179cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UString progress = GetTextConfigValue(pairs, L"Progress");
180cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (progress.IsEqualToNoCase(L"no"))
181cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      showProgress = false;
182cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    int index = FindTextConfigItem(pairs, L"Directory");
183cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (index >= 0)
184cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      dirPrefix = pairs[index].String;
185cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!installPrompt.IsEmpty() && !assumeYes)
186cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
187cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (MessageBoxW(0, installPrompt, friendlyName, MB_YESNO |
188cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          MB_ICONQUESTION) != IDYES)
189cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return 0;
190cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
191cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    appLaunched = GetTextConfigValue(pairs, L"RunProgram");
192cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
193cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    #ifdef _SHELL_EXECUTE
194cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    executeFile = GetTextConfigValue(pairs, L"ExecuteFile");
195cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    executeParameters = GetTextConfigValue(pairs, L"ExecuteParameters");
196cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    #endif
197cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
198cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
199cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CTempDir tempDir;
200cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!tempDir.Create(kTempDirPrefix))
201cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
202cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!assumeYes)
203cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ShowErrorMessage(L"Can not create temp folder archive");
204cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return 1;
205cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
206cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
207cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CCodecs *codecs = new CCodecs;
208cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CMyComPtr<IUnknown> compressCodecsInfo = codecs;
209cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HRESULT result = codecs->Load();
210cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (result != S_OK)
211cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
212cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ShowErrorMessage(L"Can not load codecs");
213cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return 1;
214cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
215cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
216cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const FString tempDirPath = tempDir.GetPath();
217cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // tempDirPath = L"M:\\1\\"; // to test low disk space
218cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
219cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool isCorrupt = false;
220cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UString errorMessage;
221cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    HRESULT result = ExtractArchive(codecs, fullPath, tempDirPath, showProgress,
222cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      isCorrupt, errorMessage);
223cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
224cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (result != S_OK)
225cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
226cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!assumeYes)
227cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
228cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (result == S_FALSE || isCorrupt)
229cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
230cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          NWindows::MyLoadString(IDS_EXTRACTION_ERROR_MESSAGE, errorMessage);
231cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          result = E_FAIL;
232cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
233cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (result != E_ABORT)
234cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
235cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          if (errorMessage.IsEmpty())
236cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            errorMessage = NError::MyFormatMessage(result);
237cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          ::MessageBoxW(0, errorMessage, NWindows::MyLoadString(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR);
238cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
239cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
240cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return 1;
241cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
242cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
243cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
244cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #ifndef UNDER_CE
245cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CCurrentDirRestorer currentDirRestorer;
246cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!SetCurrentDir(tempDirPath))
247cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return 1;
248cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #endif
249cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
250cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HANDLE hProcess = 0;
251cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#ifdef _SHELL_EXECUTE
252cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!executeFile.IsEmpty())
253cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
254cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CSysString filePath = GetSystemString(executeFile);
255cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    SHELLEXECUTEINFO execInfo;
256cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    execInfo.cbSize = sizeof(execInfo);
257cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    execInfo.fMask = SEE_MASK_NOCLOSEPROCESS
258cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      #ifndef UNDER_CE
259cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      | SEE_MASK_FLAG_DDEWAIT
260cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      #endif
261cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ;
262cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    execInfo.hwnd = NULL;
263cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    execInfo.lpVerb = NULL;
264cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    execInfo.lpFile = filePath;
265cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
266cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!switches.IsEmpty())
267cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
268cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!executeParameters.IsEmpty())
269cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        executeParameters += L' ';
270cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      executeParameters += switches;
271cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
272cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
273cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CSysString parametersSys = GetSystemString(executeParameters);
274cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (parametersSys.IsEmpty())
275cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      execInfo.lpParameters = NULL;
276cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
277cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      execInfo.lpParameters = parametersSys;
278cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    execInfo.lpDirectory = NULL;
280cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    execInfo.nShow = SW_SHOWNORMAL;
281cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    execInfo.hProcess = 0;
282cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    /* BOOL success = */ ::ShellExecuteEx(&execInfo);
283cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UINT32 result = (UINT32)(UINT_PTR)execInfo.hInstApp;
284cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if(result <= 32)
285cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
286cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!assumeYes)
287cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ShowErrorMessage(L"Can not open file");
288cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return 1;
289cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
290cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    hProcess = execInfo.hProcess;
291cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
292cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
293cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#endif
294cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
295cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (appLaunched.IsEmpty())
296cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
297cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      appLaunched = L"setup.exe";
298cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!NFind::DoesFileExist(us2fs(appLaunched)))
299cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
300cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (!assumeYes)
301cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          ShowErrorMessage(L"Can not find setup.exe");
302cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return 1;
303cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
304cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
305cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
306cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
307cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      FString s2 = tempDirPath;
308cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      NName::NormalizeDirPathPrefix(s2);
309cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      appLaunched.Replace(L"%%T" WSTRING_PATH_SEPARATOR, fs2us(s2));
310cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
311cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
312cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UString appNameForError = appLaunched; // actually we need to rtemove parameters also
313cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
314cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    appLaunched.Replace(L"%%T", fs2us(tempDirPath));
315cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
316cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!switches.IsEmpty())
317cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
318cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      appLaunched += L' ';
319cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      appLaunched += switches;
320cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
321cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    STARTUPINFO startupInfo;
322cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    startupInfo.cb = sizeof(startupInfo);
323cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    startupInfo.lpReserved = 0;
324cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    startupInfo.lpDesktop = 0;
325cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    startupInfo.lpTitle = 0;
326cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    startupInfo.dwFlags = 0;
327cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    startupInfo.cbReserved2 = 0;
328cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    startupInfo.lpReserved2 = 0;
329cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
330cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    PROCESS_INFORMATION processInformation;
331cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
332cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CSysString appLaunchedSys = GetSystemString(dirPrefix + appLaunched);
333cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
334cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    BOOL createResult = CreateProcess(NULL, (LPTSTR)(LPCTSTR)appLaunchedSys,
335cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */,
336cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      &startupInfo, &processInformation);
337cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (createResult == 0)
338cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
339cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (!assumeYes)
340cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
341cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // we print name of exe file, if error message is
342cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // ERROR_BAD_EXE_FORMAT: "%1 is not a valid Win32 application".
343cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ShowErrorMessageSpec(appNameForError);
344cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
345cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return 1;
346cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
347cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ::CloseHandle(processInformation.hThread);
348cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    hProcess = processInformation.hProcess;
349cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
350cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (hProcess != 0)
351cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
352cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    WaitForSingleObject(hProcess, INFINITE);
353cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ::CloseHandle(hProcess);
354cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
355cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return 0;
356cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
357