V86 mode fixes
[reactos.git] / reactos / subsys / smss / init.c
1 /* $Id: init.c,v 1.23 2001/03/25 02:34:30 dwelch 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
243 WCHAR UnicodeBuffer[MAX_PATH];
244 PKUSER_SHARED_DATA SharedUserData =
245 (PKUSER_SHARED_DATA)USER_SHARED_DATA_BASE;
246
247 /* Create the "\SmApiPort" object (LPC) */
248 RtlInitUnicodeString (&UnicodeString,
249 L"\\SmApiPort");
250 InitializeObjectAttributes (&ObjectAttributes,
251 &UnicodeString,
252 PORT_ALL_ACCESS,
253 NULL,
254 NULL);
255
256 Status = NtCreatePort (&SmApiPort,
257 &ObjectAttributes,
258 0,
259 0,
260 0);
261
262 if (!NT_SUCCESS(Status))
263 {
264 return FALSE;
265 }
266
267 #ifndef NDEBUG
268 DisplayString (L"SM: \\SmApiPort created...\n");
269 #endif
270
271 /* Create two threads for "\SmApiPort" */
272 RtlCreateUserThread (NtCurrentProcess (),
273 NULL,
274 FALSE,
275 0,
276 NULL,
277 NULL,
278 (PTHREAD_START_ROUTINE)SmApiThread,
279 (PVOID)SmApiPort,
280 NULL,
281 NULL);
282
283 RtlCreateUserThread (NtCurrentProcess (),
284 NULL,
285 FALSE,
286 0,
287 NULL,
288 NULL,
289 (PTHREAD_START_ROUTINE)SmApiThread,
290 (PVOID)SmApiPort,
291 NULL,
292 NULL);
293
294 /* Create the system environment */
295 Status = RtlCreateEnvironment (FALSE,
296 &SmSystemEnvironment);
297 if (!NT_SUCCESS(Status))
298 {
299 return FALSE;
300 }
301 #ifndef NDEBUG
302 DisplayString (L"SM: System Environment created\n");
303 #endif
304
305 /* FIXME: Define symbolic links to kernel devices (MS-DOS names) */
306
307 /* FIXME: Run all programs in the boot execution list */
308
309 /* FIXME: Process the file rename list */
310
311 /* FIXME: Load the well known DLLs */
312
313 /* Create paging files */
314 // SmCreatePagingFiles ();
315
316 /* Load remaining registry hives */
317 NtInitializeRegistry (FALSE);
318
319 /* Set environment variables from registry */
320 SmSetEnvironmentVariables ();
321
322 /* Load the kernel mode driver win32k.sys */
323 RtlInitUnicodeString (&CmdLineW,
324 L"\\SystemRoot\\system32\\drivers\\win32k.sys");
325 Status = NtLoadDriver (&CmdLineW);
326
327 if (!NT_SUCCESS(Status))
328 {
329 return FALSE;
330 }
331
332 /* Run csrss.exe */
333 RtlInitUnicodeString(&UnicodeString,
334 L"\\CsrssInitDone");
335 InitializeObjectAttributes(&ObjectAttributes,
336 &UnicodeString,
337 EVENT_ALL_ACCESS,
338 0,
339 NULL);
340 Status = NtCreateEvent(&CsrssInitEvent,
341 EVENT_ALL_ACCESS,
342 &ObjectAttributes,
343 TRUE,
344 FALSE);
345 if (!NT_SUCCESS(Status))
346 {
347 DbgPrint("Failed to create csrss notification event\n");
348 }
349
350 /*
351 * Start the Win32 subsystem (csrss.exe)
352 */
353 DisplayString (L"SM: Running csrss.exe\n");
354
355 /* initialize executable path */
356 wcscpy(UnicodeBuffer, L"\\??\\");
357 wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
358 wcscat(UnicodeBuffer, L"\\system32\\csrss.exe");
359 RtlInitUnicodeString (&UnicodeString,
360 UnicodeBuffer);
361
362 RtlCreateProcessParameters (&ProcessParameters,
363 &UnicodeString,
364 NULL,
365 NULL,
366 NULL,
367 SmSystemEnvironment,
368 NULL,
369 NULL,
370 NULL,
371 NULL);
372
373 Status = RtlCreateUserProcess (&UnicodeString,
374 OBJ_CASE_INSENSITIVE,
375 ProcessParameters,
376 NULL,
377 NULL,
378 NULL,
379 FALSE,
380 NULL,
381 NULL,
382 &ProcessInfo);
383
384 RtlDestroyProcessParameters (ProcessParameters);
385
386 if (!NT_SUCCESS(Status))
387 {
388 DisplayString (L"SM: Loading csrss.exe failed!\n");
389 return FALSE;
390 }
391
392 DbgPrint("SM: Waiting for csrss\n");
393 NtWaitForSingleObject(CsrssInitEvent,
394 FALSE,
395 NULL);
396 DbgPrint("SM: Finished waiting for csrss\n");
397
398 Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;
399
400 /*
401 * Start the logon process (winlogon.exe)
402 */
403 DisplayString(L"SM: Running winlogon.exe\n");
404
405 /* initialize executable path */
406 wcscpy(UnicodeBuffer, L"\\??\\");
407 wcscat(UnicodeBuffer, SharedUserData->NtSystemRoot);
408 wcscat(UnicodeBuffer, L"\\system32\\winlogon.exe");
409 RtlInitUnicodeString (&UnicodeString,
410 UnicodeBuffer);
411
412 RtlCreateProcessParameters(&ProcessParameters,
413 &UnicodeString,
414 NULL,
415 NULL,
416 NULL,
417 SmSystemEnvironment,
418 NULL,
419 NULL,
420 NULL,
421 NULL);
422
423 Status = RtlCreateUserProcess(&UnicodeString,
424 OBJ_CASE_INSENSITIVE,
425 ProcessParameters,
426 NULL,
427 NULL,
428 NULL,
429 FALSE,
430 NULL,
431 NULL,
432 &ProcessInfo);
433
434 RtlDestroyProcessParameters(ProcessParameters);
435
436 if (!NT_SUCCESS(Status))
437 {
438 DisplayString(L"SM: Loading winlogon.exe failed!\n");
439 NtTerminateProcess(Children[CHILD_CSRSS],
440 0);
441 return FALSE;
442 }
443 Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;
444
445 /* Create the \DbgSsApiPort object (LPC) */
446 RtlInitUnicodeString (&UnicodeString,
447 L"\\DbgSsApiPort");
448 InitializeObjectAttributes (&ObjectAttributes,
449 &UnicodeString,
450 PORT_ALL_ACCESS,
451 NULL,
452 NULL);
453
454 Status = NtCreatePort (&DbgSsApiPort,
455 &ObjectAttributes,
456 0,
457 0,
458 0);
459
460 if (!NT_SUCCESS(Status))
461 {
462 return FALSE;
463 }
464 #ifndef NDEBUG
465 DisplayString (L"SM: DbgSsApiPort created...\n");
466 #endif
467
468 /* Create the \DbgUiApiPort object (LPC) */
469 RtlInitUnicodeString (&UnicodeString,
470 L"\\DbgUiApiPort");
471 InitializeObjectAttributes (&ObjectAttributes,
472 &UnicodeString,
473 PORT_ALL_ACCESS,
474 NULL,
475 NULL);
476
477 Status = NtCreatePort (&DbgUiApiPort,
478 &ObjectAttributes,
479 0,
480 0,
481 0);
482
483 if (!NT_SUCCESS(Status))
484 {
485 return FALSE;
486 }
487 #ifndef NDEBUG
488 DisplayString (L"SM: DbgUiApiPort created...\n");
489 #endif
490
491 return TRUE;
492 }
493
494 /* EOF */