3 * reactos/subsys/csrss/init.c
5 * Initialize the CSRSS subsystem server process.
7 * ReactOS Operating System
11 /* INCLUDES ******************************************************************/
18 /* GLOBALS ******************************************************************/
20 HANDLE CsrHeap
= (HANDLE
) 0;
22 HANDLE CsrObjectDirectory
= (HANDLE
) 0;
24 UNICODE_STRING CsrDirectoryName
;
26 extern HANDLE CsrssApiHeap
;
27 extern PRTL_USER_PROCESS_PARAMETERS RtlProcessParameters
;
29 static unsigned InitCompleteProcCount
;
30 static CSRPLUGIN_INIT_COMPLETE_PROC
*InitCompleteProcs
= NULL
;
32 HANDLE hSbApiPort
= (HANDLE
) 0;
34 HANDLE hBootstrapOk
= (HANDLE
) 0;
36 HANDLE hSmApiPort
= (HANDLE
) 0;
38 HANDLE hApiPort
= (HANDLE
) 0;
40 /**********************************************************************
41 * CsrpAddInitCompleteProc/1
43 static NTSTATUS FASTCALL
44 CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc
)
46 CSRPLUGIN_INIT_COMPLETE_PROC
*NewProcs
;
48 DPRINT("CSR: %s called\n", __FUNCTION__
);
50 NewProcs
= RtlAllocateHeap(CsrssApiHeap
, 0,
51 (InitCompleteProcCount
+ 1)
52 * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC
));
55 return STATUS_NO_MEMORY
;
57 if (0 != InitCompleteProcCount
)
59 RtlCopyMemory(NewProcs
, InitCompleteProcs
,
60 InitCompleteProcCount
* sizeof(CSRPLUGIN_INIT_COMPLETE_PROC
));
61 RtlFreeHeap(CsrssApiHeap
, 0, InitCompleteProcs
);
63 NewProcs
[InitCompleteProcCount
] = Proc
;
64 InitCompleteProcs
= NewProcs
;
65 InitCompleteProcCount
++;
67 return STATUS_SUCCESS
;
70 /**********************************************************************
74 CallInitComplete(void)
79 DPRINT("CSR: %s called\n", __FUNCTION__
);
82 if (0 != InitCompleteProcCount
)
84 for (i
= 0; i
< InitCompleteProcCount
&& Ok
; i
++)
86 Ok
= (*(InitCompleteProcs
[i
]))();
88 RtlFreeHeap(CsrssApiHeap
, 0, InitCompleteProcs
);
95 InitializeVideoAddressSpace(VOID
);
97 /**********************************************************************
98 * CsrpParseCommandLine/2
101 CsrpParseCommandLine (
107 OBJECT_ATTRIBUTES Attributes
;
109 DPRINT("CSR: %s called\n", __FUNCTION__
);
112 /* DbgPrint ("Arguments: %ld\n", ArgumentCount);
113 for (i = 0; i < ArgumentCount; i++)
115 DbgPrint ("Argument %ld: %S\n", i, ArgumentArray[i]);
119 /* create object directory ('\Windows') */
120 RtlCreateUnicodeString (&CsrDirectoryName
,
123 InitializeObjectAttributes (&Attributes
,
129 Status
= NtOpenDirectoryObject(&CsrObjectDirectory
,
130 0xF000F, /* ea:??? */
135 /**********************************************************************
138 * TODO: we need a virtual device for sessions other than
139 * TODO: the console one
142 CsrpInitVideo (ULONG argc
, PWSTR
* argv
)
144 OBJECT_ATTRIBUTES ObjectAttributes
;
145 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\??\\DISPLAY1");
146 IO_STATUS_BLOCK Iosb
;
147 HANDLE VideoHandle
= (HANDLE
) 0;
148 NTSTATUS Status
= STATUS_SUCCESS
;
150 DPRINT("CSR: %s called\n", __FUNCTION__
);
152 InitializeVideoAddressSpace();
154 InitializeObjectAttributes(&ObjectAttributes
,
159 Status
= NtOpenFile(&VideoHandle
,
165 if (NT_SUCCESS(Status
))
167 NtClose(VideoHandle
);
172 /**********************************************************************
175 * TODO: this function should be turned more general to load an
176 * TODO: hosted server DLL as received from the command line;
177 * TODO: for instance: ServerDll=winsrv:ConServerDllInitialization,2
178 * TODO: ^method ^dll ^api ^sid
180 * TODO: CsrpHostServerDll (LPWSTR DllName,
181 * TODO: LPWSTR ApiName,
182 * TODO: DWORD ServerId)
185 CsrpInitWin32Csr (ULONG argc
, PWSTR
* argv
)
188 UNICODE_STRING DllName
;
190 ANSI_STRING ProcName
;
191 CSRPLUGIN_INITIALIZE_PROC InitProc
;
192 CSRSS_EXPORTED_FUNCS Exports
;
193 PCSRSS_API_DEFINITION ApiDefinitions
;
194 PCSRSS_OBJECT_DEFINITION ObjectDefinitions
;
195 CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc
;
197 DPRINT("CSR: %s called\n", __FUNCTION__
);
199 RtlInitUnicodeString(&DllName
, L
"win32csr.dll");
200 Status
= LdrLoadDll(NULL
, 0, &DllName
, (PVOID
*) &hInst
);
201 if (! NT_SUCCESS(Status
))
205 RtlInitAnsiString(&ProcName
, "Win32CsrInitialization");
206 Status
= LdrGetProcedureAddress(hInst
, &ProcName
, 0, (PVOID
*) &InitProc
);
207 if (! NT_SUCCESS(Status
))
211 Exports
.CsrInsertObjectProc
= CsrInsertObject
;
212 Exports
.CsrGetObjectProc
= CsrGetObject
;
213 Exports
.CsrReleaseObjectProc
= CsrReleaseObject
;
214 if (! (*InitProc
)(&ApiDefinitions
, &ObjectDefinitions
, &InitCompleteProc
,
215 &Exports
, CsrssApiHeap
))
217 return STATUS_UNSUCCESSFUL
;
220 Status
= CsrApiRegisterDefinitions(ApiDefinitions
);
221 if (! NT_SUCCESS(Status
))
225 Status
= CsrRegisterObjectDefinitions(ObjectDefinitions
);
226 if (! NT_SUCCESS(Status
))
230 if (NULL
!= InitCompleteProc
)
232 Status
= CsrpAddInitCompleteProc(InitCompleteProc
);
238 CSRSS_API_DEFINITION NativeDefinitions
[] =
240 CSRSS_DEFINE_API(CREATE_PROCESS
, CsrCreateProcess
),
241 CSRSS_DEFINE_API(TERMINATE_PROCESS
, CsrTerminateProcess
),
242 CSRSS_DEFINE_API(CONNECT_PROCESS
, CsrConnectProcess
),
243 CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS
, CsrRegisterServicesProcess
),
244 CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS
, CsrGetShutdownParameters
),
245 CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS
, CsrSetShutdownParameters
),
246 CSRSS_DEFINE_API(GET_INPUT_HANDLE
, CsrGetInputHandle
),
247 CSRSS_DEFINE_API(GET_OUTPUT_HANDLE
, CsrGetOutputHandle
),
248 CSRSS_DEFINE_API(CLOSE_HANDLE
, CsrCloseHandle
),
249 CSRSS_DEFINE_API(VERIFY_HANDLE
, CsrVerifyHandle
),
250 CSRSS_DEFINE_API(DUPLICATE_HANDLE
, CsrDuplicateHandle
),
251 CSRSS_DEFINE_API(GET_INPUT_WAIT_HANDLE
, CsrGetInputWaitHandle
),
255 static NTSTATUS STDCALL
256 CsrpCreateListenPort (IN LPWSTR Name
,
258 IN PTHREAD_START_ROUTINE ListenThread
)
260 NTSTATUS Status
= STATUS_SUCCESS
;
261 OBJECT_ATTRIBUTES PortAttributes
;
262 UNICODE_STRING PortName
;
264 DPRINT("CSR: %s called\n", __FUNCTION__
);
266 RtlInitUnicodeString (& PortName
, Name
);
267 InitializeObjectAttributes (& PortAttributes
,
272 Status
= NtCreatePort ( Port
,
274 260, /* TODO: make caller set it*/
275 328, /* TODO: make caller set it*/
276 0); /* TODO: make caller set it*/
277 if(!NT_SUCCESS(Status
))
279 DPRINT1("CSR: %s: NtCreatePort failed (Status=%08lx)\n",
280 __FUNCTION__
, Status
);
283 Status
= RtlCreateUserThread(NtCurrentProcess(),
289 (PTHREAD_START_ROUTINE
) ListenThread
,
296 /* === INIT ROUTINES === */
298 /**********************************************************************
302 CsrpCreateHeap (ULONG argc
, PWSTR
* argv
)
304 DPRINT("CSR: %s called\n", __FUNCTION__
);
306 CsrssApiHeap
= RtlCreateHeap(HEAP_GROWABLE
,
312 if (CsrssApiHeap
== NULL
)
314 return STATUS_UNSUCCESSFUL
;
316 return STATUS_SUCCESS
;
319 /**********************************************************************
320 * CsrpCreateCallbackPort/2
323 CsrpCreateCallbackPort (ULONG argc
, PWSTR
* argv
)
325 DPRINT("CSR: %s called\n", __FUNCTION__
);
327 return CsrpCreateListenPort (L
"\\Windows\\SbApiPort",
329 ServerSbApiPortThread
);
332 /**********************************************************************
333 * CsrpRegisterSubsystem/2
336 CsrpRegisterSubsystem (ULONG argc
, PWSTR
* argv
)
338 NTSTATUS Status
= STATUS_SUCCESS
;
339 OBJECT_ATTRIBUTES BootstrapOkAttributes
;
342 DPRINT("CSR: %s called\n", __FUNCTION__
);
345 * Create the event object the callback port
346 * thread will signal *if* the SM will
347 * authorize us to bootstrap.
349 RtlInitUnicodeString (& Name
, L
"\\CsrssBooting");
350 InitializeObjectAttributes(& BootstrapOkAttributes
,
353 Status
= NtCreateEvent (& hBootstrapOk
,
355 & BootstrapOkAttributes
,
356 SynchronizationEvent
,
358 if(!NT_SUCCESS(Status
))
360 DPRINT("CSR: %s: NtCreateEvent failed (Status=0x%08lx)\n",
361 __FUNCTION__
, Status
);
365 * Let's tell the SM a new environment
366 * subsystem server is in the system.
368 RtlInitUnicodeString (& Name
, L
"\\Windows\\SbApiPort");
369 DPRINT("CSR: %s: registering with SM for\n IMAGE_SUBSYSTEM_WINDOWS_CUI == 3\n", __FUNCTION__
);
370 Status
= SmConnectApiPort (& Name
,
372 IMAGE_SUBSYSTEM_WINDOWS_CUI
,
374 if(!NT_SUCCESS(Status
))
376 DPRINT("CSR: %s unable to connect to the SM (Status=0x%08lx)\n",
377 __FUNCTION__
, Status
);
378 NtClose (hBootstrapOk
);
382 * Wait for SM to reply OK... If the SM
383 * won't answer, we hang here forever!
385 DPRINT("CSR: %s: waiting for SM to OK boot...\n", __FUNCTION__
);
386 Status
= NtWaitForSingleObject (hBootstrapOk
,
389 NtClose (hBootstrapOk
);
393 /**********************************************************************
394 * CsrpLoadKernelModeDriver/2
397 CsrpLoadKernelModeDriver (ULONG argc
, PWSTR
* argv
)
399 NTSTATUS Status
= STATUS_SUCCESS
;
400 WCHAR Data
[MAX_PATH
+ 1];
401 ULONG DataLength
= sizeof Data
;
405 DPRINT("SM: %s called\n", __FUNCTION__
);
407 Status
= SmLookupSubsystem (L
"Kmode",
411 RtlProcessParameters
->Environment
);
412 if((STATUS_SUCCESS
== Status
) && (DataLength
> sizeof Data
[0]))
414 WCHAR ImagePath
[MAX_PATH
+ 1] = {0};
415 UNICODE_STRING ModuleName
;
417 wcscpy (ImagePath
, L
"\\??\\");
418 wcscat (ImagePath
, Data
);
419 RtlInitUnicodeString (& ModuleName
, ImagePath
);
420 Status
= NtSetSystemInformation(/* FIXME: SystemLoadAndCallImage */
421 SystemExtendServiceTableInformation
,
424 if(!NT_SUCCESS(Status
))
426 DPRINT("WIN: %s: loading Kmode failed (Status=0x%08lx)\n",
427 __FUNCTION__
, Status
);
433 /**********************************************************************
434 * CsrpCreateApiPort/2
437 CsrpCreateApiPort (ULONG argc
, PWSTR
* argv
)
439 DPRINT("CSR: %s called\n", __FUNCTION__
);
441 return CsrpCreateListenPort (L
"\\Windows\\ApiPort",
443 ServerApiPortThread
);
446 /**********************************************************************
447 * CsrpApiRegisterDef/0
450 CsrpApiRegisterDef (ULONG argc
, PWSTR
* argv
)
452 return CsrApiRegisterDefinitions(NativeDefinitions
);
455 /**********************************************************************
459 CsrpCCTS (ULONG argc
, PWSTR
* argv
)
462 ULONG DummyLength
= sizeof(Dummy
);
463 return CsrClientConnectToServer(L
"\\Windows",
464 0, &Dummy
, &DummyLength
, NULL
);
467 /**********************************************************************
470 * Start the logon process (winlogon.exe).
472 * TODO: this should be moved in CsrpCreateSession/x (one per session)
473 * TODO: in its own desktop (one logon desktop per winstation).
476 CsrpRunWinlogon (ULONG argc
, PWSTR
* argv
)
478 NTSTATUS Status
= STATUS_SUCCESS
;
479 UNICODE_STRING ImagePath
;
480 UNICODE_STRING CommandLine
;
481 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
= NULL
;
482 RTL_USER_PROCESS_INFORMATION ProcessInfo
;
485 DPRINT("CSR: %s called\n", __FUNCTION__
);
487 /* initialize the process parameters */
488 RtlInitUnicodeString (& ImagePath
, L
"\\SystemRoot\\system32\\winlogon.exe");
489 RtlInitUnicodeString (& CommandLine
, L
"");
490 RtlCreateProcessParameters(& ProcessParameters
,
500 /* Create the winlogon process */
501 Status
= RtlCreateUserProcess (& ImagePath
,
502 OBJ_CASE_INSENSITIVE
,
512 RtlDestroyProcessParameters (ProcessParameters
);
513 if (!NT_SUCCESS(Status
))
515 DPRINT1("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
516 __FUNCTION__
, Status
);
518 ZwResumeThread(ProcessInfo
.ThreadHandle
, NULL
);
524 typedef NTSTATUS (* CSR_INIT_ROUTINE
)(ULONG
, PWSTR
*);
528 CSR_INIT_ROUTINE EntryPoint
;
531 {TRUE
, CsrpCreateCallbackPort
, "create the callback port \\Windows\\SbApiPort"},
532 {TRUE
, CsrpRegisterSubsystem
, "register with SM"},
533 {TRUE
, CsrpCreateHeap
, "create the CSR heap"},
534 {TRUE
, CsrpCreateApiPort
, "create the api port \\Windows\\ApiPort"},
535 {TRUE
, CsrpParseCommandLine
, "parse the command line"},
536 {TRUE
, CsrpLoadKernelModeDriver
, "load Kmode driver"},
537 {TRUE
, CsrpInitVideo
, "initialize video"},
538 {TRUE
, CsrpApiRegisterDef
, "initialize api definitions"},
539 {TRUE
, CsrpCCTS
, "connect client to server"},
540 {TRUE
, CsrpInitWin32Csr
, "load usermode dll"},
541 {TRUE
, CsrpRunWinlogon
, "run WinLogon"},
544 /**********************************************************************
546 * CsrServerInitialization
549 * Initialize the Win32 environment subsystem server.
552 * TRUE: Initialization OK; otherwise FALSE.
555 CsrServerInitialization (
561 NTSTATUS Status
= STATUS_SUCCESS
;
563 DPRINT("CSR: %s called\n", __FUNCTION__
);
565 for (i
=0; i
< (sizeof InitRoutine
/ sizeof InitRoutine
[0]); i
++)
567 Status
= InitRoutine
[i
].EntryPoint(ArgumentCount
,ArgumentArray
);
568 if(!NT_SUCCESS(Status
))
570 DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n",
572 InitRoutine
[i
].ErrorMessage
,
574 if (InitRoutine
[i
].Required
)
580 if (CallInitComplete())
582 Status
= SmCompleteSession (hSmApiPort
,hSbApiPort
,hApiPort
);