https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8d788973842da2cfcb5f63...
commit 8d788973842da2cfcb5f6340a8d9b74038cf90ed Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Thu Jul 13 19:10:27 2017 +0000 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@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>