2314ab4b8a83c5b11125ac66a73945e465b38a26
[reactos.git] / reactos / subsystems / win32 / csrss / init.c
1 /* $Id$
2 *
3 * reactos/subsys/csrss/init.c
4 *
5 * Initialize the CSRSS subsystem server process.
6 *
7 * ReactOS Operating System
8 *
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <csrss.h>
14
15 #define NDEBUG
16 #include <debug.h>
17
18 /* GLOBALS ******************************************************************/
19
20 HANDLE CsrHeap = (HANDLE) 0;
21
22 HANDLE CsrObjectDirectory = (HANDLE) 0;
23
24 UNICODE_STRING CsrDirectoryName;
25
26 extern HANDLE CsrssApiHeap;
27
28 static unsigned InitCompleteProcCount;
29 static CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProcs = NULL;
30
31 static unsigned HardErrorProcCount;
32 static CSRPLUGIN_HARDERROR_PROC *HardErrorProcs = NULL;
33
34 HANDLE hSbApiPort = (HANDLE) 0;
35
36 HANDLE hBootstrapOk = (HANDLE) 0;
37
38 HANDLE hSmApiPort = (HANDLE) 0;
39
40 HANDLE hApiPort = (HANDLE) 0;
41
42 /**********************************************************************
43 * CsrpAddInitCompleteProc/1
44 */
45 static NTSTATUS FASTCALL
46 CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc)
47 {
48 CSRPLUGIN_INIT_COMPLETE_PROC *NewProcs;
49
50 DPRINT("CSR: %s called\n", __FUNCTION__);
51
52 NewProcs = RtlAllocateHeap(CsrssApiHeap, 0,
53 (InitCompleteProcCount + 1)
54 * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC));
55 if (NULL == NewProcs)
56 {
57 return STATUS_NO_MEMORY;
58 }
59 if (0 != InitCompleteProcCount)
60 {
61 RtlCopyMemory(NewProcs, InitCompleteProcs,
62 InitCompleteProcCount * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC));
63 RtlFreeHeap(CsrssApiHeap, 0, InitCompleteProcs);
64 }
65 NewProcs[InitCompleteProcCount] = Proc;
66 InitCompleteProcs = NewProcs;
67 InitCompleteProcCount++;
68
69 return STATUS_SUCCESS;
70 }
71
72 static NTSTATUS FASTCALL
73 CsrpAddHardErrorProc(CSRPLUGIN_HARDERROR_PROC Proc)
74 {
75 CSRPLUGIN_HARDERROR_PROC *NewProcs;
76
77 DPRINT("CSR: %s called\n", __FUNCTION__);
78
79 NewProcs = RtlAllocateHeap(CsrssApiHeap, 0,
80 (HardErrorProcCount + 1)
81 * sizeof(CSRPLUGIN_HARDERROR_PROC));
82 if (NULL == NewProcs)
83 {
84 return STATUS_NO_MEMORY;
85 }
86 if (0 != HardErrorProcCount)
87 {
88 RtlCopyMemory(NewProcs, HardErrorProcs,
89 HardErrorProcCount * sizeof(CSRPLUGIN_HARDERROR_PROC));
90 RtlFreeHeap(CsrssApiHeap, 0, HardErrorProcs);
91 }
92
93 NewProcs[HardErrorProcCount] = Proc;
94 HardErrorProcs = NewProcs;
95 HardErrorProcCount++;
96
97 return STATUS_SUCCESS;
98 }
99
100 /**********************************************************************
101 * CallInitComplete/0
102 */
103 static BOOL FASTCALL
104 CallInitComplete(void)
105 {
106 BOOL Ok;
107 unsigned i;
108
109 DPRINT("CSR: %s called\n", __FUNCTION__);
110
111 Ok = TRUE;
112 if (0 != InitCompleteProcCount)
113 {
114 for (i = 0; i < InitCompleteProcCount && Ok; i++)
115 {
116 Ok = (*(InitCompleteProcs[i]))();
117 }
118 RtlFreeHeap(CsrssApiHeap, 0, InitCompleteProcs);
119 }
120
121 return Ok;
122 }
123
124 BOOL
125 CallHardError(IN PCSRSS_PROCESS_DATA ProcessData,
126 IN PHARDERROR_MSG HardErrorMessage)
127 {
128 BOOL Ok;
129 unsigned i;
130
131 DPRINT("CSR: %s called\n", __FUNCTION__);
132
133 Ok = TRUE;
134 if (0 != HardErrorProcCount)
135 {
136 for (i = 0; i < HardErrorProcCount && Ok; i++)
137 {
138 Ok = (*(HardErrorProcs[i]))(ProcessData, HardErrorMessage);
139 }
140 }
141
142 return Ok;
143 }
144
145 ULONG
146 InitializeVideoAddressSpace(VOID);
147
148 /**********************************************************************
149 * CsrpCreateObjectDirectory/3
150 */
151 static NTSTATUS
152 CsrpCreateObjectDirectory (int argc, char ** argv, char ** envp)
153 {
154 NTSTATUS Status;
155 OBJECT_ATTRIBUTES Attributes;
156
157 DPRINT("CSR: %s called\n", __FUNCTION__);
158
159
160 /* create object directory ('\Windows') */
161 RtlCreateUnicodeString (&CsrDirectoryName,
162 L"\\Windows");
163
164 InitializeObjectAttributes (&Attributes,
165 &CsrDirectoryName,
166 OBJ_OPENIF,
167 NULL,
168 NULL);
169
170 Status = NtOpenDirectoryObject(&CsrObjectDirectory,
171 DIRECTORY_ALL_ACCESS,
172 &Attributes);
173 return Status;
174 }
175
176 /**********************************************************************
177 * CsrpInitVideo/3
178 *
179 * TODO: we need a virtual device for sessions other than
180 * TODO: the console one
181 */
182 static NTSTATUS
183 CsrpInitVideo (int argc, char ** argv, char ** envp)
184 {
185 OBJECT_ATTRIBUTES ObjectAttributes;
186 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\??\\DISPLAY1");
187 IO_STATUS_BLOCK Iosb;
188 HANDLE VideoHandle = (HANDLE) 0;
189 NTSTATUS Status = STATUS_SUCCESS;
190
191 DPRINT("CSR: %s called\n", __FUNCTION__);
192
193 InitializeVideoAddressSpace();
194
195 InitializeObjectAttributes(&ObjectAttributes,
196 &DeviceName,
197 0,
198 NULL,
199 NULL);
200 Status = NtOpenFile(&VideoHandle,
201 FILE_ALL_ACCESS,
202 &ObjectAttributes,
203 &Iosb,
204 0,
205 0);
206 if (NT_SUCCESS(Status))
207 {
208 NtClose(VideoHandle);
209 }
210 return Status;
211 }
212
213 /**********************************************************************
214 * CsrpInitWin32Csr/3
215 *
216 * TODO: this function should be turned more general to load an
217 * TODO: hosted server DLL as received from the command line;
218 * TODO: for instance: ServerDll=winsrv:ConServerDllInitialization,2
219 * TODO: ^method ^dll ^api ^sid
220 * TODO:
221 * TODO: CsrpHostServerDll (LPWSTR DllName,
222 * TODO: LPWSTR ApiName,
223 * TODO: DWORD ServerId)
224 */
225 static NTSTATUS
226 CsrpInitWin32Csr (int argc, char ** argv, char ** envp)
227 {
228 NTSTATUS Status;
229 UNICODE_STRING DllName;
230 HINSTANCE hInst;
231 ANSI_STRING ProcName;
232 CSRPLUGIN_INITIALIZE_PROC InitProc;
233 CSRSS_EXPORTED_FUNCS Exports;
234 PCSRSS_API_DEFINITION ApiDefinitions;
235 PCSRSS_OBJECT_DEFINITION ObjectDefinitions;
236 CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc;
237 CSRPLUGIN_HARDERROR_PROC HardErrorProc;
238
239 DPRINT("CSR: %s called\n", __FUNCTION__);
240
241 RtlInitUnicodeString(&DllName, L"win32csr.dll");
242 Status = LdrLoadDll(NULL, 0, &DllName, (PVOID *) &hInst);
243 if (! NT_SUCCESS(Status))
244 {
245 return Status;
246 }
247 RtlInitAnsiString(&ProcName, "Win32CsrInitialization");
248 Status = LdrGetProcedureAddress(hInst, &ProcName, 0, (PVOID *) &InitProc);
249 if (! NT_SUCCESS(Status))
250 {
251 return Status;
252 }
253 Exports.CsrInsertObjectProc = CsrInsertObject;
254 Exports.CsrGetObjectProc = CsrGetObject;
255 Exports.CsrReleaseObjectByPointerProc = CsrReleaseObjectByPointer;
256 Exports.CsrReleaseObjectProc = CsrReleaseObject;
257 Exports.CsrEnumProcessesProc = CsrEnumProcesses;
258 if (! (*InitProc)(&ApiDefinitions, &ObjectDefinitions, &InitCompleteProc,
259 &HardErrorProc, &Exports, CsrssApiHeap))
260 {
261 return STATUS_UNSUCCESSFUL;
262 }
263
264 Status = CsrApiRegisterDefinitions(ApiDefinitions);
265 if (! NT_SUCCESS(Status))
266 {
267 return Status;
268 }
269 Status = CsrRegisterObjectDefinitions(ObjectDefinitions);
270 if (! NT_SUCCESS(Status))
271 {
272 return Status;
273 }
274 if (NULL != InitCompleteProc)
275 {
276 Status = CsrpAddInitCompleteProc(InitCompleteProc);
277 }
278 if (HardErrorProc) Status = CsrpAddHardErrorProc(HardErrorProc);
279
280 return Status;
281 }
282
283 CSRSS_API_DEFINITION NativeDefinitions[] =
284 {
285 CSRSS_DEFINE_API(CREATE_PROCESS, CsrCreateProcess),
286 CSRSS_DEFINE_API(CREATE_THREAD, CsrCreateThread),
287 CSRSS_DEFINE_API(TERMINATE_PROCESS, CsrTerminateProcess),
288 CSRSS_DEFINE_API(CONNECT_PROCESS, CsrConnectProcess),
289 CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS, CsrRegisterServicesProcess),
290 CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS, CsrGetShutdownParameters),
291 CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS, CsrSetShutdownParameters),
292 CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetInputHandle),
293 CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetOutputHandle),
294 CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle),
295 CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle),
296 CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle),
297 CSRSS_DEFINE_API(GET_INPUT_WAIT_HANDLE, CsrGetInputWaitHandle),
298 { 0, 0, NULL }
299 };
300
301 static NTSTATUS WINAPI
302 CsrpCreateListenPort (IN LPWSTR Name,
303 IN OUT PHANDLE Port,
304 IN PTHREAD_START_ROUTINE ListenThread)
305 {
306 NTSTATUS Status = STATUS_SUCCESS;
307 OBJECT_ATTRIBUTES PortAttributes;
308 UNICODE_STRING PortName;
309 HANDLE ServerThread;
310 CLIENT_ID ClientId;
311
312 DPRINT("CSR: %s called\n", __FUNCTION__);
313
314 RtlInitUnicodeString (& PortName, Name);
315 InitializeObjectAttributes (& PortAttributes,
316 & PortName,
317 0,
318 NULL,
319 NULL);
320 Status = NtCreatePort ( Port,
321 & PortAttributes,
322 LPC_MAX_DATA_LENGTH, /* TODO: make caller set it*/
323 LPC_MAX_MESSAGE_LENGTH, /* TODO: make caller set it*/
324 0); /* TODO: make caller set it*/
325 if(!NT_SUCCESS(Status))
326 {
327 DPRINT1("CSR: %s: NtCreatePort failed (Status=%08lx)\n",
328 __FUNCTION__, Status);
329 return Status;
330 }
331 Status = RtlCreateUserThread(NtCurrentProcess(),
332 NULL,
333 TRUE,
334 0,
335 0,
336 0,
337 (PTHREAD_START_ROUTINE) ListenThread,
338 *Port,
339 &ServerThread,
340 &ClientId);
341
342 if (ListenThread == (PVOID)ClientConnectionThread)
343 {
344 CsrAddStaticServerThread(ServerThread, &ClientId, 0);
345 }
346
347 NtResumeThread(ServerThread, NULL);
348 NtClose(ServerThread);
349 return Status;
350 }
351
352 /* === INIT ROUTINES === */
353
354 /**********************************************************************
355 * CsrpCreateBNODirectory/3
356 *
357 * These used to be part of kernel32 startup, but that clearly wasn't a good
358 * idea, as races were definately possible. These are moved (as in the
359 * previous fixmes).
360 */
361 static NTSTATUS
362 CsrpCreateBNODirectory (int argc, char ** argv, char ** envp)
363 {
364 NTSTATUS Status;
365 OBJECT_ATTRIBUTES ObjectAttributes;
366 UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\BaseNamedObjects");
367 UNICODE_STRING SymName = RTL_CONSTANT_STRING(L"Local");
368 UNICODE_STRING SymName2 = RTL_CONSTANT_STRING(L"Global");
369 HANDLE DirHandle, SymHandle;
370
371 /* Seems like a good place to create these objects which are needed by
372 * win32 processes */
373 InitializeObjectAttributes(&ObjectAttributes,
374 &Name,
375 OBJ_CASE_INSENSITIVE,
376 NULL,
377 NULL);
378
379 Status = NtCreateDirectoryObject(&DirHandle,
380 DIRECTORY_ALL_ACCESS,
381 &ObjectAttributes);
382 if (!NT_SUCCESS(Status))
383 {
384 DPRINT1("NtCreateDirectoryObject() failed %08x\n", Status);
385 }
386
387 /* Create the "local" Symbolic Link.
388 * FIXME: CSR should do this -- Fixed */
389 InitializeObjectAttributes(&ObjectAttributes,
390 &SymName,
391 OBJ_CASE_INSENSITIVE,
392 DirHandle,
393 NULL);
394 Status = NtCreateSymbolicLinkObject(&SymHandle,
395 SYMBOLIC_LINK_ALL_ACCESS,
396 &ObjectAttributes,
397 &Name);
398 if (!NT_SUCCESS(Status))
399 {
400 DPRINT1("NtCreateDirectoryObject() failed %08x\n", Status);
401 }
402
403 /* Create the "global" Symbolic Link. */
404 InitializeObjectAttributes(&ObjectAttributes,
405 &SymName2,
406 OBJ_CASE_INSENSITIVE,
407 DirHandle,
408 NULL);
409 Status = NtCreateSymbolicLinkObject(&SymHandle,
410 SYMBOLIC_LINK_ALL_ACCESS,
411 &ObjectAttributes,
412 &Name);
413 if (!NT_SUCCESS(Status))
414 {
415 DPRINT1("NtCreateDirectoryObject() failed %08x\n", Status);
416 }
417
418 return Status;
419 }
420
421 /**********************************************************************
422 * CsrpCreateHeap/3
423 */
424 static NTSTATUS
425 CsrpCreateHeap (int argc, char ** argv, char ** envp)
426 {
427 DPRINT("CSR: %s called\n", __FUNCTION__);
428
429 CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE,
430 NULL,
431 65536,
432 65536,
433 NULL,
434 NULL);
435 if (CsrssApiHeap == NULL)
436 {
437 return STATUS_UNSUCCESSFUL;
438 }
439 return STATUS_SUCCESS;
440 }
441
442 /**********************************************************************
443 * CsrpCreateCallbackPort/3
444 */
445 static NTSTATUS
446 CsrpCreateCallbackPort (int argc, char ** argv, char ** envp)
447 {
448 DPRINT("CSR: %s called\n", __FUNCTION__);
449
450 return CsrpCreateListenPort (L"\\Windows\\SbApiPort",
451 & hSbApiPort,
452 ServerSbApiPortThread);
453 }
454
455 /**********************************************************************
456 * CsrpRegisterSubsystem/3
457 */
458 static NTSTATUS
459 CsrpRegisterSubsystem (int argc, char ** argv, char ** envp)
460 {
461 NTSTATUS Status = STATUS_SUCCESS;
462 OBJECT_ATTRIBUTES BootstrapOkAttributes;
463 UNICODE_STRING Name;
464
465 DPRINT("CSR: %s called\n", __FUNCTION__);
466
467 /*
468 * Create the event object the callback port
469 * thread will signal *if* the SM will
470 * authorize us to bootstrap.
471 */
472 RtlInitUnicodeString (& Name, L"\\CsrssBooting");
473 InitializeObjectAttributes(& BootstrapOkAttributes,
474 & Name,
475 0, NULL, NULL);
476 Status = NtCreateEvent (& hBootstrapOk,
477 EVENT_ALL_ACCESS,
478 & BootstrapOkAttributes,
479 SynchronizationEvent,
480 FALSE);
481 if(!NT_SUCCESS(Status))
482 {
483 DPRINT("CSR: %s: NtCreateEvent failed (Status=0x%08lx)\n",
484 __FUNCTION__, Status);
485 return Status;
486 }
487 /*
488 * Let's tell the SM a new environment
489 * subsystem server is in the system.
490 */
491 RtlInitUnicodeString (& Name, L"\\Windows\\SbApiPort");
492 DPRINT("CSR: %s: registering with SM for\n IMAGE_SUBSYSTEM_WINDOWS_CUI == 3\n", __FUNCTION__);
493 Status = SmConnectApiPort (& Name,
494 hSbApiPort,
495 IMAGE_SUBSYSTEM_WINDOWS_CUI,
496 & hSmApiPort);
497 if(!NT_SUCCESS(Status))
498 {
499 DPRINT("CSR: %s unable to connect to the SM (Status=0x%08lx)\n",
500 __FUNCTION__, Status);
501 NtClose (hBootstrapOk);
502 return Status;
503 }
504 /*
505 * Wait for SM to reply OK... If the SM
506 * won't answer, we hang here forever!
507 */
508 DPRINT("CSR: %s: waiting for SM to OK boot...\n", __FUNCTION__);
509 Status = NtWaitForSingleObject (hBootstrapOk,
510 FALSE,
511 NULL);
512 NtClose (hBootstrapOk);
513 return Status;
514 }
515
516 /**********************************************************************
517 * EnvpToUnicodeString/2
518 */
519 static ULONG FASTCALL
520 EnvpToUnicodeString (char ** envp, PUNICODE_STRING UnicodeEnv)
521 {
522 ULONG CharCount = 0;
523 ULONG Index = 0;
524 ANSI_STRING AnsiEnv;
525
526 UnicodeEnv->Buffer = NULL;
527
528 for (Index=0; NULL != envp[Index]; Index++)
529 {
530 CharCount += strlen (envp[Index]);
531 ++ CharCount;
532 }
533 ++ CharCount;
534
535 AnsiEnv.Buffer = RtlAllocateHeap (RtlGetProcessHeap(), 0, CharCount);
536 if (NULL != AnsiEnv.Buffer)
537 {
538
539 PCHAR WritePos = AnsiEnv.Buffer;
540
541 for (Index=0; NULL != envp[Index]; Index++)
542 {
543 strcpy (WritePos, envp[Index]);
544 WritePos += strlen (envp[Index]) + 1;
545 }
546
547 /* FIXME: the last (double) nullterm should perhaps not be included in Length
548 * but only in MaximumLength. -Gunnar */
549 AnsiEnv.Buffer [CharCount-1] = '\0';
550 AnsiEnv.Length = CharCount;
551 AnsiEnv.MaximumLength = CharCount;
552
553 RtlAnsiStringToUnicodeString (UnicodeEnv, & AnsiEnv, TRUE);
554 RtlFreeHeap (RtlGetProcessHeap(), 0, AnsiEnv.Buffer);
555 }
556 return CharCount;
557 }
558 /**********************************************************************
559 * CsrpLoadKernelModeDriver/3
560 */
561 static NTSTATUS
562 CsrpLoadKernelModeDriver (int argc, char ** argv, char ** envp)
563 {
564 NTSTATUS Status = STATUS_SUCCESS;
565 WCHAR Data [MAX_PATH + 1];
566 ULONG DataLength = sizeof Data;
567 ULONG DataType = 0;
568 UNICODE_STRING Environment;
569
570
571 DPRINT("SM: %s called\n", __FUNCTION__);
572
573
574 EnvpToUnicodeString (envp, & Environment);
575 Status = SmLookupSubsystem (L"Kmode",
576 Data,
577 & DataLength,
578 & DataType,
579 Environment.Buffer);
580 RtlFreeUnicodeString (& Environment);
581 if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
582 {
583 WCHAR ImagePath [MAX_PATH + 1] = {0};
584 UNICODE_STRING ModuleName;
585
586 wcscpy (ImagePath, L"\\??\\");
587 wcscat (ImagePath, Data);
588 RtlInitUnicodeString (& ModuleName, ImagePath);
589 Status = NtSetSystemInformation(/* FIXME: SystemLoadAndCallImage */
590 SystemExtendServiceTableInformation,
591 & ModuleName,
592 sizeof ModuleName);
593 if(!NT_SUCCESS(Status))
594 {
595 DPRINT("WIN: %s: loading Kmode failed (Status=0x%08lx)\n",
596 __FUNCTION__, Status);
597 }
598 }
599 return Status;
600 }
601
602 /**********************************************************************
603 * CsrpCreateApiPort/2
604 */
605 static NTSTATUS
606 CsrpCreateApiPort (int argc, char ** argv, char ** envp)
607 {
608 DPRINT("CSR: %s called\n", __FUNCTION__);
609
610 CsrInitProcessData();
611
612 return CsrpCreateListenPort(L"\\Windows\\ApiPort", &hApiPort,
613 (PTHREAD_START_ROUTINE)ClientConnectionThread);
614 }
615
616 /**********************************************************************
617 * CsrpApiRegisterDef/0
618 */
619 static NTSTATUS
620 CsrpApiRegisterDef (int argc, char ** argv, char ** envp)
621 {
622 return CsrApiRegisterDefinitions(NativeDefinitions);
623 }
624
625 /**********************************************************************
626 * CsrpCCTS/2
627 */
628 static NTSTATUS
629 CsrpCCTS (int argc, char ** argv, char ** envp)
630 {
631 ULONG Dummy;
632 ULONG DummyLength = sizeof(Dummy);
633 return CsrClientConnectToServer(L"\\Windows",
634 0, &Dummy, &DummyLength, NULL);
635 }
636
637 /**********************************************************************
638 * CsrpRunWinlogon/0
639 *
640 * Start the logon process (winlogon.exe).
641 *
642 * TODO: this should be moved in CsrpCreateSession/x (one per session)
643 * TODO: in its own desktop (one logon desktop per winstation).
644 */
645 static NTSTATUS
646 CsrpRunWinlogon (int argc, char ** argv, char ** envp)
647 {
648 NTSTATUS Status = STATUS_SUCCESS;
649 UNICODE_STRING ImagePath;
650 UNICODE_STRING CommandLine;
651 PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
652 RTL_USER_PROCESS_INFORMATION ProcessInfo;
653
654
655 DPRINT("CSR: %s called\n", __FUNCTION__);
656
657 /* initialize the process parameters */
658 RtlInitUnicodeString (& ImagePath, L"\\SystemRoot\\system32\\winlogon.exe");
659 RtlInitUnicodeString (& CommandLine, L"");
660 RtlCreateProcessParameters(& ProcessParameters,
661 & ImagePath,
662 NULL,
663 NULL,
664 & CommandLine,
665 NULL,
666 NULL,
667 NULL,
668 NULL,
669 NULL);
670 /* Create the winlogon process */
671 Status = RtlCreateUserProcess (& ImagePath,
672 OBJ_CASE_INSENSITIVE,
673 ProcessParameters,
674 NULL,
675 NULL,
676 NULL,
677 FALSE,
678 NULL,
679 NULL,
680 & ProcessInfo);
681 /* Cleanup */
682 RtlDestroyProcessParameters (ProcessParameters);
683 if (!NT_SUCCESS(Status))
684 {
685 DPRINT1("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
686 __FUNCTION__, Status);
687 }
688
689 ZwResumeThread(ProcessInfo.ThreadHandle, NULL);
690 return Status;
691 }
692
693 static NTSTATUS
694 CsrpCreateHardErrorPort (int argc, char ** argv, char ** envp)
695 {
696 return NtSetDefaultHardErrorPort(hApiPort);
697 }
698
699 typedef NTSTATUS (* CSR_INIT_ROUTINE)(int,char**,char**);
700
701 struct {
702 BOOL Required;
703 CSR_INIT_ROUTINE EntryPoint;
704 PCHAR ErrorMessage;
705 } InitRoutine [] = {
706 {TRUE, CsrpCreateBNODirectory, "create base named objects directory"},
707 {TRUE, CsrpCreateCallbackPort, "create the callback port \\Windows\\SbApiPort"},
708 {TRUE, CsrpRegisterSubsystem, "register with SM"},
709 {TRUE, CsrpCreateHeap, "create the CSR heap"},
710 {TRUE, CsrpCreateApiPort, "create the api port \\Windows\\ApiPort"},
711 {TRUE, CsrpCreateHardErrorPort, "create the hard error port"},
712 {TRUE, CsrpCreateObjectDirectory,"create the object directory \\Windows"},
713 {TRUE, CsrpLoadKernelModeDriver, "load Kmode driver"},
714 {TRUE, CsrpInitVideo, "initialize video"},
715 {TRUE, CsrpApiRegisterDef, "initialize api definitions"},
716 {TRUE, CsrpCCTS, "connect client to server"},
717 {TRUE, CsrpInitWin32Csr, "load usermode dll"},
718 {TRUE, CsrpRunWinlogon, "run WinLogon"},
719 };
720
721 /**********************************************************************
722 * NAME
723 * CsrServerInitialization
724 *
725 * DESCRIPTION
726 * Initialize the Win32 environment subsystem server.
727 *
728 * RETURN VALUE
729 * TRUE: Initialization OK; otherwise FALSE.
730 */
731 BOOL WINAPI
732 CsrServerInitialization (
733 int argc,
734 char ** argv,
735 char ** envp
736 )
737 {
738 UINT i = 0;
739 NTSTATUS Status = STATUS_SUCCESS;
740
741 DPRINT("CSR: %s called\n", __FUNCTION__);
742
743 for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++)
744 {
745 Status = InitRoutine[i].EntryPoint(argc,argv,envp);
746 if(!NT_SUCCESS(Status))
747 {
748 DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n",
749 __FUNCTION__,
750 InitRoutine[i].ErrorMessage,
751 Status);
752 if (InitRoutine[i].Required)
753 {
754 return FALSE;
755 }
756 }
757 }
758 if (CallInitComplete())
759 {
760 Status = SmCompleteSession (hSmApiPort,hSbApiPort,hApiPort);
761 return TRUE;
762 }
763 return FALSE;
764 }
765
766 /* EOF */