xref: /aosp_15_r20/external/lzma/C/Util/SfxSetup/SfxSetup.c (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker /* SfxSetup.c - 7z SFX Setup
2*f6dc9357SAndroid Build Coastguard Worker 2024-01-24 : Igor Pavlov : Public domain */
3*f6dc9357SAndroid Build Coastguard Worker 
4*f6dc9357SAndroid Build Coastguard Worker #include "Precomp.h"
5*f6dc9357SAndroid Build Coastguard Worker 
6*f6dc9357SAndroid Build Coastguard Worker #ifndef UNICODE
7*f6dc9357SAndroid Build Coastguard Worker #define UNICODE
8*f6dc9357SAndroid Build Coastguard Worker #endif
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
11*f6dc9357SAndroid Build Coastguard Worker #define _UNICODE
12*f6dc9357SAndroid Build Coastguard Worker #endif
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #ifdef _CONSOLE
15*f6dc9357SAndroid Build Coastguard Worker #include <stdio.h>
16*f6dc9357SAndroid Build Coastguard Worker #endif
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker #include "../../7z.h"
19*f6dc9357SAndroid Build Coastguard Worker #include "../../7zAlloc.h"
20*f6dc9357SAndroid Build Coastguard Worker #include "../../7zCrc.h"
21*f6dc9357SAndroid Build Coastguard Worker #include "../../7zFile.h"
22*f6dc9357SAndroid Build Coastguard Worker #include "../../CpuArch.h"
23*f6dc9357SAndroid Build Coastguard Worker #include "../../DllSecur.h"
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker #define k_EXE_ExtIndex 2
26*f6dc9357SAndroid Build Coastguard Worker 
27*f6dc9357SAndroid Build Coastguard Worker #define kInputBufSize ((size_t)1 << 18)
28*f6dc9357SAndroid Build Coastguard Worker 
29*f6dc9357SAndroid Build Coastguard Worker 
30*f6dc9357SAndroid Build Coastguard Worker #define wcscat lstrcatW
31*f6dc9357SAndroid Build Coastguard Worker #define wcslen (size_t)lstrlenW
32*f6dc9357SAndroid Build Coastguard Worker #define wcscpy lstrcpyW
33*f6dc9357SAndroid Build Coastguard Worker // wcsncpy() and lstrcpynW() work differently. We don't use them.
34*f6dc9357SAndroid Build Coastguard Worker 
35*f6dc9357SAndroid Build Coastguard Worker static const char * const kExts[] =
36*f6dc9357SAndroid Build Coastguard Worker {
37*f6dc9357SAndroid Build Coastguard Worker     "bat"
38*f6dc9357SAndroid Build Coastguard Worker   , "cmd"
39*f6dc9357SAndroid Build Coastguard Worker   , "exe"
40*f6dc9357SAndroid Build Coastguard Worker   , "inf"
41*f6dc9357SAndroid Build Coastguard Worker   , "msi"
42*f6dc9357SAndroid Build Coastguard Worker   #ifdef UNDER_CE
43*f6dc9357SAndroid Build Coastguard Worker   , "cab"
44*f6dc9357SAndroid Build Coastguard Worker   #endif
45*f6dc9357SAndroid Build Coastguard Worker   , "html"
46*f6dc9357SAndroid Build Coastguard Worker   , "htm"
47*f6dc9357SAndroid Build Coastguard Worker };
48*f6dc9357SAndroid Build Coastguard Worker 
49*f6dc9357SAndroid Build Coastguard Worker static const char * const kNames[] =
50*f6dc9357SAndroid Build Coastguard Worker {
51*f6dc9357SAndroid Build Coastguard Worker     "setup"
52*f6dc9357SAndroid Build Coastguard Worker   , "install"
53*f6dc9357SAndroid Build Coastguard Worker   , "run"
54*f6dc9357SAndroid Build Coastguard Worker   , "start"
55*f6dc9357SAndroid Build Coastguard Worker };
56*f6dc9357SAndroid Build Coastguard Worker 
FindExt(const wchar_t * s,unsigned * extLen)57*f6dc9357SAndroid Build Coastguard Worker static unsigned FindExt(const wchar_t *s, unsigned *extLen)
58*f6dc9357SAndroid Build Coastguard Worker {
59*f6dc9357SAndroid Build Coastguard Worker   unsigned len = (unsigned)wcslen(s);
60*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
61*f6dc9357SAndroid Build Coastguard Worker   for (i = len; i > 0; i--)
62*f6dc9357SAndroid Build Coastguard Worker   {
63*f6dc9357SAndroid Build Coastguard Worker     if (s[i - 1] == '.')
64*f6dc9357SAndroid Build Coastguard Worker     {
65*f6dc9357SAndroid Build Coastguard Worker       *extLen = len - i;
66*f6dc9357SAndroid Build Coastguard Worker       return i - 1;
67*f6dc9357SAndroid Build Coastguard Worker     }
68*f6dc9357SAndroid Build Coastguard Worker   }
69*f6dc9357SAndroid Build Coastguard Worker   *extLen = 0;
70*f6dc9357SAndroid Build Coastguard Worker   return len;
71*f6dc9357SAndroid Build Coastguard Worker }
72*f6dc9357SAndroid Build Coastguard Worker 
73*f6dc9357SAndroid Build Coastguard Worker #define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) - 0x20 : (c)))
74*f6dc9357SAndroid Build Coastguard Worker 
FindItem(const char * const * items,unsigned num,const wchar_t * s,unsigned len)75*f6dc9357SAndroid Build Coastguard Worker static unsigned FindItem(const char * const *items, unsigned num, const wchar_t *s, unsigned len)
76*f6dc9357SAndroid Build Coastguard Worker {
77*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
78*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < num; i++)
79*f6dc9357SAndroid Build Coastguard Worker   {
80*f6dc9357SAndroid Build Coastguard Worker     const char *item = items[i];
81*f6dc9357SAndroid Build Coastguard Worker     const unsigned itemLen = (unsigned)strlen(item);
82*f6dc9357SAndroid Build Coastguard Worker     unsigned j;
83*f6dc9357SAndroid Build Coastguard Worker     if (len != itemLen)
84*f6dc9357SAndroid Build Coastguard Worker       continue;
85*f6dc9357SAndroid Build Coastguard Worker     for (j = 0; j < len; j++)
86*f6dc9357SAndroid Build Coastguard Worker     {
87*f6dc9357SAndroid Build Coastguard Worker       const unsigned c = (Byte)item[j];
88*f6dc9357SAndroid Build Coastguard Worker       if (c != s[j] && MAKE_CHAR_UPPER(c) != s[j])
89*f6dc9357SAndroid Build Coastguard Worker         break;
90*f6dc9357SAndroid Build Coastguard Worker     }
91*f6dc9357SAndroid Build Coastguard Worker     if (j == len)
92*f6dc9357SAndroid Build Coastguard Worker       return i;
93*f6dc9357SAndroid Build Coastguard Worker   }
94*f6dc9357SAndroid Build Coastguard Worker   return i;
95*f6dc9357SAndroid Build Coastguard Worker }
96*f6dc9357SAndroid Build Coastguard Worker 
97*f6dc9357SAndroid Build Coastguard Worker #ifdef _CONSOLE
HandlerRoutine(DWORD ctrlType)98*f6dc9357SAndroid Build Coastguard Worker static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
99*f6dc9357SAndroid Build Coastguard Worker {
100*f6dc9357SAndroid Build Coastguard Worker   UNUSED_VAR(ctrlType);
101*f6dc9357SAndroid Build Coastguard Worker   return TRUE;
102*f6dc9357SAndroid Build Coastguard Worker }
103*f6dc9357SAndroid Build Coastguard Worker #endif
104*f6dc9357SAndroid Build Coastguard Worker 
105*f6dc9357SAndroid Build Coastguard Worker 
106*f6dc9357SAndroid Build Coastguard Worker #ifdef _CONSOLE
PrintStr(const char * s)107*f6dc9357SAndroid Build Coastguard Worker static void PrintStr(const char *s)
108*f6dc9357SAndroid Build Coastguard Worker {
109*f6dc9357SAndroid Build Coastguard Worker   fputs(s, stdout);
110*f6dc9357SAndroid Build Coastguard Worker }
111*f6dc9357SAndroid Build Coastguard Worker #endif
112*f6dc9357SAndroid Build Coastguard Worker 
PrintErrorMessage(const char * message)113*f6dc9357SAndroid Build Coastguard Worker static void PrintErrorMessage(const char *message)
114*f6dc9357SAndroid Build Coastguard Worker {
115*f6dc9357SAndroid Build Coastguard Worker   #ifdef _CONSOLE
116*f6dc9357SAndroid Build Coastguard Worker   PrintStr("\n7-Zip Error: ");
117*f6dc9357SAndroid Build Coastguard Worker   PrintStr(message);
118*f6dc9357SAndroid Build Coastguard Worker   PrintStr("\n");
119*f6dc9357SAndroid Build Coastguard Worker   #else
120*f6dc9357SAndroid Build Coastguard Worker   #ifdef UNDER_CE
121*f6dc9357SAndroid Build Coastguard Worker   WCHAR messageW[256 + 4];
122*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
123*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < 256 && message[i] != 0; i++)
124*f6dc9357SAndroid Build Coastguard Worker     messageW[i] = message[i];
125*f6dc9357SAndroid Build Coastguard Worker   messageW[i] = 0;
126*f6dc9357SAndroid Build Coastguard Worker   MessageBoxW(0, messageW, L"7-Zip Error", MB_ICONERROR);
127*f6dc9357SAndroid Build Coastguard Worker   #else
128*f6dc9357SAndroid Build Coastguard Worker   MessageBoxA(0, message, "7-Zip Error", MB_ICONERROR);
129*f6dc9357SAndroid Build Coastguard Worker   #endif
130*f6dc9357SAndroid Build Coastguard Worker   #endif
131*f6dc9357SAndroid Build Coastguard Worker }
132*f6dc9357SAndroid Build Coastguard Worker 
MyCreateDir(const WCHAR * name)133*f6dc9357SAndroid Build Coastguard Worker static WRes MyCreateDir(const WCHAR *name)
134*f6dc9357SAndroid Build Coastguard Worker {
135*f6dc9357SAndroid Build Coastguard Worker   return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
136*f6dc9357SAndroid Build Coastguard Worker }
137*f6dc9357SAndroid Build Coastguard Worker 
138*f6dc9357SAndroid Build Coastguard Worker #ifdef UNDER_CE
139*f6dc9357SAndroid Build Coastguard Worker #define kBufferSize (1 << 13)
140*f6dc9357SAndroid Build Coastguard Worker #else
141*f6dc9357SAndroid Build Coastguard Worker #define kBufferSize (1 << 15)
142*f6dc9357SAndroid Build Coastguard Worker #endif
143*f6dc9357SAndroid Build Coastguard Worker 
144*f6dc9357SAndroid Build Coastguard Worker #define kSignatureSearchLimit (1 << 22)
145*f6dc9357SAndroid Build Coastguard Worker 
FindSignature(CSzFile * stream,UInt64 * resPos)146*f6dc9357SAndroid Build Coastguard Worker static BoolInt FindSignature(CSzFile *stream, UInt64 *resPos)
147*f6dc9357SAndroid Build Coastguard Worker {
148*f6dc9357SAndroid Build Coastguard Worker   Byte buf[kBufferSize];
149*f6dc9357SAndroid Build Coastguard Worker   size_t numPrevBytes = 0;
150*f6dc9357SAndroid Build Coastguard Worker   *resPos = 0;
151*f6dc9357SAndroid Build Coastguard Worker   for (;;)
152*f6dc9357SAndroid Build Coastguard Worker   {
153*f6dc9357SAndroid Build Coastguard Worker     size_t processed, pos;
154*f6dc9357SAndroid Build Coastguard Worker     if (*resPos > kSignatureSearchLimit)
155*f6dc9357SAndroid Build Coastguard Worker       return False;
156*f6dc9357SAndroid Build Coastguard Worker     processed = kBufferSize - numPrevBytes;
157*f6dc9357SAndroid Build Coastguard Worker     if (File_Read(stream, buf + numPrevBytes, &processed) != 0)
158*f6dc9357SAndroid Build Coastguard Worker       return False;
159*f6dc9357SAndroid Build Coastguard Worker     processed += numPrevBytes;
160*f6dc9357SAndroid Build Coastguard Worker     if (processed < k7zStartHeaderSize ||
161*f6dc9357SAndroid Build Coastguard Worker         (processed == k7zStartHeaderSize && numPrevBytes != 0))
162*f6dc9357SAndroid Build Coastguard Worker       return False;
163*f6dc9357SAndroid Build Coastguard Worker     processed -= k7zStartHeaderSize;
164*f6dc9357SAndroid Build Coastguard Worker     for (pos = 0; pos <= processed; pos++)
165*f6dc9357SAndroid Build Coastguard Worker     {
166*f6dc9357SAndroid Build Coastguard Worker       for (; pos <= processed && buf[pos] != '7'; pos++);
167*f6dc9357SAndroid Build Coastguard Worker       if (pos > processed)
168*f6dc9357SAndroid Build Coastguard Worker         break;
169*f6dc9357SAndroid Build Coastguard Worker       if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
170*f6dc9357SAndroid Build Coastguard Worker         if (CrcCalc(buf + pos + 12, 20) == GetUi32(buf + pos + 8))
171*f6dc9357SAndroid Build Coastguard Worker         {
172*f6dc9357SAndroid Build Coastguard Worker           *resPos += pos;
173*f6dc9357SAndroid Build Coastguard Worker           return True;
174*f6dc9357SAndroid Build Coastguard Worker         }
175*f6dc9357SAndroid Build Coastguard Worker     }
176*f6dc9357SAndroid Build Coastguard Worker     *resPos += processed;
177*f6dc9357SAndroid Build Coastguard Worker     numPrevBytes = k7zStartHeaderSize;
178*f6dc9357SAndroid Build Coastguard Worker     memmove(buf, buf + processed, k7zStartHeaderSize);
179*f6dc9357SAndroid Build Coastguard Worker   }
180*f6dc9357SAndroid Build Coastguard Worker }
181*f6dc9357SAndroid Build Coastguard Worker 
DoesFileOrDirExist(const WCHAR * path)182*f6dc9357SAndroid Build Coastguard Worker static BoolInt DoesFileOrDirExist(const WCHAR *path)
183*f6dc9357SAndroid Build Coastguard Worker {
184*f6dc9357SAndroid Build Coastguard Worker   WIN32_FIND_DATAW fd;
185*f6dc9357SAndroid Build Coastguard Worker   HANDLE handle;
186*f6dc9357SAndroid Build Coastguard Worker   handle = FindFirstFileW(path, &fd);
187*f6dc9357SAndroid Build Coastguard Worker   if (handle == INVALID_HANDLE_VALUE)
188*f6dc9357SAndroid Build Coastguard Worker     return False;
189*f6dc9357SAndroid Build Coastguard Worker   FindClose(handle);
190*f6dc9357SAndroid Build Coastguard Worker   return True;
191*f6dc9357SAndroid Build Coastguard Worker }
192*f6dc9357SAndroid Build Coastguard Worker 
RemoveDirWithSubItems(WCHAR * path)193*f6dc9357SAndroid Build Coastguard Worker static WRes RemoveDirWithSubItems(WCHAR *path)
194*f6dc9357SAndroid Build Coastguard Worker {
195*f6dc9357SAndroid Build Coastguard Worker   WIN32_FIND_DATAW fd;
196*f6dc9357SAndroid Build Coastguard Worker   HANDLE handle;
197*f6dc9357SAndroid Build Coastguard Worker   WRes res = 0;
198*f6dc9357SAndroid Build Coastguard Worker   const size_t len = wcslen(path);
199*f6dc9357SAndroid Build Coastguard Worker   wcscpy(path + len, L"*");
200*f6dc9357SAndroid Build Coastguard Worker   handle = FindFirstFileW(path, &fd);
201*f6dc9357SAndroid Build Coastguard Worker   path[len] = L'\0';
202*f6dc9357SAndroid Build Coastguard Worker   if (handle == INVALID_HANDLE_VALUE)
203*f6dc9357SAndroid Build Coastguard Worker     return GetLastError();
204*f6dc9357SAndroid Build Coastguard Worker 
205*f6dc9357SAndroid Build Coastguard Worker   for (;;)
206*f6dc9357SAndroid Build Coastguard Worker   {
207*f6dc9357SAndroid Build Coastguard Worker     if (wcscmp(fd.cFileName, L".") != 0 &&
208*f6dc9357SAndroid Build Coastguard Worker         wcscmp(fd.cFileName, L"..") != 0)
209*f6dc9357SAndroid Build Coastguard Worker     {
210*f6dc9357SAndroid Build Coastguard Worker       wcscpy(path + len, fd.cFileName);
211*f6dc9357SAndroid Build Coastguard Worker       if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
212*f6dc9357SAndroid Build Coastguard Worker       {
213*f6dc9357SAndroid Build Coastguard Worker         wcscat(path, WSTRING_PATH_SEPARATOR);
214*f6dc9357SAndroid Build Coastguard Worker         res = RemoveDirWithSubItems(path);
215*f6dc9357SAndroid Build Coastguard Worker       }
216*f6dc9357SAndroid Build Coastguard Worker       else
217*f6dc9357SAndroid Build Coastguard Worker       {
218*f6dc9357SAndroid Build Coastguard Worker         SetFileAttributesW(path, 0);
219*f6dc9357SAndroid Build Coastguard Worker         if (DeleteFileW(path) == 0)
220*f6dc9357SAndroid Build Coastguard Worker           res = GetLastError();
221*f6dc9357SAndroid Build Coastguard Worker       }
222*f6dc9357SAndroid Build Coastguard Worker 
223*f6dc9357SAndroid Build Coastguard Worker       if (res != 0)
224*f6dc9357SAndroid Build Coastguard Worker         break;
225*f6dc9357SAndroid Build Coastguard Worker     }
226*f6dc9357SAndroid Build Coastguard Worker 
227*f6dc9357SAndroid Build Coastguard Worker     if (!FindNextFileW(handle, &fd))
228*f6dc9357SAndroid Build Coastguard Worker     {
229*f6dc9357SAndroid Build Coastguard Worker       res = GetLastError();
230*f6dc9357SAndroid Build Coastguard Worker       if (res == ERROR_NO_MORE_FILES)
231*f6dc9357SAndroid Build Coastguard Worker         res = 0;
232*f6dc9357SAndroid Build Coastguard Worker       break;
233*f6dc9357SAndroid Build Coastguard Worker     }
234*f6dc9357SAndroid Build Coastguard Worker   }
235*f6dc9357SAndroid Build Coastguard Worker 
236*f6dc9357SAndroid Build Coastguard Worker   path[len] = L'\0';
237*f6dc9357SAndroid Build Coastguard Worker   FindClose(handle);
238*f6dc9357SAndroid Build Coastguard Worker   if (res == 0)
239*f6dc9357SAndroid Build Coastguard Worker   {
240*f6dc9357SAndroid Build Coastguard Worker     if (!RemoveDirectoryW(path))
241*f6dc9357SAndroid Build Coastguard Worker       res = GetLastError();
242*f6dc9357SAndroid Build Coastguard Worker   }
243*f6dc9357SAndroid Build Coastguard Worker   return res;
244*f6dc9357SAndroid Build Coastguard Worker }
245*f6dc9357SAndroid Build Coastguard Worker 
246*f6dc9357SAndroid Build Coastguard Worker #ifdef _CONSOLE
main(void)247*f6dc9357SAndroid Build Coastguard Worker int Z7_CDECL main(void)
248*f6dc9357SAndroid Build Coastguard Worker #else
249*f6dc9357SAndroid Build Coastguard Worker int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
250*f6dc9357SAndroid Build Coastguard Worker   #ifdef UNDER_CE
251*f6dc9357SAndroid Build Coastguard Worker   LPWSTR
252*f6dc9357SAndroid Build Coastguard Worker   #else
253*f6dc9357SAndroid Build Coastguard Worker   LPSTR
254*f6dc9357SAndroid Build Coastguard Worker   #endif
255*f6dc9357SAndroid Build Coastguard Worker   lpCmdLine, int nCmdShow)
256*f6dc9357SAndroid Build Coastguard Worker #endif
257*f6dc9357SAndroid Build Coastguard Worker {
258*f6dc9357SAndroid Build Coastguard Worker   CFileInStream archiveStream;
259*f6dc9357SAndroid Build Coastguard Worker   CLookToRead2 lookStream;
260*f6dc9357SAndroid Build Coastguard Worker   CSzArEx db;
261*f6dc9357SAndroid Build Coastguard Worker   SRes res = SZ_OK;
262*f6dc9357SAndroid Build Coastguard Worker   ISzAlloc allocImp;
263*f6dc9357SAndroid Build Coastguard Worker   ISzAlloc allocTempImp;
264*f6dc9357SAndroid Build Coastguard Worker   WCHAR sfxPath[MAX_PATH + 2];
265*f6dc9357SAndroid Build Coastguard Worker   WCHAR path[MAX_PATH * 3 + 2];
266*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
267*f6dc9357SAndroid Build Coastguard Worker   WCHAR workCurDir[MAX_PATH + 32];
268*f6dc9357SAndroid Build Coastguard Worker   #endif
269*f6dc9357SAndroid Build Coastguard Worker   size_t pathLen;
270*f6dc9357SAndroid Build Coastguard Worker   DWORD winRes;
271*f6dc9357SAndroid Build Coastguard Worker   const wchar_t *cmdLineParams;
272*f6dc9357SAndroid Build Coastguard Worker   const char *errorMessage = NULL;
273*f6dc9357SAndroid Build Coastguard Worker   BoolInt useShellExecute = True;
274*f6dc9357SAndroid Build Coastguard Worker   DWORD exitCode = 0;
275*f6dc9357SAndroid Build Coastguard Worker 
276*f6dc9357SAndroid Build Coastguard Worker   LoadSecurityDlls();
277*f6dc9357SAndroid Build Coastguard Worker 
278*f6dc9357SAndroid Build Coastguard Worker   #ifdef _CONSOLE
279*f6dc9357SAndroid Build Coastguard Worker   SetConsoleCtrlHandler(HandlerRoutine, TRUE);
280*f6dc9357SAndroid Build Coastguard Worker   #else
281*f6dc9357SAndroid Build Coastguard Worker   UNUSED_VAR(hInstance)
282*f6dc9357SAndroid Build Coastguard Worker   UNUSED_VAR(hPrevInstance)
283*f6dc9357SAndroid Build Coastguard Worker   UNUSED_VAR(lpCmdLine)
284*f6dc9357SAndroid Build Coastguard Worker   UNUSED_VAR(nCmdShow)
285*f6dc9357SAndroid Build Coastguard Worker   #endif
286*f6dc9357SAndroid Build Coastguard Worker 
287*f6dc9357SAndroid Build Coastguard Worker   CrcGenerateTable();
288*f6dc9357SAndroid Build Coastguard Worker 
289*f6dc9357SAndroid Build Coastguard Worker   allocImp.Alloc = SzAlloc;
290*f6dc9357SAndroid Build Coastguard Worker   allocImp.Free = SzFree;
291*f6dc9357SAndroid Build Coastguard Worker 
292*f6dc9357SAndroid Build Coastguard Worker   allocTempImp.Alloc = SzAllocTemp;
293*f6dc9357SAndroid Build Coastguard Worker   allocTempImp.Free = SzFreeTemp;
294*f6dc9357SAndroid Build Coastguard Worker 
295*f6dc9357SAndroid Build Coastguard Worker   FileInStream_CreateVTable(&archiveStream);
296*f6dc9357SAndroid Build Coastguard Worker   LookToRead2_CreateVTable(&lookStream, False);
297*f6dc9357SAndroid Build Coastguard Worker   lookStream.buf = NULL;
298*f6dc9357SAndroid Build Coastguard Worker 
299*f6dc9357SAndroid Build Coastguard Worker   winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH);
300*f6dc9357SAndroid Build Coastguard Worker   if (winRes == 0 || winRes > MAX_PATH)
301*f6dc9357SAndroid Build Coastguard Worker     return 1;
302*f6dc9357SAndroid Build Coastguard Worker   {
303*f6dc9357SAndroid Build Coastguard Worker     cmdLineParams = GetCommandLineW();
304*f6dc9357SAndroid Build Coastguard Worker     #ifndef UNDER_CE
305*f6dc9357SAndroid Build Coastguard Worker     {
306*f6dc9357SAndroid Build Coastguard Worker       BoolInt quoteMode = False;
307*f6dc9357SAndroid Build Coastguard Worker       for (;; cmdLineParams++)
308*f6dc9357SAndroid Build Coastguard Worker       {
309*f6dc9357SAndroid Build Coastguard Worker         const wchar_t c = *cmdLineParams;
310*f6dc9357SAndroid Build Coastguard Worker         if (c == L'\"')
311*f6dc9357SAndroid Build Coastguard Worker           quoteMode = !quoteMode;
312*f6dc9357SAndroid Build Coastguard Worker         else if (c == 0 || (c == L' ' && !quoteMode))
313*f6dc9357SAndroid Build Coastguard Worker           break;
314*f6dc9357SAndroid Build Coastguard Worker       }
315*f6dc9357SAndroid Build Coastguard Worker     }
316*f6dc9357SAndroid Build Coastguard Worker     #endif
317*f6dc9357SAndroid Build Coastguard Worker   }
318*f6dc9357SAndroid Build Coastguard Worker 
319*f6dc9357SAndroid Build Coastguard Worker   {
320*f6dc9357SAndroid Build Coastguard Worker     unsigned i;
321*f6dc9357SAndroid Build Coastguard Worker     DWORD d;
322*f6dc9357SAndroid Build Coastguard Worker     winRes = GetTempPathW(MAX_PATH, path);
323*f6dc9357SAndroid Build Coastguard Worker     if (winRes == 0 || winRes > MAX_PATH)
324*f6dc9357SAndroid Build Coastguard Worker       return 1;
325*f6dc9357SAndroid Build Coastguard Worker     pathLen = wcslen(path);
326*f6dc9357SAndroid Build Coastguard Worker     d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
327*f6dc9357SAndroid Build Coastguard Worker 
328*f6dc9357SAndroid Build Coastguard Worker     for (i = 0;; i++, d += GetTickCount())
329*f6dc9357SAndroid Build Coastguard Worker     {
330*f6dc9357SAndroid Build Coastguard Worker       if (i >= 100)
331*f6dc9357SAndroid Build Coastguard Worker       {
332*f6dc9357SAndroid Build Coastguard Worker         res = SZ_ERROR_FAIL;
333*f6dc9357SAndroid Build Coastguard Worker         break;
334*f6dc9357SAndroid Build Coastguard Worker       }
335*f6dc9357SAndroid Build Coastguard Worker       wcscpy(path + pathLen, L"7z");
336*f6dc9357SAndroid Build Coastguard Worker 
337*f6dc9357SAndroid Build Coastguard Worker       {
338*f6dc9357SAndroid Build Coastguard Worker         wchar_t *s = path + wcslen(path);
339*f6dc9357SAndroid Build Coastguard Worker         UInt32 value = d;
340*f6dc9357SAndroid Build Coastguard Worker         unsigned k;
341*f6dc9357SAndroid Build Coastguard Worker         for (k = 0; k < 8; k++)
342*f6dc9357SAndroid Build Coastguard Worker         {
343*f6dc9357SAndroid Build Coastguard Worker           const unsigned t = value & 0xF;
344*f6dc9357SAndroid Build Coastguard Worker           value >>= 4;
345*f6dc9357SAndroid Build Coastguard Worker           s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
346*f6dc9357SAndroid Build Coastguard Worker         }
347*f6dc9357SAndroid Build Coastguard Worker         s[k] = '\0';
348*f6dc9357SAndroid Build Coastguard Worker       }
349*f6dc9357SAndroid Build Coastguard Worker 
350*f6dc9357SAndroid Build Coastguard Worker       if (DoesFileOrDirExist(path))
351*f6dc9357SAndroid Build Coastguard Worker         continue;
352*f6dc9357SAndroid Build Coastguard Worker       if (CreateDirectoryW(path, NULL))
353*f6dc9357SAndroid Build Coastguard Worker       {
354*f6dc9357SAndroid Build Coastguard Worker         wcscat(path, WSTRING_PATH_SEPARATOR);
355*f6dc9357SAndroid Build Coastguard Worker         pathLen = wcslen(path);
356*f6dc9357SAndroid Build Coastguard Worker         break;
357*f6dc9357SAndroid Build Coastguard Worker       }
358*f6dc9357SAndroid Build Coastguard Worker       if (GetLastError() != ERROR_ALREADY_EXISTS)
359*f6dc9357SAndroid Build Coastguard Worker       {
360*f6dc9357SAndroid Build Coastguard Worker         res = SZ_ERROR_FAIL;
361*f6dc9357SAndroid Build Coastguard Worker         break;
362*f6dc9357SAndroid Build Coastguard Worker       }
363*f6dc9357SAndroid Build Coastguard Worker     }
364*f6dc9357SAndroid Build Coastguard Worker 
365*f6dc9357SAndroid Build Coastguard Worker     #ifndef UNDER_CE
366*f6dc9357SAndroid Build Coastguard Worker     wcscpy(workCurDir, path);
367*f6dc9357SAndroid Build Coastguard Worker     #endif
368*f6dc9357SAndroid Build Coastguard Worker     if (res != SZ_OK)
369*f6dc9357SAndroid Build Coastguard Worker       errorMessage = "Can't create temp folder";
370*f6dc9357SAndroid Build Coastguard Worker   }
371*f6dc9357SAndroid Build Coastguard Worker 
372*f6dc9357SAndroid Build Coastguard Worker   if (res != SZ_OK)
373*f6dc9357SAndroid Build Coastguard Worker   {
374*f6dc9357SAndroid Build Coastguard Worker     if (!errorMessage)
375*f6dc9357SAndroid Build Coastguard Worker       errorMessage = "Error";
376*f6dc9357SAndroid Build Coastguard Worker     PrintErrorMessage(errorMessage);
377*f6dc9357SAndroid Build Coastguard Worker     return 1;
378*f6dc9357SAndroid Build Coastguard Worker   }
379*f6dc9357SAndroid Build Coastguard Worker 
380*f6dc9357SAndroid Build Coastguard Worker   if (InFile_OpenW(&archiveStream.file, sfxPath) != 0)
381*f6dc9357SAndroid Build Coastguard Worker   {
382*f6dc9357SAndroid Build Coastguard Worker     errorMessage = "can not open input file";
383*f6dc9357SAndroid Build Coastguard Worker     res = SZ_ERROR_FAIL;
384*f6dc9357SAndroid Build Coastguard Worker   }
385*f6dc9357SAndroid Build Coastguard Worker   else
386*f6dc9357SAndroid Build Coastguard Worker   {
387*f6dc9357SAndroid Build Coastguard Worker     UInt64 pos = 0;
388*f6dc9357SAndroid Build Coastguard Worker     if (!FindSignature(&archiveStream.file, &pos))
389*f6dc9357SAndroid Build Coastguard Worker       res = SZ_ERROR_FAIL;
390*f6dc9357SAndroid Build Coastguard Worker     else if (File_Seek(&archiveStream.file, (Int64 *)&pos, SZ_SEEK_SET) != 0)
391*f6dc9357SAndroid Build Coastguard Worker       res = SZ_ERROR_FAIL;
392*f6dc9357SAndroid Build Coastguard Worker     if (res != 0)
393*f6dc9357SAndroid Build Coastguard Worker       errorMessage = "Can't find 7z archive";
394*f6dc9357SAndroid Build Coastguard Worker   }
395*f6dc9357SAndroid Build Coastguard Worker 
396*f6dc9357SAndroid Build Coastguard Worker   if (res == SZ_OK)
397*f6dc9357SAndroid Build Coastguard Worker   {
398*f6dc9357SAndroid Build Coastguard Worker     lookStream.buf = (Byte *)ISzAlloc_Alloc(&allocImp, kInputBufSize);
399*f6dc9357SAndroid Build Coastguard Worker     if (!lookStream.buf)
400*f6dc9357SAndroid Build Coastguard Worker       res = SZ_ERROR_MEM;
401*f6dc9357SAndroid Build Coastguard Worker     else
402*f6dc9357SAndroid Build Coastguard Worker     {
403*f6dc9357SAndroid Build Coastguard Worker       lookStream.bufSize = kInputBufSize;
404*f6dc9357SAndroid Build Coastguard Worker       lookStream.realStream = &archiveStream.vt;
405*f6dc9357SAndroid Build Coastguard Worker       LookToRead2_INIT(&lookStream)
406*f6dc9357SAndroid Build Coastguard Worker     }
407*f6dc9357SAndroid Build Coastguard Worker   }
408*f6dc9357SAndroid Build Coastguard Worker 
409*f6dc9357SAndroid Build Coastguard Worker   SzArEx_Init(&db);
410*f6dc9357SAndroid Build Coastguard Worker 
411*f6dc9357SAndroid Build Coastguard Worker   if (res == SZ_OK)
412*f6dc9357SAndroid Build Coastguard Worker   {
413*f6dc9357SAndroid Build Coastguard Worker     res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp);
414*f6dc9357SAndroid Build Coastguard Worker   }
415*f6dc9357SAndroid Build Coastguard Worker 
416*f6dc9357SAndroid Build Coastguard Worker   if (res == SZ_OK)
417*f6dc9357SAndroid Build Coastguard Worker   {
418*f6dc9357SAndroid Build Coastguard Worker     UInt32 executeFileIndex = (UInt32)(Int32)-1;
419*f6dc9357SAndroid Build Coastguard Worker     UInt32 minPrice = 1 << 30;
420*f6dc9357SAndroid Build Coastguard Worker     UInt32 i;
421*f6dc9357SAndroid Build Coastguard Worker     UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
422*f6dc9357SAndroid Build Coastguard Worker     Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
423*f6dc9357SAndroid Build Coastguard Worker     size_t outBufferSize = 0;  /* it can have any value before first call (if outBuffer = 0) */
424*f6dc9357SAndroid Build Coastguard Worker 
425*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < db.NumFiles; i++)
426*f6dc9357SAndroid Build Coastguard Worker     {
427*f6dc9357SAndroid Build Coastguard Worker       size_t offset = 0;
428*f6dc9357SAndroid Build Coastguard Worker       size_t outSizeProcessed = 0;
429*f6dc9357SAndroid Build Coastguard Worker       WCHAR *temp;
430*f6dc9357SAndroid Build Coastguard Worker 
431*f6dc9357SAndroid Build Coastguard Worker       if (SzArEx_GetFileNameUtf16(&db, i, NULL) >= MAX_PATH)
432*f6dc9357SAndroid Build Coastguard Worker       {
433*f6dc9357SAndroid Build Coastguard Worker         res = SZ_ERROR_FAIL;
434*f6dc9357SAndroid Build Coastguard Worker         break;
435*f6dc9357SAndroid Build Coastguard Worker       }
436*f6dc9357SAndroid Build Coastguard Worker 
437*f6dc9357SAndroid Build Coastguard Worker       temp = path + pathLen;
438*f6dc9357SAndroid Build Coastguard Worker 
439*f6dc9357SAndroid Build Coastguard Worker       SzArEx_GetFileNameUtf16(&db, i, (UInt16 *)temp);
440*f6dc9357SAndroid Build Coastguard Worker       {
441*f6dc9357SAndroid Build Coastguard Worker         res = SzArEx_Extract(&db, &lookStream.vt, i,
442*f6dc9357SAndroid Build Coastguard Worker           &blockIndex, &outBuffer, &outBufferSize,
443*f6dc9357SAndroid Build Coastguard Worker           &offset, &outSizeProcessed,
444*f6dc9357SAndroid Build Coastguard Worker           &allocImp, &allocTempImp);
445*f6dc9357SAndroid Build Coastguard Worker         if (res != SZ_OK)
446*f6dc9357SAndroid Build Coastguard Worker           break;
447*f6dc9357SAndroid Build Coastguard Worker       }
448*f6dc9357SAndroid Build Coastguard Worker       {
449*f6dc9357SAndroid Build Coastguard Worker         CSzFile outFile;
450*f6dc9357SAndroid Build Coastguard Worker         size_t processedSize;
451*f6dc9357SAndroid Build Coastguard Worker         size_t j;
452*f6dc9357SAndroid Build Coastguard Worker         size_t nameStartPos = 0;
453*f6dc9357SAndroid Build Coastguard Worker         for (j = 0; temp[j] != 0; j++)
454*f6dc9357SAndroid Build Coastguard Worker         {
455*f6dc9357SAndroid Build Coastguard Worker           if (temp[j] == '/')
456*f6dc9357SAndroid Build Coastguard Worker           {
457*f6dc9357SAndroid Build Coastguard Worker             temp[j] = 0;
458*f6dc9357SAndroid Build Coastguard Worker             MyCreateDir(path);
459*f6dc9357SAndroid Build Coastguard Worker             temp[j] = CHAR_PATH_SEPARATOR;
460*f6dc9357SAndroid Build Coastguard Worker             nameStartPos = j + 1;
461*f6dc9357SAndroid Build Coastguard Worker           }
462*f6dc9357SAndroid Build Coastguard Worker         }
463*f6dc9357SAndroid Build Coastguard Worker 
464*f6dc9357SAndroid Build Coastguard Worker         if (SzArEx_IsDir(&db, i))
465*f6dc9357SAndroid Build Coastguard Worker         {
466*f6dc9357SAndroid Build Coastguard Worker           MyCreateDir(path);
467*f6dc9357SAndroid Build Coastguard Worker           continue;
468*f6dc9357SAndroid Build Coastguard Worker         }
469*f6dc9357SAndroid Build Coastguard Worker         else
470*f6dc9357SAndroid Build Coastguard Worker         {
471*f6dc9357SAndroid Build Coastguard Worker           unsigned extLen;
472*f6dc9357SAndroid Build Coastguard Worker           const WCHAR *name = temp + nameStartPos;
473*f6dc9357SAndroid Build Coastguard Worker           unsigned len = (unsigned)wcslen(name);
474*f6dc9357SAndroid Build Coastguard Worker           const unsigned nameLen = FindExt(temp + nameStartPos, &extLen);
475*f6dc9357SAndroid Build Coastguard Worker           const unsigned extPrice = FindItem(kExts, sizeof(kExts) / sizeof(kExts[0]), name + len - extLen, extLen);
476*f6dc9357SAndroid Build Coastguard Worker           const unsigned namePrice = FindItem(kNames, sizeof(kNames) / sizeof(kNames[0]), name, nameLen);
477*f6dc9357SAndroid Build Coastguard Worker 
478*f6dc9357SAndroid Build Coastguard Worker           const unsigned price = namePrice + extPrice * 64 + (nameStartPos == 0 ? 0 : (1 << 12));
479*f6dc9357SAndroid Build Coastguard Worker           if (minPrice > price)
480*f6dc9357SAndroid Build Coastguard Worker           {
481*f6dc9357SAndroid Build Coastguard Worker             minPrice = price;
482*f6dc9357SAndroid Build Coastguard Worker             executeFileIndex = i;
483*f6dc9357SAndroid Build Coastguard Worker             useShellExecute = (extPrice != k_EXE_ExtIndex);
484*f6dc9357SAndroid Build Coastguard Worker           }
485*f6dc9357SAndroid Build Coastguard Worker 
486*f6dc9357SAndroid Build Coastguard Worker           if (DoesFileOrDirExist(path))
487*f6dc9357SAndroid Build Coastguard Worker           {
488*f6dc9357SAndroid Build Coastguard Worker             errorMessage = "Duplicate file";
489*f6dc9357SAndroid Build Coastguard Worker             res = SZ_ERROR_FAIL;
490*f6dc9357SAndroid Build Coastguard Worker             break;
491*f6dc9357SAndroid Build Coastguard Worker           }
492*f6dc9357SAndroid Build Coastguard Worker           if (OutFile_OpenW(&outFile, path))
493*f6dc9357SAndroid Build Coastguard Worker           {
494*f6dc9357SAndroid Build Coastguard Worker             errorMessage = "Can't open output file";
495*f6dc9357SAndroid Build Coastguard Worker             res = SZ_ERROR_FAIL;
496*f6dc9357SAndroid Build Coastguard Worker             break;
497*f6dc9357SAndroid Build Coastguard Worker           }
498*f6dc9357SAndroid Build Coastguard Worker         }
499*f6dc9357SAndroid Build Coastguard Worker 
500*f6dc9357SAndroid Build Coastguard Worker         processedSize = outSizeProcessed;
501*f6dc9357SAndroid Build Coastguard Worker         if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
502*f6dc9357SAndroid Build Coastguard Worker         {
503*f6dc9357SAndroid Build Coastguard Worker           errorMessage = "Can't write output file";
504*f6dc9357SAndroid Build Coastguard Worker           res = SZ_ERROR_FAIL;
505*f6dc9357SAndroid Build Coastguard Worker         }
506*f6dc9357SAndroid Build Coastguard Worker 
507*f6dc9357SAndroid Build Coastguard Worker         #ifdef USE_WINDOWS_FILE
508*f6dc9357SAndroid Build Coastguard Worker         if (SzBitWithVals_Check(&db.MTime, i))
509*f6dc9357SAndroid Build Coastguard Worker         {
510*f6dc9357SAndroid Build Coastguard Worker           const CNtfsFileTime *t = db.MTime.Vals + i;
511*f6dc9357SAndroid Build Coastguard Worker           FILETIME mTime;
512*f6dc9357SAndroid Build Coastguard Worker           mTime.dwLowDateTime = t->Low;
513*f6dc9357SAndroid Build Coastguard Worker           mTime.dwHighDateTime = t->High;
514*f6dc9357SAndroid Build Coastguard Worker           SetFileTime(outFile.handle, NULL, NULL, &mTime);
515*f6dc9357SAndroid Build Coastguard Worker         }
516*f6dc9357SAndroid Build Coastguard Worker         #endif
517*f6dc9357SAndroid Build Coastguard Worker 
518*f6dc9357SAndroid Build Coastguard Worker         {
519*f6dc9357SAndroid Build Coastguard Worker           const WRes res2 = File_Close(&outFile);
520*f6dc9357SAndroid Build Coastguard Worker           if (res != SZ_OK)
521*f6dc9357SAndroid Build Coastguard Worker             break;
522*f6dc9357SAndroid Build Coastguard Worker           if (res2 != 0)
523*f6dc9357SAndroid Build Coastguard Worker           {
524*f6dc9357SAndroid Build Coastguard Worker             errorMessage = "Can't close output file";
525*f6dc9357SAndroid Build Coastguard Worker             res = SZ_ERROR_FAIL;
526*f6dc9357SAndroid Build Coastguard Worker             break;
527*f6dc9357SAndroid Build Coastguard Worker           }
528*f6dc9357SAndroid Build Coastguard Worker         }
529*f6dc9357SAndroid Build Coastguard Worker         #ifdef USE_WINDOWS_FILE
530*f6dc9357SAndroid Build Coastguard Worker         if (SzBitWithVals_Check(&db.Attribs, i))
531*f6dc9357SAndroid Build Coastguard Worker           SetFileAttributesW(path, db.Attribs.Vals[i]);
532*f6dc9357SAndroid Build Coastguard Worker         #endif
533*f6dc9357SAndroid Build Coastguard Worker       }
534*f6dc9357SAndroid Build Coastguard Worker     }
535*f6dc9357SAndroid Build Coastguard Worker 
536*f6dc9357SAndroid Build Coastguard Worker     if (res == SZ_OK)
537*f6dc9357SAndroid Build Coastguard Worker     {
538*f6dc9357SAndroid Build Coastguard Worker       if (executeFileIndex == (UInt32)(Int32)-1)
539*f6dc9357SAndroid Build Coastguard Worker       {
540*f6dc9357SAndroid Build Coastguard Worker         errorMessage = "There is no file to execute";
541*f6dc9357SAndroid Build Coastguard Worker         res = SZ_ERROR_FAIL;
542*f6dc9357SAndroid Build Coastguard Worker       }
543*f6dc9357SAndroid Build Coastguard Worker       else
544*f6dc9357SAndroid Build Coastguard Worker       {
545*f6dc9357SAndroid Build Coastguard Worker         WCHAR *temp = path + pathLen;
546*f6dc9357SAndroid Build Coastguard Worker         UInt32 j;
547*f6dc9357SAndroid Build Coastguard Worker         SzArEx_GetFileNameUtf16(&db, executeFileIndex, (UInt16 *)temp);
548*f6dc9357SAndroid Build Coastguard Worker         for (j = 0; temp[j] != 0; j++)
549*f6dc9357SAndroid Build Coastguard Worker           if (temp[j] == '/')
550*f6dc9357SAndroid Build Coastguard Worker             temp[j] = CHAR_PATH_SEPARATOR;
551*f6dc9357SAndroid Build Coastguard Worker       }
552*f6dc9357SAndroid Build Coastguard Worker     }
553*f6dc9357SAndroid Build Coastguard Worker     ISzAlloc_Free(&allocImp, outBuffer);
554*f6dc9357SAndroid Build Coastguard Worker   }
555*f6dc9357SAndroid Build Coastguard Worker 
556*f6dc9357SAndroid Build Coastguard Worker   SzArEx_Free(&db, &allocImp);
557*f6dc9357SAndroid Build Coastguard Worker 
558*f6dc9357SAndroid Build Coastguard Worker   ISzAlloc_Free(&allocImp, lookStream.buf);
559*f6dc9357SAndroid Build Coastguard Worker 
560*f6dc9357SAndroid Build Coastguard Worker   File_Close(&archiveStream.file);
561*f6dc9357SAndroid Build Coastguard Worker 
562*f6dc9357SAndroid Build Coastguard Worker   if (res == SZ_OK)
563*f6dc9357SAndroid Build Coastguard Worker   {
564*f6dc9357SAndroid Build Coastguard Worker     HANDLE hProcess = 0;
565*f6dc9357SAndroid Build Coastguard Worker 
566*f6dc9357SAndroid Build Coastguard Worker     #ifndef UNDER_CE
567*f6dc9357SAndroid Build Coastguard Worker     WCHAR oldCurDir[MAX_PATH + 2];
568*f6dc9357SAndroid Build Coastguard Worker     oldCurDir[0] = 0;
569*f6dc9357SAndroid Build Coastguard Worker     {
570*f6dc9357SAndroid Build Coastguard Worker       const DWORD needLen = GetCurrentDirectory(MAX_PATH + 1, oldCurDir);
571*f6dc9357SAndroid Build Coastguard Worker       if (needLen == 0 || needLen > MAX_PATH)
572*f6dc9357SAndroid Build Coastguard Worker         oldCurDir[0] = 0;
573*f6dc9357SAndroid Build Coastguard Worker       SetCurrentDirectory(workCurDir);
574*f6dc9357SAndroid Build Coastguard Worker     }
575*f6dc9357SAndroid Build Coastguard Worker     #endif
576*f6dc9357SAndroid Build Coastguard Worker 
577*f6dc9357SAndroid Build Coastguard Worker     if (useShellExecute)
578*f6dc9357SAndroid Build Coastguard Worker     {
579*f6dc9357SAndroid Build Coastguard Worker       SHELLEXECUTEINFO ei;
580*f6dc9357SAndroid Build Coastguard Worker       UINT32 executeRes;
581*f6dc9357SAndroid Build Coastguard Worker       BOOL success;
582*f6dc9357SAndroid Build Coastguard Worker 
583*f6dc9357SAndroid Build Coastguard Worker       memset(&ei, 0, sizeof(ei));
584*f6dc9357SAndroid Build Coastguard Worker       ei.cbSize = sizeof(ei);
585*f6dc9357SAndroid Build Coastguard Worker       ei.lpFile = path;
586*f6dc9357SAndroid Build Coastguard Worker       ei.fMask = SEE_MASK_NOCLOSEPROCESS
587*f6dc9357SAndroid Build Coastguard Worker           #ifndef UNDER_CE
588*f6dc9357SAndroid Build Coastguard Worker           | SEE_MASK_FLAG_DDEWAIT
589*f6dc9357SAndroid Build Coastguard Worker           #endif
590*f6dc9357SAndroid Build Coastguard Worker           /* | SEE_MASK_NO_CONSOLE */
591*f6dc9357SAndroid Build Coastguard Worker           ;
592*f6dc9357SAndroid Build Coastguard Worker       if (wcslen(cmdLineParams) != 0)
593*f6dc9357SAndroid Build Coastguard Worker         ei.lpParameters = cmdLineParams;
594*f6dc9357SAndroid Build Coastguard Worker       ei.nShow = SW_SHOWNORMAL; /* SW_HIDE; */
595*f6dc9357SAndroid Build Coastguard Worker       success = ShellExecuteEx(&ei);
596*f6dc9357SAndroid Build Coastguard Worker       executeRes = (UINT32)(UINT_PTR)ei.hInstApp;
597*f6dc9357SAndroid Build Coastguard Worker       if (!success || (executeRes <= 32 && executeRes != 0))  /* executeRes = 0 in Windows CE */
598*f6dc9357SAndroid Build Coastguard Worker         res = SZ_ERROR_FAIL;
599*f6dc9357SAndroid Build Coastguard Worker       else
600*f6dc9357SAndroid Build Coastguard Worker         hProcess = ei.hProcess;
601*f6dc9357SAndroid Build Coastguard Worker     }
602*f6dc9357SAndroid Build Coastguard Worker     else
603*f6dc9357SAndroid Build Coastguard Worker     {
604*f6dc9357SAndroid Build Coastguard Worker       STARTUPINFOW si;
605*f6dc9357SAndroid Build Coastguard Worker       PROCESS_INFORMATION pi;
606*f6dc9357SAndroid Build Coastguard Worker       WCHAR cmdLine[MAX_PATH * 3];
607*f6dc9357SAndroid Build Coastguard Worker 
608*f6dc9357SAndroid Build Coastguard Worker       wcscpy(cmdLine, path);
609*f6dc9357SAndroid Build Coastguard Worker       wcscat(cmdLine, cmdLineParams);
610*f6dc9357SAndroid Build Coastguard Worker       memset(&si, 0, sizeof(si));
611*f6dc9357SAndroid Build Coastguard Worker       si.cb = sizeof(si);
612*f6dc9357SAndroid Build Coastguard Worker       if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0)
613*f6dc9357SAndroid Build Coastguard Worker         res = SZ_ERROR_FAIL;
614*f6dc9357SAndroid Build Coastguard Worker       else
615*f6dc9357SAndroid Build Coastguard Worker       {
616*f6dc9357SAndroid Build Coastguard Worker         CloseHandle(pi.hThread);
617*f6dc9357SAndroid Build Coastguard Worker         hProcess = pi.hProcess;
618*f6dc9357SAndroid Build Coastguard Worker       }
619*f6dc9357SAndroid Build Coastguard Worker     }
620*f6dc9357SAndroid Build Coastguard Worker 
621*f6dc9357SAndroid Build Coastguard Worker     if (hProcess != 0)
622*f6dc9357SAndroid Build Coastguard Worker     {
623*f6dc9357SAndroid Build Coastguard Worker       WaitForSingleObject(hProcess, INFINITE);
624*f6dc9357SAndroid Build Coastguard Worker       if (!GetExitCodeProcess(hProcess, &exitCode))
625*f6dc9357SAndroid Build Coastguard Worker         exitCode = 1;
626*f6dc9357SAndroid Build Coastguard Worker       CloseHandle(hProcess);
627*f6dc9357SAndroid Build Coastguard Worker     }
628*f6dc9357SAndroid Build Coastguard Worker 
629*f6dc9357SAndroid Build Coastguard Worker     #ifndef UNDER_CE
630*f6dc9357SAndroid Build Coastguard Worker     SetCurrentDirectory(oldCurDir);
631*f6dc9357SAndroid Build Coastguard Worker     #endif
632*f6dc9357SAndroid Build Coastguard Worker   }
633*f6dc9357SAndroid Build Coastguard Worker 
634*f6dc9357SAndroid Build Coastguard Worker   path[pathLen] = L'\0';
635*f6dc9357SAndroid Build Coastguard Worker   RemoveDirWithSubItems(path);
636*f6dc9357SAndroid Build Coastguard Worker 
637*f6dc9357SAndroid Build Coastguard Worker   if (res == SZ_OK)
638*f6dc9357SAndroid Build Coastguard Worker     return (int)exitCode;
639*f6dc9357SAndroid Build Coastguard Worker 
640*f6dc9357SAndroid Build Coastguard Worker   {
641*f6dc9357SAndroid Build Coastguard Worker     if (res == SZ_ERROR_UNSUPPORTED)
642*f6dc9357SAndroid Build Coastguard Worker       errorMessage = "Decoder doesn't support this archive";
643*f6dc9357SAndroid Build Coastguard Worker     else if (res == SZ_ERROR_MEM)
644*f6dc9357SAndroid Build Coastguard Worker       errorMessage = "Can't allocate required memory";
645*f6dc9357SAndroid Build Coastguard Worker     else if (res == SZ_ERROR_CRC)
646*f6dc9357SAndroid Build Coastguard Worker       errorMessage = "CRC error";
647*f6dc9357SAndroid Build Coastguard Worker     else
648*f6dc9357SAndroid Build Coastguard Worker     {
649*f6dc9357SAndroid Build Coastguard Worker       if (!errorMessage)
650*f6dc9357SAndroid Build Coastguard Worker         errorMessage = "ERROR";
651*f6dc9357SAndroid Build Coastguard Worker     }
652*f6dc9357SAndroid Build Coastguard Worker 
653*f6dc9357SAndroid Build Coastguard Worker     if (errorMessage)
654*f6dc9357SAndroid Build Coastguard Worker       PrintErrorMessage(errorMessage);
655*f6dc9357SAndroid Build Coastguard Worker   }
656*f6dc9357SAndroid Build Coastguard Worker   return 1;
657*f6dc9357SAndroid Build Coastguard Worker }
658