0b66dd58cd9c51abb9df2e5f0effdd805f3963b7
[reactos.git] / reactos / subsys / csr / csrsrv / server.c
1 /* $Id$
2 *
3 * subsys/csr/csrsrv/server.c - CSR server - subsystem default server
4 *
5 * ReactOS Operating System
6 *
7 * --------------------------------------------------------------------
8 *
9 * This software is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This software is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this software; see the file COPYING.LIB. If not, write
21 * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
22 * MA 02139, USA.
23 *
24 * --------------------------------------------------------------------
25 */
26 #include "srv.h"
27
28 //#define NDEBUG
29 #include <debug.h>
30
31 typedef NTSTATUS (STDCALL * CSR_SERVER_DLL_INIT_PROC)(ULONG,LPWSTR*);
32
33 typedef struct _CSRSRV_SERVER_DLL
34 {
35 USHORT ServerIndex;
36 USHORT Sequence; // initialization order
37 UNICODE_STRING DllName;
38 UNICODE_STRING DllEntryPoint;
39 CSR_SERVER_THREAD ServerThread; // NULL ==> inactive
40
41 } CSRSRV_SERVER_DLL, *PCSRSRV_SERVER_DLL;
42
43 /*=====================================================================
44 * GLOBALS
45 *===================================================================*/
46
47 CSRSRV_OPTION CsrSrvOption;
48
49 HANDLE CsrSrvApiPortHandle = (HANDLE) 0;
50
51 /*=====================================================================
52 * LOCALS
53 *===================================================================*/
54
55 static HANDLE CsrSrvSbApiPortHandle = (HANDLE) 0;
56
57 static CSRSRV_SERVER_DLL ServerThread [CSR_SERVER_DLL_MAX];
58
59 VOID CALLBACK CsrSrvServerThread (PVOID);
60
61 /**********************************************************************
62 * CsrSrvRegisterServerDll/1
63 */
64 NTSTATUS STDCALL CsrSrvRegisterServerDll (PCSR_SERVER_DLL pServerDll)
65 {
66 static USHORT NextInSequence = 0;
67 USHORT ServerIndex = 0;
68
69 // 1st call?
70 if (0 == NextInSequence)
71 {
72 RtlZeroMemory (ServerThread, sizeof ServerThread);
73 }
74 // We can not register more than CSR_SERVER_DLL_MAX servers.
75 // Note: # servers >= # DLLs (MS Win32 has 3 servers in 2 DLLs).
76 if (NextInSequence >= CSR_SERVER_DLL_MAX)
77 {
78 return STATUS_NO_MEMORY;
79 }
80 // Validate the ServerIndex from the command line:
81 // it may be 0, 1, 2, or 3.
82 ServerIndex = pServerDll->ServerIndex;
83 if (ServerIndex >= CSR_SERVER_DLL_MAX)
84 {
85 return STATUS_INVALID_PARAMETER;
86 }
87 // Register the DLL server.
88 ServerThread [ServerIndex].ServerIndex = ServerIndex;
89 ServerThread [ServerIndex].Sequence = NextInSequence ++;
90 if (0 != ServerIndex)
91 {
92 RtlDuplicateUnicodeString (1, & pServerDll->DllName, & ServerThread [ServerIndex].DllName);
93 RtlDuplicateUnicodeString (1, & pServerDll->DllEntryPoint, & ServerThread [ServerIndex].DllEntryPoint);
94 } else {
95 // CSRSRV.DLL own static server thread
96 ServerThread [ServerIndex].ServerThread = CsrSrvServerThread;
97 }
98 return STATUS_SUCCESS;
99 }
100 /**********************************************************************
101 * CsrSrvInitializeServerDll/1 PRIVATE
102 *
103 * NOTE
104 * Code dapted from CsrpInitWin32Csr.
105 */
106 static NTSTATUS CsrSrvInitializeServerDll (USHORT ServerIndex)
107 {
108 NTSTATUS Status = STATUS_SUCCESS;
109 HINSTANCE hInst;
110 ANSI_STRING ProcName;
111 CSR_SERVER_DLL_INIT_PROC InitProc;
112
113 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
114
115 Status = LdrLoadDll (NULL, 0, & ServerThread[ServerIndex].DllName, (PVOID *) &hInst);
116 if (!NT_SUCCESS(Status))
117 {
118 DPRINT1("CSRSRV:%s: loading ServerDll '%S' failed (Status=%08lx)\n",
119 __FUNCTION__, ServerThread[ServerIndex].DllName.Buffer, Status);
120 return Status;
121 }
122 RtlInitAnsiString (& ProcName, "ServerDllInitialization");
123 Status = LdrGetProcedureAddress(hInst, &ProcName, 0, (PVOID *) &InitProc);
124 if (!NT_SUCCESS(Status))
125 {
126 DPRINT1("CSRSRV:%s: ServerDll '%S!%s' not found (Status=%08lx)\n",
127 __FUNCTION__,
128 ServerThread[ServerIndex].DllName.Buffer,
129 "ServerDllInitialization",
130 Status);
131 return Status;
132 }
133 Status = InitProc (0, NULL);
134 if (!NT_SUCCESS(Status))
135 {
136 DPRINT1("CSRSRV:%s: %S.%s failed with Status=%08lx\n",
137 __FUNCTION__,
138 ServerThread[ServerIndex].DllName.Buffer,
139 "ServerDllInitialization",
140 Status);
141 }
142 return Status;
143 }
144
145 /**********************************************************************
146 * CsrpCreateObjectDirectory/1 PRIVATE
147 */
148 NTSTATUS STDCALL CsrpCreateObjectDirectory (PUNICODE_STRING pObjectDirectory)
149 {
150 NTSTATUS Status = STATUS_SUCCESS;
151 OBJECT_ATTRIBUTES DirectoryAttributes;
152
153 DPRINT("CSRSRV:%s(%S) called\n", __FUNCTION__, pObjectDirectory->Buffer);
154
155 InitializeObjectAttributes (& DirectoryAttributes,
156 pObjectDirectory,
157 OBJ_OPENIF,
158 NULL,
159 NULL);
160
161 Status = NtCreateDirectoryObject (& CsrSrvOption.NameSpace.RootHandle,
162 (DIRECTORY_CREATE_OBJECT|DIRECTORY_CREATE_SUBDIRECTORY),
163 & DirectoryAttributes);
164 if (NT_SUCCESS(Status))
165 {
166 Status = RtlDuplicateUnicodeString (0, pObjectDirectory, & CsrSrvOption.NameSpace.Root);
167 if (!NT_SUCCESS(Status))
168 {
169 DPRINT1("CSRSRV:%s: RtlDuplicateUnicodeString failed (Status=0x%08lx)\n",
170 __FUNCTION__, Status);
171 }
172 } else {
173 DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
174 __FUNCTION__, Status);
175 }
176 return Status;
177 }
178 /**********************************************************************
179 * CsrSrvBootstrap/0
180 *
181 * DESCRIPTION
182 * This is where a subsystem begins living.
183 */
184 NTSTATUS STDCALL CsrSrvBootstrap (VOID)
185 {
186 NTSTATUS Status = STATUS_SUCCESS;
187 ULONG ServerIndex = 0;
188 ULONG ServerSequence = 0;
189
190 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
191
192 CsrSrvSbApiPortHandle = CsrSrvSbApiPortHandle; //FIXME
193
194 // OBJECT DIRECTORY
195 Status = CsrpCreateObjectDirectory (& CsrSrvOption.NameSpace.Root);
196 if(!NT_SUCCESS(Status))
197 {
198 DPRINT1("CSRSRV:%s: CsrpCreateObjectDirectory failed (Status=%08lx)\n",
199 __FUNCTION__, Status);
200 return Status;
201 }
202 // SESSIONS
203 Status = CsrSrvInitializeSession ();
204 if(!NT_SUCCESS(Status))
205 {
206 DPRINT1("CSRSRV:%s: CsrSrvInitializeSession failed (Status=%08lx)\n",
207 __FUNCTION__, Status);
208 return Status;
209 }
210 // PROCESSES
211 // TODO
212 // THREADS
213 // TODO
214 // WAITS
215 // TODO
216 // Hosted servers
217 for (ServerSequence = 0; ServerSequence < CSR_SERVER_DLL_MAX; ServerSequence ++)
218 {
219 for (ServerIndex = 0; (ServerIndex < CSR_SERVER_DLL_MAX); ++ ServerIndex)
220 {
221 if (ServerSequence == ServerThread [ServerIndex].Sequence)
222 {
223 if (NULL == ServerThread [ServerIndex].ServerThread)
224 {
225 Status = CsrSrvInitializeServerDll (ServerIndex);
226 if (!NT_SUCCESS(Status))
227 {
228 DPRINT1("CSRSRV:%s: server thread #%d init failed!\n",
229 __FUNCTION__, ServerIndex);
230 }
231 } else {
232 DPRINT1("CSRSRV:%s: server thread #%d initialized more than once!\n",
233 __FUNCTION__, ServerIndex);
234 }
235 }
236 }
237 }
238 return Status;
239 }
240 /**********************************************************************
241 * CsrSrvServerThread/1
242 *
243 * DESCRIPTION
244 * This is actually a function called by the CsrSrvMainServerThread
245 * when the server index is 0. Other server DLLs register their
246 * function with CsrAddStaticServerThread.
247 */
248 VOID STDCALL CsrSrvServerThread (PVOID x)
249 {
250 NTSTATUS Status = STATUS_SUCCESS;
251 PPORT_MESSAGE Request = (PPORT_MESSAGE) x;
252 PPORT_MESSAGE Reply = NULL;
253 ULONG MessageType = 0;
254
255 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
256
257 MessageType = Request->u2.s2.Type;
258 DPRINT("CSRSRV: %s received a message (Type=%d)\n",
259 __FUNCTION__, MessageType);
260 switch (MessageType)
261 {
262 //TODO
263 default:
264 Reply = Request;
265 Status = NtReplyPort (CsrSrvApiPortHandle, Reply);
266 break;
267 }
268 }
269
270 /**********************************************************************
271 * PUBLIC API
272 *********************************************************************/
273
274 /**********************************************************************
275 * CsrAddStaticServerThread/1
276 */
277 NTSTATUS STDCALL CsrAddStaticServerThread (CSR_SERVER_THREAD ServerThread)
278 {
279 static ULONG StaticServerThreadCount = 0;
280 NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
281
282 DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, ServerThread);
283
284 if (StaticServerThreadCount > CSR_SERVER_DLL_MAX)
285 {
286 DPRINT1("CSRSRV: subsystem tries to add mode than %d static threads!\n",
287 CSR_SERVER_DLL_MAX);
288 return STATUS_NO_MEMORY;
289 }
290 if (NT_SUCCESS(Status))
291 {
292 // FIXME: do we need to make it reentrant?
293 ++ StaticServerThreadCount;
294 }
295 return Status;
296 }
297
298 /**********************************************************************
299 * CsrCallServerFromServer
300 */
301 NTSTATUS STDCALL CsrCallServerFromServer ()
302 {
303 NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
304
305 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
306 return Status;
307 }
308
309 /**********************************************************************
310 * CsrExecServerThread
311 */
312 NTSTATUS STDCALL CsrExecServerThread ()
313 {
314 NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
315
316 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
317 return Status;
318 }
319
320 /**********************************************************************
321 * CsrImpersonateClient
322 */
323 NTSTATUS STDCALL CsrImpersonateClient ()
324 {
325 NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
326
327 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
328 return Status;
329 }
330
331 /**********************************************************************
332 * CsrQueryApiPort/0
333 *
334 * @implemented
335 */
336 HANDLE STDCALL CsrQueryApiPort (VOID)
337 {
338 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
339 return CsrSrvApiPortHandle;
340 }
341
342 /**********************************************************************
343 * CsrRevertToSelf
344 */
345 NTSTATUS STDCALL CsrRevertToSelf ()
346 {
347 NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
348
349 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
350 return Status;
351 }
352
353 /**********************************************************************
354 * CsrSetBackgroundPriority
355 */
356 NTSTATUS STDCALL CsrSetBackgroundPriority ()
357 {
358 NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
359
360 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
361 return Status;
362 }
363
364 /**********************************************************************
365 * CsrSetCallingSpooler
366 */
367 NTSTATUS STDCALL CsrSetCallingSpooler ()
368 {
369 NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
370
371 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
372 return Status;
373 }
374
375 /**********************************************************************
376 * CsrSetForegroundPriority
377 */
378 NTSTATUS STDCALL CsrSetForegroundPriority ()
379 {
380 NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
381
382 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
383 return Status;
384 }
385
386 /**********************************************************************
387 * CsrUnhandledExceptionFilter
388 */
389 NTSTATUS STDCALL CsrUnhandledExceptionFilter ()
390 {
391 NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
392
393 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
394 return Status;
395 }
396
397 /**********************************************************************
398 * CsrValidateMessageBuffer
399 */
400 NTSTATUS STDCALL CsrValidateMessageBuffer ()
401 {
402 NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
403
404 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
405 return Status;
406 }
407
408 /**********************************************************************
409 * CsrValidateMessageString
410 */
411 NTSTATUS STDCALL CsrValidateMessageString ()
412 {
413 NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
414
415 DPRINT("CSRSRV: %s called\n", __FUNCTION__);
416 return Status;
417 }
418
419 /* EOF */