3 * reactos/subsys/csrss/api/wapi.c
5 * CSRSS port message processing
7 * ReactOS Operating System
11 /* INCLUDES ******************************************************************/
20 /* GLOBALS *******************************************************************/
22 HANDLE CsrssApiHeap
= (HANDLE
) 0;
24 static unsigned ApiDefinitionsCount
= 0;
25 static PCSRSS_API_DEFINITION ApiDefinitions
= NULL
;
27 /* FUNCTIONS *****************************************************************/
30 CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions
)
33 PCSRSS_API_DEFINITION Scan
;
34 PCSRSS_API_DEFINITION New
;
36 DPRINT("CSR: %s called", __FUNCTION__
);
39 for (Scan
= NewDefinitions
; 0 != Scan
->Handler
; Scan
++)
44 New
= RtlAllocateHeap(CsrssApiHeap
, 0,
45 (ApiDefinitionsCount
+ NewCount
)
46 * sizeof(CSRSS_API_DEFINITION
));
49 DPRINT1("Unable to allocate memory\n");
50 return STATUS_NO_MEMORY
;
52 if (0 != ApiDefinitionsCount
)
54 RtlCopyMemory(New
, ApiDefinitions
,
55 ApiDefinitionsCount
* sizeof(CSRSS_API_DEFINITION
));
56 RtlFreeHeap(CsrssApiHeap
, 0, ApiDefinitions
);
58 RtlCopyMemory(New
+ ApiDefinitionsCount
, NewDefinitions
,
59 NewCount
* sizeof(CSRSS_API_DEFINITION
));
61 ApiDefinitionsCount
+= NewCount
;
63 return STATUS_SUCCESS
;
68 CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData
,
69 PCSR_API_MESSAGE Request
)
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);
79 /* FIXME: Extract DefIndex instead of looping */
80 for (DefIndex
= 0; ! Found
&& DefIndex
< ApiDefinitionsCount
; DefIndex
++)
82 if (ApiDefinitions
[DefIndex
].Type
== Type
)
84 if (Request
->Header
.u1
.s1
.DataLength
< ApiDefinitions
[DefIndex
].MinRequestSize
)
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
;
93 (ApiDefinitions
[DefIndex
].Handler
)(ProcessData
, Request
);
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
;
110 ClientConnectionThread(HANDLE ServerPort
)
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
;
118 DPRINT("CSR: %s called", __FUNCTION__
);
120 /* Reply must be NULL at the first call to NtReplyWaitReceivePort */
123 /* Loop and reply/wait for a new message */
126 /* Send the reply and wait for a new request */
127 Status
= NtReplyWaitReceivePort(ServerPort
,
131 if (!NT_SUCCESS(Status
))
133 DPRINT1("NtReplyWaitReceivePort failed\n");
137 /* If the connection was closed, handle that */
138 if (Request
->Header
.u2
.s2
.Type
== LPC_PORT_CLOSED
)
140 CsrFreeProcessData( Request
->Header
.ClientId
.UniqueProcess
);
144 DPRINT("CSR: Got CSR API: %x [Message Origin: %x]\n",
146 Request
->Header
.ClientId
.UniqueProcess
);
148 /* Get the Process Data */
149 ProcessData
= CsrGetProcessData(Request
->Header
.ClientId
.UniqueProcess
);
150 if (ProcessData
== NULL
)
152 DPRINT1("Message %d: Unable to find data for process 0x%x\n",
153 Request
->Header
.u2
.s2
.Type
,
154 Request
->Header
.ClientId
.UniqueProcess
);
157 if (ProcessData
->Terminated
)
159 DPRINT1("Message %d: process %d already terminated\n",
160 Request
->Type
, (ULONG
)Request
->Header
.ClientId
.UniqueProcess
);
164 /* Call the Handler */
165 CsrApiCallHandler(ProcessData
, Request
);
167 /* Send back the reply */
171 /* Close the port and exit the thread */
173 RtlExitUserThread(STATUS_SUCCESS
);
176 /**********************************************************************
178 * ServerApiPortThread/1
181 * Handle connection requests from clients to the port
182 * "\Windows\ApiPort".
185 ServerApiPortThread (PVOID PortHandle
)
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
;
195 CsrInitProcessData();
197 DPRINT("CSR: %s called", __FUNCTION__
);
201 REMOTE_PORT_VIEW LpcRead
;
204 Status
= NtListenPort (hApiListenPort
, Request
);
205 if (!NT_SUCCESS(Status
))
207 DPRINT1("CSR: NtListenPort() failed, status=%x\n", Status
);
210 Status
= NtAcceptConnectPort(& ServerPort
,
216 if (!NT_SUCCESS(Status
))
218 DPRINT1("CSR: NtAcceptConnectPort() failed\n");
222 ProcessData
= CsrCreateProcessData(Request
->ClientId
.UniqueProcess
);
223 if (ProcessData
== NULL
)
225 DPRINT1("Unable to allocate or find data for process 0x%x\n",
226 Request
->ClientId
.UniqueProcess
);
227 Status
= STATUS_UNSUCCESSFUL
;
232 ProcessData
->CsrSectionViewBase
= LpcRead
.ViewBase
;
233 ProcessData
->CsrSectionViewSize
= LpcRead
.ViewSize
;
235 Status
= NtCompleteConnectPort(ServerPort
);
236 if (!NT_SUCCESS(Status
))
238 DPRINT1("CSR: NtCompleteConnectPort() failed\n");
242 Status
= RtlCreateUserThread(NtCurrentProcess(),
248 (PTHREAD_START_ROUTINE
)ClientConnectionThread
,
252 if (!NT_SUCCESS(Status
))
254 DPRINT1("CSR: Unable to create server thread\n");
257 NtClose(ServerThread
);
264 NtTerminateThread(NtCurrentThread(), Status
);
268 /**********************************************************************
270 * ServerSbApiPortThread/1
273 * Handle connection requests from SM to the port
274 * "\Windows\SbApiPort". We will accept only one
275 * connection request (from the SM).
278 ServerSbApiPortThread (PVOID PortHandle
)
280 HANDLE hSbApiPortListen
= * (PHANDLE
) PortHandle
;
281 HANDLE hConnectedPort
= (HANDLE
) 0;
282 PORT_MESSAGE Request
;
283 PVOID Context
= NULL
;
284 NTSTATUS Status
= STATUS_SUCCESS
;
286 DPRINT("CSR: %s called\n", __FUNCTION__
);
288 RtlZeroMemory(&Request
, sizeof(PORT_MESSAGE
));
289 Status
= NtListenPort (hSbApiPortListen
, & Request
);
290 if (!NT_SUCCESS(Status
))
292 DPRINT1("CSR: %s: NtListenPort(SB) failed (Status=0x%08lx)\n",
293 __FUNCTION__
, Status
);
296 Status
= NtAcceptConnectPort (& hConnectedPort
,
302 if(!NT_SUCCESS(Status
))
304 DPRINT1("CSR: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
305 __FUNCTION__
, Status
);
308 Status
= NtCompleteConnectPort (hConnectedPort
);
309 if(!NT_SUCCESS(Status
))
311 DPRINT1("CSR: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
312 __FUNCTION__
, Status
);
315 PPORT_MESSAGE Reply
= NULL
;
317 * Tell the init thread the SM gave the
318 * green light for boostrapping.
320 Status
= NtSetEvent (hBootstrapOk
, NULL
);
321 if(!NT_SUCCESS(Status
))
323 DPRINT1("CSR: %s: NtSetEvent failed (Status=0x%08lx)\n",
324 __FUNCTION__
, Status
);
326 /* Wait for messages from the SM */
330 Status
= NtReplyWaitReceivePort(hConnectedPort
,
334 if(!NT_SUCCESS(Status
))
336 DPRINT1("CSR: %s: NtReplyWaitReceivePort failed (Status=0x%08lx)\n",
337 __FUNCTION__
, Status
);
340 switch (Request
.u2
.s2
.Type
)//fix .h PORT_MESSAGE_TYPE(Request))
344 DPRINT1("CSR: %s received message (type=%d)\n",
345 __FUNCTION__
, Request
.u2
.s2
.Type
);
352 DPRINT1("CSR: %s: terminating!\n", __FUNCTION__
);
353 if(hConnectedPort
) NtClose (hConnectedPort
);
354 NtClose (hSbApiPortListen
);
355 NtTerminateThread (NtCurrentThread(), Status
);