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 if (! (*InitProc
)(&ApiDefinitions
, &ObjectDefinitions
, &InitCompleteProc
,
204 &Exports
, CsrssApiHeap
))
206 return STATUS_UNSUCCESSFUL
;
209 Status
= CsrApiRegisterDefinitions(ApiDefinitions
);
210 if (! NT_SUCCESS(Status
))
214 Status
= CsrRegisterObjectDefinitions(ObjectDefinitions
);
215 if (! NT_SUCCESS(Status
))
219 if (NULL
!= InitCompleteProc
)
221 Status
= CsrpAddInitCompleteProc(InitCompleteProc
);
227 CSRSS_API_DEFINITION NativeDefinitions
[] =
229 CSRSS_DEFINE_API(CREATE_PROCESS
, CsrCreateProcess
),
230 CSRSS_DEFINE_API(TERMINATE_PROCESS
, CsrTerminateProcess
),
231 CSRSS_DEFINE_API(CONNECT_PROCESS
, CsrConnectProcess
),
232 CSRSS_DEFINE_API(REGISTER_SERVICES_PROCESS
, CsrRegisterServicesProcess
),
233 CSRSS_DEFINE_API(GET_SHUTDOWN_PARAMETERS
, CsrGetShutdownParameters
),
234 CSRSS_DEFINE_API(SET_SHUTDOWN_PARAMETERS
, CsrSetShutdownParameters
),
235 CSRSS_DEFINE_API(GET_INPUT_HANDLE
, CsrGetInputHandle
),
236 CSRSS_DEFINE_API(GET_OUTPUT_HANDLE
, CsrGetOutputHandle
),
237 CSRSS_DEFINE_API(CLOSE_HANDLE
, CsrCloseHandle
),
238 CSRSS_DEFINE_API(VERIFY_HANDLE
, CsrVerifyHandle
),
239 CSRSS_DEFINE_API(DUPLICATE_HANDLE
, CsrDuplicateHandle
),
240 CSRSS_DEFINE_API(GET_INPUT_WAIT_HANDLE
, CsrGetInputWaitHandle
),
244 static NTSTATUS STDCALL
245 CsrpCreateListenPort (IN LPWSTR Name
,
247 IN PTHREAD_START_ROUTINE ListenThread
)
249 NTSTATUS Status
= STATUS_SUCCESS
;
250 OBJECT_ATTRIBUTES PortAttributes
;
251 UNICODE_STRING PortName
;
253 DPRINT("CSR: %s called\n", __FUNCTION__
);
255 RtlInitUnicodeString (& PortName
, Name
);
256 InitializeObjectAttributes (& PortAttributes
,
261 Status
= NtCreatePort ( Port
,
263 LPC_MAX_DATA_LENGTH
, /* TODO: make caller set it*/
264 LPC_MAX_MESSAGE_LENGTH
, /* TODO: make caller set it*/
265 0); /* TODO: make caller set it*/
266 if(!NT_SUCCESS(Status
))
268 DPRINT1("CSR: %s: NtCreatePort failed (Status=%08lx)\n",
269 __FUNCTION__
, Status
);
272 Status
= RtlCreateUserThread(NtCurrentProcess(),
278 (PTHREAD_START_ROUTINE
) ListenThread
,
285 /* === INIT ROUTINES === */
287 /**********************************************************************
291 CsrpCreateHeap (int argc
, char ** argv
, char ** envp
)
293 DPRINT("CSR: %s called\n", __FUNCTION__
);
295 CsrssApiHeap
= RtlCreateHeap(HEAP_GROWABLE
,
301 if (CsrssApiHeap
== NULL
)
303 return STATUS_UNSUCCESSFUL
;
305 return STATUS_SUCCESS
;
308 /**********************************************************************
309 * CsrpCreateCallbackPort/3
312 CsrpCreateCallbackPort (int argc
, char ** argv
, char ** envp
)
314 DPRINT("CSR: %s called\n", __FUNCTION__
);
316 return CsrpCreateListenPort (L
"\\Windows\\SbApiPort",
318 ServerSbApiPortThread
);
321 /**********************************************************************
322 * CsrpRegisterSubsystem/3
325 CsrpRegisterSubsystem (int argc
, char ** argv
, char ** envp
)
327 NTSTATUS Status
= STATUS_SUCCESS
;
328 OBJECT_ATTRIBUTES BootstrapOkAttributes
;
331 DPRINT("CSR: %s called\n", __FUNCTION__
);
334 * Create the event object the callback port
335 * thread will signal *if* the SM will
336 * authorize us to bootstrap.
338 RtlInitUnicodeString (& Name
, L
"\\CsrssBooting");
339 InitializeObjectAttributes(& BootstrapOkAttributes
,
342 Status
= NtCreateEvent (& hBootstrapOk
,
344 & BootstrapOkAttributes
,
345 SynchronizationEvent
,
347 if(!NT_SUCCESS(Status
))
349 DPRINT("CSR: %s: NtCreateEvent failed (Status=0x%08lx)\n",
350 __FUNCTION__
, Status
);
354 * Let's tell the SM a new environment
355 * subsystem server is in the system.
357 RtlInitUnicodeString (& Name
, L
"\\Windows\\SbApiPort");
358 DPRINT("CSR: %s: registering with SM for\n IMAGE_SUBSYSTEM_WINDOWS_CUI == 3\n", __FUNCTION__
);
359 Status
= SmConnectApiPort (& Name
,
361 IMAGE_SUBSYSTEM_WINDOWS_CUI
,
363 if(!NT_SUCCESS(Status
))
365 DPRINT("CSR: %s unable to connect to the SM (Status=0x%08lx)\n",
366 __FUNCTION__
, Status
);
367 NtClose (hBootstrapOk
);
371 * Wait for SM to reply OK... If the SM
372 * won't answer, we hang here forever!
374 DPRINT("CSR: %s: waiting for SM to OK boot...\n", __FUNCTION__
);
375 Status
= NtWaitForSingleObject (hBootstrapOk
,
378 NtClose (hBootstrapOk
);
382 /**********************************************************************
383 * EnvpToUnicodeString/2
385 static ULONG FASTCALL
386 EnvpToUnicodeString (char ** envp
, PUNICODE_STRING UnicodeEnv
)
392 UnicodeEnv
->Buffer
= NULL
;
394 for (Index
=0; NULL
!= envp
[Index
]; Index
++)
396 CharCount
+= strlen (envp
[Index
]);
401 AnsiEnv
.Buffer
= RtlAllocateHeap (RtlGetProcessHeap(), 0, CharCount
);
402 if (NULL
!= AnsiEnv
.Buffer
)
405 PCHAR WritePos
= AnsiEnv
.Buffer
;
407 for (Index
=0; NULL
!= envp
[Index
]; Index
++)
409 strcpy (WritePos
, envp
[Index
]);
410 WritePos
+= strlen (envp
[Index
]) + 1;
413 /* FIXME: the last (double) nullterm should perhaps not be included in Length
414 * but only in MaximumLength. -Gunnar */
415 AnsiEnv
.Buffer
[CharCount
-1] = '\0';
416 AnsiEnv
.Length
= CharCount
;
417 AnsiEnv
.MaximumLength
= CharCount
;
419 RtlAnsiStringToUnicodeString (UnicodeEnv
, & AnsiEnv
, TRUE
);
420 RtlFreeHeap (RtlGetProcessHeap(), 0, AnsiEnv
.Buffer
);
424 /**********************************************************************
425 * CsrpLoadKernelModeDriver/3
428 CsrpLoadKernelModeDriver (int argc
, char ** argv
, char ** envp
)
430 NTSTATUS Status
= STATUS_SUCCESS
;
431 WCHAR Data
[MAX_PATH
+ 1];
432 ULONG DataLength
= sizeof Data
;
434 UNICODE_STRING Environment
;
437 DPRINT("SM: %s called\n", __FUNCTION__
);
440 EnvpToUnicodeString (envp
, & Environment
);
441 Status
= SmLookupSubsystem (L
"Kmode",
446 RtlFreeUnicodeString (& Environment
);
447 if((STATUS_SUCCESS
== Status
) && (DataLength
> sizeof Data
[0]))
449 WCHAR ImagePath
[MAX_PATH
+ 1] = {0};
450 UNICODE_STRING ModuleName
;
452 wcscpy (ImagePath
, L
"\\??\\");
453 wcscat (ImagePath
, Data
);
454 RtlInitUnicodeString (& ModuleName
, ImagePath
);
455 Status
= NtSetSystemInformation(/* FIXME: SystemLoadAndCallImage */
456 SystemExtendServiceTableInformation
,
459 if(!NT_SUCCESS(Status
))
461 DPRINT("WIN: %s: loading Kmode failed (Status=0x%08lx)\n",
462 __FUNCTION__
, Status
);
468 /**********************************************************************
469 * CsrpCreateApiPort/2
472 CsrpCreateApiPort (int argc
, char ** argv
, char ** envp
)
474 DPRINT("CSR: %s called\n", __FUNCTION__
);
476 return CsrpCreateListenPort (L
"\\Windows\\ApiPort",
478 ServerApiPortThread
);
481 /**********************************************************************
482 * CsrpApiRegisterDef/0
485 CsrpApiRegisterDef (int argc
, char ** argv
, char ** envp
)
487 return CsrApiRegisterDefinitions(NativeDefinitions
);
490 /**********************************************************************
494 CsrpCCTS (int argc
, char ** argv
, char ** envp
)
497 ULONG DummyLength
= sizeof(Dummy
);
498 return CsrClientConnectToServer(L
"\\Windows",
499 0, &Dummy
, &DummyLength
, NULL
);
502 /**********************************************************************
505 * Start the logon process (winlogon.exe).
507 * TODO: this should be moved in CsrpCreateSession/x (one per session)
508 * TODO: in its own desktop (one logon desktop per winstation).
511 CsrpRunWinlogon (int argc
, char ** argv
, char ** envp
)
513 NTSTATUS Status
= STATUS_SUCCESS
;
514 UNICODE_STRING ImagePath
;
515 UNICODE_STRING CommandLine
;
516 PRTL_USER_PROCESS_PARAMETERS ProcessParameters
= NULL
;
517 RTL_USER_PROCESS_INFORMATION ProcessInfo
;
520 DPRINT("CSR: %s called\n", __FUNCTION__
);
522 /* initialize the process parameters */
523 RtlInitUnicodeString (& ImagePath
, L
"\\SystemRoot\\system32\\winlogon.exe");
524 RtlInitUnicodeString (& CommandLine
, L
"");
525 RtlCreateProcessParameters(& ProcessParameters
,
535 /* Create the winlogon process */
536 Status
= RtlCreateUserProcess (& ImagePath
,
537 OBJ_CASE_INSENSITIVE
,
547 RtlDestroyProcessParameters (ProcessParameters
);
548 if (!NT_SUCCESS(Status
))
550 DPRINT1("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
551 __FUNCTION__
, Status
);
553 ZwResumeThread(ProcessInfo
.ThreadHandle
, NULL
);
559 typedef NTSTATUS (* CSR_INIT_ROUTINE
)(int,char**,char**);
563 CSR_INIT_ROUTINE EntryPoint
;
566 {TRUE
, CsrpCreateCallbackPort
, "create the callback port \\Windows\\SbApiPort"},
567 {TRUE
, CsrpRegisterSubsystem
, "register with SM"},
568 {TRUE
, CsrpCreateHeap
, "create the CSR heap"},
569 {TRUE
, CsrpCreateApiPort
, "create the api port \\Windows\\ApiPort"},
570 {TRUE
, CsrpCreateObjectDirectory
,"create the object directory \\Windows"},
571 {TRUE
, CsrpLoadKernelModeDriver
, "load Kmode driver"},
572 {TRUE
, CsrpInitVideo
, "initialize video"},
573 {TRUE
, CsrpApiRegisterDef
, "initialize api definitions"},
574 {TRUE
, CsrpCCTS
, "connect client to server"},
575 {TRUE
, CsrpInitWin32Csr
, "load usermode dll"},
576 {TRUE
, CsrpRunWinlogon
, "run WinLogon"},
579 /**********************************************************************
581 * CsrServerInitialization
584 * Initialize the Win32 environment subsystem server.
587 * TRUE: Initialization OK; otherwise FALSE.
590 CsrServerInitialization (
597 NTSTATUS Status
= STATUS_SUCCESS
;
599 DPRINT("CSR: %s called\n", __FUNCTION__
);
601 for (i
=0; i
< (sizeof InitRoutine
/ sizeof InitRoutine
[0]); i
++)
603 Status
= InitRoutine
[i
].EntryPoint(argc
,argv
,envp
);
604 if(!NT_SUCCESS(Status
))
606 DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n",
608 InitRoutine
[i
].ErrorMessage
,
610 if (InitRoutine
[i
].Required
)
616 if (CallInitComplete())
618 Status
= SmCompleteSession (hSmApiPort
,hSbApiPort
,hApiPort
);