1 /* $Id: init.c,v 1.45 2003/02/25 23:08:52 gvg Exp $
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
);