-/* $Id: init.c,v 1.13 2000/02/21 22:43:15 ekohl Exp $
+/* $Id: init.c,v 1.32 2002/03/18 22:44:42 hbirr Exp $
*
* init.c - Session Manager initialization
*
* 19990530 (Emanuele Aliberti)
* Compiled successfully with egcs 1.1.2
*/
-#include <ddk/ntddk.h>
+#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 DbgSsApiPort = INVALID_HANDLE_VALUE;
HANDLE DbgUiApiPort = INVALID_HANDLE_VALUE;
-PVOID SmSystemEnvironment = NULL;
+PWSTR SmSystemEnvironment = NULL;
/* FUNCTIONS ****************************************************************/
-#if 0
static VOID
SmCreatePagingFiles (VOID)
{
- UNICODE_STRING FileName;
- ULONG ulCurrentSize;
-
- /* FIXME: Read file names from registry */
+ 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);
+ }
+}
- RtlInitUnicodeString (&FileName,
- L"\\??\\C:\\reactos\\pagefile.sys");
- NtCreatePagingFile (&FileName,
- 50,
- 80,
- &ulCurrentSize);
-}
+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
{
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.
- * Since the registry does not work yet, the environment variables
- * are set one by one, using hard-coded default values.
+ * Because the registry does not work yet, the environment variables
+ * are set one by one, using information from the shared user page.
*
- * Variables:
+ * Variables (example):
* SystemRoot = C:\reactos
* SystemDrive = C:
*
* windir = %SystemRoot%
*/
- /* Set "SystemRoot = C:\reactos" */
+ /* copy system root into value buffer */
+ wcscpy (ValueBuffer, SharedUserData->NtSystemRoot);
+
+ /* set "SystemRoot = C:\reactos" */
RtlInitUnicodeString (&EnvVariable,
L"SystemRoot");
RtlInitUnicodeString (&EnvValue,
- L"C:\\reactos");
+ ValueBuffer);
RtlSetEnvironmentVariable (&SmSystemEnvironment,
&EnvVariable,
&EnvValue);
+ /* cut off trailing path */
+ ValueBuffer[2] = 0;
+
/* Set "SystemDrive = C:" */
RtlInitUnicodeString (&EnvVariable,
L"SystemDrive");
RtlInitUnicodeString (&EnvValue,
- L"C:");
+ ValueBuffer);
RtlSetEnvironmentVariable (&SmSystemEnvironment,
&EnvVariable,
&EnvValue);
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[]
- )
+BOOL InitSessionManager (HANDLE Children[])
{
- NTSTATUS Status;
- UNICODE_STRING UnicodeString;
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING CmdLineW;
- UNICODE_STRING CurrentDirectoryW;
- PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
-
- /* Create the "\SmApiPort" object (LPC) */
- RtlInitUnicodeString (&UnicodeString,
- L"\\SmApiPort");
- InitializeObjectAttributes (&ObjectAttributes,
- &UnicodeString,
- 0xff,
- NULL,
- NULL);
-
- Status = NtCreatePort (&SmApiPort,
- &ObjectAttributes,
- 0,
- 0,
- 0);
-
- if (!NT_SUCCESS(Status))
- {
- return FALSE;
- }
+ 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");
+ 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 (TRUE,
- &SmSystemEnvironment);
- if (!NT_SUCCESS(Status))
- return FALSE;
+ /* 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");
+ DisplayString (L"SM: System Environment created\n");
#endif
- /* FIXME: Define symbolic links to kernel devices (MS-DOS names) */
+ /* Define symbolic links to kernel devices (MS-DOS names) */
+ SmInitDosDevices();
- /* FIXME: Run all programs in the boot execution list */
+ /* FIXME: Run all programs in the boot execution list */
+// SmRunBootApps();
- /* FIXME: Process the file rename list */
+ /* FIXME: Process the file rename list */
+// SmProcessFileRenameList();
- /* FIXME: Load the well known DLLs */
+ /* FIXME: Load the well known DLLs */
+// SmPreloadDlls();
- /* Create paging files */
-#if 0
- SmCreatePagingFiles ();
-#endif
-
- /* Load missing registry hives */
-// NtInitializeRegistry (FALSE);
-
- /* Set environment variables from registry */
- SmSetEnvironmentVariables ();
+ /* Create paging files */
+ SmCreatePagingFiles();
-//#if 0
- /* Load the kernel mode driver win32k.sys */
- RtlInitUnicodeString (&CmdLineW,
- L"\\??\\C:\\reactos\\system32\\drivers\\win32k.sys");
- Status = NtLoadDriver (&CmdLineW);
+ /* Load remaining registry hives */
+ NtInitializeRegistry(FALSE);
- if (!NT_SUCCESS(Status))
- {
- return FALSE;
- }
-//#endif
+ /* 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
- /* Start the Win32 subsystem (csrss.exe) */
- DisplayString (L"SM: Executing csrss.exe\n");
-
- RtlInitUnicodeString (&UnicodeString,
- L"\\??\\C:\\reactos\\system32\\csrss.exe");
-
- /* initialize current directory */
- RtlInitUnicodeString (&CurrentDirectoryW,
- L"C:\\reactos\\system32\\");
-
- RtlCreateProcessParameters (&ProcessParameters,
- &UnicodeString,
- NULL,
- &CurrentDirectoryW,
- NULL,
- SmSystemEnvironment,
- NULL,
- NULL,
- NULL,
- NULL);
-
- Status = RtlCreateUserProcess (&UnicodeString,
- 0,
- ProcessParameters,
- NULL,
- NULL,
- FALSE,
- 0,
- NULL,
- &Children[CHILD_CSRSS],
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DisplayString (L"SM: Loading csrss.exe failed!\n");
- return FALSE;
- }
-
- RtlDestroyProcessParameters (ProcessParameters);
+ if (!NT_SUCCESS(Status))
+ {
+ return FALSE;
+ }
#endif
-
- /* Start the simple shell (shell.exe) */
- DisplayString (L"SM: Executing shell\n");
- RtlInitUnicodeString (&UnicodeString,
- L"\\??\\C:\\reactos\\system32\\shell.exe");
-#if 0
- /* Start the logon process (winlogon.exe) */
- RtlInitUnicodeString (&CmdLineW,
- L"\\??\\C:\\reactos\\system32\\winlogon.exe");
-#endif
-
- /* initialize current directory (trailing backslash!!)*/
- RtlInitUnicodeString (&CurrentDirectoryW,
- L"C:\\reactos\\");
-
- RtlCreateProcessParameters (&ProcessParameters,
- &UnicodeString,
- NULL,
- &CurrentDirectoryW,
- NULL,
- SmSystemEnvironment,
- NULL,
- NULL,
- NULL,
- NULL);
-
-
- Status = RtlCreateUserProcess (&UnicodeString,
- 0,
- ProcessParameters,
- NULL,
- NULL,
- FALSE,
- 0,
- NULL,
- &Children[CHILD_WINLOGON],
- NULL);
-
- RtlDestroyProcessParameters (ProcessParameters);
-
- if (!NT_SUCCESS(Status))
- {
- DisplayString (L"SM: Loading shell.exe failed!\n");
-#if 0
- NtTerminateProcess (Children[CHILD_CSRSS],
- 0);
-#endif
- return FALSE;
- }
-
- /* Create the \DbgSsApiPort object (LPC) */
- RtlInitUnicodeString (&UnicodeString,
- L"\\DbgSsApiPort");
- InitializeObjectAttributes (&ObjectAttributes,
- &UnicodeString,
- 0xff,
- NULL,
- NULL);
-
- Status = NtCreatePort (&DbgSsApiPort,
- &ObjectAttributes,
- 0,
- 0,
- 0);
-
- if (!NT_SUCCESS(Status))
- {
- return FALSE;
- }
+ /* 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");
+ DisplayString(L"SM: DbgSsApiPort created...\n");
#endif
- /* Create the \DbgUiApiPort object (LPC) */
- RtlInitUnicodeString (&UnicodeString,
- L"\\DbgUiApiPort");
- InitializeObjectAttributes (&ObjectAttributes,
- &UnicodeString,
- 0xff,
- NULL,
- NULL);
-
- Status = NtCreatePort (&DbgUiApiPort,
- &ObjectAttributes,
- 0,
- 0,
- 0);
-
- if (!NT_SUCCESS(Status))
- {
- return FALSE;
- }
+ /* 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");
+ DisplayString (L"SM: DbgUiApiPort created...\n");
#endif
- return TRUE;
+ return TRUE;
}
/* EOF */