Window stations and desktops
[reactos.git] / reactos / subsys / smss / init.c
1 /* $Id: init.c,v 1.25 2001/06/12 17:50:28 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 #include <ntos.h>
30 #include <ntdll/rtl.h>
31 #include <napi/lpc.h>
32 #include <napi/shared_data.h>
33
34 #include "smss.h"
35
36 #define NDEBUG
37
38 /* GLOBAL VARIABLES *********************************************************/
39
40 HANDLE SmApiPort = INVALID_HANDLE_VALUE;
41 HANDLE DbgSsApiPort = INVALID_HANDLE_VALUE;
42 HANDLE DbgUiApiPort = INVALID_HANDLE_VALUE;
43
44 PWSTR SmSystemEnvironment = NULL;
45
46
47 /* FUNCTIONS ****************************************************************/
48
49 static VOID
50 SmCreatePagingFiles (VOID)
51 {
52 UNICODE_STRING FileName;
53 ULONG ulCurrentSize;
54 ULONG i, j;
55 CHAR FileNameBufA[255];
56 ANSI_STRING FileNameA;
57 NTSTATUS Status;
58 HANDLE FileHandle;
59 OBJECT_ATTRIBUTES ObjectAttributes;
60 IO_STATUS_BLOCK Iosb;
61 LARGE_INTEGER Offset;
62 static CHAR Buffer[4096];
63 BOOL Found = FALSE;
64
65 for (i = 0; i < 4; i++)
66 {
67 for (j = 0; j < 4; j++)
68 {
69 sprintf(FileNameBufA, "\\Device\\Harddisk%d\\Partition%d", i, j);
70 RtlInitAnsiString(&FileNameA, FileNameBufA);
71 RtlAnsiStringToUnicodeString(&FileName, &FileNameA, TRUE);
72 InitializeObjectAttributes(&ObjectAttributes,
73 &FileName,
74 0,
75 NULL,
76 NULL);
77
78 Status = ZwOpenFile(&FileHandle,
79 FILE_ALL_ACCESS,
80 &ObjectAttributes,
81 &Iosb,
82 0,
83 0);
84 if (!NT_SUCCESS(Status))
85 {
86 continue;
87 }
88
89 Offset.QuadPart = 0;
90 Status = ZwReadFile(FileHandle,
91 NULL,
92 NULL,
93 NULL,
94 &Iosb,
95 Buffer,
96 4096,
97 &Offset,
98 NULL);
99 if (!NT_SUCCESS(Status))
100 {
101 DbgPrint("SM: Failed to read first page of partition\n");
102 continue;
103 }
104
105 if (memcmp(&Buffer[4096 - 10], "SWAP-SPACE", 10) == 0 ||
106 memcmp(&Buffer[4096 - 10], "SWAPSPACE2", 10) == 0)
107 {
108 DbgPrint("SM: Found swap space at %s\n", FileNameA);
109 Found = TRUE;
110 break;
111 }
112
113 ZwClose(FileHandle);
114 }
115 }
116 }
117
118 #if 0
119 static VOID
120 SmCreatePagingFiles (VOID)
121 {
122 UNICODE_STRING FileName;
123 ULONG ulCurrentSize;
124
125 /* FIXME: Read file names from registry */
126
127 RtlInitUnicodeString (&FileName,
128 L"\\SystemRoot\\pagefile.sys");
129
130 NtCreatePagingFile (&FileName,
131 50,
132 80,
133 &ulCurrentSize);
134 }
135 #endif
136
137
138 static VOID
139 SmSetEnvironmentVariables (VOID)
140 {
141 UNICODE_STRING EnvVariable;
142 UNICODE_STRING EnvValue;
143 UNICODE_STRING EnvExpandedValue;
144 ULONG ExpandedLength;
145 WCHAR ExpandBuffer[512];
146 WCHAR ValueBuffer[MAX_PATH];
147 PKUSER_SHARED_DATA SharedUserData =
148 (PKUSER_SHARED_DATA)USER_SHARED_DATA_BASE;
149
150 /*
151 * The following environment variables are read from the registry.
152 * Because the registry does not work yet, the environment variables
153 * are set one by one, using information from the shared user page.
154 *
155 * Variables (example):
156 * SystemRoot = C:\reactos
157 * SystemDrive = C:
158 *
159 * OS = ReactOS
160 * Path = %SystemRoot%\system32;%SystemRoot%
161 * windir = %SystemRoot%
162 */
163
164 /* copy system root into value buffer */
165 wcscpy (ValueBuffer, SharedUserData->NtSystemRoot);
166
167 /* set "SystemRoot = C:\reactos" */
168 RtlInitUnicodeString (&EnvVariable,
169 L"SystemRoot");
170 RtlInitUnicodeString (&EnvValue,
171 ValueBuffer);
172 RtlSetEnvironmentVariable (&SmSystemEnvironment,
173 &EnvVariable,
174 &EnvValue);
175
176 /* cut off trailing path */
177 ValueBuffer[2] = 0;
178
179 /* Set "SystemDrive = C:" */
180 RtlInitUnicodeString (&EnvVariable,
181 L"SystemDrive");
182 RtlSetEnvironmentVariable (&SmSystemEnvironment,
183 &EnvVariable,
184 &EnvValue);
185
186
187 /* Set "OS = ReactOS" */
188 RtlInitUnicodeString (&EnvVariable,
189 L"OS");
190 RtlInitUnicodeString (&EnvValue,
191 L"ReactOS");
192 RtlSetEnvironmentVariable (&SmSystemEnvironment,
193 &EnvVariable,
194 &EnvValue);
195
196
197 /* Set "Path = %SystemRoot%\system32;%SystemRoot%" */
198 RtlInitUnicodeString (&EnvVariable,
199 L"Path");
200 RtlInitUnicodeString (&EnvValue,
201 L"%SystemRoot%\\system32;%SystemRoot%");
202 EnvExpandedValue.Length = 0;
203 EnvExpandedValue.MaximumLength = 512 * sizeof(WCHAR);
204 EnvExpandedValue.Buffer = ExpandBuffer;
205 *ExpandBuffer = 0;
206 RtlExpandEnvironmentStrings_U (SmSystemEnvironment,
207 &EnvValue,
208 &EnvExpandedValue,
209 &ExpandedLength);
210 RtlSetEnvironmentVariable (&SmSystemEnvironment,
211 &EnvVariable,
212 &EnvExpandedValue);
213
214 /* Set "windir = %SystemRoot%" */
215 RtlInitUnicodeString (&EnvVariable,
216 L"windir");
217 RtlInitUnicodeString (&EnvValue,
218 L"%SystemRoot%");
219 EnvExpandedValue.Length = 0;
220 EnvExpandedValue.MaximumLength = 512 * sizeof(WCHAR);
221 EnvExpandedValue.Buffer = ExpandBuffer;
222 *ExpandBuffer = 0;
223 RtlExpandEnvironmentStrings_U (SmSystemEnvironment,
224 &EnvValue,
225 &EnvExpandedValue,
226 &ExpandedLength);
227 RtlSetEnvironmentVariable (&SmSystemEnvironment,
228 &EnvVariable,
229 &EnvExpandedValue);
230 }
231
232
233 BOOL InitSessionManager (HANDLE Children[])
234 {
235 NTSTATUS Status;
236 UNICODE_STRING UnicodeString;
237 OBJECT_ATTRIBUTES ObjectAttributes;
238 UNICODE_STRING CmdLineW;
239 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
240 RTL_PROCESS_INFO ProcessInfo;
241 HANDLE CsrssInitEvent;
242 HANDLE WindowsDirectory;
243 WCHAR UnicodeBuffer[MAX_PATH];
244 PKUSER_SHARED_DATA SharedUserData =
245 (PKUSER_SHARED_DATA)USER_SHARED_DATA_BASE;
246
247 /*
248 * FIXME: The '\Windows' directory is created by csrss.exe but
249 * win32k.sys needs it at intialization and it is loaded
250 * before csrss.exe
251 */
252
253 /*
254 * Create the '\Windows' directory
255 */
256 RtlInitUnicodeString(
257 &UnicodeString,
258 L"\\Windows");
259
260 InitializeObjectAttributes(
261 &ObjectAttributes,
262 &UnicodeString,
263 0,
264 NULL,
265 NULL);
266
267 Status = ZwCreateDirectoryObject(
268 &WindowsDirectory,
269 0,
270 &ObjectAttributes);
271 if (!NT_SUCCESS(Status))
272 {
273 DisplayString (L"SM: Could not create \\Windows directory!\n");
274 return FALSE;
275 }
276
277 /* Create the "\SmApiPort" object (LPC) */
278 RtlInitUnicodeString (&UnicodeString,
279 L"\\SmApiPort");
280 InitializeObjectAttributes (&ObjectAttributes,
281 &UnicodeString,
282 PORT_ALL_ACCESS,
283 NULL,
284 NULL);
285
286 Status = NtCreatePort (&SmApiPort,
287 &ObjectAttributes,
288 0,
289 0,
290 0);
291
292 if (!NT_SUCCESS(Status))
293 {
294 return FALSE;
295 }
296
297 #ifndef NDEBUG
298 DisplayString (L"SM: \\SmApiPort created...\n");
299 #endif
300
301 /* Create two threads for "\SmApiPort" */
302 RtlCreateUserThread (NtCurrentProcess (),
303 NULL,
304 FALSE,
305 0,
306 NULL,
307 NULL,
308 (PTHREAD_START_ROUTINE)SmApiThread,
309 (PVOID)SmApiPort,
310 NULL,
311 NULL);
312
313 RtlCreateUserThread (NtCurrentProcess (),
314 NULL,
315 FALSE,
316 0,
317 NULL,
318 NULL,
319 (PTHREAD_START_ROUTINE)SmApiThread,
320 (PVOID)SmApiPort,
321 NULL,
322 NULL);
323
324 /* Create the system environment */
325 Status = RtlCreateEnvironment (FALSE,
326 &SmSystemEnvironment);
327 if (!NT_SUCCESS(Status))
328 {
329 return FALSE;
330 }
331 #ifndef NDEBUG
332 DisplayString (L"SM: System Environment created\n");
333 #endif
334
335 /* FIXME: Define symbolic links to kernel devices (MS-DOS names) */
336
337 /* FIXME: Run all programs in the boot execution list */
338
339 /* FIXME: Process the file rename list */
340
341 /* FIXME: Load the well known DLLs */
342
343 /* Create paging files */
344 // SmCreatePagingFiles ();
345
346 /* Load remaining registry hives */
347 NtInitializeRegistry (FALSE);
348
349 /* Set environment variables from registry */
350 SmSetEnvironmentVariables ();
351
352 /* Load the kernel mode driver win32k.sys */
353 RtlInitUnicodeString (&CmdLineW,
354 L"\\SystemRoot\\system32\\drivers\\win32k.sys");
355 Status = NtLoadDriver (&CmdLineW);
356
357 #if 0
358 if (!NT_SUCCESS(Status))
359 {
360 return FALSE;
361 }
362 #endif
363 /* Run csrss.exe */
364 RtlInitUnicodeString(&UnicodeString,
365 L"\\CsrssInitDone");
366 InitializeObjectAttributes(&ObjectAttributes,
367 &UnicodeString,
368 EVENT_ALL_ACCESS,
369 0,
370 NULL);
371 Status = NtCreateEvent(&CsrssInitEvent,
372 EVENT_ALL_ACCESS,
373 &ObjectAttributes,
374 TRUE,
375 FALSE);
376 if (!NT_SUCCESS(Status))
377 {
378 DbgPrint("Failed to create csrss notification event\n");
379 }
380
381 /*
382 * Start the Win32 subsystem (csrss.exe)
383 */
384 DisplayString (L"SM: Running csrss.exe\n");
385
386 /* initialize executable path */
387 wcscpy(UnicodeBuffer, L"\\??\\");
388 wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
389 wcscat(UnicodeBuffer, L"\\system32\\csrss.exe");
390 RtlInitUnicodeString (&UnicodeString,
391 UnicodeBuffer);
392
393 RtlCreateProcessParameters (&ProcessParameters,
394 &UnicodeString,
395 NULL,
396 NULL,
397 NULL,
398 SmSystemEnvironment,
399 NULL,
400 NULL,
401 NULL,
402 NULL);
403
404 Status = RtlCreateUserProcess (&UnicodeString,
405 OBJ_CASE_INSENSITIVE,
406 ProcessParameters,
407 NULL,
408 NULL,
409 NULL,
410 FALSE,
411 NULL,
412 NULL,
413 &ProcessInfo);
414
415 RtlDestroyProcessParameters (ProcessParameters);
416
417 if (!NT_SUCCESS(Status))
418 {
419 DisplayString (L"SM: Loading csrss.exe failed!\n");
420 return FALSE;
421 }
422
423 DbgPrint("SM: Waiting for csrss\n");
424 NtWaitForSingleObject(CsrssInitEvent,
425 FALSE,
426 NULL);
427 DbgPrint("SM: Finished waiting for csrss\n");
428
429 Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;
430
431 /*
432 * Start the logon process (winlogon.exe)
433 */
434 DisplayString(L"SM: Running winlogon.exe\n");
435
436 /* initialize executable path */
437 wcscpy(UnicodeBuffer, L"\\??\\");
438 wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
439 wcscat(UnicodeBuffer, L"\\system32\\winlogon.exe");
440 RtlInitUnicodeString (&UnicodeString,
441 UnicodeBuffer);
442
443 RtlCreateProcessParameters(&ProcessParameters,
444 &UnicodeString,
445 NULL,
446 NULL,
447 NULL,
448 SmSystemEnvironment,
449 NULL,
450 NULL,
451 NULL,
452 NULL);
453
454 Status = RtlCreateUserProcess(&UnicodeString,
455 OBJ_CASE_INSENSITIVE,
456 ProcessParameters,
457 NULL,
458 NULL,
459 NULL,
460 FALSE,
461 NULL,
462 NULL,
463 &ProcessInfo);
464
465 RtlDestroyProcessParameters(ProcessParameters);
466
467 if (!NT_SUCCESS(Status))
468 {
469 DisplayString(L"SM: Loading winlogon.exe failed!\n");
470 NtTerminateProcess(Children[CHILD_CSRSS],
471 0);
472 return FALSE;
473 }
474 Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
475
476 /* Create the \DbgSsApiPort object (LPC) */
477 RtlInitUnicodeString (&UnicodeString,
478 L"\\DbgSsApiPort");
479 InitializeObjectAttributes (&ObjectAttributes,
480 &UnicodeString,
481 PORT_ALL_ACCESS,
482 NULL,
483 NULL);
484
485 Status = NtCreatePort (&DbgSsApiPort,
486 &ObjectAttributes,
487 0,
488 0,
489 0);
490
491 if (!NT_SUCCESS(Status))
492 {
493 return FALSE;
494 }
495 #ifndef NDEBUG
496 DisplayString (L"SM: DbgSsApiPort created...\n");
497 #endif
498
499 /* Create the \DbgUiApiPort object (LPC) */
500 RtlInitUnicodeString (&UnicodeString,
501 L"\\DbgUiApiPort");
502 InitializeObjectAttributes (&ObjectAttributes,
503 &UnicodeString,
504 PORT_ALL_ACCESS,
505 NULL,
506 NULL);
507
508 Status = NtCreatePort (&DbgUiApiPort,
509 &ObjectAttributes,
510 0,
511 0,
512 0);
513
514 if (!NT_SUCCESS(Status))
515 {
516 return FALSE;
517 }
518 #ifndef NDEBUG
519 DisplayString (L"SM: DbgUiApiPort created...\n");
520 #endif
521
522 return TRUE;
523 }
524
525 /* EOF */