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
;
28 static unsigned InitCompleteProcCount
;
29 static CSRPLUGIN_INIT_COMPLETE_PROC
*InitCompleteProcs
= NULL
;
31 HANDLE hSbApiPort
= (HANDLE
) 0;
33 HANDLE hBootstrapOk
= (HANDLE
) 0;
35 HANDLE hSmApiPort
= (HANDLE
) 0;
37 HANDLE hApiPort
= (HANDLE
) 0;
39 /**********************************************************************
40 * CsrpAddInitCompleteProc/1
42 static NTSTATUS FASTCALL
43 CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc
)
45 CSRPLUGIN_INIT_COMPLETE_PROC
*NewProcs
;
47 DPRINT("CSR: %s called\n", __FUNCTION__
);
49 NewProcs
= RtlAllocateHeap(CsrssApiHeap
, 0,
50 (InitCompleteProcCount
+ 1)
51 * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC
));
54 return STATUS_NO_MEMORY
;
56 if (0 != InitCompleteProcCount
)
58 RtlCopyMemory(NewProcs
, InitCompleteProcs
,
59 InitCompleteProcCount
* sizeof(CSRPLUGIN_INIT_COMPLETE_PROC
));
60 RtlFreeHeap(CsrssApiHeap
, 0, InitCompleteProcs
);
62 NewProcs
[InitCompleteProcCount
] = Proc
;
63 InitCompleteProcs
= NewProcs
;
64 InitCompleteProcCount
++;
66 return STATUS_SUCCESS
;
69 /**********************************************************************
73 CallInitComplete(void)
78 DPRINT("CSR: %s called\n", __FUNCTION__
);
81 if (0 != InitCompleteProcCount
)
83 for (i
= 0; i
< InitCompleteProcCount
&& Ok
; i
++)
85 Ok
= (*(InitCompleteProcs
[i
]))();
87 RtlFreeHeap(CsrssApiHeap
, 0, InitCompleteProcs
);
94 InitializeVideoAddressSpace(VOID
);
96 /**********************************************************************
97 * CsrpCreateObjectDirectory/3
100 CsrpCreateObjectDirectory (int argc
, char ** argv
, char ** envp
)
103 OBJECT_ATTRIBUTES Attributes
;
105 DPRINT("CSR: %s called\n", __FUNCTION__
);
108 /* create object directory ('\Windows') */
109 RtlCreateUnicodeString (&CsrDirectoryName
,
112 InitializeObjectAttributes (&Attributes
,
118 Status
= NtOpenDirectoryObject(&CsrObjectDirectory
,
119 0xF000F, /* ea:??? */
124 /**********************************************************************
127 * TODO: we need a virtual device for sessions other than
128 * TODO: the console one
131 CsrpInitVideo (int argc
, char ** argv
, char ** envp
)
133 OBJECT_ATTRIBUTES ObjectAttributes
;
134 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\??\\DISPLAY1");
135 IO_STATUS_BLOCK Iosb
;
136 HANDLE VideoHandle
= (HANDLE
) 0;
137 NTSTATUS Status
= STATUS_SUCCESS
;
139 DPRINT("CSR: %s called\n", __FUNCTION__
);
141 InitializeVideoAddressSpace();
143 InitializeObjectAttributes(&ObjectAttributes
,
148 Status
= NtOpenFile(&VideoHandle
,
154 if (NT_SUCCESS(Status
))
156 NtClose(VideoHandle
);
161 /**********************************************************************
164 * TODO: this function should be turned more general to load an
165 * TODO: hosted server DLL as received from the command line;
166 * TODO: for instance: ServerDll=winsrv:ConServerDllInitialization,2
167 * TODO: ^method ^dll ^api ^sid
169 * TODO: CsrpHostServerDll (LPWSTR DllName,
170 * TODO: LPWSTR ApiName,
171 * TODO: DWORD ServerId)
174 CsrpInitWin32Csr (int argc
, char ** argv
, char ** envp
)
177 UNICODE_STRING DllName
;
179 ANSI_STRING ProcName
;
180 CSRPLUGIN_INITIALIZE_PROC InitProc
;
181 CSRSS_EXPORTED_FUNCS Exports
;
182 PCSRSS_API_DEFINITION ApiDefinitions
;
183 PCSRSS_OBJECT_DEFINITION ObjectDefinitions
;
184 CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc
;
186 DPRINT("CSR: %s called\n", __FUNCTION__
);
188 RtlInitUnicodeString(&DllName
, L
"win32csr.dll");
189 Status
= LdrLoadDll(NULL
, 0, &DllName
, (PVOID
*) &hInst
);
190 if (! NT_SUCCESS(Status
))
194 RtlInitAnsiString(&ProcName
, "Win32CsrInitialization");
195 Status
= LdrGetProcedureAddress(hInst
, &ProcName
, 0, (PVOID
*) &InitProc
);
196 if (! NT_SUCCESS(Status
))
200 Exports
.CsrInsertObjectProc
= CsrInsertObject
;
201 Exports
.CsrGetObjectProc
= CsrGetObject
;
202 Exports
.CsrReleaseObjectProc
= CsrReleaseObject
;
203 Exports
.CsrEnumProcessesProc
= CsrEnumProcesses
;
204 if (! (*InitProc
)(&ApiDefinitions
, &ObjectDefinitions
, &InitCompleteProc
,
205 &Exports
, CsrssApiHeap
))
207 return STATUS_UNSUCCESSFUL
;
210 Status
= CsrApiRegisterDefinitions(ApiDefinitions
);
211 if (! NT_SUCCESS(Status
))
215 Status
= CsrRegisterObjectDefinitions(ObjectDefinitions
);
216 if (! NT_SUCCESS(Status
))
220 if (NULL
!= InitCompleteProc
)
222 Status
= CsrpAddInitCompleteProc(InitCompleteProc
);
228 CSRSS_API_DEFINITION NativeDefinitions
[] =
230 CSRSS_DEFINE_API(CREATE_PROCESS
, CsrCreateProcess
),
231 CSRSS_DEFINE_API(TERMINATE_PROCESS
, CsrTerminateProcess
),
232 CSRSS_DEFINE_API(CONNECT_PROCESS
, CsrConnectProcess
),
233 CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS
, CsrRegisterServicesProcess
),
234 CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS
, CsrGetShutdownParameters
),
235 CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS
, CsrSetShutdownParameters
),
236 CSRSS_DEFINE_API(GET_INPUT_HANDLE
, CsrGetInputHandle
),
237 CSRSS_DEFINE_API(GET_OUTPUT_HANDLE
, CsrGetOutputHandle
),
238 CSRSS_DEFINE_API(CLOSE_HANDLE
, CsrCloseHandle
),
239 CSRSS_DEFINE_API(VERIFY_HANDLE
, CsrVerifyHandle
),
240 CSRSS_DEFINE_API(DUPLICATE_HANDLE
, CsrDuplicateHandle
),
241 CSRSS_DEFINE_API(GET_INPUT_WAIT_HANDLE
, CsrGetInputWaitHandle
),
245 static NTSTATUS STDCALL
246 CsrpCreateListenPort (IN LPWSTR Name
,
248 IN PTHREAD_START_ROUTINE ListenThread
)
250 NTSTATUS Status
= STATUS_SUCCESS
;
251 OBJECT_ATTRIBUTES PortAttributes
;
252 UNICODE_STRING PortName
;
254 DPRINT("CSR: %s called\n", __FUNCTION__
);
256 RtlInitUnicodeString (& PortName
, Name
);
257 InitializeObjectAttributes (& PortAttributes
,
262 Status
= NtCreatePort ( Port
,
264 LPC_MAX_DATA_LENGTH
, /* TODO: make caller set it*/
265 LPC_MAX_MESSAGE_LENGTH
, /* TODO: make caller set it*/
266 0); /* TODO: make caller set it*/
267 if(!NT_SUCCESS(Status
))
269 DPRINT1("CSR: %s: NtCreatePort failed (Status=%08lx)\n",
270 __FUNCTION__
, Status
);
273 Status
= RtlCreateUserThread(NtCurrentProcess(),
279 (PTHREAD_START_ROUTINE
) ListenThread
,
286 /* === INIT ROUTINES === */
288 /**********************************************************************
292 CsrpCreateHeap (int argc
, char ** argv
, char ** envp
)
294 DPRINT("CSR: %s called\n", __FUNCTION__
);
296 CsrssApiHeap
= RtlCreateHeap(HEAP_GROWABLE
,
302 if (CsrssApiHeap
== NULL
)
304 return STATUS_UNSUCCESSFUL
;
306 return STATUS_SUCCESS
;
309 /**********************************************************************
310 * CsrpCreateCallbackPort/3
313 CsrpCreateCallbackPort (int argc
, char ** argv
, char ** envp
)
315 DPRINT("CSR: %s called\n", __FUNCTION__
);
317 return CsrpCreateListenPort (L
"\\Windows\\SbApiPort",
319 ServerSbApiPortThread
);
322 /**********************************************************************
323 * CsrpRegisterSubsystem/3
326 CsrpRegisterSubsystem (int argc
, char ** argv
, char ** envp
)
328 NTSTATUS Status
= STATUS_SUCCESS
;
329 OBJECT_ATTRIBUTES BootstrapOkAttributes
;
332 DPRINT("CSR: %s called\n", __FUNCTION__
);
335 * Create the event object the callback port
336 * thread will signal *if* the SM will
337 * authorize us to bootstrap.
339 RtlInitUnicodeString (& Name
, L
"\\CsrssBooting");
340 InitializeObjectAttributes(& BootstrapOkAttributes
,
343 Status
= NtCreateEvent (& hBootstrapOk
,
345 & BootstrapOkAttributes
,
346 SynchronizationEvent
,
348 if(!NT_SUCCESS(Status
))
350 DPRINT("CSR: %s: NtCreateEvent failed (Status=0x%08lx)\n",
351 __FUNCTION__
, Status
);
355 * Let's tell the SM a new environment
356 * subsystem server is in the system.
358 RtlInitUnicodeString (& Name
, L
"\\Windows\\SbApiPort");
359 DPRINT("CSR: %s: registering with SM for\n IMAGE_SUBSYSTEM_WINDOWS_CUI == 3\n", __FUNCTION__
);
360 Status
= SmConnectApiPort (& Name
,
362 IMAGE_SUBSYSTEM_WINDOWS_CUI
,
364 if(!NT_SUCCESS(Status
))
366 DPRINT("CSR: %s unable to connect to the SM (Status=0x%08lx)\n",
367 __FUNCTION__
, Status
);
368 NtClose (hBootstrapOk
);
372 * Wait for SM to reply OK... If the SM
373 * won't answer, we hang here forever!
375 DPRINT("CSR: %s: waiting for SM to OK boot...\n", __FUNCTION__
);
376 Status
= NtWaitForSingleObject (hBootstrapOk
,
379 NtClose (hBootstrapOk
);
383 /**********************************************************************
384 * EnvpToUnicodeString/2
386 static ULONG FASTCALL
387 EnvpToUnicodeString (char ** envp
, PUNICODE_STRING UnicodeEnv
)
393 UnicodeEnv
->Buffer
= NULL
;
395 for (Index
=0; NULL
!= envp
[Index
]; Index
++)
397 CharCount
+= strlen (envp
[Index
]);
402 AnsiEnv
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap(), 0, CharCount
);
403 if (NULL
!= AnsiEnv
.Buffer
)
406 PCHAR WritePos
= AnsiEnv
.Buffer
;
408 for (Index
=0; NULL
!= envp
[Index
]; Index
++)
410 strcpy (WritePos
, envp
[Index
]);
411 WritePos
+= strlen (envp
[Index
]) + 1;
414 /* FIXME: the last (double) nullterm should perhaps not be included in Length
415 * but only in MaximumLength. -Gunnar */
416 AnsiEnv
.Buffer
[CharCount
-1] = '\0';
417 AnsiEnv
.Length
= CharCount
;
418 AnsiEnv
.MaximumLength
= CharCount
;
420 RtlAnsiStringToUnicodeString (UnicodeEnv
, & AnsiEnv
, TRUE
);
421 RtlFreeHeap (RtlGetProcessHeap(), 0, AnsiEnv
.Buffer
);
425 /**********************************************************************
426 * CsrpLoadKernelModeDriver/3
429 CsrpLoadKernelModeDriver (int argc
, char ** argv
, char ** envp
)
431 NTSTATUS Status
= STATUS_SUCCESS
;
432 WCHAR Data
[MAX_PATH
+ 1];
433 ULONG DataLength
= sizeof Data
;
435 UNICODE_STRING Environment
;
438 DPRINT("SM: %s called\n", __FUNCTION__
);
441 EnvpToUnicodeString (envp
, & Environment
);
442 Status
= SmLookupSubsystem (L
"Kmode",
447 RtlFreeUnicodeString (& Environment
);
448 if((STATUS_SUCCESS
== Status
) && (DataLength
> sizeof Data
[0]))
450 WCHAR ImagePath
[MAX_PATH
+ 1] = {0};
451 UNICODE_STRING ModuleName
;
453 wcscpy (ImagePath
, L
"\\??\\");
454 wcscat (ImagePath
, Data
);
455 RtlInitUnicodeString (& ModuleName
, ImagePath
);
456 Status
= NtSetSystemInformation(/* FIXME: SystemLoadAndCallImage */
457 SystemExtendServiceTableInformation
,
460 if(!NT_SUCCESS(Status
))
462 DPRINT("WIN: %s: loading Kmode failed (Status=0x%08lx)\n",
463 __FUNCTION__
, Status
);
469 /**********************************************************************
470 * CsrpCreateApiPort/2
473 CsrpCreateApiPort (int argc
, char ** argv
, char ** envp
)
475 DPRINT("CSR: %s called\n", __FUNCTION__
);
477 return CsrpCreateListenPort (L
"\\Windows\\ApiPort",
479 ServerApiPortThread
);
482 /**********************************************************************
483 * CsrpApiRegisterDef/0
486 CsrpApiRegisterDef (int argc
, char ** argv
, char ** envp
)
488 return CsrApiRegisterDefinitions(NativeDefinitions
);
491 /**********************************************************************
495 CsrpCCTS (int argc
, char ** argv
, char ** envp
)
498 ULONG DummyLength
= sizeof(Dummy
);
499 return CsrClientConnectToServer(L
"\\Windows",
500 0, &Dummy
, &DummyLength
, NULL
);
503 /**********************************************************************
506 * Start the logon process (winlogon.exe).
508 * TODO: this should be moved in CsrpCreateSession/x (one per session)
509 * TODO: in its own desktop (one logon desktop per winstation).
512 CsrpRunWinlogon (int argc
, char ** argv
, char ** envp
)
514 NTSTATUS Status
= STATUS_SUCCESS
;
515 UNICODE_STRING ImagePath
;
516 UNICODE_STRING CommandLine
;
517 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
= NULL
;
518 RTL_USER_PROCESS_INFORMATION ProcessInfo
;
521 DPRINT("CSR: %s called\n", __FUNCTION__
);
523 /* initialize the process parameters */
524 RtlInitUnicodeString (& ImagePath
, L
"\\SystemRoot\\system32\\winlogon.exe");
525 RtlInitUnicodeString (& CommandLine
, L
"");
526 RtlCreateProcessParameters(& ProcessParameters
,
536 /* Create the winlogon process */
537 Status
= RtlCreateUserProcess (& ImagePath
,
538 OBJ_CASE_INSENSITIVE
,
548 RtlDestroyProcessParameters (ProcessParameters
);
549 if (!NT_SUCCESS(Status
))
551 DPRINT1("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
552 __FUNCTION__
, Status
);
554 ZwResumeThread(ProcessInfo
.ThreadHandle
, NULL
);
560 typedef NTSTATUS (* CSR_INIT_ROUTINE
)(int,char**,char**);
564 CSR_INIT_ROUTINE EntryPoint
;
567 {TRUE
, CsrpCreateCallbackPort
, "create the callback port \\Windows\\SbApiPort"},
568 {TRUE
, CsrpRegisterSubsystem
, "register with SM"},
569 {TRUE
, CsrpCreateHeap
, "create the CSR heap"},
570 {TRUE
, CsrpCreateApiPort
, "create the api port \\Windows\\ApiPort"},
571 {TRUE
, CsrpCreateObjectDirectory
,"create the object directory \\Windows"},
572 {TRUE
, CsrpLoadKernelModeDriver
, "load Kmode driver"},
573 {TRUE
, CsrpInitVideo
, "initialize video"},
574 {TRUE
, CsrpApiRegisterDef
, "initialize api definitions"},
575 {TRUE
, CsrpCCTS
, "connect client to server"},
576 {TRUE
, CsrpInitWin32Csr
, "load usermode dll"},
577 {TRUE
, CsrpRunWinlogon
, "run WinLogon"},
580 /**********************************************************************
582 * CsrServerInitialization
585 * Initialize the Win32 environment subsystem server.
588 * TRUE: Initialization OK; otherwise FALSE.
591 CsrServerInitialization (
598 NTSTATUS Status
= STATUS_SUCCESS
;
600 DPRINT("CSR: %s called\n", __FUNCTION__
);
602 for (i
=0; i
< (sizeof InitRoutine
/ sizeof InitRoutine
[0]); i
++)
604 Status
= InitRoutine
[i
].EntryPoint(argc
,argv
,envp
);
605 if(!NT_SUCCESS(Status
))
607 DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n",
609 InitRoutine
[i
].ErrorMessage
,
611 if (InitRoutine
[i
].Required
)
617 if (CallInitComplete())
619 Status
= SmCompleteSession (hSmApiPort
,hSbApiPort
,hApiPort
);