https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8d788973842da2cfcb5f6…
commit 8d788973842da2cfcb5f6340a8d9b74038cf90ed
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Thu Jul 13 19:10:27 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Mon Oct 8 21:16:46 2018 +0200
[USERINIT] Enhancements for starting ReactOS GUI installer or Explorer shell.
- Transform TryToStartShell() into a StartProcess() function whose aim
is just to start processes, since there is no extra initialization needed
for starting a shell process.
- Modify StartInstaller() to call StartProcess() for starting the ReactOS GUI
installer found on the installation media, from a path automatically expanded
depending on the ambient CPU architecture.
svn path=/branches/setup_improvements/; revision=75331
---
base/system/userinit/userinit.c | 164 ++++++++++++++++++++++++++++++++--------
base/system/userinit/userinit.h | 17 +++--
2 files changed, 141 insertions(+), 40 deletions(-)
diff --git a/base/system/userinit/userinit.c b/base/system/userinit/userinit.c
index 4369a499c2..182c823dce 100644
--- a/base/system/userinit/userinit.c
+++ b/base/system/userinit/userinit.c
@@ -183,14 +183,16 @@ GetShell(
}
static BOOL
-TryToStartShell(
- IN LPCWSTR Shell)
+StartProcess(
+ IN LPCWSTR CommandLine)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
- WCHAR ExpandedShell[MAX_PATH];
+ WCHAR ExpandedCmdLine[MAX_PATH];
- TRACE("(%s)\n", debugstr_w(Shell));
+ TRACE("(%s)\n", debugstr_w(CommandLine));
+
+ ExpandEnvironmentStringsW(CommandLine, ExpandedCmdLine, ARRAYSIZE(ExpandedCmdLine));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
@@ -198,10 +200,8 @@ TryToStartShell(
si.wShowWindow = SW_SHOWNORMAL;
ZeroMemory(&pi, sizeof(pi));
- ExpandEnvironmentStringsW(Shell, ExpandedShell, ARRAYSIZE(ExpandedShell));
-
if (!CreateProcessW(NULL,
- ExpandedShell,
+ ExpandedCmdLine,
NULL,
NULL,
FALSE,
@@ -211,7 +211,7 @@ TryToStartShell(
&si,
&pi))
{
- WARN("CreateProcess() failed with error %lu\n", GetLastError());
+ WARN("CreateProcessW() failed with error %lu\n", GetLastError());
return FALSE;
}
@@ -267,7 +267,7 @@ StartShell(VOID)
TRACE("Key located - %s\n",
debugstr_w(Shell));
/* Try to run alternate shell */
- if (TryToStartShell(Shell))
+ if (StartProcess(Shell))
{
TRACE("Alternate shell started (Safe
Mode)\n");
return TRUE;
@@ -294,14 +294,14 @@ StartShell(VOID)
}
/* Try to run shell in user key */
- if (GetShell(Shell, HKEY_CURRENT_USER) && TryToStartShell(Shell))
+ if (GetShell(Shell, HKEY_CURRENT_USER) && StartProcess(Shell))
{
TRACE("Started shell from HKEY_CURRENT_USER\n");
return TRUE;
}
/* Try to run shell in local machine key */
- if (GetShell(Shell, HKEY_LOCAL_MACHINE) && TryToStartShell(Shell))
+ if (GetShell(Shell, HKEY_LOCAL_MACHINE) && StartProcess(Shell))
{
TRACE("Started shell from HKEY_LOCAL_MACHINE\n");
return TRUE;
@@ -310,22 +310,22 @@ StartShell(VOID)
/* Try default shell */
if (IsConsoleShell())
{
+ *Shell = UNICODE_NULL;
if (GetSystemDirectoryW(Shell, ARRAYSIZE(Shell) - 8))
- wcscat(Shell, L"\\cmd.exe");
- else
- wcscpy(Shell, L"cmd.exe");
+ StringCchCatW(Shell, ARRAYSIZE(Shell), L"\\");
+ StringCchCatW(Shell, ARRAYSIZE(Shell), L"cmd.exe");
}
else
{
- if (GetWindowsDirectoryW(Shell, ARRAYSIZE(Shell) - 13))
- wcscat(Shell, L"\\explorer.exe");
- else
- wcscpy(Shell, L"explorer.exe");
+ *Shell = UNICODE_NULL;
+ if (GetSystemWindowsDirectoryW(Shell, ARRAYSIZE(Shell) - 13))
+ StringCchCatW(Shell, ARRAYSIZE(Shell), L"\\");
+ StringCchCatW(Shell, ARRAYSIZE(Shell), L"explorer.exe");
}
- if (!TryToStartShell(Shell))
+ if (!StartProcess(Shell))
{
- WARN("Failed to start default shell %s\n", debugstr_w(Shell));
+ WARN("Failed to start default shell '%s'\n",
debugstr_w(Shell));
LoadStringW(GetModuleHandle(NULL), IDS_SHELL_FAIL, szMsg, ARRAYSIZE(szMsg));
MessageBoxW(NULL, szMsg, NULL, MB_OK);
return FALSE;
@@ -501,24 +501,124 @@ NotifyLogon(VOID)
}
static BOOL
-StartInstaller(VOID)
+StartInstaller(IN LPCTSTR lpInstallerName)
{
- WCHAR Shell[MAX_PATH];
+ SYSTEM_INFO SystemInfo;
+ SIZE_T cchInstallerNameLen;
+ PWSTR ptr;
+ DWORD dwAttribs;
+ WCHAR Installer[MAX_PATH];
WCHAR szMsg[RC_STRING_MAX_SIZE];
- if (GetWindowsDirectoryW(Shell, ARRAYSIZE(Shell) - 12))
- wcscat(Shell, L"\\reactos.exe");
+ cchInstallerNameLen = wcslen(lpInstallerName);
+ if (ARRAYSIZE(Installer) < cchInstallerNameLen)
+ {
+ /* The buffer is not large enough to contain the installer file name */
+ return FALSE;
+ }
+
+ /*
+ * First, try to find the installer using the default drive, under
+ * the directory whose name corresponds to the currently-running
+ * CPU architecture.
+ */
+ GetSystemInfo(&SystemInfo);
+
+ *Installer = UNICODE_NULL;
+ /* Alternatively one can use SharedUserData->NtSystemRoot */
+ GetSystemWindowsDirectoryW(Installer, ARRAYSIZE(Installer) - cchInstallerNameLen -
1);
+ ptr = wcschr(Installer, L'\\');
+ if (ptr)
+ *++ptr = UNICODE_NULL;
else
- wcscpy(Shell, L"reactos.exe");
+ *Installer = UNICODE_NULL;
- if (!TryToStartShell(Shell))
+ /* Append the corresponding CPU architecture */
+ switch (SystemInfo.wProcessorArchitecture)
{
- WARN("Failed to start the installer: %s\n", debugstr_w(Shell));
- LoadStringW(GetModuleHandle(NULL), IDS_INSTALLER_FAIL, szMsg, ARRAYSIZE(szMsg));
- MessageBoxW(NULL, szMsg, NULL, MB_OK);
- return FALSE;
+ case PROCESSOR_ARCHITECTURE_INTEL:
+ StringCchCatW(Installer, ARRAYSIZE(Installer), L"I386");
+ break;
+
+ case PROCESSOR_ARCHITECTURE_MIPS:
+ StringCchCatW(Installer, ARRAYSIZE(Installer), L"MIPS");
+ break;
+
+ case PROCESSOR_ARCHITECTURE_ALPHA:
+ StringCchCatW(Installer, ARRAYSIZE(Installer), L"ALPHA");
+ break;
+
+ case PROCESSOR_ARCHITECTURE_PPC:
+ StringCchCatW(Installer, ARRAYSIZE(Installer), L"PPC");
+ break;
+
+ case PROCESSOR_ARCHITECTURE_SHX:
+ StringCchCatW(Installer, ARRAYSIZE(Installer), L"SHX");
+ break;
+
+ case PROCESSOR_ARCHITECTURE_ARM:
+ StringCchCatW(Installer, ARRAYSIZE(Installer), L"ARM");
+ break;
+
+ case PROCESSOR_ARCHITECTURE_IA64:
+ StringCchCatW(Installer, ARRAYSIZE(Installer), L"IA64");
+ break;
+
+ case PROCESSOR_ARCHITECTURE_ALPHA64:
+ StringCchCatW(Installer, ARRAYSIZE(Installer), L"ALPHA64");
+ break;
+
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ StringCchCatW(Installer, ARRAYSIZE(Installer), L"AMD64");
+ break;
+
+ // case PROCESSOR_ARCHITECTURE_MSIL: /* .NET CPU-independent code */
+ case PROCESSOR_ARCHITECTURE_UNKNOWN:
+ default:
+ WARN("Unknown processor architecture %lu\n",
SystemInfo.wProcessorArchitecture);
+ SystemInfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_UNKNOWN;
+ break;
}
- return TRUE;
+
+ if (SystemInfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_UNKNOWN)
+ StringCchCatW(Installer, ARRAYSIZE(Installer), L"\\");
+ StringCchCatW(Installer, ARRAYSIZE(Installer), lpInstallerName);
+
+ dwAttribs = GetFileAttributesW(Installer);
+ if ((dwAttribs != INVALID_FILE_ATTRIBUTES) &&
+ !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ /* We have found the installer */
+ if (StartProcess(Installer))
+ return TRUE;
+ }
+
+ ERR("Failed to start the installer '%s', trying alternative.\n",
debugstr_w(Installer));
+
+ /*
+ * We failed. Try to find the installer from either the current
+ * ReactOS installation directory, or from our current directory.
+ */
+ *Installer = UNICODE_NULL;
+ /* Alternatively one can use SharedUserData->NtSystemRoot */
+ if (GetSystemWindowsDirectoryW(Installer, ARRAYSIZE(Installer) - cchInstallerNameLen
- 1))
+ StringCchCatW(Installer, ARRAYSIZE(Installer), L"\\");
+ StringCchCatW(Installer, ARRAYSIZE(Installer), lpInstallerName);
+
+ dwAttribs = GetFileAttributesW(Installer);
+ if ((dwAttribs != INVALID_FILE_ATTRIBUTES) &&
+ !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ /* We have found the installer */
+ if (StartProcess(Installer))
+ return TRUE;
+ }
+
+ /* We failed. Display an error message and quit. */
+ ERR("Failed to start the installer '%s'.\n",
debugstr_w(Installer));
+ LoadStringW(GetModuleHandle(NULL), IDS_INSTALLER_FAIL, szMsg, ARRAYSIZE(szMsg));
+ MessageBoxW(NULL, szMsg, NULL, MB_OK);
+ return FALSE;
}
/* Used to get the shutdown privilege */
@@ -591,7 +691,7 @@ Restart:
break;
case INSTALLER:
- Success = StartInstaller();
+ Success = StartInstaller(L"reactos.exe");
break;
case REBOOT:
diff --git a/base/system/userinit/userinit.h b/base/system/userinit/userinit.h
index bd22b60fee..46079756a6 100644
--- a/base/system/userinit/userinit.h
+++ b/base/system/userinit/userinit.h
@@ -4,22 +4,23 @@
#ifndef __USERINIT_H__
#define __USERINIT_H__
+#include <stdio.h>
+#include <stdlib.h>
+
+/* PSDK/NDK Headers */
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
-#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
-#include <winreg.h>
#include <wingdi.h>
-#include <wincon.h>
-#include <shellapi.h>
+#include <winreg.h>
#include <regstr.h>
-#include <shlobj.h>
-#include <shlwapi.h>
-#include <undocuser.h>
#include <winnls.h>
-#include <stdio.h>
+#include <winuser.h>
+#include <undocuser.h>
+
+#include <strsafe.h>
#include <ndk/exfuncs.h>