3 * reactos/subsys/csrss/api/wapi.c
5 * CSRSS port message processing
7 * ReactOS Operating System
11 /* INCLUDES ******************************************************************/
18 /* GLOBALS *******************************************************************/
20 HANDLE CsrssApiHeap
= (HANDLE
) 0;
22 static unsigned ApiDefinitionsCount
= 0;
23 static PCSRSS_API_DEFINITION ApiDefinitions
= NULL
;
25 /* FUNCTIONS *****************************************************************/
28 CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions
)
31 PCSRSS_API_DEFINITION Scan
;
32 PCSRSS_API_DEFINITION New
;
34 DPRINT("CSR: %s called", __FUNCTION__
);
37 for (Scan
= NewDefinitions
; 0 != Scan
->Handler
; Scan
++)
42 New
= RtlAllocateHeap(CsrssApiHeap
, 0,
43 (ApiDefinitionsCount
+ NewCount
)
44 * sizeof(CSRSS_API_DEFINITION
));
47 DPRINT1("Unable to allocate memory\n");
48 return STATUS_NO_MEMORY
;
50 if (0 != ApiDefinitionsCount
)
52 RtlCopyMemory(New
, ApiDefinitions
,
53 ApiDefinitionsCount
* sizeof(CSRSS_API_DEFINITION
));
54 RtlFreeHeap(CsrssApiHeap
, 0, ApiDefinitions
);
56 RtlCopyMemory(New
+ ApiDefinitionsCount
, NewDefinitions
,
57 NewCount
* sizeof(CSRSS_API_DEFINITION
));
59 ApiDefinitionsCount
+= NewCount
;
61 return STATUS_SUCCESS
;
66 CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData
,
67 PCSR_API_MESSAGE Request
)
73 DPRINT("CSR: Calling handler for type: %x.\n", Request
->Type
);
74 Type
= Request
->Type
& 0xFFFF; /* FIXME: USE MACRO */
75 DPRINT("CSR: API Number: %x ServerID: %x\n",Type
, Request
->Type
>> 16);
77 /* FIXME: Extract DefIndex instead of looping */
78 for (DefIndex
= 0; ! Found
&& DefIndex
< ApiDefinitionsCount
; DefIndex
++)
80 if (ApiDefinitions
[DefIndex
].Type
== Type
)
82 if (Request
->Header
.u1
.s1
.DataLength
< ApiDefinitions
[DefIndex
].MinRequestSize
)
84 DPRINT1("Request type %d min request size %d actual %d\n",
85 Type
, ApiDefinitions
[DefIndex
].MinRequestSize
,
86 Request
->Header
.u1
.s1
.DataLength
);
87 Request
->Status
= STATUS_INVALID_PARAMETER
;
91 (ApiDefinitions
[DefIndex
].Handler
)(ProcessData
, Request
);
98 DPRINT1("CSR: Unknown request type 0x%x\n", Request
->Type
);
99 Request
->Header
.u1
.s1
.TotalLength
= sizeof(CSR_API_MESSAGE
);
100 Request
->Header
.u1
.s1
.DataLength
= sizeof(CSR_API_MESSAGE
) - sizeof(PORT_MESSAGE
);
101 Request
->Status
= STATUS_INVALID_SYSTEM_SERVICE
;
108 ClientConnectionThread(HANDLE ServerPort
)
111 BYTE RawRequest
[LPC_MAX_DATA_LENGTH
];
112 PCSR_API_MESSAGE Request
= (PCSR_API_MESSAGE
)RawRequest
;
113 PCSR_API_MESSAGE Reply
;
114 PCSRSS_PROCESS_DATA ProcessData
;
116 DPRINT("CSR: %s called", __FUNCTION__
);
118 /* Reply must be NULL at the first call to NtReplyWaitReceivePort */
121 /* Loop and reply/wait for a new message */
124 /* Send the reply and wait for a new request */
125 Status
= NtReplyWaitReceivePort(ServerPort
,
129 if (!NT_SUCCESS(Status
))
131 DPRINT1("CSR: NtReplyWaitReceivePort failed\n");
135 /* If the connection was closed, handle that */
136 if (Request
->Header
.u2
.s2
.Type
== LPC_PORT_CLOSED
)
138 CsrFreeProcessData( Request
->Header
.ClientId
.UniqueProcess
);
142 DPRINT("CSR: Got CSR API: %x [Message Origin: %x]\n",
144 Request
->Header
.ClientId
.UniqueProcess
);
146 /* Get the Process Data */
147 ProcessData
= CsrGetProcessData(Request
->Header
.ClientId
.UniqueProcess
);
148 if (ProcessData
== NULL
)
150 DPRINT1("CSR: Message %d: Unable to find data for process 0x%x\n",
151 Request
->Header
.u2
.s2
.Type
,
152 Request
->Header
.ClientId
.UniqueProcess
);
156 /* Call the Handler */
157 CsrApiCallHandler(ProcessData
, Request
);
159 /* Send back the reply */
163 /* Close the port and exit the thread */
165 RtlExitUserThread(STATUS_SUCCESS
);
168 /**********************************************************************
170 * ServerApiPortThread/1
173 * Handle connection requests from clients to the port
174 * "\Windows\ApiPort".
177 ServerApiPortThread (PVOID PortHandle
)
179 NTSTATUS Status
= STATUS_SUCCESS
;
180 PORT_MESSAGE Request
;
181 HANDLE hApiListenPort
= * (PHANDLE
) PortHandle
;
182 HANDLE ServerPort
= (HANDLE
) 0;
183 HANDLE ServerThread
= (HANDLE
) 0;
184 PCSRSS_PROCESS_DATA ProcessData
= NULL
;
186 CsrInitProcessData();
188 DPRINT("CSR: %s called", __FUNCTION__
);
192 REMOTE_PORT_VIEW LpcRead
;
195 Status
= NtListenPort (hApiListenPort
, &Request
);
196 if (!NT_SUCCESS(Status
))
198 DPRINT1("CSR: NtListenPort() failed\n");
201 Status
= NtAcceptConnectPort(& ServerPort
,
207 if (!NT_SUCCESS(Status
))
209 DPRINT1("CSR: NtAcceptConnectPort() failed\n");
213 ProcessData
= CsrCreateProcessData(Request
.ClientId
.UniqueProcess
);
214 if (ProcessData
== NULL
)
216 DPRINT1("Unable to allocate or find data for process 0x%x\n",
217 Request
.ClientId
.UniqueProcess
);
218 Status
= STATUS_UNSUCCESSFUL
;
223 ProcessData
->CsrSectionViewBase
= LpcRead
.ViewBase
;
224 ProcessData
->CsrSectionViewSize
= LpcRead
.ViewSize
;
226 Status
= NtCompleteConnectPort(ServerPort
);
227 if (!NT_SUCCESS(Status
))
229 DPRINT1("CSR: NtCompleteConnectPort() failed\n");
233 Status
= RtlCreateUserThread(NtCurrentProcess(),
239 (PTHREAD_START_ROUTINE
)ClientConnectionThread
,
243 if (!NT_SUCCESS(Status
))
245 DPRINT1("CSR: Unable to create server thread\n");
248 NtClose(ServerThread
);
255 NtTerminateThread(NtCurrentThread(), Status
);
259 /**********************************************************************
261 * ServerSbApiPortThread/1
264 * Handle connection requests from SM to the port
265 * "\Windows\SbApiPort". We will accept only one
266 * connection request (from the SM).
269 ServerSbApiPortThread (PVOID PortHandle
)
271 HANDLE hSbApiPortListen
= * (PHANDLE
) PortHandle
;
272 HANDLE hConnectedPort
= (HANDLE
) 0;
273 PORT_MESSAGE Request
;
274 PVOID Context
= NULL
;
275 NTSTATUS Status
= STATUS_SUCCESS
;
277 DPRINT("CSR: %s called\n", __FUNCTION__
);
279 RtlZeroMemory(&Request
, sizeof(PORT_MESSAGE
));
280 Status
= NtListenPort (hSbApiPortListen
, & Request
);
281 if (!NT_SUCCESS(Status
))
283 DPRINT1("CSR: %s: NtListenPort(SB) failed (Status=0x%08lx)\n",
284 __FUNCTION__
, Status
);
287 Status
= NtAcceptConnectPort (& hConnectedPort
,
293 if(!NT_SUCCESS(Status
))
295 DPRINT1("CSR: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
296 __FUNCTION__
, Status
);
299 Status
= NtCompleteConnectPort (hConnectedPort
);
300 if(!NT_SUCCESS(Status
))
302 DPRINT1("CSR: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
303 __FUNCTION__
, Status
);
306 PPORT_MESSAGE Reply
= NULL
;
308 * Tell the init thread the SM gave the
309 * green light for boostrapping.
311 Status
= NtSetEvent (hBootstrapOk
, NULL
);
312 if(!NT_SUCCESS(Status
))
314 DPRINT1("CSR: %s: NtSetEvent failed (Status=0x%08lx)\n",
315 __FUNCTION__
, Status
);
317 /* Wait for messages from the SM */
321 Status
= NtReplyWaitReceivePort(hConnectedPort
,
325 if(!NT_SUCCESS(Status
))
327 DPRINT1("CSR: %s: NtReplyWaitReceivePort failed (Status=0x%08lx)\n",
328 __FUNCTION__
, Status
);
331 switch (Request
.u2
.s2
.Type
)//fix .h PORT_MESSAGE_TYPE(Request))
335 DPRINT1("CSR: %s received message (type=%d)\n",
336 __FUNCTION__
, Request
.u2
.s2
.Type
);
343 DPRINT1("CSR: %s: terminating!\n", __FUNCTION__
);
344 if(hConnectedPort
) NtClose (hConnectedPort
);
345 NtClose (hSbApiPortListen
);
346 NtTerminateThread (NtCurrentThread(), Status
);