- Move GDI drivers and win32k.sys from system32\drivers to system32
[reactos.git] / reactos / subsys / smss / init.c
1 /* $Id: init.c,v 1.45 2003/02/25 23:08:52 gvg 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 <napi/lpc.h>
35
36 #include "smss.h"
37
38 #define NDEBUG
39
40
41 /* GLOBALS ******************************************************************/
42
43 HANDLE DbgSsApiPort = INVALID_HANDLE_VALUE;
44 HANDLE DbgUiApiPort = INVALID_HANDLE_VALUE;
45
46 PWSTR SmSystemEnvironment = NULL;
47
48
49 /* FUNCTIONS ****************************************************************/
50
51 static NTSTATUS STDCALL
52 SmObjectDirectoryQueryRoutine(PWSTR ValueName,
53 ULONG ValueType,
54 PVOID ValueData,
55 ULONG ValueLength,
56 PVOID Context,
57 PVOID EntryContext)
58 {
59 OBJECT_ATTRIBUTES ObjectAttributes;
60 UNICODE_STRING UnicodeString;
61 HANDLE WindowsDirectory;
62 NTSTATUS Status = STATUS_SUCCESS;
63
64 #ifndef NDEBUG
65 PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
66 PrintString("ValueData '%S'\n", (PWSTR)ValueData);
67 #endif
68 if (ValueType != REG_SZ)
69 {
70 return(STATUS_SUCCESS);
71 }
72
73 RtlInitUnicodeString(&UnicodeString,
74 (PWSTR)ValueData);
75
76 InitializeObjectAttributes(&ObjectAttributes,
77 &UnicodeString,
78 0,
79 NULL,
80 NULL);
81
82 Status = ZwCreateDirectoryObject(&WindowsDirectory,
83 0,
84 &ObjectAttributes);
85
86 return(Status);
87 }
88
89
90 static NTSTATUS
91 SmCreateObjectDirectories(VOID)
92 {
93 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
94 NTSTATUS Status;
95
96 RtlZeroMemory(&QueryTable,
97 sizeof(QueryTable));
98
99 QueryTable[0].Name = L"ObjectDirectories";
100 QueryTable[0].QueryRoutine = SmObjectDirectoryQueryRoutine;
101
102 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
103 L"\\Session Manager",
104 QueryTable,
105 NULL,
106 NULL);
107
108 return(Status);
109 }
110
111
112 static NTSTATUS STDCALL
113 SmDosDevicesQueryRoutine(PWSTR ValueName,
114 ULONG ValueType,
115 PVOID ValueData,
116 ULONG ValueLength,
117 PVOID Context,
118 PVOID EntryContext)
119 {
120 OBJECT_ATTRIBUTES ObjectAttributes;
121 UNICODE_STRING DeviceName;
122 UNICODE_STRING LinkName;
123 HANDLE LinkHandle;
124 WCHAR LinkBuffer[80];
125 NTSTATUS Status;
126
127 #ifndef NDEBUG
128 PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
129 PrintString("ValueData '%S'\n", (PWSTR)ValueData);
130 #endif
131
132 if (ValueType != REG_SZ)
133 {
134 return(STATUS_SUCCESS);
135 }
136
137 swprintf(LinkBuffer,
138 L"\\??\\%s",
139 ValueName);
140 RtlInitUnicodeString(&LinkName,
141 LinkBuffer);
142 RtlInitUnicodeString(&DeviceName,
143 (PWSTR)ValueData);
144
145 #ifndef NDEBUG
146 PrintString("SM: Linking %wZ --> %wZ\n",
147 &LinkName,
148 &DeviceName);
149 #endif
150
151 /* create symbolic link */
152 InitializeObjectAttributes(&ObjectAttributes,
153 &LinkName,
154 OBJ_PERMANENT,
155 NULL,
156 NULL);
157 Status = NtCreateSymbolicLinkObject(&LinkHandle,
158 SYMBOLIC_LINK_ALL_ACCESS,
159 &ObjectAttributes,
160 &DeviceName);
161 if (!NT_SUCCESS(Status))
162 {
163 PrintString("SmDosDevicesQueryRoutine: NtCreateSymbolicLink( %wZ --> %wZ ) failed!\n",
164 &LinkName,
165 &DeviceName);
166 }
167 NtClose(LinkHandle);
168
169 return(Status);
170 }
171
172
173 static NTSTATUS
174 SmInitDosDevices(VOID)
175 {
176 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
177 NTSTATUS Status;
178
179 RtlZeroMemory(&QueryTable,
180 sizeof(QueryTable));
181
182 QueryTable[0].QueryRoutine = SmDosDevicesQueryRoutine;
183
184 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
185 L"\\Session Manager\\DOS Devices",
186 QueryTable,
187 NULL,
188 NULL);
189 return(Status);
190 }
191
192
193 static NTSTATUS STDCALL
194 SmRunBootAppsQueryRoutine(PWSTR ValueName,
195 ULONG ValueType,
196 PVOID ValueData,
197 ULONG ValueLength,
198 PVOID Context,
199 PVOID EntryContext)
200 {
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];
209 PWSTR p1, p2;
210 ULONG len;
211 NTSTATUS Status;
212
213 #ifndef NDEBUG
214 PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
215 PrintString("ValueData '%S'\n", (PWSTR)ValueData);
216 #endif
217
218 if (ValueType != REG_SZ)
219 {
220 return(STATUS_SUCCESS);
221 }
222
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;
228
229 /* Extract the image name */
230 p1++;
231 p2 = wcschr(p1, L' ');
232 if (p2 != NULL)
233 len = p2 - p1;
234 else
235 len = wcslen(p1);
236 memcpy(ImageName, p1, len * sizeof(WCHAR));
237 ImageName[len] = 0;
238
239 /* Extract the command line */
240 if (p2 == NULL)
241 {
242 CommandLine[0] = 0;
243 }
244 else
245 {
246 p2++;
247 wcscpy(CommandLine, p2);
248 }
249
250 PrintString("Running %S...\n", Description);
251 #ifndef NDEBUG
252 PrintString("ImageName: '%S'\n", ImageName);
253 PrintString("CommandLine: '%S'\n", CommandLine);
254 #endif
255
256 /* initialize executable path */
257 wcscpy(ImagePath, L"\\SystemRoot\\system32\\");
258 wcscat(ImagePath, ImageName);
259 wcscat(ImagePath, L".exe");
260
261 RtlInitUnicodeString(&ImagePathString,
262 ImagePath);
263
264 RtlInitUnicodeString(&CommandLineString,
265 CommandLine);
266
267 RtlCreateProcessParameters(&ProcessParameters,
268 &ImagePathString,
269 NULL,
270 NULL,
271 &CommandLineString,
272 NULL,
273 NULL,
274 NULL,
275 NULL,
276 NULL);
277
278 Status = RtlCreateUserProcess(&ImagePathString,
279 OBJ_CASE_INSENSITIVE,
280 ProcessParameters,
281 NULL,
282 NULL,
283 NULL,
284 FALSE,
285 NULL,
286 NULL,
287 &ProcessInfo);
288 if (!NT_SUCCESS(Status))
289 {
290 PrintString("Running %s failed (Status %lx)\n", Description, Status);
291 return(STATUS_SUCCESS);
292 }
293
294 RtlDestroyProcessParameters(ProcessParameters);
295
296 /* Wait for process termination */
297 NtWaitForSingleObject(ProcessInfo.ProcessHandle,
298 FALSE,
299 NULL);
300
301 NtClose(ProcessInfo.ThreadHandle);
302 NtClose(ProcessInfo.ProcessHandle);
303
304 return(STATUS_SUCCESS);
305 }
306
307
308 /*
309 * Run native applications listed in the registry.
310 *
311 * Key:
312 * \Registry\Machine\SYSTEM\CurrentControlSet\Control\Session Manager
313 *
314 * Value (format: "<description> <executable> <command line>":
315 * BootExecute = "autocheck autochk *"
316 */
317 static NTSTATUS
318 SmRunBootApps(VOID)
319 {
320 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
321 NTSTATUS Status;
322
323 RtlZeroMemory(&QueryTable,
324 sizeof(QueryTable));
325
326 QueryTable[0].Name = L"BootExecute";
327 QueryTable[0].QueryRoutine = SmRunBootAppsQueryRoutine;
328
329 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
330 L"\\Session Manager",
331 QueryTable,
332 NULL,
333 NULL);
334 if (!NT_SUCCESS(Status))
335 {
336 PrintString("SmRunBootApps: RtlQueryRegistryValues() failed! (Status %lx)\n", Status);
337 }
338
339 return(Status);
340 }
341
342
343 static NTSTATUS
344 SmProcessFileRenameList(VOID)
345 {
346 #ifndef NDEBUG
347 PrintString("SmProcessFileRenameList() called\n");
348 #endif
349
350 /* FIXME: implement it! */
351
352 #ifndef NDEBUG
353 PrintString("SmProcessFileRenameList() done\n");
354 #endif
355
356 return(STATUS_SUCCESS);
357 }
358
359
360 static NTSTATUS
361 SmPreloadDlls(VOID)
362 {
363 #ifndef NDEBUG
364 PrintString("SmPreloadDlls() called\n");
365 #endif
366
367 /* FIXME: implement it! */
368
369 #ifndef NDEBUG
370 PrintString("SmPreloadDlls() done\n");
371 #endif
372
373 return(STATUS_SUCCESS);
374 }
375
376
377 static NTSTATUS STDCALL
378 SmPagingFilesQueryRoutine(PWSTR ValueName,
379 ULONG ValueType,
380 PVOID ValueData,
381 ULONG ValueLength,
382 PVOID Context,
383 PVOID EntryContext)
384 {
385 UNICODE_STRING FileName;
386 LARGE_INTEGER InitialSize;
387 LARGE_INTEGER MaximumSize;
388 NTSTATUS Status;
389 LPWSTR p;
390
391 #ifndef NDEBUG
392 PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
393 PrintString("ValueData '%S'\n", (PWSTR)ValueData);
394 #endif
395
396 if (ValueType != REG_SZ)
397 {
398 return(STATUS_SUCCESS);
399 }
400
401 /*
402 * Format: "<path>[ <initial_size>[ <maximum_size>]]"
403 */
404 if ((p = wcschr(ValueData, ' ')) != NULL)
405 {
406 *p = L'\0';
407 InitialSize.QuadPart = wcstoul(p + 1, &p, 0) * 256 * 4096;
408 if (*p == ' ')
409 {
410 MaximumSize.QuadPart = wcstoul(p + 1, NULL, 0) * 256 * 4096;
411 }
412 else
413 MaximumSize = InitialSize;
414 }
415 else
416 {
417 InitialSize.QuadPart = 50 * 4096;
418 MaximumSize.QuadPart = 80 * 4096;
419 }
420
421 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,
422 &FileName,
423 NULL,
424 NULL))
425 {
426 return (STATUS_SUCCESS);
427 }
428
429 DbgPrint("SMSS: Created paging file %wZ with size %dKB\n",
430 &FileName, InitialSize.QuadPart / 1024);
431 Status = NtCreatePagingFile(&FileName,
432 &InitialSize,
433 &MaximumSize,
434 0);
435
436 RtlFreeUnicodeString(&FileName);
437
438 return(STATUS_SUCCESS);
439 }
440
441
442 static NTSTATUS
443 SmCreatePagingFiles(VOID)
444 {
445 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
446 NTSTATUS Status;
447
448 RtlZeroMemory(&QueryTable,
449 sizeof(QueryTable));
450
451 QueryTable[0].Name = L"PagingFiles";
452 QueryTable[0].QueryRoutine = SmPagingFilesQueryRoutine;
453
454 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
455 L"\\Session Manager\\Memory Management",
456 QueryTable,
457 NULL,
458 NULL);
459
460 return(Status);
461 }
462
463
464 static NTSTATUS STDCALL
465 SmEnvironmentQueryRoutine(PWSTR ValueName,
466 ULONG ValueType,
467 PVOID ValueData,
468 ULONG ValueLength,
469 PVOID Context,
470 PVOID EntryContext)
471 {
472 UNICODE_STRING EnvVariable;
473 UNICODE_STRING EnvValue;
474
475 #ifndef NDEBUG
476 PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
477 PrintString("ValueData '%S'\n", (PWSTR)ValueData);
478 #endif
479
480 if (ValueType != REG_SZ)
481 {
482 return(STATUS_SUCCESS);
483 }
484
485 RtlInitUnicodeString(&EnvVariable,
486 ValueName);
487 RtlInitUnicodeString(&EnvValue,
488 (PWSTR)ValueData);
489 RtlSetEnvironmentVariable(Context,
490 &EnvVariable,
491 &EnvValue);
492
493 return(STATUS_SUCCESS);
494 }
495
496
497 static NTSTATUS
498 SmSetEnvironmentVariables(VOID)
499 {
500 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
501 UNICODE_STRING EnvVariable;
502 UNICODE_STRING EnvValue;
503 WCHAR ValueBuffer[MAX_PATH];
504 NTSTATUS Status;
505
506 /*
507 * The following environment variables must be set prior to reading
508 * other variables from the registry.
509 *
510 * Variables (example):
511 * SystemRoot = "C:\reactos"
512 * SystemDrive = "C:"
513 */
514
515 /* Copy system root into value buffer */
516 wcscpy(ValueBuffer,
517 SharedUserData->NtSystemRoot);
518
519 /* Cet SystemRoot = "C:\reactos" */
520 RtlInitUnicodeStringFromLiteral(&EnvVariable,
521 L"SystemRoot");
522 RtlInitUnicodeString(&EnvValue,
523 ValueBuffer);
524 RtlSetEnvironmentVariable(&SmSystemEnvironment,
525 &EnvVariable,
526 &EnvValue);
527
528 /* Cut off trailing path */
529 ValueBuffer[2] = 0;
530
531 /* Set SystemDrive = "C:" */
532 RtlInitUnicodeStringFromLiteral(&EnvVariable,
533 L"SystemDrive");
534 RtlInitUnicodeString(&EnvValue,
535 ValueBuffer);
536 RtlSetEnvironmentVariable(&SmSystemEnvironment,
537 &EnvVariable,
538 &EnvValue);
539
540 /* Read system environment from the registry. */
541 RtlZeroMemory(&QueryTable,
542 sizeof(QueryTable));
543
544 QueryTable[0].QueryRoutine = SmEnvironmentQueryRoutine;
545
546 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
547 L"\\Session Manager\\Environment",
548 QueryTable,
549 &SmSystemEnvironment,
550 SmSystemEnvironment);
551
552 return(Status);
553 }
554
555
556 static NTSTATUS
557 SmLoadSubsystems(VOID)
558 {
559 SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
560 NTSTATUS Status;
561
562 /* Load kernel mode subsystem (aka win32k.sys) */
563 RtlInitUnicodeStringFromLiteral(&ImageInfo.ModuleName,
564 L"\\SystemRoot\\system32\\win32k.sys");
565
566 Status = NtSetSystemInformation(SystemLoadAndCallImage,
567 &ImageInfo,
568 sizeof(SYSTEM_LOAD_AND_CALL_IMAGE));
569
570 PrintString("SMSS: Loaded win32k.sys (Status %lx)\n", Status);
571 #if 0
572 if (!NT_SUCCESS(Status))
573 {
574 return(Status);
575 }
576 #endif
577
578 /* FIXME: load more subsystems (csrss!) */
579
580 return(Status);
581 }
582
583
584 NTSTATUS
585 InitSessionManager(HANDLE Children[])
586 {
587 NTSTATUS Status;
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];
595
596 /* Create object directories */
597 Status = SmCreateObjectDirectories();
598 if (!NT_SUCCESS(Status))
599 {
600 PrintString("SM: Failed to create object directories (Status %lx)\n", Status);
601 return(Status);
602 }
603
604 /* Create the SmApiPort object (LPC) */
605 Status = SmCreateApiPort();
606 if (!NT_SUCCESS(Status))
607 {
608 PrintString("SM: Failed to create SmApiPort (Status %lx)\n", Status);
609 return(Status);
610 }
611
612 /* Create the system environment */
613 Status = RtlCreateEnvironment(FALSE,
614 &SmSystemEnvironment);
615 if (!NT_SUCCESS(Status))
616 {
617 PrintString("SM: Failed to create the system environment (Status %lx)\n", Status);
618 return(Status);
619 }
620
621 /* Define symbolic links to kernel devices (MS-DOS names) */
622 Status = SmInitDosDevices();
623 if (!NT_SUCCESS(Status))
624 {
625 PrintString("SM: Failed to create dos device links (Status %lx)\n", Status);
626 return(Status);
627 }
628
629 /* Run all programs in the boot execution list */
630 Status = SmRunBootApps();
631 if (!NT_SUCCESS(Status))
632 {
633 PrintString("SM: Failed to run boot applications (Status %lx)\n", Status);
634 return(Status);
635 }
636
637 /* Process the file rename list */
638 Status = SmProcessFileRenameList();
639 if (!NT_SUCCESS(Status))
640 {
641 PrintString("SM: Failed to process the file rename list (Status %lx)\n", Status);
642 return(Status);
643 }
644
645 /* Load the well known DLLs */
646 Status = SmPreloadDlls();
647 if (!NT_SUCCESS(Status))
648 {
649 PrintString("SM: Failed to preload system DLLs (Status %lx)\n", Status);
650 return(Status);
651 }
652
653 /* Create paging files */
654 Status = SmCreatePagingFiles();
655 if (!NT_SUCCESS(Status))
656 {
657 PrintString("SM: Failed to create paging files (Status %lx)\n", Status);
658 return(Status);
659 }
660
661 /* Load remaining registry hives */
662 NtInitializeRegistry(FALSE);
663
664 /* Set environment variables from registry */
665 Status = SmSetEnvironmentVariables();
666 if (!NT_SUCCESS(Status))
667 {
668 PrintString("SM: Failed to set system environment variables (Status %lx)\n", Status);
669 return(Status);
670 }
671
672 /* Load the subsystems */
673 Status = SmLoadSubsystems();
674 if (!NT_SUCCESS(Status))
675 {
676 PrintString("SM: Failed to load subsystems (Status %lx)\n", Status);
677 return(Status);
678 }
679
680 /* Run csrss.exe */
681 RtlInitUnicodeStringFromLiteral(&UnicodeString,
682 L"\\CsrssInitDone");
683 InitializeObjectAttributes(&ObjectAttributes,
684 &UnicodeString,
685 EVENT_ALL_ACCESS,
686 0,
687 NULL);
688 Status = NtCreateEvent(&CsrssInitEvent,
689 EVENT_ALL_ACCESS,
690 &ObjectAttributes,
691 TRUE,
692 FALSE);
693 if (!NT_SUCCESS(Status))
694 {
695 DbgPrint("Failed to create csrss notification event\n");
696 }
697
698 /*
699 * Start the Win32 subsystem (csrss.exe)
700 */
701
702 /* initialize executable path */
703 wcscpy(UnicodeBuffer, L"\\??\\");
704 wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
705 wcscat(UnicodeBuffer, L"\\system32\\csrss.exe");
706 RtlInitUnicodeString(&UnicodeString,
707 UnicodeBuffer);
708
709 RtlCreateProcessParameters(&ProcessParameters,
710 &UnicodeString,
711 NULL,
712 NULL,
713 NULL,
714 SmSystemEnvironment,
715 NULL,
716 NULL,
717 NULL,
718 NULL);
719
720 Status = RtlCreateUserProcess(&UnicodeString,
721 OBJ_CASE_INSENSITIVE,
722 ProcessParameters,
723 NULL,
724 NULL,
725 NULL,
726 FALSE,
727 NULL,
728 NULL,
729 &ProcessInfo);
730
731 RtlDestroyProcessParameters (ProcessParameters);
732
733 if (!NT_SUCCESS(Status))
734 {
735 DisplayString(L"SM: Loading csrss.exe failed!\n");
736 return(Status);
737 }
738
739 NtWaitForSingleObject(CsrssInitEvent,
740 FALSE,
741 NULL);
742
743 Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;
744
745 /*
746 * Start the logon process (winlogon.exe)
747 */
748
749 /* initialize executable path */
750 wcscpy(UnicodeBuffer, L"\\??\\");
751 wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
752 wcscat(UnicodeBuffer, L"\\system32\\winlogon.exe");
753 RtlInitUnicodeString(&UnicodeString,
754 UnicodeBuffer);
755
756 RtlCreateProcessParameters(&ProcessParameters,
757 &UnicodeString,
758 NULL,
759 NULL,
760 NULL,
761 SmSystemEnvironment,
762 NULL,
763 NULL,
764 NULL,
765 NULL);
766
767 Status = RtlCreateUserProcess(&UnicodeString,
768 OBJ_CASE_INSENSITIVE,
769 ProcessParameters,
770 NULL,
771 NULL,
772 NULL,
773 FALSE,
774 NULL,
775 NULL,
776 &ProcessInfo);
777
778 RtlDestroyProcessParameters(ProcessParameters);
779
780 if (!NT_SUCCESS(Status))
781 {
782 DisplayString(L"SM: Loading winlogon.exe failed!\n");
783 NtTerminateProcess(Children[CHILD_CSRSS],
784 0);
785 return(Status);
786 }
787 Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
788
789 /* Create the \DbgSsApiPort object (LPC) */
790 RtlInitUnicodeStringFromLiteral(&UnicodeString,
791 L"\\DbgSsApiPort");
792 InitializeObjectAttributes(&ObjectAttributes,
793 &UnicodeString,
794 PORT_ALL_ACCESS,
795 NULL,
796 NULL);
797
798 Status = NtCreatePort(&DbgSsApiPort,
799 &ObjectAttributes,
800 0,
801 0,
802 0);
803
804 if (!NT_SUCCESS(Status))
805 {
806 return(Status);
807 }
808 #ifndef NDEBUG
809 DisplayString(L"SM: DbgSsApiPort created...\n");
810 #endif
811
812 /* Create the \DbgUiApiPort object (LPC) */
813 RtlInitUnicodeStringFromLiteral(&UnicodeString,
814 L"\\DbgUiApiPort");
815 InitializeObjectAttributes(&ObjectAttributes,
816 &UnicodeString,
817 PORT_ALL_ACCESS,
818 NULL,
819 NULL);
820
821 Status = NtCreatePort(&DbgUiApiPort,
822 &ObjectAttributes,
823 0,
824 0,
825 0);
826 if (!NT_SUCCESS(Status))
827 {
828 return(Status);
829 }
830 #ifndef NDEBUG
831 DisplayString (L"SM: DbgUiApiPort created...\n");
832 #endif
833
834 return(STATUS_SUCCESS);
835 }
836
837 /* EOF */