mirror of
https://github.com/reactos/reactos.git
synced 2026-06-08 08:52:59 +08:00
[USERINIT] In LiveCD/"MiniNT" mode, start the shell with a suitable environment block
Using `userenv!CreateEnvironmentBlock()` when starting the shell ensures that, even if it's started as LocalSystem, its environment inherits the "dynamical" environment variables created by SMSS at runtime (stored in `HKLM\SYSTEM\CurrentControlSet\Session Manager\Environment`). In ReactOS/Windows PE "MiniNT" mode, the Winlogon environment doesn't contain these values, and doesn't start the Setup with this augmented environment. (This is compatible with what Windows does, on WinPE or during a clean installation.) Winlogon creates an augmented environment only when a user logs in and starts its shell (standard boot), which isn't the case in "MiniNT" mode. It is thus the responsibility of the module that starts the shell instead to do it: in ReactOS' case, userinit.exe in LiveCD mode. As a result, we get access to the `COMPUTERNAME`, `NUMBER_OF_PROCESSORS`, `OS`, and `PROCESSOR_*` environment variables, amongst others.
This commit is contained in:
@@ -7,6 +7,6 @@ list(APPEND SOURCE
|
||||
add_executable(userinit ${SOURCE} userinit.rc)
|
||||
target_link_libraries(userinit wine)
|
||||
set_module_type(userinit win32gui UNICODE)
|
||||
add_importlibs(userinit advapi32 gdi32 user32 msvcrt kernel32 ntdll)
|
||||
add_importlibs(userinit advapi32 userenv gdi32 user32 msvcrt kernel32 ntdll)
|
||||
add_pch(userinit userinit.h SOURCE)
|
||||
add_cd_file(TARGET userinit DESTINATION reactos/system32 FOR all)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "userinit.h"
|
||||
#include <userenv.h>
|
||||
|
||||
#define CMP_MAGIC 0x01234567
|
||||
|
||||
@@ -178,7 +179,8 @@ GetShell(
|
||||
|
||||
static BOOL
|
||||
StartProcess(
|
||||
IN LPCWSTR CommandLine)
|
||||
_In_ PCWSTR CommandLine,
|
||||
_In_opt_ PVOID pEnvironment)
|
||||
{
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
@@ -197,8 +199,8 @@ StartProcess(
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
NORMAL_PRIORITY_CLASS,
|
||||
NULL,
|
||||
NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT,
|
||||
pEnvironment,
|
||||
NULL,
|
||||
&si,
|
||||
&pi))
|
||||
@@ -213,7 +215,8 @@ StartProcess(
|
||||
}
|
||||
|
||||
static BOOL
|
||||
StartShell(VOID)
|
||||
StartShell(
|
||||
_In_opt_ PVOID pEnvironment)
|
||||
{
|
||||
DWORD Type, Size;
|
||||
DWORD Value = 0;
|
||||
@@ -257,7 +260,7 @@ StartShell(VOID)
|
||||
TRACE("Key located - %s\n", debugstr_w(Shell));
|
||||
|
||||
/* Try to run alternate shell */
|
||||
if (StartProcess(Shell))
|
||||
if (StartProcess(Shell, pEnvironment))
|
||||
{
|
||||
TRACE("Alternate shell started (Safe Mode)\n");
|
||||
return TRUE;
|
||||
@@ -284,14 +287,14 @@ StartShell(VOID)
|
||||
}
|
||||
|
||||
/* Try to run shell in user key */
|
||||
if (GetShell(Shell, HKEY_CURRENT_USER) && StartProcess(Shell))
|
||||
if (GetShell(Shell, HKEY_CURRENT_USER) && StartProcess(Shell, pEnvironment))
|
||||
{
|
||||
TRACE("Started shell from HKEY_CURRENT_USER\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Try to run shell in local machine key */
|
||||
if (GetShell(Shell, HKEY_LOCAL_MACHINE) && StartProcess(Shell))
|
||||
if (GetShell(Shell, HKEY_LOCAL_MACHINE) && StartProcess(Shell, pEnvironment))
|
||||
{
|
||||
TRACE("Started shell from HKEY_LOCAL_MACHINE\n");
|
||||
return TRUE;
|
||||
@@ -313,7 +316,7 @@ StartShell(VOID)
|
||||
StringCchCatW(Shell, ARRAYSIZE(Shell), L"explorer.exe");
|
||||
}
|
||||
|
||||
if (StartProcess(Shell))
|
||||
if (StartProcess(Shell, pEnvironment))
|
||||
return TRUE;
|
||||
|
||||
/* We failed, display an error message and quit */
|
||||
@@ -613,7 +616,7 @@ StartInstaller(IN LPCWSTR lpInstallerName)
|
||||
if (ExpandInstallerPath(lpInstallerName, Installer, ARRAYSIZE(Installer)))
|
||||
{
|
||||
/* We have found the installer */
|
||||
if (StartProcess(Installer))
|
||||
if (StartProcess(Installer, NULL))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -688,10 +691,23 @@ Restart:
|
||||
switch (State.Run)
|
||||
{
|
||||
case SHELL:
|
||||
Success = StartShell();
|
||||
{
|
||||
/* In LiveCD mode, create a suitable environment block for the
|
||||
* shell; otherwise, use the current one (built by WinLogon) */
|
||||
PVOID pEnvironment = NULL;
|
||||
if (bIsLiveCD && /* In LiveCD mode we run under the LocalSystem account */
|
||||
!CreateEnvironmentBlock(&pEnvironment, NULL, TRUE))
|
||||
{
|
||||
WARN("CreateEnvironmentBlock() failed, fall back to default (error %lu)\n",
|
||||
GetLastError());
|
||||
}
|
||||
Success = StartShell(pEnvironment);
|
||||
if (pEnvironment)
|
||||
DestroyEnvironmentBlock(pEnvironment);
|
||||
if (Success)
|
||||
NotifyLogon();
|
||||
break;
|
||||
}
|
||||
|
||||
case INSTALLER:
|
||||
Success = StartInstaller(L"reactos.exe");
|
||||
|
||||
Reference in New Issue
Block a user