mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 11:12:58 +00:00
552 lines
13 KiB
C
552 lines
13 KiB
C
/* $Id: init.c,v 1.32 2002/03/18 22:44:42 hbirr Exp $
|
|
*
|
|
* init.c - Session Manager initialization
|
|
*
|
|
* ReactOS Operating System
|
|
*
|
|
* --------------------------------------------------------------------
|
|
*
|
|
* This software is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this software; see the file COPYING.LIB. If not, write
|
|
* to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
|
|
* MA 02139, USA.
|
|
*
|
|
* --------------------------------------------------------------------
|
|
*
|
|
* 19990530 (Emanuele Aliberti)
|
|
* Compiled successfully with egcs 1.1.2
|
|
*/
|
|
#include <ntos.h>
|
|
#include <ntdll/rtl.h>
|
|
#include <napi/lpc.h>
|
|
#include <napi/shared_data.h>
|
|
|
|
#include "smss.h"
|
|
|
|
#define NDEBUG
|
|
|
|
/* TYPES ********************************************************************/
|
|
|
|
/*
|
|
* NOTE: This is only used until the dos device links are
|
|
* read from the registry!!
|
|
*/
|
|
typedef struct
|
|
{
|
|
PWSTR DeviceName;
|
|
PWSTR LinkName;
|
|
} LINKDATA, *PLINKDATA;
|
|
|
|
/* GLOBAL VARIABLES *********************************************************/
|
|
|
|
HANDLE SmApiPort = INVALID_HANDLE_VALUE;
|
|
HANDLE DbgSsApiPort = INVALID_HANDLE_VALUE;
|
|
HANDLE DbgUiApiPort = INVALID_HANDLE_VALUE;
|
|
|
|
PWSTR SmSystemEnvironment = NULL;
|
|
|
|
|
|
/* FUNCTIONS ****************************************************************/
|
|
|
|
static VOID
|
|
SmCreatePagingFiles (VOID)
|
|
{
|
|
UNICODE_STRING FileName;
|
|
LARGE_INTEGER InitialSize;
|
|
LARGE_INTEGER MaximumSize;
|
|
NTSTATUS Status;
|
|
|
|
/* FIXME: Read file names from registry */
|
|
|
|
RtlInitUnicodeString (&FileName,
|
|
L"\\SystemRoot\\pagefile.sys");
|
|
|
|
InitialSize.QuadPart = 50 * 4096;
|
|
MaximumSize.QuadPart = 80 * 4096;
|
|
|
|
Status = NtCreatePagingFile(&FileName,
|
|
&InitialSize,
|
|
&MaximumSize,
|
|
0);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
PrintString("SM: Failed to create paging file (Status was 0x%.8X)\n", Status);
|
|
}
|
|
}
|
|
|
|
|
|
static VOID
|
|
SmInitDosDevices(VOID)
|
|
{
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
UNICODE_STRING DeviceName;
|
|
UNICODE_STRING LinkName;
|
|
HANDLE LinkHandle;
|
|
#if 0
|
|
HANDLE DeviceHandle;
|
|
IO_STATUS_BLOCK StatusBlock;
|
|
#endif
|
|
NTSTATUS Status;
|
|
WCHAR LinkBuffer[80];
|
|
|
|
PLINKDATA LinkPtr;
|
|
LINKDATA LinkData[] =
|
|
{{L"\\Device\\NamedPipe", L"PIPE"},
|
|
{L"\\Device\\Null", L"NUL"},
|
|
{L"\\Device\\Mup", L"UNC"},
|
|
{L"\\Device\\MailSlot", L"MAILSLOT"},
|
|
{L"\\DosDevices\\COM1", L"AUX"},
|
|
{L"\\DosDevices\\LPT1", L"PRN"},
|
|
{NULL, NULL}};
|
|
|
|
/* FIXME: Read the list of symbolic links from the registry!! */
|
|
|
|
LinkPtr = &LinkData[0];
|
|
while (LinkPtr->DeviceName != NULL)
|
|
{
|
|
swprintf(LinkBuffer, L"\\??\\%s",
|
|
LinkPtr->LinkName);
|
|
RtlInitUnicodeString(&LinkName,
|
|
LinkBuffer);
|
|
RtlInitUnicodeString(&DeviceName,
|
|
LinkPtr->DeviceName);
|
|
|
|
#if 0
|
|
/* check if target device exists (can be opened) */
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&DeviceName,
|
|
0,
|
|
NULL,
|
|
NULL);
|
|
|
|
Status = NtOpenFile(&DeviceHandle,
|
|
0x10001,
|
|
&ObjectAttributes,
|
|
&StatusBlock,
|
|
1,
|
|
FILE_SYNCHRONOUS_IO_NONALERT);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
NtClose(DeviceHandle);
|
|
#endif
|
|
/* create symbolic link */
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&LinkName,
|
|
OBJ_PERMANENT,
|
|
NULL,
|
|
NULL);
|
|
|
|
Status = NtCreateSymbolicLinkObject(&LinkHandle,
|
|
SYMBOLIC_LINK_ALL_ACCESS,
|
|
&ObjectAttributes,
|
|
&DeviceName);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
PrintString("SM: NtCreateSymbolicLink( %wZ --> %wZ ) failed!\n",
|
|
&LinkName,
|
|
&DeviceName);
|
|
}
|
|
NtClose(LinkHandle);
|
|
#if 0
|
|
}
|
|
#endif
|
|
LinkPtr++;
|
|
}
|
|
}
|
|
|
|
|
|
static VOID
|
|
SmSetEnvironmentVariables (VOID)
|
|
{
|
|
UNICODE_STRING EnvVariable;
|
|
UNICODE_STRING EnvValue;
|
|
UNICODE_STRING EnvExpandedValue;
|
|
ULONG ExpandedLength;
|
|
WCHAR ExpandBuffer[512];
|
|
WCHAR ValueBuffer[MAX_PATH];
|
|
PKUSER_SHARED_DATA SharedUserData =
|
|
(PKUSER_SHARED_DATA)USER_SHARED_DATA_BASE;
|
|
|
|
/*
|
|
* The following environment variables are read from the registry.
|
|
* Because the registry does not work yet, the environment variables
|
|
* are set one by one, using information from the shared user page.
|
|
*
|
|
* Variables (example):
|
|
* SystemRoot = C:\reactos
|
|
* SystemDrive = C:
|
|
*
|
|
* OS = ReactOS
|
|
* Path = %SystemRoot%\system32;%SystemRoot%
|
|
* windir = %SystemRoot%
|
|
*/
|
|
|
|
/* copy system root into value buffer */
|
|
wcscpy (ValueBuffer, SharedUserData->NtSystemRoot);
|
|
|
|
/* set "SystemRoot = C:\reactos" */
|
|
RtlInitUnicodeString (&EnvVariable,
|
|
L"SystemRoot");
|
|
RtlInitUnicodeString (&EnvValue,
|
|
ValueBuffer);
|
|
RtlSetEnvironmentVariable (&SmSystemEnvironment,
|
|
&EnvVariable,
|
|
&EnvValue);
|
|
|
|
/* cut off trailing path */
|
|
ValueBuffer[2] = 0;
|
|
|
|
/* Set "SystemDrive = C:" */
|
|
RtlInitUnicodeString (&EnvVariable,
|
|
L"SystemDrive");
|
|
RtlInitUnicodeString (&EnvValue,
|
|
ValueBuffer);
|
|
RtlSetEnvironmentVariable (&SmSystemEnvironment,
|
|
&EnvVariable,
|
|
&EnvValue);
|
|
|
|
|
|
/* Set "OS = ReactOS" */
|
|
RtlInitUnicodeString (&EnvVariable,
|
|
L"OS");
|
|
RtlInitUnicodeString (&EnvValue,
|
|
L"ReactOS");
|
|
RtlSetEnvironmentVariable (&SmSystemEnvironment,
|
|
&EnvVariable,
|
|
&EnvValue);
|
|
|
|
|
|
/* Set "Path = %SystemRoot%\system32;%SystemRoot%" */
|
|
RtlInitUnicodeString (&EnvVariable,
|
|
L"Path");
|
|
RtlInitUnicodeString (&EnvValue,
|
|
L"%SystemRoot%\\system32;%SystemRoot%");
|
|
EnvExpandedValue.Length = 0;
|
|
EnvExpandedValue.MaximumLength = 512 * sizeof(WCHAR);
|
|
EnvExpandedValue.Buffer = ExpandBuffer;
|
|
*ExpandBuffer = 0;
|
|
RtlExpandEnvironmentStrings_U (SmSystemEnvironment,
|
|
&EnvValue,
|
|
&EnvExpandedValue,
|
|
&ExpandedLength);
|
|
RtlSetEnvironmentVariable (&SmSystemEnvironment,
|
|
&EnvVariable,
|
|
&EnvExpandedValue);
|
|
|
|
/* Set "windir = %SystemRoot%" */
|
|
RtlInitUnicodeString (&EnvVariable,
|
|
L"windir");
|
|
RtlInitUnicodeString (&EnvValue,
|
|
L"%SystemRoot%");
|
|
EnvExpandedValue.Length = 0;
|
|
EnvExpandedValue.MaximumLength = 512 * sizeof(WCHAR);
|
|
EnvExpandedValue.Buffer = ExpandBuffer;
|
|
*ExpandBuffer = 0;
|
|
RtlExpandEnvironmentStrings_U (SmSystemEnvironment,
|
|
&EnvValue,
|
|
&EnvExpandedValue,
|
|
&ExpandedLength);
|
|
RtlSetEnvironmentVariable (&SmSystemEnvironment,
|
|
&EnvVariable,
|
|
&EnvExpandedValue);
|
|
}
|
|
|
|
|
|
BOOL InitSessionManager (HANDLE Children[])
|
|
{
|
|
NTSTATUS Status;
|
|
UNICODE_STRING UnicodeString;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
UNICODE_STRING CmdLineW;
|
|
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
|
|
RTL_PROCESS_INFO ProcessInfo;
|
|
HANDLE CsrssInitEvent;
|
|
HANDLE WindowsDirectory;
|
|
WCHAR UnicodeBuffer[MAX_PATH];
|
|
PKUSER_SHARED_DATA SharedUserData =
|
|
(PKUSER_SHARED_DATA)USER_SHARED_DATA_BASE;
|
|
|
|
/*
|
|
* FIXME: The '\Windows' directory is created by csrss.exe but
|
|
* win32k.sys needs it at intialization and it is loaded
|
|
* before csrss.exe
|
|
*/
|
|
|
|
/*
|
|
* Create the '\Windows' directory
|
|
*/
|
|
RtlInitUnicodeString(&UnicodeString,
|
|
L"\\Windows");
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&UnicodeString,
|
|
0,
|
|
NULL,
|
|
NULL);
|
|
|
|
Status = ZwCreateDirectoryObject(&WindowsDirectory,
|
|
0,
|
|
&ObjectAttributes);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DisplayString(L"SM: Could not create \\Windows directory!\n");
|
|
return FALSE;
|
|
}
|
|
|
|
/* Create the "\SmApiPort" object (LPC) */
|
|
RtlInitUnicodeString(&UnicodeString,
|
|
L"\\SmApiPort");
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&UnicodeString,
|
|
PORT_ALL_ACCESS,
|
|
NULL,
|
|
NULL);
|
|
|
|
Status = NtCreatePort(&SmApiPort,
|
|
&ObjectAttributes,
|
|
0,
|
|
0,
|
|
0);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
DisplayString (L"SM: \\SmApiPort created...\n");
|
|
#endif
|
|
|
|
/* Create two threads for "\SmApiPort" */
|
|
RtlCreateUserThread(NtCurrentProcess(),
|
|
NULL,
|
|
FALSE,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
(PTHREAD_START_ROUTINE)SmApiThread,
|
|
(PVOID)SmApiPort,
|
|
NULL,
|
|
NULL);
|
|
|
|
RtlCreateUserThread (NtCurrentProcess (),
|
|
NULL,
|
|
FALSE,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
(PTHREAD_START_ROUTINE)SmApiThread,
|
|
(PVOID)SmApiPort,
|
|
NULL,
|
|
NULL);
|
|
|
|
/* Create the system environment */
|
|
Status = RtlCreateEnvironment(FALSE,
|
|
&SmSystemEnvironment);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return FALSE;
|
|
}
|
|
#ifndef NDEBUG
|
|
DisplayString (L"SM: System Environment created\n");
|
|
#endif
|
|
|
|
/* Define symbolic links to kernel devices (MS-DOS names) */
|
|
SmInitDosDevices();
|
|
|
|
/* FIXME: Run all programs in the boot execution list */
|
|
// SmRunBootApps();
|
|
|
|
/* FIXME: Process the file rename list */
|
|
// SmProcessFileRenameList();
|
|
|
|
/* FIXME: Load the well known DLLs */
|
|
// SmPreloadDlls();
|
|
|
|
/* Create paging files */
|
|
SmCreatePagingFiles();
|
|
|
|
/* Load remaining registry hives */
|
|
NtInitializeRegistry(FALSE);
|
|
|
|
/* Set environment variables from registry */
|
|
SmSetEnvironmentVariables();
|
|
|
|
/* Load the kernel mode driver win32k.sys */
|
|
RtlInitUnicodeString(&CmdLineW,
|
|
L"\\SystemRoot\\system32\\drivers\\win32k.sys");
|
|
Status = NtLoadDriver(&CmdLineW);
|
|
#if 0
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
/* Run csrss.exe */
|
|
RtlInitUnicodeString(&UnicodeString,
|
|
L"\\CsrssInitDone");
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&UnicodeString,
|
|
EVENT_ALL_ACCESS,
|
|
0,
|
|
NULL);
|
|
Status = NtCreateEvent(&CsrssInitEvent,
|
|
EVENT_ALL_ACCESS,
|
|
&ObjectAttributes,
|
|
TRUE,
|
|
FALSE);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DbgPrint("Failed to create csrss notification event\n");
|
|
}
|
|
|
|
/*
|
|
* Start the Win32 subsystem (csrss.exe)
|
|
*/
|
|
|
|
/* initialize executable path */
|
|
wcscpy(UnicodeBuffer, L"\\??\\");
|
|
wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
|
|
wcscat(UnicodeBuffer, L"\\system32\\csrss.exe");
|
|
RtlInitUnicodeString(&UnicodeString,
|
|
UnicodeBuffer);
|
|
|
|
RtlCreateProcessParameters(&ProcessParameters,
|
|
&UnicodeString,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
SmSystemEnvironment,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
|
|
Status = RtlCreateUserProcess(&UnicodeString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
ProcessParameters,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
FALSE,
|
|
NULL,
|
|
NULL,
|
|
&ProcessInfo);
|
|
|
|
RtlDestroyProcessParameters (ProcessParameters);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DisplayString(L"SM: Loading csrss.exe failed!\n");
|
|
return FALSE;
|
|
}
|
|
|
|
NtWaitForSingleObject(CsrssInitEvent,
|
|
FALSE,
|
|
NULL);
|
|
|
|
Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;
|
|
|
|
/*
|
|
* Start the logon process (winlogon.exe)
|
|
*/
|
|
|
|
/* initialize executable path */
|
|
wcscpy(UnicodeBuffer, L"\\??\\");
|
|
wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
|
|
wcscat(UnicodeBuffer, L"\\system32\\winlogon.exe");
|
|
RtlInitUnicodeString(&UnicodeString,
|
|
UnicodeBuffer);
|
|
|
|
RtlCreateProcessParameters(&ProcessParameters,
|
|
&UnicodeString,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
SmSystemEnvironment,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
|
|
Status = RtlCreateUserProcess(&UnicodeString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
ProcessParameters,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
FALSE,
|
|
NULL,
|
|
NULL,
|
|
&ProcessInfo);
|
|
|
|
RtlDestroyProcessParameters(ProcessParameters);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DisplayString(L"SM: Loading winlogon.exe failed!\n");
|
|
NtTerminateProcess(Children[CHILD_CSRSS],
|
|
0);
|
|
return FALSE;
|
|
}
|
|
Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
|
|
|
|
/* Create the \DbgSsApiPort object (LPC) */
|
|
RtlInitUnicodeString(&UnicodeString,
|
|
L"\\DbgSsApiPort");
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&UnicodeString,
|
|
PORT_ALL_ACCESS,
|
|
NULL,
|
|
NULL);
|
|
|
|
Status = NtCreatePort(&DbgSsApiPort,
|
|
&ObjectAttributes,
|
|
0,
|
|
0,
|
|
0);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return FALSE;
|
|
}
|
|
#ifndef NDEBUG
|
|
DisplayString(L"SM: DbgSsApiPort created...\n");
|
|
#endif
|
|
|
|
/* Create the \DbgUiApiPort object (LPC) */
|
|
RtlInitUnicodeString(&UnicodeString,
|
|
L"\\DbgUiApiPort");
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&UnicodeString,
|
|
PORT_ALL_ACCESS,
|
|
NULL,
|
|
NULL);
|
|
|
|
Status = NtCreatePort(&DbgUiApiPort,
|
|
&ObjectAttributes,
|
|
0,
|
|
0,
|
|
0);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return FALSE;
|
|
}
|
|
#ifndef NDEBUG
|
|
DisplayString (L"SM: DbgUiApiPort created...\n");
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* EOF */
|