3 * reactos/subsys/csrss/api/wapi.c
5 * CSRSS port message processing
7 * ReactOS Operating System
11 /* INCLUDES ******************************************************************/
20 /* GLOBALS *******************************************************************/
22 extern HANDLE hApiPort
;
24 HANDLE CsrssApiHeap
= (HANDLE
) 0;
26 static unsigned ApiDefinitionsCount
= 0;
27 static PCSRSS_API_DEFINITION ApiDefinitions
= NULL
;
29 /* FUNCTIONS *****************************************************************/
32 CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions
)
35 PCSRSS_API_DEFINITION Scan
;
36 PCSRSS_API_DEFINITION New
;
38 DPRINT("CSR: %s called\n", __FUNCTION__
);
41 for (Scan
= NewDefinitions
; 0 != Scan
->Handler
; Scan
++)
46 New
= RtlAllocateHeap(CsrssApiHeap
, 0,
47 (ApiDefinitionsCount
+ NewCount
)
48 * sizeof(CSRSS_API_DEFINITION
));
51 DPRINT1("Unable to allocate memory\n");
52 return STATUS_NO_MEMORY
;
54 if (0 != ApiDefinitionsCount
)
56 RtlCopyMemory(New
, ApiDefinitions
,
57 ApiDefinitionsCount
* sizeof(CSRSS_API_DEFINITION
));
58 RtlFreeHeap(CsrssApiHeap
, 0, ApiDefinitions
);
60 RtlCopyMemory(New
+ ApiDefinitionsCount
, NewDefinitions
,
61 NewCount
* sizeof(CSRSS_API_DEFINITION
));
63 ApiDefinitionsCount
+= NewCount
;
65 return STATUS_SUCCESS
;
70 CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData
,
71 PCSR_API_MESSAGE Request
)
77 DPRINT("CSR: Calling handler for type: %x.\n", Request
->Type
);
78 Type
= Request
->Type
& 0xFFFF; /* FIXME: USE MACRO */
79 DPRINT("CSR: API Number: %x ServerID: %x\n",Type
, Request
->Type
>> 16);
81 /* FIXME: Extract DefIndex instead of looping */
82 for (DefIndex
= 0; ! Found
&& DefIndex
< ApiDefinitionsCount
; DefIndex
++)
84 if (ApiDefinitions
[DefIndex
].Type
== Type
)
86 if (Request
->Header
.u1
.s1
.DataLength
< ApiDefinitions
[DefIndex
].MinRequestSize
)
88 DPRINT1("Request type %d min request size %d actual %d\n",
89 Type
, ApiDefinitions
[DefIndex
].MinRequestSize
,
90 Request
->Header
.u1
.s1
.DataLength
);
91 Request
->Status
= STATUS_INVALID_PARAMETER
;
95 (ApiDefinitions
[DefIndex
].Handler
)(ProcessData
, Request
);
102 DPRINT1("CSR: Unknown request type 0x%x\n", Request
->Type
);
103 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
104 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
105 Request
->Status
= STATUS_INVALID_SYSTEM_SERVICE
;
110 CallHardError(IN PCSRSS_PROCESS_DATA ProcessData
,
111 IN PHARDERROR_MSG HardErrorMessage
);
116 CsrHandleHardError(IN PCSRSS_PROCESS_DATA ProcessData
,
117 IN OUT PHARDERROR_MSG Message
)
119 DPRINT1("CSR: received hard error %lx\n", Message
->Status
);
121 /* Call the hard error handler in win32csr */
122 (VOID
)CallHardError(ProcessData
, Message
);
126 CsrpHandleConnectionRequest (PPORT_MESSAGE Request
,
127 IN HANDLE hApiListenPort
)
130 HANDLE ServerPort
= (HANDLE
) 0;
131 PCSRSS_PROCESS_DATA ProcessData
= NULL
;
132 REMOTE_PORT_VIEW LpcRead
;
133 LpcRead
.Length
= sizeof(LpcRead
);
136 DPRINT("CSR: %s: Handling: %p\n", __FUNCTION__
, Request
);
138 Status
= NtAcceptConnectPort(&ServerPort
,
144 if (!NT_SUCCESS(Status
))
146 DPRINT1("CSR: NtAcceptConnectPort() failed\n");
150 ProcessData
= CsrGetProcessData(Request
->ClientId
.UniqueProcess
);
151 if (ProcessData
== NULL
)
153 ProcessData
= CsrCreateProcessData(Request
->ClientId
.UniqueProcess
);
154 if (ProcessData
== NULL
)
156 DPRINT1("Unable to allocate or find data for process 0x%x\n",
157 Request
->ClientId
.UniqueProcess
);
158 Status
= STATUS_UNSUCCESSFUL
;
163 ProcessData
->CsrSectionViewBase
= LpcRead
.ViewBase
;
164 ProcessData
->CsrSectionViewSize
= LpcRead
.ViewSize
;
165 ProcessData
->ServerCommunicationPort
= ServerPort
;
167 Status
= NtCompleteConnectPort(ServerPort
);
168 if (!NT_SUCCESS(Status
))
170 DPRINT1("CSR: NtCompleteConnectPort() failed\n");
174 HANDLE ServerThread
= (HANDLE
) 0;
175 Status
= RtlCreateUserThread(NtCurrentProcess(),
181 (PTHREAD_START_ROUTINE
)ClientConnectionThread
,
185 if (!NT_SUCCESS(Status
))
187 DPRINT1("CSR: Unable to create server thread\n");
191 NtClose(ServerThread
);
193 Status
= STATUS_SUCCESS
;
194 DPRINT("CSR: %s done\n", __FUNCTION__
);
200 ClientConnectionThread(HANDLE ServerPort
)
203 BYTE RawRequest
[LPC_MAX_DATA_LENGTH
];
204 PCSR_API_MESSAGE Request
= (PCSR_API_MESSAGE
)RawRequest
;
205 PCSR_API_MESSAGE Reply
;
206 PCSRSS_PROCESS_DATA ProcessData
;
208 DPRINT("CSR: %s called\n", __FUNCTION__
);
210 /* Reply must be NULL at the first call to NtReplyWaitReceivePort */
213 /* Loop and reply/wait for a new message */
216 /* Send the reply and wait for a new request */
217 Status
= NtReplyWaitReceivePort(hApiPort
,
221 /* Client died, continue */
222 if (Status
== STATUS_INVALID_CID
)
228 if (!NT_SUCCESS(Status
))
230 DPRINT1("NtReplyWaitReceivePort failed: %lx\n", Status
);
234 /* If the connection was closed, handle that */
235 if (Request
->Header
.u2
.s2
.Type
== LPC_PORT_CLOSED
)
237 DPRINT("Port died, oh well\n");
238 CsrFreeProcessData( Request
->Header
.ClientId
.UniqueProcess
);
242 if (Request
->Header
.u2
.s2
.Type
== LPC_CONNECTION_REQUEST
)
244 CsrpHandleConnectionRequest((PPORT_MESSAGE
)Request
, ServerPort
);
249 if (Request
->Header
.u2
.s2
.Type
== LPC_CLIENT_DIED
)
251 DPRINT("Client died, oh well\n");
256 if ((Request
->Header
.u2
.s2
.Type
!= LPC_ERROR_EVENT
) &&
257 (Request
->Header
.u2
.s2
.Type
!= LPC_REQUEST
))
259 DPRINT1("CSR: received message %d\n", Request
->Header
.u2
.s2
.Type
);
264 DPRINT("CSR: Got CSR API: %x [Message Origin: %x]\n",
266 Request
->Header
.ClientId
.UniqueThread
);
268 /* Get the Process Data */
269 ProcessData
= CsrGetProcessData(Request
->Header
.ClientId
.UniqueProcess
);
270 if (ProcessData
== NULL
)
272 DPRINT1("Message %d: Unable to find data for process 0x%x\n",
273 Request
->Header
.u2
.s2
.Type
,
274 Request
->Header
.ClientId
.UniqueProcess
);
277 if (ProcessData
->Terminated
)
279 DPRINT1("Message %d: process %d already terminated\n",
280 Request
->Type
, (ULONG
)Request
->Header
.ClientId
.UniqueProcess
);
284 /* Check if we got a hard error */
285 if (Request
->Header
.u2
.s2
.Type
== LPC_ERROR_EVENT
)
287 /* Call the Handler */
288 CsrHandleHardError(ProcessData
, (PHARDERROR_MSG
)Request
);
292 /* Call the Handler */
293 CsrApiCallHandler(ProcessData
, Request
);
296 /* Send back the reply */
300 /* Close the port and exit the thread */
301 // NtClose(ServerPort);
303 DPRINT("CSR: %s done\n", __FUNCTION__
);
304 RtlExitUserThread(STATUS_SUCCESS
);
307 /**********************************************************************
309 * ServerApiPortThread/1
312 * Handle connection requests from clients to the port
313 * "\Windows\ApiPort".
317 ServerApiPortThread (HANDLE hApiListenPort
)
319 NTSTATUS Status
= STATUS_SUCCESS
;
320 BYTE RawRequest
[sizeof(PORT_MESSAGE
) + sizeof(CSR_CONNECTION_INFO
)];
321 PPORT_MESSAGE Request
= (PPORT_MESSAGE
)RawRequest
;
323 DPRINT("CSR: %s called", __FUNCTION__
);
327 REMOTE_PORT_VIEW LpcRead
;
328 LpcRead
.Length
= sizeof(LpcRead
);
330 Status
= NtListenPort (hApiListenPort
, Request
);
331 if (!NT_SUCCESS(Status
))
333 DPRINT1("CSR: NtListenPort() failed, status=%x\n", Status
);
337 Status
= CsrpHandleConnectionRequest(Request
, hApiListenPort
);
338 if(!NT_SUCCESS(Status
))
340 DPRINT1("CSR: %s: SmpHandleConnectionRequest failed (Status=0x%08lx)\n",
341 __FUNCTION__
, Status
);
346 NtClose(hApiListenPort
);
347 NtTerminateThread(NtCurrentThread(), Status
);
352 /**********************************************************************
354 * ServerSbApiPortThread/1
357 * Handle connection requests from SM to the port
358 * "\Windows\SbApiPort". We will accept only one
359 * connection request (from the SM).
362 ServerSbApiPortThread (HANDLE hSbApiPortListen
)
364 HANDLE hConnectedPort
= (HANDLE
) 0;
365 PORT_MESSAGE Request
;
366 PVOID Context
= NULL
;
367 NTSTATUS Status
= STATUS_SUCCESS
;
368 PPORT_MESSAGE Reply
= NULL
;
370 DPRINT("CSR: %s called\n", __FUNCTION__
);
372 RtlZeroMemory(&Request
, sizeof(PORT_MESSAGE
));
373 Status
= NtListenPort (hSbApiPortListen
, & Request
);
375 if (!NT_SUCCESS(Status
))
377 DPRINT1("CSR: %s: NtListenPort(SB) failed (Status=0x%08lx)\n",
378 __FUNCTION__
, Status
);
381 Status
= NtAcceptConnectPort(&hConnectedPort
,
387 if(!NT_SUCCESS(Status
))
389 DPRINT1("CSR: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
390 __FUNCTION__
, Status
);
393 Status
= NtCompleteConnectPort (hConnectedPort
);
394 if(!NT_SUCCESS(Status
))
396 DPRINT1("CSR: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
397 __FUNCTION__
, Status
);
401 * Tell the init thread the SM gave the
402 * green light for boostrapping.
404 Status
= NtSetEvent (hBootstrapOk
, NULL
);
405 if(!NT_SUCCESS(Status
))
407 DPRINT1("CSR: %s: NtSetEvent failed (Status=0x%08lx)\n",
408 __FUNCTION__
, Status
);
410 /* Wait for messages from the SM */
414 Status
= NtReplyWaitReceivePort(hConnectedPort
,
418 if(!NT_SUCCESS(Status
))
420 DPRINT1("CSR: %s: NtReplyWaitReceivePort failed (Status=0x%08lx)\n",
421 __FUNCTION__
, Status
);
425 switch (Request
.u2
.s2
.Type
) //fix .h PORT_MESSAGE_TYPE(Request))
429 DPRINT1("CSR: %s received message (type=%d)\n",
430 __FUNCTION__
, Request
.u2
.s2
.Type
);
438 DPRINT("CSR: %s: terminating!\n", __FUNCTION__
);
439 if(hConnectedPort
) NtClose (hConnectedPort
);
440 NtClose (hSbApiPortListen
);
441 NtTerminateThread (NtCurrentThread(), Status
);