3 * init.c - Session Manager initialization
5 * ReactOS Operating System
7 * --------------------------------------------------------------------
9 * This software is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
14 * This software is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this software; see the file COPYING.LIB. If not, write
21 * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
24 * --------------------------------------------------------------------
26 * 19990530 (Emanuele Aliberti)
27 * Compiled successfully with egcs 1.1.2
30 /* INCLUDES *****************************************************************/
33 #include <ntdll/rtl.h>
41 /* GLOBALS ******************************************************************/
43 HANDLE DbgSsApiPort = INVALID_HANDLE_VALUE;
44 HANDLE DbgUiApiPort = INVALID_HANDLE_VALUE;
46 PWSTR SmSystemEnvironment = NULL;
49 /* FUNCTIONS ****************************************************************/
51 static NTSTATUS STDCALL
52 SmObjectDirectoryQueryRoutine(PWSTR ValueName,
59 OBJECT_ATTRIBUTES ObjectAttributes;
60 UNICODE_STRING UnicodeString;
61 HANDLE WindowsDirectory;
62 NTSTATUS Status = STATUS_SUCCESS;
65 PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
66 PrintString("ValueData '%S'\n", (PWSTR)ValueData);
68 if (ValueType != REG_SZ)
70 return(STATUS_SUCCESS);
73 RtlInitUnicodeString(&UnicodeString,
76 InitializeObjectAttributes(&ObjectAttributes,
82 Status = ZwCreateDirectoryObject(&WindowsDirectory,
91 SmCreateObjectDirectories(VOID)
93 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
96 RtlZeroMemory(&QueryTable,
99 QueryTable[0].Name = L"ObjectDirectories";
100 QueryTable[0].QueryRoutine = SmObjectDirectoryQueryRoutine;
102 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
103 L"\\Session Manager",
112 static NTSTATUS STDCALL
113 SmDosDevicesQueryRoutine(PWSTR ValueName,
120 OBJECT_ATTRIBUTES ObjectAttributes;
121 UNICODE_STRING DeviceName;
122 UNICODE_STRING LinkName;
124 WCHAR LinkBuffer[80];
128 PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
129 PrintString("ValueData '%S'\n", (PWSTR)ValueData);
132 if (ValueType != REG_SZ)
134 return(STATUS_SUCCESS);
140 RtlInitUnicodeString(&LinkName,
142 RtlInitUnicodeString(&DeviceName,
146 PrintString("SM: Linking %wZ --> %wZ\n",
151 /* create symbolic link */
152 InitializeObjectAttributes(&ObjectAttributes,
157 Status = NtCreateSymbolicLinkObject(&LinkHandle,
158 SYMBOLIC_LINK_ALL_ACCESS,
161 if (!NT_SUCCESS(Status))
163 PrintString("SmDosDevicesQueryRoutine: NtCreateSymbolicLink( %wZ --> %wZ ) failed!\n",
174 SmInitDosDevices(VOID)
176 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
179 RtlZeroMemory(&QueryTable,
182 QueryTable[0].QueryRoutine = SmDosDevicesQueryRoutine;
184 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
185 L"\\Session Manager\\DOS Devices",
193 static NTSTATUS STDCALL
194 SmRunBootAppsQueryRoutine(PWSTR ValueName,
201 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
202 RTL_PROCESS_INFO ProcessInfo;
203 UNICODE_STRING ImagePathString;
204 UNICODE_STRING CommandLineString;
205 WCHAR Description[256];
206 WCHAR ImageName[256];
207 WCHAR ImagePath[256];
208 WCHAR CommandLine[256];
214 PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
215 PrintString("ValueData '%S'\n", (PWSTR)ValueData);
218 if (ValueType != REG_SZ)
220 return(STATUS_SUCCESS);
223 /* Extract the description */
224 p1 = wcschr((PWSTR)ValueData, L' ');
225 len = p1 - (PWSTR)ValueData;
226 memcpy(Description,ValueData, len * sizeof(WCHAR));
227 Description[len] = 0;
229 /* Extract the image name */
231 p2 = wcschr(p1, L' ');
236 memcpy(ImageName, p1, len * sizeof(WCHAR));
239 /* Extract the command line */
247 wcscpy(CommandLine, p2);
250 PrintString("Running %S...\n", Description);
252 PrintString("ImageName: '%S'\n", ImageName);
253 PrintString("CommandLine: '%S'\n", CommandLine);
256 /* initialize executable path */
257 wcscpy(ImagePath, L"\\SystemRoot\\system32\\");
258 wcscat(ImagePath, ImageName);
259 wcscat(ImagePath, L".exe");
261 RtlInitUnicodeString(&ImagePathString,
264 RtlInitUnicodeString(&CommandLineString,
267 RtlCreateProcessParameters(&ProcessParameters,
278 Status = RtlCreateUserProcess(&ImagePathString,
279 OBJ_CASE_INSENSITIVE,
288 if (!NT_SUCCESS(Status))
290 PrintString("Running %s failed (Status %lx)\n", Description, Status);
291 return(STATUS_SUCCESS);
294 RtlDestroyProcessParameters(ProcessParameters);
296 /* Wait for process termination */
297 NtWaitForSingleObject(ProcessInfo.ProcessHandle,
301 NtClose(ProcessInfo.ThreadHandle);
302 NtClose(ProcessInfo.ProcessHandle);
304 return(STATUS_SUCCESS);
309 * Run native applications listed in the registry.
312 * \Registry\Machine\SYSTEM\CurrentControlSet\Control\Session Manager
314 * Value (format: "<description> <executable> <command line>":
315 * BootExecute = "autocheck autochk *"
320 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
323 RtlZeroMemory(&QueryTable,
326 QueryTable[0].Name = L"BootExecute";
327 QueryTable[0].QueryRoutine = SmRunBootAppsQueryRoutine;
329 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
330 L"\\Session Manager",
334 if (!NT_SUCCESS(Status))
336 PrintString("SmRunBootApps: RtlQueryRegistryValues() failed! (Status %lx)\n", Status);
344 SmProcessFileRenameList(VOID)
347 PrintString("SmProcessFileRenameList() called\n");
350 /* FIXME: implement it! */
353 PrintString("SmProcessFileRenameList() done\n");
356 return(STATUS_SUCCESS);
364 PrintString("SmPreloadDlls() called\n");
367 /* FIXME: implement it! */
370 PrintString("SmPreloadDlls() done\n");
373 return(STATUS_SUCCESS);
377 static NTSTATUS STDCALL
378 SmPagingFilesQueryRoutine(PWSTR ValueName,
385 UNICODE_STRING FileName;
386 LARGE_INTEGER InitialSize;
387 LARGE_INTEGER MaximumSize;
392 PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
393 PrintString("ValueData '%S'\n", (PWSTR)ValueData);
396 if (ValueType != REG_SZ)
398 return(STATUS_SUCCESS);
402 * Format: "<path>[ <initial_size>[ <maximum_size>]]"
404 if ((p = wcschr(ValueData, ' ')) != NULL)
407 InitialSize.QuadPart = wcstoul(p + 1, &p, 0) * 256 * 4096;
410 MaximumSize.QuadPart = wcstoul(p + 1, NULL, 0) * 256 * 4096;
413 MaximumSize = InitialSize;
417 InitialSize.QuadPart = 50 * 4096;
418 MaximumSize.QuadPart = 80 * 4096;
421 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,
426 return (STATUS_SUCCESS);
429 DbgPrint("SMSS: Created paging file %wZ with size %dKB\n",
430 &FileName, InitialSize.QuadPart / 1024);
431 Status = NtCreatePagingFile(&FileName,
436 RtlFreeUnicodeString(&FileName);
438 return(STATUS_SUCCESS);
443 SmCreatePagingFiles(VOID)
445 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
448 RtlZeroMemory(&QueryTable,
451 QueryTable[0].Name = L"PagingFiles";
452 QueryTable[0].QueryRoutine = SmPagingFilesQueryRoutine;
454 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
455 L"\\Session Manager\\Memory Management",
464 static NTSTATUS STDCALL
465 SmEnvironmentQueryRoutine(PWSTR ValueName,
472 UNICODE_STRING EnvVariable;
473 UNICODE_STRING EnvValue;
476 PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
477 PrintString("ValueData '%S'\n", (PWSTR)ValueData);
480 if (ValueType != REG_SZ)
482 return(STATUS_SUCCESS);
485 RtlInitUnicodeString(&EnvVariable,
487 RtlInitUnicodeString(&EnvValue,
489 RtlSetEnvironmentVariable(Context,
493 return(STATUS_SUCCESS);
498 SmSetEnvironmentVariables(VOID)
500 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
501 UNICODE_STRING EnvVariable;
502 UNICODE_STRING EnvValue;
503 WCHAR ValueBuffer[MAX_PATH];
507 * The following environment variables must be set prior to reading
508 * other variables from the registry.
510 * Variables (example):
511 * SystemRoot = "C:\reactos"
515 /* Copy system root into value buffer */
517 SharedUserData->NtSystemRoot);
519 /* Cet SystemRoot = "C:\reactos" */
520 RtlInitUnicodeStringFromLiteral(&EnvVariable,
522 RtlInitUnicodeString(&EnvValue,
524 RtlSetEnvironmentVariable(&SmSystemEnvironment,
528 /* Cut off trailing path */
531 /* Set SystemDrive = "C:" */
532 RtlInitUnicodeStringFromLiteral(&EnvVariable,
534 RtlInitUnicodeString(&EnvValue,
536 RtlSetEnvironmentVariable(&SmSystemEnvironment,
540 /* Read system environment from the registry. */
541 RtlZeroMemory(&QueryTable,
544 QueryTable[0].QueryRoutine = SmEnvironmentQueryRoutine;
546 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
547 L"\\Session Manager\\Environment",
549 &SmSystemEnvironment,
550 SmSystemEnvironment);
557 SmLoadSubsystems(VOID)
559 SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
562 /* Load kernel mode subsystem (aka win32k.sys) */
563 RtlInitUnicodeStringFromLiteral(&ImageInfo.ModuleName,
564 L"\\SystemRoot\\system32\\win32k.sys");
566 Status = NtSetSystemInformation(SystemLoadAndCallImage,
568 sizeof(SYSTEM_LOAD_AND_CALL_IMAGE));
570 PrintString("SMSS: Loaded win32k.sys (Status %lx)\n", Status);
572 if (!NT_SUCCESS(Status))
578 /* FIXME: load more subsystems (csrss!) */
585 InitSessionManager(HANDLE Children[])
588 UNICODE_STRING UnicodeString;
589 OBJECT_ATTRIBUTES ObjectAttributes;
590 UNICODE_STRING CmdLineW;
591 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
592 RTL_PROCESS_INFO ProcessInfo;
593 HANDLE CsrssInitEvent;
594 WCHAR UnicodeBuffer[MAX_PATH];
596 /* Create object directories */
597 Status = SmCreateObjectDirectories();
598 if (!NT_SUCCESS(Status))
600 PrintString("SM: Failed to create object directories (Status %lx)\n", Status);
604 /* Create the SmApiPort object (LPC) */
605 Status = SmCreateApiPort();
606 if (!NT_SUCCESS(Status))
608 PrintString("SM: Failed to create SmApiPort (Status %lx)\n", Status);
612 /* Create the system environment */
613 Status = RtlCreateEnvironment(FALSE,
614 &SmSystemEnvironment);
615 if (!NT_SUCCESS(Status))
617 PrintString("SM: Failed to create the system environment (Status %lx)\n", Status);
621 /* Define symbolic links to kernel devices (MS-DOS names) */
622 Status = SmInitDosDevices();
623 if (!NT_SUCCESS(Status))
625 PrintString("SM: Failed to create dos device links (Status %lx)\n", Status);
629 /* Run all programs in the boot execution list */
630 Status = SmRunBootApps();
631 if (!NT_SUCCESS(Status))
633 PrintString("SM: Failed to run boot applications (Status %lx)\n", Status);
637 /* Process the file rename list */
638 Status = SmProcessFileRenameList();
639 if (!NT_SUCCESS(Status))
641 PrintString("SM: Failed to process the file rename list (Status %lx)\n", Status);
645 /* Load the well known DLLs */
646 Status = SmPreloadDlls();
647 if (!NT_SUCCESS(Status))
649 PrintString("SM: Failed to preload system DLLs (Status %lx)\n", Status);
653 /* Create paging files */
654 Status = SmCreatePagingFiles();
655 if (!NT_SUCCESS(Status))
657 PrintString("SM: Failed to create paging files (Status %lx)\n", Status);
661 /* Load remaining registry hives */
662 NtInitializeRegistry(FALSE);
664 /* Set environment variables from registry */
665 Status = SmSetEnvironmentVariables();
666 if (!NT_SUCCESS(Status))
668 PrintString("SM: Failed to set system environment variables (Status %lx)\n", Status);
672 /* Load the subsystems */
673 Status = SmLoadSubsystems();
674 if (!NT_SUCCESS(Status))
676 PrintString("SM: Failed to load subsystems (Status %lx)\n", Status);
681 RtlInitUnicodeStringFromLiteral(&UnicodeString,
683 InitializeObjectAttributes(&ObjectAttributes,
688 Status = NtCreateEvent(&CsrssInitEvent,
693 if (!NT_SUCCESS(Status))
695 DbgPrint("Failed to create csrss notification event\n");
699 * Start the Win32 subsystem (csrss.exe)
702 /* initialize executable path */
703 wcscpy(UnicodeBuffer, L"\\??\\");
704 wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
705 wcscat(UnicodeBuffer, L"\\system32\\csrss.exe");
706 RtlInitUnicodeString(&UnicodeString,
709 RtlCreateProcessParameters(&ProcessParameters,
720 Status = RtlCreateUserProcess(&UnicodeString,
721 OBJ_CASE_INSENSITIVE,
731 RtlDestroyProcessParameters (ProcessParameters);
733 if (!NT_SUCCESS(Status))
735 DisplayString(L"SM: Loading csrss.exe failed!\n");
739 NtWaitForSingleObject(CsrssInitEvent,
743 Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;
746 * Start the logon process (winlogon.exe)
749 /* initialize executable path */
750 wcscpy(UnicodeBuffer, L"\\??\\");
751 wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
752 wcscat(UnicodeBuffer, L"\\system32\\winlogon.exe");
753 RtlInitUnicodeString(&UnicodeString,
756 RtlCreateProcessParameters(&ProcessParameters,
767 Status = RtlCreateUserProcess(&UnicodeString,
768 OBJ_CASE_INSENSITIVE,
778 RtlDestroyProcessParameters(ProcessParameters);
780 if (!NT_SUCCESS(Status))
782 DisplayString(L"SM: Loading winlogon.exe failed!\n");
783 NtTerminateProcess(Children[CHILD_CSRSS],
787 Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
789 /* Create the \DbgSsApiPort object (LPC) */
790 RtlInitUnicodeStringFromLiteral(&UnicodeString,
792 InitializeObjectAttributes(&ObjectAttributes,
798 Status = NtCreatePort(&DbgSsApiPort,
804 if (!NT_SUCCESS(Status))
809 DisplayString(L"SM: DbgSsApiPort created...\n");
812 /* Create the \DbgUiApiPort object (LPC) */
813 RtlInitUnicodeStringFromLiteral(&UnicodeString,
815 InitializeObjectAttributes(&ObjectAttributes,
821 Status = NtCreatePort(&DbgUiApiPort,
826 if (!NT_SUCCESS(Status))
831 DisplayString (L"SM: DbgUiApiPort created...\n");
834 return(STATUS_SUCCESS);