SMDLL + SMLIB (static code in SMSS.EXE)
[reactos.git] / reactos / subsys / smss / initss.c
1 /* $Id: init.c 13449 2005-02-06 21:55:07Z ea $
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
27
28 #include "smss.h"
29
30 #include <rosrtl/string.h>
31
32 #define NDEBUG
33 #include <debug.h>
34
35 /* SM handle for its own \SmApiPort */
36 HANDLE hSmApiPort = (HANDLE) 0;
37
38
39 /* TODO: this file should be totally rewritten
40 *
41 * a) look if a special option is set for smss.exe in
42 * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
43 *
44 * b) make smss register with itself for IMAGE_SUBSYSTEM_NATIVE
45 * (programmatically)
46 *
47 * d) make smss initialize Debug (DBGSS) and Windows (CSRSS) as described
48 * in the registry key Required="Debug Windows"
49 * HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems
50 *
51 * e) make optional subsystems loadable (again: they must be described in the registry
52 * key Optional="Posix Os2" to be allowed to run)
53 */
54
55 /**********************************************************************
56 * SmpRegisterSmss/0
57 *
58 * DESCRIPTION
59 * Make smss register with itself for IMAGE_SUBSYSTEM_NATIVE
60 * (programmatically). This also open hSmApiPort to be used
61 * in loading required subsystems.
62 */
63
64 static NTSTATUS
65 SmpRegisterSmss(VOID)
66 {
67 NTSTATUS Status = STATUS_SUCCESS;
68 UNICODE_STRING SbApiPortName = {0,0,NULL};
69
70 DPRINT("SM: %s called\n",__FUNCTION__);
71
72 RtlInitUnicodeString (& SbApiPortName, L"");
73 Status = SmConnectApiPort(& SbApiPortName,
74 (HANDLE) 0,
75 IMAGE_SUBSYSTEM_NATIVE,
76 & hSmApiPort);
77 if(!NT_SUCCESS(Status))
78 {
79 DPRINT("SM: %s: SMDLL!SmConnectApiPort failed (Status=0x%08lx)\n",
80 __FUNCTION__,Status);
81 return Status;
82 }
83 DPRINT("SM self registered\n");
84 /*
85 * Note that you don't need to call complete session
86 * because connection handling code autocompletes
87 * the client structure for IMAGE_SUBSYSTEM_NATIVE.
88 */
89 return Status;
90 }
91
92
93 /**********************************************************************
94 */
95 NTSTATUS
96 SmLoadSubsystems(VOID)
97 {
98 SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
99 NTSTATUS Status = STATUS_SUCCESS;
100 WCHAR Data [MAX_PATH + 1];
101 ULONG DataLength = sizeof Data;
102 ULONG DataType = 0;
103
104
105 DPRINT("SM: loading subsystems\n");
106
107 /* SM self registers */
108 Status = SmpRegisterSmss();
109 if(!NT_SUCCESS(Status))
110 {
111 DPRINT1("SM: SM failed to self register: system is not secure!\n");
112 }
113
114 /* Load Kmode subsystem (aka win32k.sys) */
115 Status = SmLookupSubsystem (L"Kmode",
116 Data,
117 & DataLength,
118 & DataType,
119 TRUE);
120 if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
121 {
122 WCHAR ImagePath [MAX_PATH + 1] = {0};
123
124 wcscpy (ImagePath, L"\\??\\");
125 wcscat (ImagePath, Data);
126 RtlZeroMemory (& ImageInfo, sizeof ImageInfo);
127 RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath);
128 Status = NtSetSystemInformation(SystemLoadAndCallImage,
129 & ImageInfo,
130 sizeof ImageInfo);
131 if(!NT_SUCCESS(Status))
132 {
133 DPRINT("SM: loading Kmode failed (Status=0x%08lx)\n",
134 Status);
135 return Status;
136 }
137 }
138 /* TODO: load Required subsystems (Debug Windows) */
139 #if 0
140 Status = SmExecuteProgram (hSmApiPort, L"DEBUG");
141 if(!NT_SUCCESS(Status))
142 {
143 DPRINT1("SM: DBSS failed to initialize!\n");
144 }
145 #endif
146 return Status;
147 }
148
149 NTSTATUS
150 SmRunCsrss(VOID)
151 {
152 NTSTATUS Status;
153 UNICODE_STRING UnicodeString;
154 OBJECT_ATTRIBUTES ObjectAttributes;
155 RTL_PROCESS_INFO ProcessInfo;
156 HANDLE CsrssInitEvent;
157 WCHAR ImagePath [MAX_PATH];
158
159 DPRINT("SM: initializing csrss\n");
160
161 /* Run csrss.exe */
162 RtlRosInitUnicodeStringFromLiteral(&UnicodeString,
163 L"\\CsrssInitDone");
164 InitializeObjectAttributes(&ObjectAttributes,
165 &UnicodeString,
166 EVENT_ALL_ACCESS,
167 0,
168 NULL);
169 Status = NtCreateEvent(&CsrssInitEvent,
170 EVENT_ALL_ACCESS,
171 &ObjectAttributes,
172 NotificationEvent,
173 FALSE);
174 if (!NT_SUCCESS(Status))
175 {
176 DbgPrint("Failed to create csrss notification event\n");
177 }
178
179 /*
180 * Start the Win32 subsystem (csrss.exe)
181 */
182
183 /* initialize executable path */
184 wcscpy(ImagePath, L"\\??\\");
185 wcscat(ImagePath, SharedUserData->NtSystemRoot);
186 wcscat(ImagePath, L"\\system32\\csrss.exe");
187
188 Status = SmCreateUserProcess(ImagePath,
189 L"",
190 FALSE, /* wait */
191 NULL,
192 FALSE, /* terminate */
193 & ProcessInfo);
194
195 if (!NT_SUCCESS(Status))
196 {
197 DPRINT("SM: %s: Loading csrss.exe failed!\n", __FUNCTION__);
198 return(Status);
199 }
200
201 Status = NtWaitForSingleObject(CsrssInitEvent,
202 FALSE,
203 NULL);
204
205 Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;
206
207 return Status;
208 }
209
210 NTSTATUS
211 SmRunWinlogon(VOID)
212 {
213 NTSTATUS Status = STATUS_SUCCESS;
214 RTL_PROCESS_INFO ProcessInfo;
215 WCHAR ImagePath [MAX_PATH];
216
217 /*
218 * Start the logon process (winlogon.exe)
219 */
220
221 DPRINT("SM: starting winlogon\n");
222
223 /* initialize executable path */
224 wcscpy(ImagePath, L"\\??\\");
225 wcscat(ImagePath, SharedUserData->NtSystemRoot);
226 wcscat(ImagePath, L"\\system32\\winlogon.exe");
227
228 Status = SmCreateUserProcess(ImagePath,
229 L"",
230 FALSE, /* wait */
231 NULL,
232 FALSE, /* terminate */
233 & ProcessInfo);
234 if (!NT_SUCCESS(Status))
235 {
236 DPRINT("SM: %s: Loading winlogon.exe failed!\n", __FUNCTION__);
237 NtTerminateProcess(Children[CHILD_CSRSS], 0);
238 return(Status);
239 }
240
241 Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
242
243 return Status;
244 }
245
246 /* EOF */