- get csrss, ntvdm, smss compiling on msvc.
[reactos.git] / reactos / subsys / csrss / api / wapi.c
1 /* $Id$
2 *
3 * reactos/subsys/csrss/api/wapi.c
4 *
5 * CSRSS port message processing
6 *
7 * ReactOS Operating System
8 *
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <csrss.h>
14
15 #define NDEBUG
16
17 #define NDEBUG
18 #include <debug.h>
19
20 /* GLOBALS *******************************************************************/
21
22 HANDLE CsrssApiHeap = (HANDLE) 0;
23
24 static unsigned ApiDefinitionsCount = 0;
25 static PCSRSS_API_DEFINITION ApiDefinitions = NULL;
26
27 /* FUNCTIONS *****************************************************************/
28
29 NTSTATUS FASTCALL
30 CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions)
31 {
32 unsigned NewCount;
33 PCSRSS_API_DEFINITION Scan;
34 PCSRSS_API_DEFINITION New;
35
36 DPRINT("CSR: %s called", __FUNCTION__);
37
38 NewCount = 0;
39 for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++)
40 {
41 NewCount++;
42 }
43
44 New = RtlAllocateHeap(CsrssApiHeap, 0,
45 (ApiDefinitionsCount + NewCount)
46 * sizeof(CSRSS_API_DEFINITION));
47 if (NULL == New)
48 {
49 DPRINT1("Unable to allocate memory\n");
50 return STATUS_NO_MEMORY;
51 }
52 if (0 != ApiDefinitionsCount)
53 {
54 RtlCopyMemory(New, ApiDefinitions,
55 ApiDefinitionsCount * sizeof(CSRSS_API_DEFINITION));
56 RtlFreeHeap(CsrssApiHeap, 0, ApiDefinitions);
57 }
58 RtlCopyMemory(New + ApiDefinitionsCount, NewDefinitions,
59 NewCount * sizeof(CSRSS_API_DEFINITION));
60 ApiDefinitions = New;
61 ApiDefinitionsCount += NewCount;
62
63 return STATUS_SUCCESS;
64 }
65
66 VOID
67 FASTCALL
68 CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData,
69 PCSR_API_MESSAGE Request)
70 {
71 BOOL Found = FALSE;
72 unsigned DefIndex;
73 ULONG Type;
74
75 DPRINT("CSR: Calling handler for type: %x.\n", Request->Type);
76 Type = Request->Type & 0xFFFF; /* FIXME: USE MACRO */
77 DPRINT("CSR: API Number: %x ServerID: %x\n",Type, Request->Type >> 16);
78
79 /* FIXME: Extract DefIndex instead of looping */
80 for (DefIndex = 0; ! Found && DefIndex < ApiDefinitionsCount; DefIndex++)
81 {
82 if (ApiDefinitions[DefIndex].Type == Type)
83 {
84 if (Request->Header.u1.s1.DataLength < ApiDefinitions[DefIndex].MinRequestSize)
85 {
86 DPRINT1("Request type %d min request size %d actual %d\n",
87 Type, ApiDefinitions[DefIndex].MinRequestSize,
88 Request->Header.u1.s1.DataLength);
89 Request->Status = STATUS_INVALID_PARAMETER;
90 }
91 else
92 {
93 (ApiDefinitions[DefIndex].Handler)(ProcessData, Request);
94 Found = TRUE;
95 }
96 }
97 }
98 if (! Found)
99 {
100 DPRINT1("CSR: Unknown request type 0x%x\n", Request->Type);
101 Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
102 Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
103 Request->Status = STATUS_INVALID_SYSTEM_SERVICE;
104 }
105 }
106
107 static
108 VOID
109 STDCALL
110 ClientConnectionThread(HANDLE ServerPort)
111 {
112 NTSTATUS Status;
113 BYTE RawRequest[LPC_MAX_DATA_LENGTH];
114 PCSR_API_MESSAGE Request = (PCSR_API_MESSAGE)RawRequest;
115 PCSR_API_MESSAGE Reply;
116 PCSRSS_PROCESS_DATA ProcessData;
117
118 DPRINT("CSR: %s called", __FUNCTION__);
119
120 /* Reply must be NULL at the first call to NtReplyWaitReceivePort */
121 Reply = NULL;
122
123 /* Loop and reply/wait for a new message */
124 for (;;)
125 {
126 /* Send the reply and wait for a new request */
127 Status = NtReplyWaitReceivePort(ServerPort,
128 0,
129 &Reply->Header,
130 &Request->Header);
131 if (!NT_SUCCESS(Status))
132 {
133 DPRINT1("NtReplyWaitReceivePort failed\n");
134 break;
135 }
136
137 /* If the connection was closed, handle that */
138 if (Request->Header.u2.s2.Type == LPC_PORT_CLOSED)
139 {
140 CsrFreeProcessData( Request->Header.ClientId.UniqueProcess );
141 break;
142 }
143
144 DPRINT("CSR: Got CSR API: %x [Message Origin: %x]\n",
145 Request->Type,
146 Request->Header.ClientId.UniqueProcess);
147
148 /* Get the Process Data */
149 ProcessData = CsrGetProcessData(Request->Header.ClientId.UniqueProcess);
150 if (ProcessData == NULL)
151 {
152 DPRINT1("Message %d: Unable to find data for process 0x%x\n",
153 Request->Header.u2.s2.Type,
154 Request->Header.ClientId.UniqueProcess);
155 break;
156 }
157 if (ProcessData->Terminated)
158 {
159 DPRINT1("Message %d: process %d already terminated\n",
160 Request->Type, (ULONG)Request->Header.ClientId.UniqueProcess);
161 continue;
162 }
163
164 /* Call the Handler */
165 CsrApiCallHandler(ProcessData, Request);
166
167 /* Send back the reply */
168 Reply = Request;
169 }
170
171 /* Close the port and exit the thread */
172 NtClose(ServerPort);
173 RtlExitUserThread(STATUS_SUCCESS);
174 }
175
176 /**********************************************************************
177 * NAME
178 * ServerApiPortThread/1
179 *
180 * DESCRIPTION
181 * Handle connection requests from clients to the port
182 * "\Windows\ApiPort".
183 */
184 DWORD STDCALL
185 ServerApiPortThread (PVOID PortHandle)
186 {
187 NTSTATUS Status = STATUS_SUCCESS;
188 BYTE RawRequest[sizeof(PORT_MESSAGE) + sizeof(CSR_CONNECTION_INFO)];
189 PPORT_MESSAGE Request = (PPORT_MESSAGE)RawRequest;
190 HANDLE hApiListenPort = * (PHANDLE) PortHandle;
191 HANDLE ServerPort = (HANDLE) 0;
192 HANDLE ServerThread = (HANDLE) 0;
193 PCSRSS_PROCESS_DATA ProcessData = NULL;
194
195 CsrInitProcessData();
196
197 DPRINT("CSR: %s called", __FUNCTION__);
198
199 for (;;)
200 {
201 REMOTE_PORT_VIEW LpcRead;
202 ServerPort = NULL;
203
204 Status = NtListenPort (hApiListenPort, Request);
205 if (!NT_SUCCESS(Status))
206 {
207 DPRINT1("CSR: NtListenPort() failed, status=%x\n", Status);
208 break;
209 }
210 Status = NtAcceptConnectPort(& ServerPort,
211 hApiListenPort,
212 NULL,
213 TRUE,
214 0,
215 & LpcRead);
216 if (!NT_SUCCESS(Status))
217 {
218 DPRINT1("CSR: NtAcceptConnectPort() failed\n");
219 break;
220 }
221
222 ProcessData = CsrCreateProcessData(Request->ClientId.UniqueProcess);
223 if (ProcessData == NULL)
224 {
225 DPRINT1("Unable to allocate or find data for process 0x%x\n",
226 Request->ClientId.UniqueProcess);
227 Status = STATUS_UNSUCCESSFUL;
228 break;
229 }
230
231
232 ProcessData->CsrSectionViewBase = LpcRead.ViewBase;
233 ProcessData->CsrSectionViewSize = LpcRead.ViewSize;
234
235 Status = NtCompleteConnectPort(ServerPort);
236 if (!NT_SUCCESS(Status))
237 {
238 DPRINT1("CSR: NtCompleteConnectPort() failed\n");
239 break;
240 }
241
242 Status = RtlCreateUserThread(NtCurrentProcess(),
243 NULL,
244 FALSE,
245 0,
246 0,
247 0,
248 (PTHREAD_START_ROUTINE)ClientConnectionThread,
249 ServerPort,
250 & ServerThread,
251 NULL);
252 if (!NT_SUCCESS(Status))
253 {
254 DPRINT1("CSR: Unable to create server thread\n");
255 break;
256 }
257 NtClose(ServerThread);
258 }
259 if (ServerPort)
260 {
261 NtClose(ServerPort);
262 }
263 NtClose(PortHandle);
264 NtTerminateThread(NtCurrentThread(), Status);
265 return 0;
266 }
267
268 /**********************************************************************
269 * NAME
270 * ServerSbApiPortThread/1
271 *
272 * DESCRIPTION
273 * Handle connection requests from SM to the port
274 * "\Windows\SbApiPort". We will accept only one
275 * connection request (from the SM).
276 */
277 DWORD STDCALL
278 ServerSbApiPortThread (PVOID PortHandle)
279 {
280 HANDLE hSbApiPortListen = * (PHANDLE) PortHandle;
281 HANDLE hConnectedPort = (HANDLE) 0;
282 PORT_MESSAGE Request;
283 PVOID Context = NULL;
284 NTSTATUS Status = STATUS_SUCCESS;
285 PPORT_MESSAGE Reply = NULL;
286
287 DPRINT("CSR: %s called\n", __FUNCTION__);
288
289 RtlZeroMemory(&Request, sizeof(PORT_MESSAGE));
290 Status = NtListenPort (hSbApiPortListen, & Request);
291 if (!NT_SUCCESS(Status))
292 {
293 DPRINT1("CSR: %s: NtListenPort(SB) failed (Status=0x%08lx)\n",
294 __FUNCTION__, Status);
295 } else {
296 DPRINT("-- 1\n");
297 Status = NtAcceptConnectPort (& hConnectedPort,
298 hSbApiPortListen,
299 NULL,
300 TRUE,
301 NULL,
302 NULL);
303 if(!NT_SUCCESS(Status))
304 {
305 DPRINT1("CSR: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
306 __FUNCTION__, Status);
307 } else {
308 DPRINT("-- 2\n");
309 Status = NtCompleteConnectPort (hConnectedPort);
310 if(!NT_SUCCESS(Status))
311 {
312 DPRINT1("CSR: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
313 __FUNCTION__, Status);
314 } else {
315 DPRINT("-- 3\n");
316
317 /*
318 * Tell the init thread the SM gave the
319 * green light for boostrapping.
320 */
321 Status = NtSetEvent (hBootstrapOk, NULL);
322 if(!NT_SUCCESS(Status))
323 {
324 DPRINT1("CSR: %s: NtSetEvent failed (Status=0x%08lx)\n",
325 __FUNCTION__, Status);
326 }
327 /* Wait for messages from the SM */
328 DPRINT("-- 4\n");
329 while (TRUE)
330 {
331 Status = NtReplyWaitReceivePort(hConnectedPort,
332 Context,
333 Reply,
334 & Request);
335 if(!NT_SUCCESS(Status))
336 {
337 DPRINT1("CSR: %s: NtReplyWaitReceivePort failed (Status=0x%08lx)\n",
338 __FUNCTION__, Status);
339 break;
340 }
341 switch (Request.u2.s2.Type)//fix .h PORT_MESSAGE_TYPE(Request))
342 {
343 /* TODO */
344 default:
345 DPRINT1("CSR: %s received message (type=%d)\n",
346 __FUNCTION__, Request.u2.s2.Type);
347 }
348 DPRINT("-- 5\n");
349 }
350 }
351 }
352 }
353 DPRINT1("CSR: %s: terminating!\n", __FUNCTION__);
354 if(hConnectedPort) NtClose (hConnectedPort);
355 NtClose (hSbApiPortListen);
356 NtTerminateThread (NtCurrentThread(), Status);
357 return 0;
358 }
359
360 /* EOF */