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
;
37 extern PRTL_USER_PROCESS_PARAMETERS RtlProcessParameters
;
39 static unsigned InitCompleteProcCount
;
40 static CSRPLUGIN_INIT_COMPLETE_PROC
*InitCompleteProcs
= NULL
;
42 HANDLE hSbApiPort
= (HANDLE
) 0;
44 HANDLE hBootstrapOk
= (HANDLE
) 0;
46 HANDLE hSmApiPort
= (HANDLE
) 0;
48 HANDLE hApiPort
= (HANDLE
) 0;
50 /**********************************************************************
51 * CsrpAddInitCompleteProc/1
53 static NTSTATUS FASTCALL
54 CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc
)
56 CSRPLUGIN_INIT_COMPLETE_PROC
*NewProcs
;
58 DPRINT("CSR: %s called\n", __FUNCTION__
);
60 NewProcs
= RtlAllocateHeap(CsrssApiHeap
, 0,
61 (InitCompleteProcCount
+ 1)
62 * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC
));
65 return STATUS_NO_MEMORY
;
67 if (0 != InitCompleteProcCount
)
69 RtlCopyMemory(NewProcs
, InitCompleteProcs
,
70 InitCompleteProcCount
* sizeof(CSRPLUGIN_INIT_COMPLETE_PROC
));
71 RtlFreeHeap(CsrssApiHeap
, 0, InitCompleteProcs
);
73 NewProcs
[InitCompleteProcCount
] = Proc
;
74 InitCompleteProcs
= NewProcs
;
75 InitCompleteProcCount
++;
77 return STATUS_SUCCESS
;
80 /**********************************************************************
84 CallInitComplete(void)
89 DPRINT("CSR: %s called\n", __FUNCTION__
);
92 if (0 != InitCompleteProcCount
)
94 for (i
= 0; i
< InitCompleteProcCount
&& Ok
; i
++)
96 Ok
= (*(InitCompleteProcs
[i
]))();
98 RtlFreeHeap(CsrssApiHeap
, 0, InitCompleteProcs
);
105 InitializeVideoAddressSpace(VOID
);
107 /**********************************************************************
108 * CsrpParseCommandLine/2
111 CsrpParseCommandLine (
117 OBJECT_ATTRIBUTES Attributes
;
119 DPRINT("CSR: %s called\n", __FUNCTION__
);
122 /* DbgPrint ("Arguments: %ld\n", ArgumentCount);
123 for (i = 0; i < ArgumentCount; i++)
125 DbgPrint ("Argument %ld: %S\n", i, ArgumentArray[i]);
129 /* create object directory ('\Windows') */
130 RtlCreateUnicodeString (&CsrDirectoryName
,
133 InitializeObjectAttributes (&Attributes
,
139 Status
= NtOpenDirectoryObject(&CsrObjectDirectory
,
140 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 /**********************************************************************
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/2
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 * CsrpLoadKernelModeDriver/2
408 CsrpLoadKernelModeDriver (ULONG argc
, PWSTR
* argv
)
410 NTSTATUS Status
= STATUS_SUCCESS
;
411 WCHAR Data
[MAX_PATH
+ 1];
412 ULONG DataLength
= sizeof Data
;
416 DPRINT("SM: %s called\n", __FUNCTION__
);
418 Status
= SmLookupSubsystem (L
"Kmode",
422 RtlProcessParameters
->Environment
);
423 if((STATUS_SUCCESS
== Status
) && (DataLength
> sizeof Data
[0]))
425 WCHAR ImagePath
[MAX_PATH
+ 1] = {0};
426 SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo
;
428 wcscpy (ImagePath
, L
"\\??\\");
429 wcscat (ImagePath
, Data
);
430 RtlZeroMemory (& ImageInfo
, sizeof ImageInfo
);
431 RtlInitUnicodeString (& ImageInfo
.ModuleName
, ImagePath
);
432 Status
= NtSetSystemInformation(SystemLoadAndCallImage
,
435 if(!NT_SUCCESS(Status
))
437 DPRINT("WIN: %s: loading Kmode failed (Status=0x%08lx)\n",
438 __FUNCTION__
, Status
);
444 /**********************************************************************
445 * CsrpCreateApiPort/2
448 CsrpCreateApiPort (ULONG argc
, PWSTR
* argv
)
450 DPRINT("CSR: %s called\n", __FUNCTION__
);
452 return CsrpCreateListenPort (L
"\\Windows\\ApiPort",
454 ServerApiPortThread
);
457 /**********************************************************************
458 * CsrpApiRegisterDef/0
461 CsrpApiRegisterDef (ULONG argc
, PWSTR
* argv
)
463 return CsrApiRegisterDefinitions(NativeDefinitions
);
466 /**********************************************************************
470 CsrpCCTS (ULONG argc
, PWSTR
* argv
)
472 return CsrClientConnectToServer();
475 /**********************************************************************
478 * Start the logon process (winlogon.exe).
480 * TODO: this should be moved in CsrpCreateSession/x (one per session)
481 * TODO: in its own desktop (one logon desktop per winstation).
484 CsrpRunWinlogon (ULONG argc
, PWSTR
* argv
)
486 NTSTATUS Status
= STATUS_SUCCESS
;
487 UNICODE_STRING ImagePath
;
488 UNICODE_STRING CommandLine
;
489 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
= NULL
;
490 RTL_PROCESS_INFO ProcessInfo
;
493 DPRINT("CSR: %s called\n", __FUNCTION__
);
495 /* initialize the process parameters */
496 RtlInitUnicodeString (& ImagePath
, L
"\\SystemRoot\\system32\\winlogon.exe");
497 RtlInitUnicodeString (& CommandLine
, L
"");
498 RtlCreateProcessParameters(& ProcessParameters
,
508 /* Create the winlogon process */
509 Status
= RtlCreateUserProcess (& ImagePath
,
510 OBJ_CASE_INSENSITIVE
,
520 RtlDestroyProcessParameters (ProcessParameters
);
521 if (!NT_SUCCESS(Status
))
523 DPRINT1("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
524 __FUNCTION__
, Status
);
526 ZwResumeThread(ProcessInfo
.ThreadHandle
, NULL
);
532 typedef NTSTATUS (* CSR_INIT_ROUTINE
)(ULONG
, PWSTR
*);
536 CSR_INIT_ROUTINE EntryPoint
;
539 {TRUE
, CsrpCreateCallbackPort
, "create the callback port \\Windows\\SbApiPort"},
540 {TRUE
, CsrpRegisterSubsystem
, "register with SM"},
541 {TRUE
, CsrpCreateHeap
, "create the CSR heap"},
542 {TRUE
, CsrpCreateApiPort
, "create the api port \\Windows\\ApiPort"},
543 {TRUE
, CsrpParseCommandLine
, "parse the command line"},
544 {TRUE
, CsrpLoadKernelModeDriver
, "load Kmode driver"},
545 {TRUE
, CsrpInitVideo
, "initialize video"},
546 {TRUE
, CsrpApiRegisterDef
, "initialize api definitions"},
547 {TRUE
, CsrpCCTS
, "connect client to server"},
548 {TRUE
, CsrpInitWin32Csr
, "load usermode dll"},
549 {TRUE
, CsrpRunWinlogon
, "run WinLogon"},
552 /**********************************************************************
554 * CsrServerInitialization
557 * Initialize the Win32 environment subsystem server.
560 * TRUE: Initialization OK; otherwise FALSE.
563 CsrServerInitialization (
569 NTSTATUS Status
= STATUS_SUCCESS
;
571 DPRINT("CSR: %s called\n", __FUNCTION__
);
573 for (i
=0; i
< (sizeof InitRoutine
/ sizeof InitRoutine
[0]); i
++)
575 Status
= InitRoutine
[i
].EntryPoint(ArgumentCount
,ArgumentArray
);
576 if(!NT_SUCCESS(Status
))
578 DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n",
580 InitRoutine
[i
].ErrorMessage
,
582 if (InitRoutine
[i
].Required
)
588 if (CallInitComplete())
590 Status
= SmCompleteSession (hSmApiPort
,hSbApiPort
,hApiPort
);