2003-08-11 Casper S. Hornstrup <chorns@users.sourceforge.net>
[reactos.git] / reactos / subsys / smss / init.c
1 /* $Id: init.c,v 1.50 2003/08/11 18:50:12 chorns Exp $
2 *
3 * init.c - Session Manager initialization
4 *
5 * ReactOS Operating System
6 *
7 * --------------------------------------------------------------------
8 *
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.
13 *
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.
18 *
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,
22 * MA 02139, USA.
23 *
24 * --------------------------------------------------------------------
25 *
26 * 19990530 (Emanuele Aliberti)
27 * Compiled successfully with egcs 1.1.2
28 */
29
30 /* INCLUDES *****************************************************************/
31
32 #include <ntos.h>
33 #include <ntdll/rtl.h>
34 #include <ntdll/ldr.h>
35 #include <napi/lpc.h>
36
37 #include "smss.h"
38
39 #define NDEBUG
40 #include <debug.h>
41
42 /* GLOBALS ******************************************************************/
43
44 HANDLE DbgSsApiPort = INVALID_HANDLE_VALUE;
45 HANDLE DbgUiApiPort = INVALID_HANDLE_VALUE;
46
47 PWSTR SmSystemEnvironment = NULL;
48
49
50 /* FUNCTIONS ****************************************************************/
51
52 static NTSTATUS STDCALL
53 SmObjectDirectoryQueryRoutine(PWSTR ValueName,
54 ULONG ValueType,
55 PVOID ValueData,
56 ULONG ValueLength,
57 PVOID Context,
58 PVOID EntryContext)
59 {
60 OBJECT_ATTRIBUTES ObjectAttributes;
61 UNICODE_STRING UnicodeString;
62 HANDLE WindowsDirectory;
63 NTSTATUS Status = STATUS_SUCCESS;
64
65 #ifndef NDEBUG
66 DbgPrint("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
67 DbgPrint("ValueData '%S'\n", (PWSTR)ValueData);
68 #endif
69 if (ValueType != REG_SZ)
70 {
71 return(STATUS_SUCCESS);
72 }
73
74 RtlInitUnicodeString(&UnicodeString,
75 (PWSTR)ValueData);
76
77 InitializeObjectAttributes(&ObjectAttributes,
78 &UnicodeString,
79 0,
80 NULL,
81 NULL);
82
83 Status = ZwCreateDirectoryObject(&WindowsDirectory,
84 0,
85 &ObjectAttributes);
86
87 return(Status);
88 }
89
90
91 static NTSTATUS
92 SmCreateObjectDirectories(VOID)
93 {
94 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
95 NTSTATUS Status;
96
97 RtlZeroMemory(&QueryTable,
98 sizeof(QueryTable));
99
100 QueryTable[0].Name = L"ObjectDirectories";
101 QueryTable[0].QueryRoutine = SmObjectDirectoryQueryRoutine;
102
103 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
104 L"\\Session Manager",
105 QueryTable,
106 NULL,
107 NULL);
108
109 return(Status);
110 }
111
112
113 static NTSTATUS STDCALL
114 SmDosDevicesQueryRoutine(PWSTR ValueName,
115 ULONG ValueType,
116 PVOID ValueData,
117 ULONG ValueLength,
118 PVOID Context,
119 PVOID EntryContext)
120 {
121 OBJECT_ATTRIBUTES ObjectAttributes;
122 UNICODE_STRING DeviceName;
123 UNICODE_STRING LinkName;
124 HANDLE LinkHandle;
125 WCHAR LinkBuffer[80];
126 NTSTATUS Status;
127
128 DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
129 DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
130
131 if (ValueType != REG_SZ)
132 {
133 return(STATUS_SUCCESS);
134 }
135
136 swprintf(LinkBuffer,
137 L"\\??\\%s",
138 ValueName);
139 RtlInitUnicodeString(&LinkName,
140 LinkBuffer);
141 RtlInitUnicodeString(&DeviceName,
142 (PWSTR)ValueData);
143
144 DPRINT("SM: Linking %wZ --> %wZ\n",
145 &LinkName,
146 &DeviceName);
147
148 /* create symbolic link */
149 InitializeObjectAttributes(&ObjectAttributes,
150 &LinkName,
151 OBJ_PERMANENT,
152 NULL,
153 NULL);
154 Status = NtCreateSymbolicLinkObject(&LinkHandle,
155 SYMBOLIC_LINK_ALL_ACCESS,
156 &ObjectAttributes,
157 &DeviceName);
158 if (!NT_SUCCESS(Status))
159 {
160 DPRINT1("SmDosDevicesQueryRoutine: NtCreateSymbolicLink( %wZ --> %wZ ) failed!\n",
161 &LinkName,
162 &DeviceName);
163 }
164 NtClose(LinkHandle);
165
166 return(Status);
167 }
168
169
170 static NTSTATUS
171 SmInitDosDevices(VOID)
172 {
173 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
174 NTSTATUS Status;
175
176 RtlZeroMemory(&QueryTable,
177 sizeof(QueryTable));
178
179 QueryTable[0].QueryRoutine = SmDosDevicesQueryRoutine;
180
181 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
182 L"\\Session Manager\\DOS Devices",
183 QueryTable,
184 NULL,
185 NULL);
186 return(Status);
187 }
188
189
190 static NTSTATUS STDCALL
191 SmRunBootAppsQueryRoutine(PWSTR ValueName,
192 ULONG ValueType,
193 PVOID ValueData,
194 ULONG ValueLength,
195 PVOID Context,
196 PVOID EntryContext)
197 {
198 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
199 RTL_PROCESS_INFO ProcessInfo;
200 UNICODE_STRING ImagePathString;
201 UNICODE_STRING CommandLineString;
202 WCHAR Description[256];
203 WCHAR ImageName[256];
204 WCHAR ImagePath[256];
205 WCHAR CommandLine[256];
206 PWSTR p1, p2;
207 ULONG len;
208 NTSTATUS Status;
209
210 DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
211 DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
212
213 if (ValueType != REG_SZ)
214 {
215 return(STATUS_SUCCESS);
216 }
217
218 /* Extract the description */
219 p1 = wcschr((PWSTR)ValueData, L' ');
220 len = p1 - (PWSTR)ValueData;
221 memcpy(Description,ValueData, len * sizeof(WCHAR));
222 Description[len] = 0;
223
224 /* Extract the image name */
225 p1++;
226 p2 = wcschr(p1, L' ');
227 if (p2 != NULL)
228 len = p2 - p1;
229 else
230 len = wcslen(p1);
231 memcpy(ImageName, p1, len * sizeof(WCHAR));
232 ImageName[len] = 0;
233
234 /* Extract the command line */
235 if (p2 == NULL)
236 {
237 CommandLine[0] = 0;
238 }
239 else
240 {
241 p2++;
242 wcscpy(CommandLine, p2);
243 }
244
245 DPRINT("Running %S...\n", Description);
246 DPRINT("ImageName: '%S'\n", ImageName);
247 DPRINT("CommandLine: '%S'\n", CommandLine);
248
249 /* initialize executable path */
250 wcscpy(ImagePath, L"\\SystemRoot\\system32\\");
251 wcscat(ImagePath, ImageName);
252 wcscat(ImagePath, L".exe");
253
254 RtlInitUnicodeString(&ImagePathString,
255 ImagePath);
256
257 RtlInitUnicodeString(&CommandLineString,
258 CommandLine);
259
260 RtlCreateProcessParameters(&ProcessParameters,
261 &ImagePathString,
262 NULL,
263 NULL,
264 &CommandLineString,
265 NULL,
266 NULL,
267 NULL,
268 NULL,
269 NULL);
270
271 Status = RtlCreateUserProcess(&ImagePathString,
272 OBJ_CASE_INSENSITIVE,
273 ProcessParameters,
274 NULL,
275 NULL,
276 NULL,
277 FALSE,
278 NULL,
279 NULL,
280 &ProcessInfo);
281 if (!NT_SUCCESS(Status))
282 {
283 DPRINT1("Running %s failed (Status %lx)\n", Description, Status);
284 return(STATUS_SUCCESS);
285 }
286
287 RtlDestroyProcessParameters(ProcessParameters);
288
289 /* Wait for process termination */
290 NtWaitForSingleObject(ProcessInfo.ProcessHandle,
291 FALSE,
292 NULL);
293
294 NtClose(ProcessInfo.ThreadHandle);
295 NtClose(ProcessInfo.ProcessHandle);
296
297 return(STATUS_SUCCESS);
298 }
299
300
301 /*
302 * Run native applications listed in the registry.
303 *
304 * Key:
305 * \Registry\Machine\SYSTEM\CurrentControlSet\Control\Session Manager
306 *
307 * Value (format: "<description> <executable> <command line>":
308 * BootExecute = "autocheck autochk *"
309 */
310 static NTSTATUS
311 SmRunBootApps(VOID)
312 {
313 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
314 NTSTATUS Status;
315
316 RtlZeroMemory(&QueryTable,
317 sizeof(QueryTable));
318
319 QueryTable[0].Name = L"BootExecute";
320 QueryTable[0].QueryRoutine = SmRunBootAppsQueryRoutine;
321
322 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
323 L"\\Session Manager",
324 QueryTable,
325 NULL,
326 NULL);
327 if (!NT_SUCCESS(Status))
328 {
329 DPRINT1("SmRunBootApps: RtlQueryRegistryValues() failed! (Status %lx)\n", Status);
330 }
331
332 return(Status);
333 }
334
335
336 static NTSTATUS
337 SmProcessFileRenameList(VOID)
338 {
339 DPRINT("SmProcessFileRenameList() called\n");
340
341 /* FIXME: implement it! */
342
343 DPRINT("SmProcessFileRenameList() done\n");
344
345 return(STATUS_SUCCESS);
346 }
347
348
349 static NTSTATUS STDCALL
350 SmKnownDllsQueryRoutine(PWSTR ValueName,
351 ULONG ValueType,
352 PVOID ValueData,
353 ULONG ValueLength,
354 PVOID Context,
355 PVOID EntryContext)
356 {
357 OBJECT_ATTRIBUTES ObjectAttributes;
358 IO_STATUS_BLOCK IoStatusBlock;
359 UNICODE_STRING ImageName;
360 HANDLE FileHandle;
361 HANDLE SectionHandle;
362 NTSTATUS Status;
363
364 DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
365 DPRINT("ValueData '%S' Context %p EntryContext %p\n", (PWSTR)ValueData, Context, EntryContext);
366
367 /* Ignore the 'DllDirectory' value */
368 if (!_wcsicmp(ValueName, L"DllDirectory"))
369 return STATUS_SUCCESS;
370
371 /* Open the DLL image file */
372 RtlInitUnicodeString(&ImageName,
373 ValueData);
374 InitializeObjectAttributes(&ObjectAttributes,
375 &ImageName,
376 OBJ_CASE_INSENSITIVE,
377 (HANDLE)Context,
378 NULL);
379 Status = NtOpenFile(&FileHandle,
380 SYNCHRONIZE | FILE_EXECUTE,
381 &ObjectAttributes,
382 &IoStatusBlock,
383 FILE_SHARE_READ,
384 FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
385 if (!NT_SUCCESS(Status))
386 {
387 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
388 return STATUS_SUCCESS;
389 }
390
391 DPRINT("Opened file %wZ successfully\n", &ImageName);
392
393 /* Check for valid image checksum */
394 Status = LdrVerifyImageMatchesChecksum (FileHandle,
395 0,
396 0,
397 0);
398 if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH)
399 {
400 /* Raise a hard error (crash the system/BSOD) */
401 NtRaiseHardError (Status,
402 0,
403 0,
404 0,
405 0,
406 0);
407 }
408 else if (!NT_SUCCESS(Status))
409 {
410 DPRINT1("Failed to check the image checksum\n");
411
412 NtClose(SectionHandle);
413 NtClose(FileHandle);
414
415 return STATUS_SUCCESS;
416 }
417
418 InitializeObjectAttributes(&ObjectAttributes,
419 &ImageName,
420 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
421 (HANDLE)EntryContext,
422 NULL);
423 Status = NtCreateSection(&SectionHandle,
424 SECTION_ALL_ACCESS,
425 &ObjectAttributes,
426 NULL,
427 PAGE_EXECUTE,
428 SEC_IMAGE,
429 FileHandle);
430 if (NT_SUCCESS(Status))
431 {
432 DPRINT("Created section successfully\n");
433 NtClose(SectionHandle);
434 }
435
436 NtClose(FileHandle);
437
438 return STATUS_SUCCESS;
439 }
440
441
442 static NTSTATUS
443 SmLoadKnownDlls(VOID)
444 {
445 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
446 OBJECT_ATTRIBUTES ObjectAttributes;
447 IO_STATUS_BLOCK IoStatusBlock;
448 UNICODE_STRING DllDosPath;
449 UNICODE_STRING DllNtPath;
450 UNICODE_STRING Name;
451 HANDLE ObjectDirHandle;
452 HANDLE FileDirHandle;
453 HANDLE SymlinkHandle;
454 NTSTATUS Status;
455
456 DPRINT("SmLoadKnownDlls() called\n");
457
458 /* Create 'KnownDlls' object directory */
459 RtlInitUnicodeString(&Name,
460 L"\\KnownDlls");
461 InitializeObjectAttributes(&ObjectAttributes,
462 &Name,
463 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
464 NULL,
465 NULL);
466 Status = NtCreateDirectoryObject(&ObjectDirHandle,
467 DIRECTORY_ALL_ACCESS,
468 &ObjectAttributes);
469 if (!NT_SUCCESS(Status))
470 {
471 DPRINT1("NtCreateDirectoryObject() failed (Status %lx)\n", Status);
472 return Status;
473 }
474
475 RtlInitUnicodeString(&DllDosPath, NULL);
476
477 RtlZeroMemory(&QueryTable,
478 sizeof(QueryTable));
479
480 QueryTable[0].Name = L"DllDirectory";
481 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
482 QueryTable[0].EntryContext = &DllDosPath;
483
484 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
485 L"\\Session Manager\\KnownDlls",
486 QueryTable,
487 NULL,
488 SmSystemEnvironment);
489 if (!NT_SUCCESS(Status))
490 {
491 DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
492 return Status;
493 }
494
495 DPRINT("DllDosPath: '%wZ'\n", &DllDosPath);
496
497 if (!RtlDosPathNameToNtPathName_U(DllDosPath.Buffer,
498 &DllNtPath,
499 NULL,
500 NULL))
501 {
502 DPRINT1("RtlDosPathNameToNtPathName_U() failed\n");
503 return STATUS_OBJECT_NAME_INVALID;
504 }
505
506 DPRINT("DllNtPath: '%wZ'\n", &DllNtPath);
507
508 /* Open the dll path directory */
509 InitializeObjectAttributes(&ObjectAttributes,
510 &DllNtPath,
511 OBJ_CASE_INSENSITIVE,
512 NULL,
513 NULL);
514 Status = NtOpenFile(&FileDirHandle,
515 SYNCHRONIZE | FILE_READ_DATA,
516 &ObjectAttributes,
517 &IoStatusBlock,
518 FILE_SHARE_READ | FILE_SHARE_WRITE,
519 FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
520 if (!NT_SUCCESS(Status))
521 {
522 DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
523 return Status;
524 }
525
526 /* Link 'KnownDllPath' the dll path directory */
527 RtlInitUnicodeString(&Name,
528 L"KnownDllPath");
529 InitializeObjectAttributes(&ObjectAttributes,
530 &Name,
531 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
532 ObjectDirHandle,
533 NULL);
534 Status = NtCreateSymbolicLinkObject(&SymlinkHandle,
535 SYMBOLIC_LINK_ALL_ACCESS,
536 &ObjectAttributes,
537 &DllDosPath);
538 if (!NT_SUCCESS(Status))
539 {
540 DPRINT1("NtCreateSymbolicLink() failed (Status %lx)\n", Status);
541 return Status;
542 }
543
544 NtClose(SymlinkHandle);
545
546 RtlZeroMemory(&QueryTable,
547 sizeof(QueryTable));
548
549 QueryTable[0].QueryRoutine = SmKnownDllsQueryRoutine;
550 QueryTable[0].EntryContext = ObjectDirHandle;
551
552 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
553 L"\\Session Manager\\KnownDlls",
554 QueryTable,
555 (PVOID)FileDirHandle,
556 NULL);
557 if (!NT_SUCCESS(Status))
558 {
559 DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
560 }
561
562 DPRINT("SmLoadKnownDlls() done\n");
563
564 return Status;
565 }
566
567
568 static NTSTATUS STDCALL
569 SmPagingFilesQueryRoutine(PWSTR ValueName,
570 ULONG ValueType,
571 PVOID ValueData,
572 ULONG ValueLength,
573 PVOID Context,
574 PVOID EntryContext)
575 {
576 UNICODE_STRING FileName;
577 LARGE_INTEGER InitialSize;
578 LARGE_INTEGER MaximumSize;
579 NTSTATUS Status;
580 LPWSTR p;
581
582 DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
583 DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
584
585 if (ValueType != REG_SZ)
586 {
587 return(STATUS_SUCCESS);
588 }
589
590 /*
591 * Format: "<path>[ <initial_size>[ <maximum_size>]]"
592 */
593 if ((p = wcschr(ValueData, ' ')) != NULL)
594 {
595 *p = L'\0';
596 InitialSize.QuadPart = wcstoul(p + 1, &p, 0) * 256 * 4096;
597 if (*p == ' ')
598 {
599 MaximumSize.QuadPart = wcstoul(p + 1, NULL, 0) * 256 * 4096;
600 }
601 else
602 MaximumSize = InitialSize;
603 }
604 else
605 {
606 InitialSize.QuadPart = 50 * 4096;
607 MaximumSize.QuadPart = 80 * 4096;
608 }
609
610 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,
611 &FileName,
612 NULL,
613 NULL))
614 {
615 return (STATUS_SUCCESS);
616 }
617
618 DbgPrint("SMSS: Created paging file %wZ with size %dKB\n",
619 &FileName, InitialSize.QuadPart / 1024);
620 Status = NtCreatePagingFile(&FileName,
621 &InitialSize,
622 &MaximumSize,
623 0);
624
625 RtlFreeUnicodeString(&FileName);
626
627 return(STATUS_SUCCESS);
628 }
629
630
631 static NTSTATUS
632 SmCreatePagingFiles(VOID)
633 {
634 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
635 NTSTATUS Status;
636
637 RtlZeroMemory(&QueryTable,
638 sizeof(QueryTable));
639
640 QueryTable[0].Name = L"PagingFiles";
641 QueryTable[0].QueryRoutine = SmPagingFilesQueryRoutine;
642
643 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
644 L"\\Session Manager\\Memory Management",
645 QueryTable,
646 NULL,
647 NULL);
648
649 return(Status);
650 }
651
652
653 static NTSTATUS STDCALL
654 SmEnvironmentQueryRoutine(PWSTR ValueName,
655 ULONG ValueType,
656 PVOID ValueData,
657 ULONG ValueLength,
658 PVOID Context,
659 PVOID EntryContext)
660 {
661 UNICODE_STRING EnvVariable;
662 UNICODE_STRING EnvValue;
663
664 DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
665 DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
666
667 if (ValueType != REG_SZ)
668 {
669 return(STATUS_SUCCESS);
670 }
671
672 RtlInitUnicodeString(&EnvVariable,
673 ValueName);
674 RtlInitUnicodeString(&EnvValue,
675 (PWSTR)ValueData);
676 RtlSetEnvironmentVariable(Context,
677 &EnvVariable,
678 &EnvValue);
679
680 return(STATUS_SUCCESS);
681 }
682
683
684 static NTSTATUS
685 SmSetEnvironmentVariables(VOID)
686 {
687 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
688 UNICODE_STRING EnvVariable;
689 UNICODE_STRING EnvValue;
690 WCHAR ValueBuffer[MAX_PATH];
691 NTSTATUS Status;
692
693 /*
694 * The following environment variables must be set prior to reading
695 * other variables from the registry.
696 *
697 * Variables (example):
698 * SystemRoot = "C:\reactos"
699 * SystemDrive = "C:"
700 */
701
702 /* Copy system root into value buffer */
703 wcscpy(ValueBuffer,
704 SharedUserData->NtSystemRoot);
705
706 /* Set SystemRoot = "C:\reactos" */
707 RtlInitUnicodeStringFromLiteral(&EnvVariable,
708 L"SystemRoot");
709 RtlInitUnicodeString(&EnvValue,
710 ValueBuffer);
711 RtlSetEnvironmentVariable(&SmSystemEnvironment,
712 &EnvVariable,
713 &EnvValue);
714
715 /* Cut off trailing path */
716 ValueBuffer[2] = 0;
717
718 /* Set SystemDrive = "C:" */
719 RtlInitUnicodeStringFromLiteral(&EnvVariable,
720 L"SystemDrive");
721 RtlInitUnicodeString(&EnvValue,
722 ValueBuffer);
723 RtlSetEnvironmentVariable(&SmSystemEnvironment,
724 &EnvVariable,
725 &EnvValue);
726
727 /* Read system environment from the registry. */
728 RtlZeroMemory(&QueryTable,
729 sizeof(QueryTable));
730
731 QueryTable[0].QueryRoutine = SmEnvironmentQueryRoutine;
732
733 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
734 L"\\Session Manager\\Environment",
735 QueryTable,
736 &SmSystemEnvironment,
737 SmSystemEnvironment);
738
739 return(Status);
740 }
741
742
743 static NTSTATUS
744 SmLoadSubsystems(VOID)
745 {
746 SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
747 NTSTATUS Status;
748
749 /* Load kernel mode subsystem (aka win32k.sys) */
750 RtlInitUnicodeStringFromLiteral(&ImageInfo.ModuleName,
751 L"\\SystemRoot\\system32\\win32k.sys");
752
753 Status = NtSetSystemInformation(SystemLoadAndCallImage,
754 &ImageInfo,
755 sizeof(SYSTEM_LOAD_AND_CALL_IMAGE));
756
757 DPRINT("SMSS: Loaded win32k.sys (Status %lx)\n", Status);
758 #if 0
759 if (!NT_SUCCESS(Status))
760 {
761 return(Status);
762 }
763 #endif
764
765 /* FIXME: load more subsystems (csrss!) */
766
767 return(Status);
768 }
769
770
771 static VOID
772 SignalInitEvent()
773 {
774 NTSTATUS Status;
775 OBJECT_ATTRIBUTES ObjectAttributes;
776 UNICODE_STRING UnicodeString;
777 HANDLE ReactOSInitEvent;
778
779 RtlInitUnicodeStringFromLiteral(&UnicodeString, L"\\ReactOSInitDone");
780 InitializeObjectAttributes(&ObjectAttributes,
781 &UnicodeString,
782 EVENT_ALL_ACCESS,
783 0,
784 NULL);
785 Status = NtOpenEvent(&ReactOSInitEvent,
786 EVENT_ALL_ACCESS,
787 &ObjectAttributes);
788 if (NT_SUCCESS(Status))
789 {
790 LARGE_INTEGER Timeout;
791 /* This will cause the boot screen image to go away (if displayed) */
792 NtPulseEvent(ReactOSInitEvent, NULL);
793
794 /* Wait for the display mode to be changed (if in graphics mode) */
795 Timeout.QuadPart = -50000000LL; /* 5 second timeout */
796 NtWaitForSingleObject(ReactOSInitEvent, FALSE, &Timeout);
797
798 NtClose(ReactOSInitEvent);
799 }
800 else
801 {
802 /* We don't really care if this fails */
803 DPRINT1("SM: Failed to open ReactOS init notification event\n");
804 }
805 }
806
807
808 NTSTATUS
809 InitSessionManager(HANDLE Children[])
810 {
811 NTSTATUS Status;
812 UNICODE_STRING UnicodeString;
813 OBJECT_ATTRIBUTES ObjectAttributes;
814 UNICODE_STRING CmdLineW;
815 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
816 RTL_PROCESS_INFO ProcessInfo;
817 HANDLE CsrssInitEvent;
818 WCHAR UnicodeBuffer[MAX_PATH];
819
820 /* Create object directories */
821 Status = SmCreateObjectDirectories();
822 if (!NT_SUCCESS(Status))
823 {
824 DPRINT1("SM: Failed to create object directories (Status %lx)\n", Status);
825 return(Status);
826 }
827
828 /* Create the SmApiPort object (LPC) */
829 Status = SmCreateApiPort();
830 if (!NT_SUCCESS(Status))
831 {
832 DPRINT1("SM: Failed to create SmApiPort (Status %lx)\n", Status);
833 return(Status);
834 }
835
836 /* Create the system environment */
837 Status = RtlCreateEnvironment(FALSE,
838 &SmSystemEnvironment);
839 if (!NT_SUCCESS(Status))
840 {
841 DPRINT1("SM: Failed to create the system environment (Status %lx)\n", Status);
842 return(Status);
843 }
844
845 /* Set environment variables */
846 Status = SmSetEnvironmentVariables();
847 if (!NT_SUCCESS(Status))
848 {
849 DPRINT1("SM: Failed to set system environment variables (Status %lx)\n", Status);
850 return(Status);
851 }
852
853 /* Define symbolic links to kernel devices (MS-DOS names) */
854 Status = SmInitDosDevices();
855 if (!NT_SUCCESS(Status))
856 {
857 DPRINT1("SM: Failed to create dos device links (Status %lx)\n", Status);
858 return(Status);
859 }
860
861 /* Run all programs in the boot execution list */
862 Status = SmRunBootApps();
863 if (!NT_SUCCESS(Status))
864 {
865 DPRINT1("SM: Failed to run boot applications (Status %lx)\n", Status);
866 return(Status);
867 }
868
869 /* Process the file rename list */
870 Status = SmProcessFileRenameList();
871 if (!NT_SUCCESS(Status))
872 {
873 DPRINT1("SM: Failed to process the file rename list (Status %lx)\n", Status);
874 return(Status);
875 }
876
877 DPRINT("SM: loading well-known DLLs\n");
878
879 /* Load the well known DLLs */
880 Status = SmLoadKnownDlls();
881 if (!NT_SUCCESS(Status))
882 {
883 DPRINT1("SM: Failed to preload system DLLs (Status %lx)\n", Status);
884 /* Don't crash ReactOS if DLLs cannot be loaded */
885 }
886
887 DPRINT("SM: creating system paging files\n");
888
889 /* Create paging files */
890 Status = SmCreatePagingFiles();
891 if (!NT_SUCCESS(Status))
892 {
893 DPRINT1("SM: Failed to create paging files (Status %lx)\n", Status);
894 return(Status);
895 }
896
897 DPRINT("SM: initializing registry\n");
898
899 /* Load remaining registry hives */
900 NtInitializeRegistry(FALSE);
901
902 /* Set environment variables from registry */
903 #if 0
904 Status = SmUpdateEnvironment();
905 if (!NT_SUCCESS(Status))
906 {
907 DPRINT1("SM: Failed to update environment variables (Status %lx)\n", Status);
908 return(Status);
909 }
910 #endif
911
912 DPRINT("SM: loading subsystems\n");
913
914 /* Load the subsystems */
915 Status = SmLoadSubsystems();
916 if (!NT_SUCCESS(Status))
917 {
918 DPRINT1("SM: Failed to load subsystems (Status %lx)\n", Status);
919 return(Status);
920 }
921
922
923 SignalInitEvent();
924
925
926 DPRINT("SM: initializing csrss\n");
927
928 /* Run csrss.exe */
929 RtlInitUnicodeStringFromLiteral(&UnicodeString,
930 L"\\CsrssInitDone");
931 InitializeObjectAttributes(&ObjectAttributes,
932 &UnicodeString,
933 EVENT_ALL_ACCESS,
934 0,
935 NULL);
936 Status = NtCreateEvent(&CsrssInitEvent,
937 EVENT_ALL_ACCESS,
938 &ObjectAttributes,
939 TRUE,
940 FALSE);
941 if (!NT_SUCCESS(Status))
942 {
943 DbgPrint("Failed to create csrss notification event\n");
944 }
945
946 /*
947 * Start the Win32 subsystem (csrss.exe)
948 */
949
950 /* initialize executable path */
951 wcscpy(UnicodeBuffer, L"\\??\\");
952 wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
953 wcscat(UnicodeBuffer, L"\\system32\\csrss.exe");
954 RtlInitUnicodeString(&UnicodeString,
955 UnicodeBuffer);
956
957 RtlCreateProcessParameters(&ProcessParameters,
958 &UnicodeString,
959 NULL,
960 NULL,
961 NULL,
962 SmSystemEnvironment,
963 NULL,
964 NULL,
965 NULL,
966 NULL);
967
968 Status = RtlCreateUserProcess(&UnicodeString,
969 OBJ_CASE_INSENSITIVE,
970 ProcessParameters,
971 NULL,
972 NULL,
973 NULL,
974 FALSE,
975 NULL,
976 NULL,
977 &ProcessInfo);
978
979 RtlDestroyProcessParameters (ProcessParameters);
980
981 if (!NT_SUCCESS(Status))
982 {
983 DisplayString(L"SM: Loading csrss.exe failed!\n");
984 return(Status);
985 }
986
987 NtWaitForSingleObject(CsrssInitEvent,
988 FALSE,
989 NULL);
990
991 Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;
992
993 /*
994 * Start the logon process (winlogon.exe)
995 */
996
997 DPRINT("SM: starting winlogon\n");
998
999 /* initialize executable path */
1000 wcscpy(UnicodeBuffer, L"\\??\\");
1001 wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
1002 wcscat(UnicodeBuffer, L"\\system32\\winlogon.exe");
1003 RtlInitUnicodeString(&UnicodeString,
1004 UnicodeBuffer);
1005
1006 RtlCreateProcessParameters(&ProcessParameters,
1007 &UnicodeString,
1008 NULL,
1009 NULL,
1010 NULL,
1011 SmSystemEnvironment,
1012 NULL,
1013 NULL,
1014 NULL,
1015 NULL);
1016
1017 Status = RtlCreateUserProcess(&UnicodeString,
1018 OBJ_CASE_INSENSITIVE,
1019 ProcessParameters,
1020 NULL,
1021 NULL,
1022 NULL,
1023 FALSE,
1024 NULL,
1025 NULL,
1026 &ProcessInfo);
1027
1028 RtlDestroyProcessParameters(ProcessParameters);
1029
1030 if (!NT_SUCCESS(Status))
1031 {
1032 DisplayString(L"SM: Loading winlogon.exe failed!\n");
1033 NtTerminateProcess(Children[CHILD_CSRSS],
1034 0);
1035 return(Status);
1036 }
1037 Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
1038
1039 /* Create the \DbgSsApiPort object (LPC) */
1040 RtlInitUnicodeStringFromLiteral(&UnicodeString,
1041 L"\\DbgSsApiPort");
1042 InitializeObjectAttributes(&ObjectAttributes,
1043 &UnicodeString,
1044 PORT_ALL_ACCESS,
1045 NULL,
1046 NULL);
1047
1048 Status = NtCreatePort(&DbgSsApiPort,
1049 &ObjectAttributes,
1050 0,
1051 0,
1052 0);
1053
1054 if (!NT_SUCCESS(Status))
1055 {
1056 return(Status);
1057 }
1058 #ifndef NDEBUG
1059 DisplayString(L"SM: DbgSsApiPort created...\n");
1060 #endif
1061
1062 /* Create the \DbgUiApiPort object (LPC) */
1063 RtlInitUnicodeStringFromLiteral(&UnicodeString,
1064 L"\\DbgUiApiPort");
1065 InitializeObjectAttributes(&ObjectAttributes,
1066 &UnicodeString,
1067 PORT_ALL_ACCESS,
1068 NULL,
1069 NULL);
1070
1071 Status = NtCreatePort(&DbgUiApiPort,
1072 &ObjectAttributes,
1073 0,
1074 0,
1075 0);
1076 if (!NT_SUCCESS(Status))
1077 {
1078 return(Status);
1079 }
1080 #ifndef NDEBUG
1081 DisplayString (L"SM: DbgUiApiPort created...\n");
1082 #endif
1083
1084 return(STATUS_SUCCESS);
1085 }
1086
1087 /* EOF */