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