Fix a typo.
[reactos.git] / reactos / subsys / smss / initss.c
1 /* $Id$
2 *
3 * initss.c - Load the subsystems
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 #include "smss.h"
27
28 #define NDEBUG
29 #include <debug.h>
30
31 /* SM handle for its own \SmApiPort */
32 HANDLE hSmApiPort = (HANDLE) 0;
33
34
35 /* TODO:
36 *
37 * a) look if a special option is set for smss.exe in
38 * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
39 */
40
41 /**********************************************************************
42 * SmRegisterInternalSubsystem/3
43 *
44 * DESCRIPTION
45 * Register with itself for ImageSubsystemId
46 * (programmatically).
47 */
48 NTSTATUS STDCALL SmRegisterInternalSubsystem (LPWSTR PgmName,
49 USHORT ImageSubsystemId,
50 PHANDLE ApiPort)
51 {
52 NTSTATUS Status = STATUS_SUCCESS;
53 RTL_USER_PROCESS_INFORMATION ProcessInfo;
54
55
56 DPRINT("SM: %s(%S,%d) called\n",__FUNCTION__, PgmName, ImageSubsystemId);
57
58 RtlZeroMemory (& ProcessInfo, sizeof ProcessInfo);
59 ProcessInfo.Size = sizeof ProcessInfo;
60 ProcessInfo.ProcessHandle = (HANDLE) SmSsProcessId;
61 ProcessInfo.ClientId.UniqueProcess = (HANDLE) SmSsProcessId;
62 DPRINT("SM: %s: ProcessInfo.ProcessHandle=%lx\n",
63 __FUNCTION__,ProcessInfo.ProcessHandle);
64 Status = SmCreateClient (& ProcessInfo, PgmName);
65 if (NT_SUCCESS(Status))
66 {
67 UNICODE_STRING SbApiPortName = {0,0,NULL};
68
69 RtlInitUnicodeString (& SbApiPortName, L"");
70 Status = SmConnectApiPort(& SbApiPortName,
71 (HANDLE) -1, /* internal SS have no SB port */
72 ImageSubsystemId,
73 ApiPort);
74 if(!NT_SUCCESS(Status))
75 {
76 DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n",
77 __FUNCTION__,Status);
78 return Status;
79 }
80 DPRINT("SM:%s: %S self registered\n", __FUNCTION__, PgmName);
81 }
82 else
83 {
84 DPRINT1("SM: %s: SmCreateClient(%S) failed (Status=0x%08lx)\n",
85 __FUNCTION__, PgmName, Status);
86 }
87 /*
88 * Note that you don't need to call complete session
89 * here because connection handling code autocompletes
90 * the client structure for IMAGE_SUBSYSTEM_NATIVE and
91 * -1.
92 */
93 return Status;
94 }
95 /**********************************************************************
96 * SmpLoadRequiredSubsystems/0
97 */
98 static NTSTATUS
99 SmpLoadRequiredSubsystems (VOID)
100 {
101 NTSTATUS Status = STATUS_SUCCESS;
102 WCHAR Data [MAX_PATH + 1];
103 ULONG DataLength = sizeof Data;
104 ULONG DataType = 0;
105
106
107 DPRINT("SM: %s called\n", __FUNCTION__);
108
109 RtlZeroMemory (Data, DataLength);
110 Status = SmLookupSubsystem (L"Required",
111 Data,
112 & DataLength,
113 & DataType,
114 NULL);
115 if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
116 {
117 PWCHAR Name = NULL;
118 ULONG Offset = 0;
119
120 for (Name = Data; (Offset < DataLength); )
121 {
122 if(L'\0' != *Name)
123 {
124 UNICODE_STRING Program;
125
126 /* Run the current program */
127 RtlInitUnicodeString (& Program, Name);
128 Status = SmExecuteProgram (hSmApiPort, & Program);
129 if(!NT_SUCCESS(Status))
130 {
131 DPRINT1("SM: %s failed to run '%S' program (Status=0x%08lx)\n",
132 __FUNCTION__, Name, Status);
133 }
134 /* Look for the next program */
135 while ((L'\0' != *Name) && (Offset < DataLength))
136 {
137 ++ Name;
138 ++ Offset;
139 }
140 }
141 ++ Name;
142 ++ Offset;
143 }
144 }
145
146 return Status;
147 }
148
149 /**********************************************************************
150 * SmLoadSubsystems/0
151 */
152 NTSTATUS
153 SmLoadSubsystems(VOID)
154 {
155 NTSTATUS Status = STATUS_SUCCESS;
156
157
158 DPRINT("SM: loading subsystems...\n");
159
160 /*
161 * SM self registers: this also opens hSmApiPort to be used
162 * in loading required subsystems.
163 */
164 Status = SmRegisterInternalSubsystem (L"Session Manager", IMAGE_SUBSYSTEM_NATIVE, & hSmApiPort);
165 if(!NT_SUCCESS(Status))
166 {
167 DPRINT1("SM: SmRegisterInternalSubsystem failed Status=%08lx\n", __FUNCTION__, Status);
168 return Status;
169 }
170 /* Load Required subsystems (Debug Windows) */
171 Status = SmpLoadRequiredSubsystems();
172 if(!NT_SUCCESS(Status))
173 {
174 DPRINT1("SM: SmpLoadRequiredSubsystems failed Status=%08lx\n", __FUNCTION__, Status);
175 return Status;
176 }
177 /* done */
178 DPRINT("SM: done loading subsystems\n");
179 return Status;
180 }
181
182 /* EOF */