Copy riched20
[reactos.git] / reactos / subsys / csrss / init.c
1 /* $Id$
2 *
3 * reactos/subsys/csrss/init.c
4 *
5 * Initialize the CSRSS subsystem server process.
6 *
7 * ReactOS Operating System
8 *
9 */
10
11 /* INCLUDES ******************************************************************/
12
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>
21
22 #include "api.h"
23 #include "csrplugin.h"
24
25 #define NDEBUG
26 #include <debug.h>
27
28 /* GLOBALS ******************************************************************/
29
30 HANDLE CsrInitEvent = INVALID_HANDLE_VALUE;
31 HANDLE CsrHeap = INVALID_HANDLE_VALUE;
32
33 HANDLE CsrObjectDirectory = INVALID_HANDLE_VALUE;
34
35 UNICODE_STRING CsrDirectoryName;
36
37 extern HANDLE CsrssApiHeap;
38
39 static unsigned InitCompleteProcCount;
40 static CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProcs = NULL;
41
42 static NTSTATUS FASTCALL
43 AddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc)
44 {
45 CSRPLUGIN_INIT_COMPLETE_PROC *NewProcs;
46
47 NewProcs = RtlAllocateHeap(CsrssApiHeap, 0,
48 (InitCompleteProcCount + 1)
49 * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC));
50 if (NULL == NewProcs)
51 {
52 return STATUS_NO_MEMORY;
53 }
54 if (0 != InitCompleteProcCount)
55 {
56 RtlCopyMemory(NewProcs, InitCompleteProcs,
57 InitCompleteProcCount * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC));
58 RtlFreeHeap(CsrssApiHeap, 0, InitCompleteProcs);
59 }
60 NewProcs[InitCompleteProcCount] = Proc;
61 InitCompleteProcs = NewProcs;
62 InitCompleteProcCount++;
63
64 return STATUS_SUCCESS;
65 }
66
67 static BOOL FASTCALL
68 CallInitComplete(void)
69 {
70 BOOL Ok;
71 unsigned i;
72
73 Ok = TRUE;
74 if (0 != InitCompleteProcCount)
75 {
76 for (i = 0; i < InitCompleteProcCount && Ok; i++)
77 {
78 Ok = (*(InitCompleteProcs[i]))();
79 }
80 RtlFreeHeap(CsrssApiHeap, 0, InitCompleteProcs);
81 }
82
83 return Ok;
84 }
85
86 ULONG
87 InitializeVideoAddressSpace(VOID);
88
89 static NTSTATUS
90 CsrParseCommandLine (
91 ULONG ArgumentCount,
92 PWSTR *ArgumentArray
93 )
94 {
95 NTSTATUS Status;
96 OBJECT_ATTRIBUTES Attributes;
97
98
99 /* DbgPrint ("Arguments: %ld\n", ArgumentCount);
100 for (i = 0; i < ArgumentCount; i++)
101 {
102 DbgPrint ("Argument %ld: %S\n", i, ArgumentArray[i]);
103 }*/
104
105
106 /* create object directory ('\Windows') */
107 RtlCreateUnicodeString (&CsrDirectoryName,
108 L"\\Windows");
109
110 InitializeObjectAttributes (&Attributes,
111 &CsrDirectoryName,
112 0,
113 NULL,
114 NULL);
115
116 Status = NtCreateDirectoryObject(&CsrObjectDirectory,
117 0xF000F,
118 &Attributes);
119
120 return Status;
121 }
122
123
124 static VOID
125 CsrInitVideo(VOID)
126 {
127 OBJECT_ATTRIBUTES ObjectAttributes;
128 UNICODE_STRING DeviceName;
129 IO_STATUS_BLOCK Iosb;
130 HANDLE VideoHandle;
131 NTSTATUS Status;
132
133 InitializeVideoAddressSpace();
134
135 RtlRosInitUnicodeStringFromLiteral(&DeviceName, L"\\??\\DISPLAY1");
136 InitializeObjectAttributes(&ObjectAttributes,
137 &DeviceName,
138 0,
139 NULL,
140 NULL);
141 Status = NtOpenFile(&VideoHandle,
142 FILE_ALL_ACCESS,
143 &ObjectAttributes,
144 &Iosb,
145 0,
146 0);
147 if (NT_SUCCESS(Status))
148 {
149 NtClose(VideoHandle);
150 }
151 }
152
153 static NTSTATUS FASTCALL
154 InitWin32Csr()
155 {
156 NTSTATUS Status;
157 UNICODE_STRING DllName;
158 HINSTANCE hInst;
159 ANSI_STRING ProcName;
160 CSRPLUGIN_INITIALIZE_PROC InitProc;
161 CSRSS_EXPORTED_FUNCS Exports;
162 PCSRSS_API_DEFINITION ApiDefinitions;
163 PCSRSS_OBJECT_DEFINITION ObjectDefinitions;
164 CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc;
165
166 RtlInitUnicodeString(&DllName, L"win32csr.dll");
167 Status = LdrLoadDll(NULL, 0, &DllName, (PVOID *) &hInst);
168 if (! NT_SUCCESS(Status))
169 {
170 return Status;
171 }
172 RtlInitAnsiString(&ProcName, "Win32CsrInitialization");
173 Status = LdrGetProcedureAddress(hInst, &ProcName, 0, (PVOID *) &InitProc);
174 if (! NT_SUCCESS(Status))
175 {
176 return Status;
177 }
178 Exports.CsrInsertObjectProc = CsrInsertObject;
179 Exports.CsrGetObjectProc = CsrGetObject;
180 Exports.CsrReleaseObjectProc = CsrReleaseObject;
181 if (! (*InitProc)(&ApiDefinitions, &ObjectDefinitions, &InitCompleteProc,
182 &Exports, CsrssApiHeap))
183 {
184 return STATUS_UNSUCCESSFUL;
185 }
186
187 Status = CsrApiRegisterDefinitions(ApiDefinitions);
188 if (! NT_SUCCESS(Status))
189 {
190 return Status;
191 }
192 Status = CsrRegisterObjectDefinitions(ObjectDefinitions);
193 if (! NT_SUCCESS(Status))
194 {
195 return Status;
196 }
197 if (NULL != InitCompleteProc)
198 {
199 Status = AddInitCompleteProc(InitCompleteProc);
200 }
201
202 return Status;
203 }
204
205 CSRSS_API_DEFINITION NativeDefinitions[] =
206 {
207 CSRSS_DEFINE_API(CSRSS_CREATE_PROCESS, CsrCreateProcess),
208 CSRSS_DEFINE_API(CSRSS_TERMINATE_PROCESS, CsrTerminateProcess),
209 CSRSS_DEFINE_API(CSRSS_CONNECT_PROCESS, CsrConnectProcess),
210 CSRSS_DEFINE_API(CSRSS_REGISTER_SERVICES_PROCESS, CsrRegisterServicesProcess),
211 CSRSS_DEFINE_API(CSRSS_GET_SHUTDOWN_PARAMETERS, CsrGetShutdownParameters),
212 CSRSS_DEFINE_API(CSRSS_SET_SHUTDOWN_PARAMETERS, CsrSetShutdownParameters),
213 CSRSS_DEFINE_API(CSRSS_GET_INPUT_HANDLE, CsrGetInputHandle),
214 CSRSS_DEFINE_API(CSRSS_GET_OUTPUT_HANDLE, CsrGetOutputHandle),
215 CSRSS_DEFINE_API(CSRSS_CLOSE_HANDLE, CsrCloseHandle),
216 CSRSS_DEFINE_API(CSRSS_VERIFY_HANDLE, CsrVerifyHandle),
217 CSRSS_DEFINE_API(CSRSS_DUPLICATE_HANDLE, CsrDuplicateHandle),
218 CSRSS_DEFINE_API(CSRSS_GET_INPUT_WAIT_HANDLE, CsrGetInputWaitHandle),
219 { 0, 0, 0, NULL }
220 };
221
222 /**********************************************************************
223 * NAME
224 * CsrpRegisterSubsystem/0
225 *
226 * DESCRIPTION
227 * Register CSRSS in the SM to manage IMAGE_SUBSYSTEM_WINDOWS_CUI
228 * processes (environment subsystem server).
229 *
230 * RETURN VALUE
231 * STATUS_SUCCESS on success.
232 */
233 static NTSTATUS FASTCALL
234 CsrpRegisterSubsystem(PHANDLE hSmApiPort)
235 {
236 NTSTATUS Status = STATUS_SUCCESS;
237 UNICODE_STRING SbApiPortName;
238
239 RtlInitUnicodeString (& SbApiPortName, L"\\Windows\\SbApiPort");
240 Status = SmConnectApiPort (& SbApiPortName,
241 (HANDLE)-1, //unused
242 IMAGE_SUBSYSTEM_WINDOWS_CUI,
243 hSmApiPort);
244 if(!NT_SUCCESS(Status))
245 {
246 DPRINT("CSR: unable to connect to the SM (Status=0x%lx)\n", Status);
247 return Status;
248 }
249 DisplayString(L"CSR: registered with SM\n");
250 return Status;
251 }
252
253
254 /**********************************************************************
255 * NAME
256 * CsrServerInitialization
257 *
258 * DESCRIPTION
259 * Create a directory object (\windows) and a named LPC port
260 * (\windows\ApiPort)
261 *
262 * RETURN VALUE
263 * TRUE: Initialization OK; otherwise FALSE.
264 */
265 BOOL
266 STDCALL
267 CsrServerInitialization (
268 ULONG ArgumentCount,
269 PWSTR *ArgumentArray
270 )
271 {
272 NTSTATUS Status;
273 HANDLE hSmApiPort = (HANDLE) 0;
274 OBJECT_ATTRIBUTES ObAttributes;
275 UNICODE_STRING PortName;
276 HANDLE ApiPortHandle;
277 // HANDLE hSbApiPort = (HANDLE) 0;
278
279 DisplayString(L"CSR: CsrServerInitialization\n");
280
281 Status = CsrpRegisterSubsystem(& hSmApiPort);
282 if (! NT_SUCCESS(Status))
283 {
284 DPRINT1("CSR: Unable to register subsystem (Status: %x)\n", Status);
285 return FALSE;
286 }
287
288 Status = CsrParseCommandLine (ArgumentCount, ArgumentArray);
289 if (! NT_SUCCESS(Status))
290 {
291 DPRINT1("CSR: Unable to parse the command line (Status: %x)\n", Status);
292 return FALSE;
293 }
294
295 CsrInitVideo();
296
297 CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE,
298 NULL,
299 65536,
300 65536,
301 NULL,
302 NULL);
303 if (CsrssApiHeap == NULL)
304 {
305 DPRINT1("CSR: Failed to create private heap, aborting\n");
306 return FALSE;
307 }
308
309 Status = CsrApiRegisterDefinitions(NativeDefinitions);
310 if (! NT_SUCCESS(Status))
311 {
312 return Status;
313 }
314
315 /* NEW NAMED PORT: \Windows\ApiPort */
316 RtlRosInitUnicodeStringFromLiteral(&PortName, L"\\Windows\\ApiPort");
317 InitializeObjectAttributes(&ObAttributes,
318 &PortName,
319 0,
320 NULL,
321 NULL);
322 Status = NtCreatePort(&ApiPortHandle,
323 &ObAttributes,
324 260,
325 328,
326 0);
327 if (! NT_SUCCESS(Status))
328 {
329 DPRINT1("CSR: Unable to create \\Windows\\ApiPort (Status %x)\n", Status);
330 return FALSE;
331 }
332 Status = RtlCreateUserThread(NtCurrentProcess(),
333 NULL,
334 FALSE,
335 0,
336 NULL,
337 NULL,
338 (PTHREAD_START_ROUTINE)ServerApiPortThread,
339 ApiPortHandle,
340 NULL,
341 NULL);
342 if (! NT_SUCCESS(Status))
343 {
344 DPRINT1("CSR: Unable to create server thread\n");
345 NtClose(ApiPortHandle);
346 return FALSE;
347 }
348
349 /* TODO: create \Windows\SbApiPort */
350
351 Status = CsrClientConnectToServer();
352 if (!NT_SUCCESS(Status))
353 {
354 DPRINT1("CsrClientConnectToServer() failed (Status %x)\n", Status);
355 return FALSE;
356 }
357 Status = InitWin32Csr();
358 if (! NT_SUCCESS(Status))
359 {
360 DPRINT1("CSR: Unable to load usermode dll (Status %x)\n", Status);
361 return FALSE;
362 }
363
364 if (CallInitComplete())
365 {
366 #if 0
367 Status = SmCompleteSession (hSmApiPort,hSbApiPort,ApiPortHandle);
368 #endif
369 NtClose (hSmApiPort);
370 return TRUE;
371 }
372 return FALSE;
373 }
374
375 /* EOF */