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