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