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
= NtOpenDirectoryObject(&CsrObjectDirectory
,
139 0xF000F, /* ea:??? */
144 /**********************************************************************
147 * TODO: we need a virtual device for sessions other than
148 * TODO: the console one
151 CsrpInitVideo (ULONG argc
, PWSTR
* argv
)
153 OBJECT_ATTRIBUTES ObjectAttributes
;
154 UNICODE_STRING DeviceName
;
155 IO_STATUS_BLOCK Iosb
;
156 HANDLE VideoHandle
= (HANDLE
) 0;
157 NTSTATUS Status
= STATUS_SUCCESS
;
159 DPRINT("CSR: %s called\n", __FUNCTION__
);
161 InitializeVideoAddressSpace();
163 RtlRosInitUnicodeStringFromLiteral(&DeviceName
, L
"\\??\\DISPLAY1");
164 InitializeObjectAttributes(&ObjectAttributes
,
169 Status
= NtOpenFile(&VideoHandle
,
175 if (NT_SUCCESS(Status
))
177 NtClose(VideoHandle
);
182 /**********************************************************************
185 * TODO: this function should be turned more general to load an
186 * TODO: hosted server DLL as received from the command line;
187 * TODO: for instance: ServerDll=winsrv:ConServerDllInitialization,2
188 * TODO: ^method ^dll ^api ^sid
190 * TODO: CsrpHostServerDll (LPWSTR DllName,
191 * TODO: LPWSTR ApiName,
192 * TODO: DWORD ServerId)
195 CsrpInitWin32Csr (ULONG argc
, PWSTR
* argv
)
198 UNICODE_STRING DllName
;
200 ANSI_STRING ProcName
;
201 CSRPLUGIN_INITIALIZE_PROC InitProc
;
202 CSRSS_EXPORTED_FUNCS Exports
;
203 PCSRSS_API_DEFINITION ApiDefinitions
;
204 PCSRSS_OBJECT_DEFINITION ObjectDefinitions
;
205 CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc
;
207 DPRINT("CSR: %s called\n", __FUNCTION__
);
209 RtlInitUnicodeString(&DllName
, L
"win32csr.dll");
210 Status
= LdrLoadDll(NULL
, 0, &DllName
, (PVOID
*) &hInst
);
211 if (! NT_SUCCESS(Status
))
215 RtlInitAnsiString(&ProcName
, "Win32CsrInitialization");
216 Status
= LdrGetProcedureAddress(hInst
, &ProcName
, 0, (PVOID
*) &InitProc
);
217 if (! NT_SUCCESS(Status
))
221 Exports
.CsrInsertObjectProc
= CsrInsertObject
;
222 Exports
.CsrGetObjectProc
= CsrGetObject
;
223 Exports
.CsrReleaseObjectProc
= CsrReleaseObject
;
224 if (! (*InitProc
)(&ApiDefinitions
, &ObjectDefinitions
, &InitCompleteProc
,
225 &Exports
, CsrssApiHeap
))
227 return STATUS_UNSUCCESSFUL
;
230 Status
= CsrApiRegisterDefinitions(ApiDefinitions
);
231 if (! NT_SUCCESS(Status
))
235 Status
= CsrRegisterObjectDefinitions(ObjectDefinitions
);
236 if (! NT_SUCCESS(Status
))
240 if (NULL
!= InitCompleteProc
)
242 Status
= CsrpAddInitCompleteProc(InitCompleteProc
);
248 CSRSS_API_DEFINITION NativeDefinitions
[] =
250 CSRSS_DEFINE_API(CSRSS_CREATE_PROCESS
, CsrCreateProcess
),
251 CSRSS_DEFINE_API(CSRSS_TERMINATE_PROCESS
, CsrTerminateProcess
),
252 CSRSS_DEFINE_API(CSRSS_CONNECT_PROCESS
, CsrConnectProcess
),
253 CSRSS_DEFINE_API(CSRSS_REGISTER_SERVICES_PROCESS
, CsrRegisterServicesProcess
),
254 CSRSS_DEFINE_API(CSRSS_GET_SHUTDOWN_PARAMETERS
, CsrGetShutdownParameters
),
255 CSRSS_DEFINE_API(CSRSS_SET_SHUTDOWN_PARAMETERS
, CsrSetShutdownParameters
),
256 CSRSS_DEFINE_API(CSRSS_GET_INPUT_HANDLE
, CsrGetInputHandle
),
257 CSRSS_DEFINE_API(CSRSS_GET_OUTPUT_HANDLE
, CsrGetOutputHandle
),
258 CSRSS_DEFINE_API(CSRSS_CLOSE_HANDLE
, CsrCloseHandle
),
259 CSRSS_DEFINE_API(CSRSS_VERIFY_HANDLE
, CsrVerifyHandle
),
260 CSRSS_DEFINE_API(CSRSS_DUPLICATE_HANDLE
, CsrDuplicateHandle
),
261 CSRSS_DEFINE_API(CSRSS_GET_INPUT_WAIT_HANDLE
, CsrGetInputWaitHandle
),
265 static NTSTATUS STDCALL
266 CsrpCreateListenPort (IN LPWSTR Name
,
268 IN PTHREAD_START_ROUTINE ListenThread
)
270 NTSTATUS Status
= STATUS_SUCCESS
;
271 OBJECT_ATTRIBUTES PortAttributes
;
272 UNICODE_STRING PortName
;
274 DPRINT("CSR: %s called\n", __FUNCTION__
);
276 RtlInitUnicodeString (& PortName
, Name
);
277 InitializeObjectAttributes (& PortAttributes
,
282 Status
= NtCreatePort ( Port
,
284 260, /* TODO: make caller set it*/
285 328, /* TODO: make caller set it*/
286 0); /* TODO: make caller set it*/
287 if(!NT_SUCCESS(Status
))
289 DPRINT1("CSR: %s: NtCreatePort failed (Status=%08lx)\n",
290 __FUNCTION__
, Status
);
293 Status
= RtlCreateUserThread(NtCurrentProcess(),
299 (PTHREAD_START_ROUTINE
) ListenThread
,
306 /* === INIT ROUTINES === */
308 /**********************************************************************
309 * CsrpCreateCallbackPort/0
312 CsrpCreateHeap (ULONG argc
, PWSTR
* argv
)
314 DPRINT("CSR: %s called\n", __FUNCTION__
);
316 CsrssApiHeap
= RtlCreateHeap(HEAP_GROWABLE
,
322 if (CsrssApiHeap
== NULL
)
324 return STATUS_UNSUCCESSFUL
;
326 return STATUS_SUCCESS
;
329 /**********************************************************************
330 * CsrpCreateCallbackPort/0
333 CsrpCreateCallbackPort (ULONG argc
, PWSTR
* argv
)
335 DPRINT("CSR: %s called\n", __FUNCTION__
);
337 return CsrpCreateListenPort (L
"\\Windows\\SbApiPort",
339 ServerSbApiPortThread
);
342 /**********************************************************************
343 * CsrpRegisterSubsystem/2
346 CsrpRegisterSubsystem (ULONG argc
, PWSTR
* argv
)
348 NTSTATUS Status
= STATUS_SUCCESS
;
349 OBJECT_ATTRIBUTES BootstrapOkAttributes
;
352 DPRINT("CSR: %s called\n", __FUNCTION__
);
355 * Create the event object the callback port
356 * thread will signal *if* the SM will
357 * authorize us to bootstrap.
359 RtlInitUnicodeString (& Name
, L
"\\CsrssBooting");
360 InitializeObjectAttributes(& BootstrapOkAttributes
,
363 Status
= NtCreateEvent (& hBootstrapOk
,
365 & BootstrapOkAttributes
,
366 SynchronizationEvent
,
368 if(!NT_SUCCESS(Status
))
370 DPRINT("CSR: %s: NtCreateEvent failed (Status=0x%08lx)\n",
371 __FUNCTION__
, Status
);
375 * Let's tell the SM a new environment
376 * subsystem server is in the system.
378 RtlInitUnicodeString (& Name
, L
"\\Windows\\SbApiPort");
379 DPRINT("CSR: %s: registering with SM for\n IMAGE_SUBSYSTEM_WINDOWS_CUI == 3\n", __FUNCTION__
);
380 Status
= SmConnectApiPort (& Name
,
382 IMAGE_SUBSYSTEM_WINDOWS_CUI
,
384 if(!NT_SUCCESS(Status
))
386 DPRINT("CSR: %s unable to connect to the SM (Status=0x%08lx)\n",
387 __FUNCTION__
, Status
);
388 NtClose (hBootstrapOk
);
392 * Wait for SM to reply OK... If the SM
393 * won't answer, we hang here forever!
395 DPRINT("CSR: %s: waiting for SM to OK boot...\n", __FUNCTION__
);
396 Status
= NtWaitForSingleObject (hBootstrapOk
,
399 NtClose (hBootstrapOk
);
403 /**********************************************************************
404 * CsrpCreateApiPort/0
407 CsrpCreateApiPort (ULONG argc
, PWSTR
* argv
)
409 DPRINT("CSR: %s called\n", __FUNCTION__
);
411 return CsrpCreateListenPort (L
"\\Windows\\ApiPort",
413 ServerApiPortThread
);
416 /**********************************************************************
417 * CsrpApiRegisterDef/0
420 CsrpApiRegisterDef (ULONG argc
, PWSTR
* argv
)
422 return CsrApiRegisterDefinitions(NativeDefinitions
);
425 /**********************************************************************
429 CsrpCCTS (ULONG argc
, PWSTR
* argv
)
431 return CsrClientConnectToServer();
434 /**********************************************************************
437 * Start the logon process (winlogon.exe).
439 * TODO: this should be moved in CsrpCreateSession/x (one per session)
440 * TODO: in its own desktop (one logon desktop per winstation).
443 CsrpRunWinlogon (ULONG argc
, PWSTR
* argv
)
445 NTSTATUS Status
= STATUS_SUCCESS
;
446 UNICODE_STRING ImagePath
;
447 UNICODE_STRING CommandLine
;
448 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
= NULL
;
449 RTL_PROCESS_INFO ProcessInfo
;
452 DPRINT("CSR: %s called\n", __FUNCTION__
);
454 /* initialize the process parameters */
455 RtlInitUnicodeString (& ImagePath
, L
"\\SystemRoot\\system32\\winlogon.exe");
456 RtlInitUnicodeString (& CommandLine
, L
"");
457 RtlCreateProcessParameters(& ProcessParameters
,
467 /* Create the winlogon process */
468 Status
= RtlCreateUserProcess (& ImagePath
,
469 OBJ_CASE_INSENSITIVE
,
479 RtlDestroyProcessParameters (ProcessParameters
);
480 if (!NT_SUCCESS(Status
))
482 DPRINT1("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
483 __FUNCTION__
, Status
);
485 ZwResumeThread(ProcessInfo
.ThreadHandle
, NULL
);
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
);