-/* $Id: init.c,v 1.34 2002/05/22 15:55:51 ekohl Exp $
+/* $Id: init.c,v 1.50 2003/08/11 18:50:12 chorns Exp $
*
* init.c - Session Manager initialization
*
* 19990530 (Emanuele Aliberti)
* Compiled successfully with egcs 1.1.2
*/
+
+/* INCLUDES *****************************************************************/
+
#include <ntos.h>
#include <ntdll/rtl.h>
+#include <ntdll/ldr.h>
#include <napi/lpc.h>
#include "smss.h"
#define NDEBUG
+#include <debug.h>
-/* TYPES ********************************************************************/
-
+/* GLOBALS ******************************************************************/
-/* GLOBAL VARIABLES *********************************************************/
-
-HANDLE SmApiPort = INVALID_HANDLE_VALUE;
HANDLE DbgSsApiPort = INVALID_HANDLE_VALUE;
HANDLE DbgUiApiPort = INVALID_HANDLE_VALUE;
/* FUNCTIONS ****************************************************************/
-
static NTSTATUS STDCALL
SmObjectDirectoryQueryRoutine(PWSTR ValueName,
ULONG ValueType,
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING UnicodeString;
HANDLE WindowsDirectory;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
#ifndef NDEBUG
- PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
- PrintString("ValueData '%S'\n", (PWSTR)ValueData);
+ DbgPrint("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ DbgPrint("ValueData '%S'\n", (PWSTR)ValueData);
#endif
+ if (ValueType != REG_SZ)
+ {
+ return(STATUS_SUCCESS);
+ }
RtlInitUnicodeString(&UnicodeString,
(PWSTR)ValueData);
UNICODE_STRING LinkName;
HANDLE LinkHandle;
WCHAR LinkBuffer[80];
- NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status;
-#ifndef NDEBUG
- PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
- PrintString("ValueData '%S'\n", (PWSTR)ValueData);
-#endif
+ DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
- if (ValueType = REG_SZ)
+ if (ValueType != REG_SZ)
{
- swprintf(LinkBuffer, L"\\??\\%s",
- ValueName);
- RtlInitUnicodeString(&LinkName,
- LinkBuffer);
- RtlInitUnicodeString(&DeviceName,
- (PWSTR)ValueData);
+ return(STATUS_SUCCESS);
+ }
-#ifndef NDEBUG
- PrintString("SM: Linking %wZ --> %wZ\n",
+ swprintf(LinkBuffer,
+ L"\\??\\%s",
+ ValueName);
+ RtlInitUnicodeString(&LinkName,
+ LinkBuffer);
+ RtlInitUnicodeString(&DeviceName,
+ (PWSTR)ValueData);
+
+ DPRINT("SM: Linking %wZ --> %wZ\n",
+ &LinkName,
+ &DeviceName);
+
+ /* create symbolic link */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &LinkName,
+ OBJ_PERMANENT,
+ NULL,
+ NULL);
+ Status = NtCreateSymbolicLinkObject(&LinkHandle,
+ SYMBOLIC_LINK_ALL_ACCESS,
+ &ObjectAttributes,
+ &DeviceName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SmDosDevicesQueryRoutine: NtCreateSymbolicLink( %wZ --> %wZ ) failed!\n",
&LinkName,
&DeviceName);
-#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("SmDosDevicesQueryRoutine: NtCreateSymbolicLink( %wZ --> %wZ ) failed!\n",
- &LinkName,
- &DeviceName);
- }
- NtClose(LinkHandle);
}
+ NtClose(LinkHandle);
return(Status);
}
PVOID Context,
PVOID EntryContext)
{
-#if 0
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
RTL_PROCESS_INFO ProcessInfo;
+ UNICODE_STRING ImagePathString;
+ UNICODE_STRING CommandLineString;
WCHAR Description[256];
+ WCHAR ImageName[256];
WCHAR ImagePath[256];
WCHAR CommandLine[256];
PWSTR p1, p2;
ULONG len;
- NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status;
-#ifndef NDEBUG
- PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
- PrintString("ValueData '%S'\n", (PWSTR)ValueData);
-#endif
+ DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
+
+ if (ValueType != REG_SZ)
+ {
+ return(STATUS_SUCCESS);
+ }
/* Extract the description */
p1 = wcschr((PWSTR)ValueData, L' ');
memcpy(Description,ValueData, len * sizeof(WCHAR));
Description[len] = 0;
- /* Extract the full image path */
+ /* Extract the image name */
p1++;
p2 = wcschr(p1, L' ');
if (p2 != NULL)
len = p2 - p1;
else
len = wcslen(p1);
- memcpy(ImagePath, p1, len * sizeof(WCHAR));
- ImagePath[len] = 0;
+ memcpy(ImageName, p1, len * sizeof(WCHAR));
+ ImageName[len] = 0;
/* Extract the command line */
if (p2 == NULL)
wcscpy(CommandLine, p2);
}
-#ifndef NDEBUG
- PrintString("Running %S...\n", Description);
- PrintString("Executable: '%S'\n", ImagePath);
- PrintString("CommandLine: '%S'\n", CommandLine);
-#endif
+ DPRINT("Running %S...\n", Description);
+ DPRINT("ImageName: '%S'\n", ImageName);
+ DPRINT("CommandLine: '%S'\n", CommandLine);
-#if 0
/* initialize executable path */
- wcscpy(UnicodeBuffer, L"\\??\\");
- wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
- wcscat(UnicodeBuffer, L"\\system32\\csrss.exe");
+ wcscpy(ImagePath, L"\\SystemRoot\\system32\\");
+ wcscat(ImagePath, ImageName);
+ wcscat(ImagePath, L".exe");
+
RtlInitUnicodeString(&ImagePathString,
- UnicodeBuffer);
+ ImagePath);
RtlInitUnicodeString(&CommandLineString,
CommandLine);
NULL,
NULL);
- Status = RtlCreateUserProcess(&UnicodeString,
+ Status = RtlCreateUserProcess(&ImagePathString,
OBJ_CASE_INSENSITIVE,
ProcessParameters,
NULL,
NULL,
NULL,
&ProcessInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Running %s failed (Status %lx)\n", Description, Status);
+ return(STATUS_SUCCESS);
+ }
- RtlDestroyProcessParameters (ProcessParameters);
+ RtlDestroyProcessParameters(ProcessParameters);
- /* FIXME: wait for process termination */
+ /* Wait for process termination */
+ NtWaitForSingleObject(ProcessInfo.ProcessHandle,
+ FALSE,
+ NULL);
-#endif
+ NtClose(ProcessInfo.ThreadHandle);
+ NtClose(ProcessInfo.ProcessHandle);
- return(Status);
-#endif
return(STATUS_SUCCESS);
}
NULL);
if (!NT_SUCCESS(Status))
{
- PrintString("SmRunBootApps: RtlQueryRegistryValues() failed! (Status %lx)\n", Status);
+ DPRINT1("SmRunBootApps: RtlQueryRegistryValues() failed! (Status %lx)\n", Status);
}
-// PrintString("*** System stopped ***\n");
-// for(;;);
-
return(Status);
}
static NTSTATUS
SmProcessFileRenameList(VOID)
{
-#ifndef NDEBUG
- PrintString("SmProcessFileRenameList() called\n");
-#endif
+ DPRINT("SmProcessFileRenameList() called\n");
-#ifndef NDEBUG
- PrintString("SmProcessFileRenameList() done\n");
-#endif
+ /* FIXME: implement it! */
+
+ DPRINT("SmProcessFileRenameList() done\n");
return(STATUS_SUCCESS);
}
+static NTSTATUS STDCALL
+SmKnownDllsQueryRoutine(PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING ImageName;
+ HANDLE FileHandle;
+ HANDLE SectionHandle;
+ NTSTATUS Status;
+
+ DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ DPRINT("ValueData '%S' Context %p EntryContext %p\n", (PWSTR)ValueData, Context, EntryContext);
+
+ /* Ignore the 'DllDirectory' value */
+ if (!_wcsicmp(ValueName, L"DllDirectory"))
+ return STATUS_SUCCESS;
+
+ /* Open the DLL image file */
+ RtlInitUnicodeString(&ImageName,
+ ValueData);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ImageName,
+ OBJ_CASE_INSENSITIVE,
+ (HANDLE)Context,
+ NULL);
+ Status = NtOpenFile(&FileHandle,
+ SYNCHRONIZE | FILE_EXECUTE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
+ return STATUS_SUCCESS;
+ }
+
+ DPRINT("Opened file %wZ successfully\n", &ImageName);
+
+ /* Check for valid image checksum */
+ Status = LdrVerifyImageMatchesChecksum (FileHandle,
+ 0,
+ 0,
+ 0);
+ if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH)
+ {
+ /* Raise a hard error (crash the system/BSOD) */
+ NtRaiseHardError (Status,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0);
+ }
+ else if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to check the image checksum\n");
+
+ NtClose(SectionHandle);
+ NtClose(FileHandle);
+
+ return STATUS_SUCCESS;
+ }
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ImageName,
+ OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
+ (HANDLE)EntryContext,
+ NULL);
+ Status = NtCreateSection(&SectionHandle,
+ SECTION_ALL_ACCESS,
+ &ObjectAttributes,
+ NULL,
+ PAGE_EXECUTE,
+ SEC_IMAGE,
+ FileHandle);
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT("Created section successfully\n");
+ NtClose(SectionHandle);
+ }
+
+ NtClose(FileHandle);
+
+ return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+SmLoadKnownDlls(VOID)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING DllDosPath;
+ UNICODE_STRING DllNtPath;
+ UNICODE_STRING Name;
+ HANDLE ObjectDirHandle;
+ HANDLE FileDirHandle;
+ HANDLE SymlinkHandle;
+ NTSTATUS Status;
+
+ DPRINT("SmLoadKnownDlls() called\n");
+
+ /* Create 'KnownDlls' object directory */
+ RtlInitUnicodeString(&Name,
+ L"\\KnownDlls");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+ NULL,
+ NULL);
+ Status = NtCreateDirectoryObject(&ObjectDirHandle,
+ DIRECTORY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtCreateDirectoryObject() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ RtlInitUnicodeString(&DllDosPath, NULL);
+
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].Name = L"DllDirectory";
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[0].EntryContext = &DllDosPath;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"\\Session Manager\\KnownDlls",
+ QueryTable,
+ NULL,
+ SmSystemEnvironment);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ DPRINT("DllDosPath: '%wZ'\n", &DllDosPath);
+
+ if (!RtlDosPathNameToNtPathName_U(DllDosPath.Buffer,
+ &DllNtPath,
+ NULL,
+ NULL))
+ {
+ DPRINT1("RtlDosPathNameToNtPathName_U() failed\n");
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+
+ DPRINT("DllNtPath: '%wZ'\n", &DllNtPath);
+
+ /* Open the dll path directory */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DllNtPath,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtOpenFile(&FileDirHandle,
+ SYNCHRONIZE | FILE_READ_DATA,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ /* Link 'KnownDllPath' the dll path directory */
+ RtlInitUnicodeString(&Name,
+ L"KnownDllPath");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+ ObjectDirHandle,
+ NULL);
+ Status = NtCreateSymbolicLinkObject(&SymlinkHandle,
+ SYMBOLIC_LINK_ALL_ACCESS,
+ &ObjectAttributes,
+ &DllDosPath);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtCreateSymbolicLink() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ NtClose(SymlinkHandle);
+
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].QueryRoutine = SmKnownDllsQueryRoutine;
+ QueryTable[0].EntryContext = ObjectDirHandle;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"\\Session Manager\\KnownDlls",
+ QueryTable,
+ (PVOID)FileDirHandle,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+ }
+
+ DPRINT("SmLoadKnownDlls() done\n");
+
+ return Status;
+}
+
+
static NTSTATUS STDCALL
SmPagingFilesQueryRoutine(PWSTR ValueName,
ULONG ValueType,
LARGE_INTEGER InitialSize;
LARGE_INTEGER MaximumSize;
NTSTATUS Status;
+ LPWSTR p;
-#ifndef NDEBUG
- PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
- PrintString("ValueData '%S'\n", (PWSTR)ValueData);
-#endif
+ DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
- RtlInitUnicodeString(&FileName,
- (PWSTR)ValueData);
+ if (ValueType != REG_SZ)
+ {
+ return(STATUS_SUCCESS);
+ }
/*
- * FIXME:
- * read initial and maximum size from the registry or use default values
- *
* Format: "<path>[ <initial_size>[ <maximum_size>]]"
*/
+ if ((p = wcschr(ValueData, ' ')) != NULL)
+ {
+ *p = L'\0';
+ InitialSize.QuadPart = wcstoul(p + 1, &p, 0) * 256 * 4096;
+ if (*p == ' ')
+ {
+ MaximumSize.QuadPart = wcstoul(p + 1, NULL, 0) * 256 * 4096;
+ }
+ else
+ MaximumSize = InitialSize;
+ }
+ else
+ {
+ InitialSize.QuadPart = 50 * 4096;
+ MaximumSize.QuadPart = 80 * 4096;
+ }
- InitialSize.QuadPart = 50 * 4096;
- MaximumSize.QuadPart = 80 * 4096;
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,
+ &FileName,
+ NULL,
+ NULL))
+ {
+ return (STATUS_SUCCESS);
+ }
+ DbgPrint("SMSS: Created paging file %wZ with size %dKB\n",
+ &FileName, InitialSize.QuadPart / 1024);
Status = NtCreatePagingFile(&FileName,
&InitialSize,
&MaximumSize,
0);
+ RtlFreeUnicodeString(&FileName);
+
return(STATUS_SUCCESS);
}
}
+static NTSTATUS STDCALL
+SmEnvironmentQueryRoutine(PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ UNICODE_STRING EnvVariable;
+ UNICODE_STRING EnvValue;
+
+ DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
+
+ if (ValueType != REG_SZ)
+ {
+ return(STATUS_SUCCESS);
+ }
+
+ RtlInitUnicodeString(&EnvVariable,
+ ValueName);
+ RtlInitUnicodeString(&EnvValue,
+ (PWSTR)ValueData);
+ RtlSetEnvironmentVariable(Context,
+ &EnvVariable,
+ &EnvValue);
+
+ return(STATUS_SUCCESS);
+}
+
+
static NTSTATUS
SmSetEnvironmentVariables(VOID)
{
- UNICODE_STRING EnvVariable;
- UNICODE_STRING EnvValue;
- UNICODE_STRING EnvExpandedValue;
- ULONG ExpandedLength;
- WCHAR ExpandBuffer[512];
- WCHAR ValueBuffer[MAX_PATH];
-
- /*
- * 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);
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ UNICODE_STRING EnvVariable;
+ UNICODE_STRING EnvValue;
+ WCHAR ValueBuffer[MAX_PATH];
+ NTSTATUS Status;
- return(STATUS_SUCCESS);
+ /*
+ * The following environment variables must be set prior to reading
+ * other variables from the registry.
+ *
+ * Variables (example):
+ * SystemRoot = "C:\reactos"
+ * SystemDrive = "C:"
+ */
+
+ /* Copy system root into value buffer */
+ wcscpy(ValueBuffer,
+ SharedUserData->NtSystemRoot);
+
+ /* Set SystemRoot = "C:\reactos" */
+ RtlInitUnicodeStringFromLiteral(&EnvVariable,
+ L"SystemRoot");
+ RtlInitUnicodeString(&EnvValue,
+ ValueBuffer);
+ RtlSetEnvironmentVariable(&SmSystemEnvironment,
+ &EnvVariable,
+ &EnvValue);
+
+ /* Cut off trailing path */
+ ValueBuffer[2] = 0;
+
+ /* Set SystemDrive = "C:" */
+ RtlInitUnicodeStringFromLiteral(&EnvVariable,
+ L"SystemDrive");
+ RtlInitUnicodeString(&EnvValue,
+ ValueBuffer);
+ RtlSetEnvironmentVariable(&SmSystemEnvironment,
+ &EnvVariable,
+ &EnvValue);
+
+ /* Read system environment from the registry. */
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].QueryRoutine = SmEnvironmentQueryRoutine;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"\\Session Manager\\Environment",
+ QueryTable,
+ &SmSystemEnvironment,
+ SmSystemEnvironment);
+
+ return(Status);
+}
+
+
+static NTSTATUS
+SmLoadSubsystems(VOID)
+{
+ SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
+ NTSTATUS Status;
+
+ /* Load kernel mode subsystem (aka win32k.sys) */
+ RtlInitUnicodeStringFromLiteral(&ImageInfo.ModuleName,
+ L"\\SystemRoot\\system32\\win32k.sys");
+
+ Status = NtSetSystemInformation(SystemLoadAndCallImage,
+ &ImageInfo,
+ sizeof(SYSTEM_LOAD_AND_CALL_IMAGE));
+
+ DPRINT("SMSS: Loaded win32k.sys (Status %lx)\n", Status);
+#if 0
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+#endif
+
+ /* FIXME: load more subsystems (csrss!) */
+
+ return(Status);
+}
+
+
+static VOID
+SignalInitEvent()
+{
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING UnicodeString;
+ HANDLE ReactOSInitEvent;
+
+ RtlInitUnicodeStringFromLiteral(&UnicodeString, L"\\ReactOSInitDone");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &UnicodeString,
+ EVENT_ALL_ACCESS,
+ 0,
+ NULL);
+ Status = NtOpenEvent(&ReactOSInitEvent,
+ EVENT_ALL_ACCESS,
+ &ObjectAttributes);
+ if (NT_SUCCESS(Status))
+ {
+ LARGE_INTEGER Timeout;
+ /* This will cause the boot screen image to go away (if displayed) */
+ NtPulseEvent(ReactOSInitEvent, NULL);
+
+ /* Wait for the display mode to be changed (if in graphics mode) */
+ Timeout.QuadPart = -50000000LL; /* 5 second timeout */
+ NtWaitForSingleObject(ReactOSInitEvent, FALSE, &Timeout);
+
+ NtClose(ReactOSInitEvent);
+ }
+ else
+ {
+ /* We don't really care if this fails */
+ DPRINT1("SM: Failed to open ReactOS init notification event\n");
+ }
}
Status = SmCreateObjectDirectories();
if (!NT_SUCCESS(Status))
{
- PrintString("SM: Failed to create object directories! (Status %lx)\n", Status);
+ DPRINT1("SM: Failed to create object directories (Status %lx)\n", Status);
return(Status);
}
- /* Create the "\SmApiPort" object (LPC) */
- RtlInitUnicodeString(&UnicodeString,
- L"\\SmApiPort");
- InitializeObjectAttributes(&ObjectAttributes,
- &UnicodeString,
- PORT_ALL_ACCESS,
- NULL,
- NULL);
-
- Status = NtCreatePort(&SmApiPort,
- &ObjectAttributes,
- 0,
- 0,
- 0);
+ /* Create the SmApiPort object (LPC) */
+ Status = SmCreateApiPort();
if (!NT_SUCCESS(Status))
{
+ DPRINT1("SM: Failed to create SmApiPort (Status %lx)\n", Status);
return(Status);
}
-#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))
{
+ DPRINT1("SM: Failed to create the system environment (Status %lx)\n", Status);
+ return(Status);
+ }
+
+ /* Set environment variables */
+ Status = SmSetEnvironmentVariables();
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: Failed to set system environment variables (Status %lx)\n", Status);
return(Status);
}
-#ifndef NDEBUG
- DisplayString(L"SM: System Environment created\n");
-#endif
/* Define symbolic links to kernel devices (MS-DOS names) */
Status = SmInitDosDevices();
if (!NT_SUCCESS(Status))
{
- PrintString("SM: Failed to create dos device links! (Status %lx)\n", Status);
+ DPRINT1("SM: Failed to create dos device links (Status %lx)\n", Status);
return(Status);
}
Status = SmRunBootApps();
if (!NT_SUCCESS(Status))
{
- PrintString("SM: Failed to run boot applications! (Status %lx)\n", Status);
+ DPRINT1("SM: Failed to run boot applications (Status %lx)\n", Status);
return(Status);
}
Status = SmProcessFileRenameList();
if (!NT_SUCCESS(Status))
{
- PrintString("SM: Failed to process the file rename list (Status %lx)\n", Status);
+ DPRINT1("SM: Failed to process the file rename list (Status %lx)\n", Status);
return(Status);
}
- /* FIXME: Load the well known DLLs */
-// SmPreloadDlls();
+ DPRINT("SM: loading well-known DLLs\n");
+
+ /* Load the well known DLLs */
+ Status = SmLoadKnownDlls();
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: Failed to preload system DLLs (Status %lx)\n", Status);
+ /* Don't crash ReactOS if DLLs cannot be loaded */
+ }
+
+ DPRINT("SM: creating system paging files\n");
/* Create paging files */
Status = SmCreatePagingFiles();
if (!NT_SUCCESS(Status))
{
- PrintString("SM: Failed to create paging files (Status %lx)\n", Status);
+ DPRINT1("SM: Failed to create paging files (Status %lx)\n", Status);
return(Status);
}
+ DPRINT("SM: initializing registry\n");
+
/* Load remaining registry hives */
NtInitializeRegistry(FALSE);
/* Set environment variables from registry */
- Status = SmSetEnvironmentVariables();
+#if 0
+ Status = SmUpdateEnvironment();
if (!NT_SUCCESS(Status))
{
- PrintString("SM: Failed to initialize the system environment (Status %lx)\n", Status);
+ DPRINT1("SM: Failed to update environment variables (Status %lx)\n", Status);
return(Status);
}
+#endif
- /* Load the kernel mode driver win32k.sys */
- RtlInitUnicodeString(&CmdLineW,
- L"\\SystemRoot\\system32\\drivers\\win32k.sys");
- Status = NtLoadDriver(&CmdLineW);
-#if 0
+ DPRINT("SM: loading subsystems\n");
+
+ /* Load the subsystems */
+ Status = SmLoadSubsystems();
if (!NT_SUCCESS(Status))
{
+ DPRINT1("SM: Failed to load subsystems (Status %lx)\n", Status);
return(Status);
}
-#endif
+
+
+ SignalInitEvent();
+
+
+ DPRINT("SM: initializing csrss\n");
/* Run csrss.exe */
- RtlInitUnicodeString(&UnicodeString,
- L"\\CsrssInitDone");
+ RtlInitUnicodeStringFromLiteral(&UnicodeString,
+ L"\\CsrssInitDone");
InitializeObjectAttributes(&ObjectAttributes,
&UnicodeString,
EVENT_ALL_ACCESS,
* Start the logon process (winlogon.exe)
*/
+ DPRINT("SM: starting winlogon\n");
+
/* initialize executable path */
wcscpy(UnicodeBuffer, L"\\??\\");
wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
/* Create the \DbgSsApiPort object (LPC) */
- RtlInitUnicodeString(&UnicodeString,
+ RtlInitUnicodeStringFromLiteral(&UnicodeString,
L"\\DbgSsApiPort");
InitializeObjectAttributes(&ObjectAttributes,
&UnicodeString,
#endif
/* Create the \DbgUiApiPort object (LPC) */
- RtlInitUnicodeString(&UnicodeString,
+ RtlInitUnicodeStringFromLiteral(&UnicodeString,
L"\\DbgUiApiPort");
InitializeObjectAttributes(&ObjectAttributes,
&UnicodeString,