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