-/* $Id: init.c,v 1.42 2002/08/20 20:37:17 hyperion Exp $
+/* $Id: init.c,v 1.50 2003/08/11 18:50:12 chorns Exp $
*
* init.c - Session Manager initialization
*
#include <ntos.h>
#include <ntdll/rtl.h>
+#include <ntdll/ldr.h>
#include <napi/lpc.h>
#include "smss.h"
#define NDEBUG
-
+#include <debug.h>
/* GLOBALS ******************************************************************/
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)
{
WCHAR LinkBuffer[80];
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)
{
RtlInitUnicodeString(&DeviceName,
(PWSTR)ValueData);
-#ifndef NDEBUG
- PrintString("SM: Linking %wZ --> %wZ\n",
+ DPRINT("SM: Linking %wZ --> %wZ\n",
&LinkName,
&DeviceName);
-#endif
/* create symbolic link */
InitializeObjectAttributes(&ObjectAttributes,
&DeviceName);
if (!NT_SUCCESS(Status))
{
- PrintString("SmDosDevicesQueryRoutine: NtCreateSymbolicLink( %wZ --> %wZ ) failed!\n",
+ DPRINT1("SmDosDevicesQueryRoutine: NtCreateSymbolicLink( %wZ --> %wZ ) failed!\n",
&LinkName,
&DeviceName);
}
ULONG len;
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)
{
wcscpy(CommandLine, p2);
}
- PrintString("Running %S...\n", Description);
-#ifndef NDEBUG
- PrintString("ImageName: '%S'\n", ImageName);
- PrintString("CommandLine: '%S'\n", CommandLine);
-#endif
+ DPRINT("Running %S...\n", Description);
+ DPRINT("ImageName: '%S'\n", ImageName);
+ DPRINT("CommandLine: '%S'\n", CommandLine);
/* initialize executable path */
wcscpy(ImagePath, L"\\SystemRoot\\system32\\");
&ProcessInfo);
if (!NT_SUCCESS(Status))
{
- PrintString("Running %s failed (Status %lx)\n", Description, Status);
+ DPRINT1("Running %s failed (Status %lx)\n", Description, Status);
return(STATUS_SUCCESS);
}
NULL);
if (!NT_SUCCESS(Status))
{
- PrintString("SmRunBootApps: RtlQueryRegistryValues() failed! (Status %lx)\n", Status);
+ DPRINT1("SmRunBootApps: RtlQueryRegistryValues() failed! (Status %lx)\n", Status);
}
return(Status);
static NTSTATUS
SmProcessFileRenameList(VOID)
{
-#ifndef NDEBUG
- PrintString("SmProcessFileRenameList() called\n");
-#endif
+ DPRINT("SmProcessFileRenameList() called\n");
/* FIXME: implement it! */
-#ifndef NDEBUG
- PrintString("SmProcessFileRenameList() done\n");
-#endif
+ 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
-SmPreloadDlls(VOID)
+SmLoadKnownDlls(VOID)
{
-#ifndef NDEBUG
- PrintString("SmPreloadDlls() called\n");
-#endif
+ 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;
- /* FIXME: implement it! */
+ DPRINT("SmLoadKnownDlls() called\n");
-#ifndef NDEBUG
- PrintString("SmPreloadDlls() done\n");
-#endif
+ /* 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;
+ }
- return(STATUS_SUCCESS);
+ 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;
}
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);
if (ValueType != REG_SZ)
{
MaximumSize.QuadPart = 80 * 4096;
}
- if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,
&FileName,
NULL,
NULL))
{
return (STATUS_SUCCESS);
- }
+ }
- DbgPrint("SMSS: Created paging file %wZ with size %dKB\n",
+ DbgPrint("SMSS: Created paging file %wZ with size %dKB\n",
&FileName, InitialSize.QuadPart / 1024);
Status = NtCreatePagingFile(&FileName,
&InitialSize,
UNICODE_STRING EnvVariable;
UNICODE_STRING EnvValue;
-#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)
{
wcscpy(ValueBuffer,
SharedUserData->NtSystemRoot);
- /* Cet SystemRoot = "C:\reactos" */
+ /* Set SystemRoot = "C:\reactos" */
RtlInitUnicodeStringFromLiteral(&EnvVariable,
L"SystemRoot");
RtlInitUnicodeString(&EnvValue,
/* Load kernel mode subsystem (aka win32k.sys) */
RtlInitUnicodeStringFromLiteral(&ImageInfo.ModuleName,
- L"\\SystemRoot\\system32\\drivers\\win32k.sys");
+ L"\\SystemRoot\\system32\\win32k.sys");
Status = NtSetSystemInformation(SystemLoadAndCallImage,
&ImageInfo,
sizeof(SYSTEM_LOAD_AND_CALL_IMAGE));
- PrintString("SMSS: Loaded win32k.sys (Status %lx)\n", Status);
+ DPRINT("SMSS: Loaded win32k.sys (Status %lx)\n", Status);
#if 0
if (!NT_SUCCESS(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");
+ }
+}
+
+
NTSTATUS
InitSessionManager(HANDLE Children[])
{
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);
}
Status = SmCreateApiPort();
if (!NT_SUCCESS(Status))
{
- PrintString("SM: Failed to create SmApiPort (Status %lx)\n", Status);
+ DPRINT1("SM: Failed to create SmApiPort (Status %lx)\n", Status);
return(Status);
}
&SmSystemEnvironment);
if (!NT_SUCCESS(Status))
{
- PrintString("SM: Failed to create the system environment (Status %lx)\n", 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);
}
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);
}
+ DPRINT("SM: loading well-known DLLs\n");
+
/* Load the well known DLLs */
- Status = SmPreloadDlls();
+ Status = SmLoadKnownDlls();
if (!NT_SUCCESS(Status))
{
- PrintString("SM: Failed to preload system DLLs (Status %lx)\n", Status);
- return(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 set system environment variables (Status %lx)\n", Status);
+ DPRINT1("SM: Failed to update environment variables (Status %lx)\n", Status);
return(Status);
}
+#endif
+
+ DPRINT("SM: loading subsystems\n");
/* Load the subsystems */
Status = SmLoadSubsystems();
if (!NT_SUCCESS(Status))
{
- PrintString("SM: Failed to load subsystems (Status %lx)\n", Status);
+ DPRINT1("SM: Failed to load subsystems (Status %lx)\n", Status);
return(Status);
}
+
+ SignalInitEvent();
+
+
+ DPRINT("SM: initializing csrss\n");
+
/* Run csrss.exe */
RtlInitUnicodeStringFromLiteral(&UnicodeString,
- L"\\CsrssInitDone");
+ 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);