3 * reactos/subsys/csrss/init.c
5 * Initialize the CSRSS subsystem server process.
7 * ReactOS Operating System
11 /* INCLUDES ******************************************************************/
13 #include <csrss/csrss.h>
14 #include <ddk/ntddk.h>
15 #include <ntdll/csr.h>
16 #include <ntdll/rtl.h>
17 #include <ntdll/ldr.h>
18 #include <win32k/win32k.h>
19 #include <rosrtl/string.h>
20 #include <sm/helper.h>
23 #include "csrplugin.h"
28 /* GLOBALS ******************************************************************/
30 HANDLE CsrHeap
= (HANDLE
) 0;
32 HANDLE CsrObjectDirectory
= (HANDLE
) 0;
34 UNICODE_STRING CsrDirectoryName
;
36 extern HANDLE CsrssApiHeap
;
38 static unsigned InitCompleteProcCount
;
39 static CSRPLUGIN_INIT_COMPLETE_PROC
*InitCompleteProcs
= NULL
;
41 HANDLE hSbApiPort
= (HANDLE
) 0;
43 HANDLE hBootstrapOk
= (HANDLE
) 0;
45 HANDLE hSmApiPort
= (HANDLE
) 0;
47 HANDLE hApiPort
= (HANDLE
) 0;
49 /**********************************************************************
50 * CsrpAddInitCompleteProc/1
52 static NTSTATUS FASTCALL
53 CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc
)
55 CSRPLUGIN_INIT_COMPLETE_PROC
*NewProcs
;
57 DPRINT("CSR: %s called\n", __FUNCTION__
);
59 NewProcs
= RtlAllocateHeap(CsrssApiHeap
, 0,
60 (InitCompleteProcCount
+ 1)
61 * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC
));
64 return STATUS_NO_MEMORY
;
66 if (0 != InitCompleteProcCount
)
68 RtlCopyMemory(NewProcs
, InitCompleteProcs
,
69 InitCompleteProcCount
* sizeof(CSRPLUGIN_INIT_COMPLETE_PROC
));
70 RtlFreeHeap(CsrssApiHeap
, 0, InitCompleteProcs
);
72 NewProcs
[InitCompleteProcCount
] = Proc
;
73 InitCompleteProcs
= NewProcs
;
74 InitCompleteProcCount
++;
76 return STATUS_SUCCESS
;
79 /**********************************************************************
83 CallInitComplete(void)
88 DPRINT("CSR: %s called\n", __FUNCTION__
);
91 if (0 != InitCompleteProcCount
)
93 for (i
= 0; i
< InitCompleteProcCount
&& Ok
; i
++)
95 Ok
= (*(InitCompleteProcs
[i
]))();
97 RtlFreeHeap(CsrssApiHeap
, 0, InitCompleteProcs
);
104 InitializeVideoAddressSpace(VOID
);
106 /**********************************************************************
107 * CsrpParseCommandLine/2
110 CsrpParseCommandLine (
116 OBJECT_ATTRIBUTES Attributes
;
118 DPRINT("CSR: %s called\n", __FUNCTION__
);
121 /* DbgPrint ("Arguments: %ld\n", ArgumentCount);
122 for (i = 0; i < ArgumentCount; i++)
124 DbgPrint ("Argument %ld: %S\n", i, ArgumentArray[i]);
128 /* create object directory ('\Windows') */
129 RtlCreateUnicodeString (&CsrDirectoryName
,
132 InitializeObjectAttributes (&Attributes
,
138 Status
= NtCreateDirectoryObject(&CsrObjectDirectory
,
139 0xF000F, /* ea:??? */
145 /**********************************************************************
148 * TODO: we need a virtual device for sessions other than
149 * TODO: the console one
152 CsrpInitVideo (ULONG argc
, PWSTR
* argv
)
154 OBJECT_ATTRIBUTES ObjectAttributes
;
155 UNICODE_STRING DeviceName
;
156 IO_STATUS_BLOCK Iosb
;
157 HANDLE VideoHandle
= (HANDLE
) 0;
158 NTSTATUS Status
= STATUS_SUCCESS
;
160 DPRINT("CSR: %s called\n", __FUNCTION__
);
162 InitializeVideoAddressSpace();
164 RtlRosInitUnicodeStringFromLiteral(&DeviceName
, L
"\\??\\DISPLAY1");
165 InitializeObjectAttributes(&ObjectAttributes
,
170 Status
= NtOpenFile(&VideoHandle
,
176 if (NT_SUCCESS(Status
))
178 NtClose(VideoHandle
);
183 /**********************************************************************
186 * TODO: this function should be turned more general to load an
187 * TODO: hosted server DLL as received from the command line;
188 * TODO: for instance: ServerDll=winsrv:ConServerDllInitialization,2
189 * TODO: ^method ^dll ^api ^sid
191 * TODO: CsrpHostServerDll (LPWSTR DllName,
192 * TODO: LPWSTR ApiName,
193 * TODO: DWORD ServerId)
196 CsrpInitWin32Csr (ULONG argc
, PWSTR
* argv
)
199 UNICODE_STRING DllName
;
201 ANSI_STRING ProcName
;
202 CSRPLUGIN_INITIALIZE_PROC InitProc
;
203 CSRSS_EXPORTED_FUNCS Exports
;
204 PCSRSS_API_DEFINITION ApiDefinitions
;
205 PCSRSS_OBJECT_DEFINITION ObjectDefinitions
;
206 CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc
;
208 DPRINT("CSR: %s called\n", __FUNCTION__
);
210 RtlInitUnicodeString(&DllName
, L
"win32csr.dll");
211 Status
= LdrLoadDll(NULL
, 0, &DllName
, (PVOID
*) &hInst
);
212 if (! NT_SUCCESS(Status
))
216 RtlInitAnsiString(&ProcName
, "Win32CsrInitialization");
217 Status
= LdrGetProcedureAddress(hInst
, &ProcName
, 0, (PVOID
*) &InitProc
);
218 if (! NT_SUCCESS(Status
))
222 Exports
.CsrInsertObjectProc
= CsrInsertObject
;
223 Exports
.CsrGetObjectProc
= CsrGetObject
;
224 Exports
.CsrReleaseObjectProc
= CsrReleaseObject
;
225 if (! (*InitProc
)(&ApiDefinitions
, &ObjectDefinitions
, &InitCompleteProc
,
226 &Exports
, CsrssApiHeap
))
228 return STATUS_UNSUCCESSFUL
;
231 Status
= CsrApiRegisterDefinitions(ApiDefinitions
);
232 if (! NT_SUCCESS(Status
))
236 Status
= CsrRegisterObjectDefinitions(ObjectDefinitions
);
237 if (! NT_SUCCESS(Status
))
241 if (NULL
!= InitCompleteProc
)
243 Status
= CsrpAddInitCompleteProc(InitCompleteProc
);
249 CSRSS_API_DEFINITION NativeDefinitions
[] =
251 CSRSS_DEFINE_API(CSRSS_CREATE_PROCESS
, CsrCreateProcess
),
252 CSRSS_DEFINE_API(CSRSS_TERMINATE_PROCESS
, CsrTerminateProcess
),
253 CSRSS_DEFINE_API(CSRSS_CONNECT_PROCESS
, CsrConnectProcess
),
254 CSRSS_DEFINE_API(CSRSS_REGISTER_SERVICES_PROCESS
, CsrRegisterServicesProcess
),
255 CSRSS_DEFINE_API(CSRSS_GET_SHUTDOWN_PARAMETERS
, CsrGetShutdownParameters
),
256 CSRSS_DEFINE_API(CSRSS_SET_SHUTDOWN_PARAMETERS
, CsrSetShutdownParameters
),
257 CSRSS_DEFINE_API(CSRSS_GET_INPUT_HANDLE
, CsrGetInputHandle
),
258 CSRSS_DEFINE_API(CSRSS_GET_OUTPUT_HANDLE
, CsrGetOutputHandle
),
259 CSRSS_DEFINE_API(CSRSS_CLOSE_HANDLE
, CsrCloseHandle
),
260 CSRSS_DEFINE_API(CSRSS_VERIFY_HANDLE
, CsrVerifyHandle
),
261 CSRSS_DEFINE_API(CSRSS_DUPLICATE_HANDLE
, CsrDuplicateHandle
),
262 CSRSS_DEFINE_API(CSRSS_GET_INPUT_WAIT_HANDLE
, CsrGetInputWaitHandle
),
266 static NTSTATUS STDCALL
267 CsrpCreateListenPort (IN LPWSTR Name
,
269 IN PTHREAD_START_ROUTINE ListenThread
)
271 NTSTATUS Status
= STATUS_SUCCESS
;
272 OBJECT_ATTRIBUTES PortAttributes
;
273 UNICODE_STRING PortName
;
275 DPRINT("CSR: %s called\n", __FUNCTION__
);
277 RtlInitUnicodeString (& PortName
, Name
);
278 InitializeObjectAttributes (& PortAttributes
,
283 Status
= NtCreatePort ( Port
,
285 260, /* TODO: make caller set it*/
286 328, /* TODO: make caller set it*/
287 0); /* TODO: make caller set it*/
288 if(!NT_SUCCESS(Status
))
290 DPRINT1("CSR: %s: NtCreatePort failed (Status=%08lx)\n",
291 __FUNCTION__
, Status
);
294 Status
= RtlCreateUserThread(NtCurrentProcess(),
300 (PTHREAD_START_ROUTINE
) ListenThread
,
307 /* === INIT ROUTINES === */
309 /**********************************************************************
310 * CsrpCreateCallbackPort/0
313 CsrpCreateHeap (ULONG argc
, PWSTR
* argv
)
315 DPRINT("CSR: %s called\n", __FUNCTION__
);
317 CsrssApiHeap
= RtlCreateHeap(HEAP_GROWABLE
,
323 if (CsrssApiHeap
== NULL
)
325 return STATUS_UNSUCCESSFUL
;
327 return STATUS_SUCCESS
;
330 /**********************************************************************
331 * CsrpCreateCallbackPort/0
334 CsrpCreateCallbackPort (ULONG argc
, PWSTR
* argv
)
336 DPRINT("CSR: %s called\n", __FUNCTION__
);
338 return CsrpCreateListenPort (L
"\\Windows\\SbApiPort",
340 ServerSbApiPortThread
);
343 /**********************************************************************
344 * CsrpRegisterSubsystem/2
347 CsrpRegisterSubsystem (ULONG argc
, PWSTR
* argv
)
349 NTSTATUS Status
= STATUS_SUCCESS
;
350 OBJECT_ATTRIBUTES BootstrapOkAttributes
;
353 DPRINT("CSR: %s called\n", __FUNCTION__
);
356 * Create the event object the callback port
357 * thread will signal *if* the SM will
358 * authorize us to bootstrap.
360 RtlInitUnicodeString (& Name
, L
"\\CsrssBooting");
361 InitializeObjectAttributes(& BootstrapOkAttributes
,
364 Status
= NtCreateEvent (& hBootstrapOk
,
366 & BootstrapOkAttributes
,
367 SynchronizationEvent
,
369 if(!NT_SUCCESS(Status
))
371 DPRINT("CSR: %s: NtCreateEvent failed (Status=0x%08lx)\n",
372 __FUNCTION__
, Status
);
376 * Let's tell the SM a new environment
377 * subsystem server is in the system.
379 RtlInitUnicodeString (& Name
, L
"\\Windows\\SbApiPort");
380 DPRINT("CSR: %s: registering with SM for\n IMAGE_SUBSYSTEM_WINDOWS_CUI == 3\n", __FUNCTION__
);
381 Status
= SmConnectApiPort (& Name
,
383 IMAGE_SUBSYSTEM_WINDOWS_CUI
,
385 if(!NT_SUCCESS(Status
))
387 DPRINT("CSR: %s unable to connect to the SM (Status=0x%08lx)\n",
388 __FUNCTION__
, Status
);
389 NtClose (hBootstrapOk
);
393 * Wait for SM to reply OK... If the SM
394 * won't answer, we hang here forever!
396 DPRINT("CSR: %s: waiting for SM to OK boot...\n", __FUNCTION__
);
397 Status
= NtWaitForSingleObject (hBootstrapOk
,
400 NtClose (hBootstrapOk
);
404 /**********************************************************************
405 * CsrpCreateApiPort/0
408 CsrpCreateApiPort (ULONG argc
, PWSTR
* argv
)
410 DPRINT("CSR: %s called\n", __FUNCTION__
);
412 return CsrpCreateListenPort (L
"\\Windows\\ApiPort",
414 ServerApiPortThread
);
417 /**********************************************************************
418 * CsrpApiRegisterDef/0
421 CsrpApiRegisterDef (ULONG argc
, PWSTR
* argv
)
423 return CsrApiRegisterDefinitions(NativeDefinitions
);
426 /**********************************************************************
430 CsrpCCTS (ULONG argc
, PWSTR
* argv
)
432 return CsrClientConnectToServer();
435 /**********************************************************************
438 * Start the logon process (winlogon.exe).
440 * TODO: this should be moved in CsrpCreateSession/x (one per session)
441 * TODO: in its own desktop (one logon desktop per winstation).
444 CsrpRunWinlogon (ULONG argc
, PWSTR
* argv
)
446 NTSTATUS Status
= STATUS_SUCCESS
;
447 UNICODE_STRING ImagePath
;
448 UNICODE_STRING CommandLine
;
449 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
= NULL
;
450 RTL_PROCESS_INFO ProcessInfo
;
453 DPRINT("CSR: %s called\n", __FUNCTION__
);
455 /* initialize the process parameters */
456 RtlInitUnicodeString (& ImagePath
, L
"\\SystemRoot\\system32\\winlogon.exe");
457 RtlInitUnicodeString (& CommandLine
, L
"");
458 RtlCreateProcessParameters(& ProcessParameters
,
468 /* Create the winlogon process */
469 Status
= RtlCreateUserProcess (& ImagePath
,
470 OBJ_CASE_INSENSITIVE
,
480 RtlDestroyProcessParameters (ProcessParameters
);
481 if (!NT_SUCCESS(Status
))
483 DPRINT("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
484 __FUNCTION__
, Status
);
491 typedef NTSTATUS (* CSR_INIT_ROUTINE
)(ULONG
, PWSTR
*);
495 CSR_INIT_ROUTINE EntryPoint
;
498 {TRUE
, CsrpCreateCallbackPort
, "create the callback port \\Windows\\SbApiPort"},
499 {TRUE
, CsrpRegisterSubsystem
, "register with SM"},
500 {TRUE
, CsrpCreateHeap
, "create the CSR heap"},
501 {TRUE
, CsrpCreateApiPort
, "create the api port \\Windows\\ApiPort"},
502 {TRUE
, CsrpParseCommandLine
, "parse the command line"},
503 {TRUE
, CsrpInitVideo
, "initialize video"},
504 {TRUE
, CsrpApiRegisterDef
, "initialize api definitions"},
505 {TRUE
, CsrpCCTS
, "connect client to server"},
506 {TRUE
, CsrpInitWin32Csr
, "load usermode dll"},
507 {TRUE
, CsrpRunWinlogon
, "run WinLogon"},
510 /**********************************************************************
512 * CsrServerInitialization
515 * Initialize the Win32 environment subsystem server.
518 * TRUE: Initialization OK; otherwise FALSE.
521 CsrServerInitialization (
527 NTSTATUS Status
= STATUS_SUCCESS
;
529 DPRINT("CSR: %s called\n", __FUNCTION__
);
531 for (i
=0; i
< (sizeof InitRoutine
/ sizeof InitRoutine
[0]); i
++)
533 Status
= InitRoutine
[i
].EntryPoint(ArgumentCount
,ArgumentArray
);
534 if(!NT_SUCCESS(Status
))
536 DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n",
538 InitRoutine
[i
].ErrorMessage
,
540 if (InitRoutine
[i
].Required
)
546 if (CallInitComplete())
548 Status
= SmCompleteSession (hSmApiPort
,hSbApiPort
,hApiPort
);