CSR pre-init cleanup
[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/csrss.h>
14 #include <ddk/ntddk.h>
15 #include <ntdll/rtl.h>
16 #include <debug.h>
17
18 #include "api.h"
19
20 /* GLOBALS *******************************************************************/
21
22 HANDLE CsrssApiHeap;
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 NewCount = 0;
37 for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++)
38 {
39 NewCount++;
40 }
41
42 New = RtlAllocateHeap(CsrssApiHeap, 0,
43 (ApiDefinitionsCount + NewCount)
44 * sizeof(CSRSS_API_DEFINITION));
45 if (NULL == New)
46 {
47 DPRINT1("Unable to allocate memory\n");
48 return STATUS_NO_MEMORY;
49 }
50 if (0 != ApiDefinitionsCount)
51 {
52 RtlCopyMemory(New, ApiDefinitions,
53 ApiDefinitionsCount * sizeof(CSRSS_API_DEFINITION));
54 RtlFreeHeap(CsrssApiHeap, 0, ApiDefinitions);
55 }
56 RtlCopyMemory(New + ApiDefinitionsCount, NewDefinitions,
57 NewCount * sizeof(CSRSS_API_DEFINITION));
58 ApiDefinitions = New;
59 ApiDefinitionsCount += NewCount;
60
61 return STATUS_SUCCESS;
62 }
63
64 VOID FASTCALL
65 CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData,
66 PCSRSS_API_REQUEST Request,
67 PCSRSS_API_REPLY Reply)
68 {
69 BOOL Found;
70 unsigned DefIndex;
71
72 Found = FALSE;
73 for (DefIndex = 0; ! Found && DefIndex < ApiDefinitionsCount; DefIndex++)
74 {
75 if (ApiDefinitions[DefIndex].Type == Request->Type)
76 {
77 if (Request->Header.DataSize < ApiDefinitions[DefIndex].MinRequestSize)
78 {
79 DPRINT1("Request type %d min request size %d actual %d\n",
80 Request->Type, ApiDefinitions[DefIndex].MinRequestSize,
81 Request->Header.DataSize);
82 Reply->Status = STATUS_INVALID_PARAMETER;
83 }
84 else
85 {
86 (ApiDefinitions[DefIndex].Handler)(ProcessData, Request, Reply);
87 Found = TRUE;
88 }
89 }
90 }
91 if (! Found)
92 {
93 DPRINT1("CSR: Unknown request type 0x%x\n", Request->Type);
94 Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
95 Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE;
96 Reply->Status = STATUS_INVALID_SYSTEM_SERVICE;
97 }
98 }
99
100 static void STDCALL
101 ClientConnectionThread(HANDLE ServerPort)
102 {
103 NTSTATUS Status;
104 LPC_MAX_MESSAGE LpcReply;
105 LPC_MAX_MESSAGE LpcRequest;
106 PCSRSS_API_REQUEST Request;
107 PCSRSS_PROCESS_DATA ProcessData;
108 PCSRSS_API_REPLY Reply;
109
110 Reply = NULL;
111
112 for (;;)
113 {
114 Status = NtReplyWaitReceivePort(ServerPort,
115 0,
116 &Reply->Header,
117 &LpcRequest.Header);
118 if (! NT_SUCCESS(Status))
119 {
120 DPRINT1("CSR: NtReplyWaitReceivePort failed\n");
121 break;
122 }
123
124 if (LpcRequest.Header.MessageType == LPC_PORT_CLOSED)
125 {
126 CsrFreeProcessData( LpcRequest.Header.ClientId.UniqueProcess );
127 break;
128 }
129
130 Request = (PCSRSS_API_REQUEST)&LpcRequest;
131 Reply = (PCSRSS_API_REPLY)&LpcReply;
132
133 ProcessData = CsrGetProcessData(LpcRequest.Header.ClientId.UniqueProcess);
134 if (ProcessData == NULL)
135 {
136 DPRINT1("CSR: Message %d: Unable to find data for process 0x%x\n",
137 LpcRequest.Header.MessageType, LpcRequest.Header.ClientId.UniqueProcess);
138 break;
139 }
140
141
142 CsrApiCallHandler(ProcessData, Request, Reply);
143 }
144 NtClose(ServerPort);
145 RtlRosExitUserThread(STATUS_SUCCESS);
146 }
147
148 /**********************************************************************
149 * NAME
150 * ServerApiPortThread/1
151 *
152 * DESCRIPTION
153 * Handle connection requests from clients to the port
154 * "\Windows\ApiPort".
155 */
156 void STDCALL
157 ServerApiPortThread (PVOID PortHandle)
158 {
159 NTSTATUS Status;
160 LPC_MAX_MESSAGE Request;
161 HANDLE ServerPort;
162 HANDLE ServerThread;
163 PCSRSS_PROCESS_DATA ProcessData;
164
165 CsrInitProcessData();
166
167 for (;;)
168 {
169 LPC_SECTION_READ LpcRead;
170 ServerPort = NULL;
171
172 Status = NtListenPort(PortHandle, &Request.Header);
173 if (!NT_SUCCESS(Status))
174 {
175 DPRINT1("CSR: NtListenPort() failed\n");
176 break;
177 }
178 Status = NtAcceptConnectPort(&ServerPort,
179 PortHandle,
180 NULL,
181 TRUE,
182 0,
183 &LpcRead);
184 if (!NT_SUCCESS(Status))
185 {
186 DPRINT1("CSR: NtAcceptConnectPort() failed\n");
187 break;
188 }
189
190 ProcessData = CsrCreateProcessData(Request.Header.ClientId.UniqueProcess);
191 if (ProcessData == NULL)
192 {
193 DPRINT1("Unable to allocate or find data for process 0x%x\n",
194 Request.Header.ClientId.UniqueProcess);
195 Status = STATUS_UNSUCCESSFUL;
196 break;
197 }
198
199
200 ProcessData->CsrSectionViewBase = LpcRead.ViewBase;
201 ProcessData->CsrSectionViewSize = LpcRead.ViewSize;
202
203 Status = NtCompleteConnectPort(ServerPort);
204 if (!NT_SUCCESS(Status))
205 {
206 DPRINT1("CSR: NtCompleteConnectPort() failed\n");
207 break;
208 }
209
210 Status = RtlCreateUserThread(NtCurrentProcess(),
211 NULL,
212 FALSE,
213 0,
214 NULL,
215 NULL,
216 (PTHREAD_START_ROUTINE)ClientConnectionThread,
217 ServerPort,
218 &ServerThread,
219 NULL);
220 if (!NT_SUCCESS(Status))
221 {
222 DPRINT1("CSR: Unable to create server thread\n");
223 break;
224 }
225 NtClose(ServerThread);
226 }
227 if (ServerPort)
228 {
229 NtClose(ServerPort);
230 }
231 NtClose(PortHandle);
232 NtTerminateThread(NtCurrentThread(), Status);
233 }
234
235 /**********************************************************************
236 * NAME
237 * ServerSbApiPortThread/1
238 *
239 * DESCRIPTION
240 * Handle connection requests from SM to the port
241 * "\Windows\SbApiPort".
242 */
243 VOID STDCALL
244 ServerSbApiPortThread (PVOID PortHandle)
245 {
246 HANDLE hSbApiPortListen = (HANDLE) PortHandle;
247 HANDLE hConnectedPort = (HANDLE) 0;
248 LPC_MAX_MESSAGE Request = {{0}};
249 NTSTATUS Status = STATUS_SUCCESS;
250
251 while (TRUE)
252 {
253 Status = NtListenPort (hSbApiPortListen, & Request.Header);
254 if (!NT_SUCCESS(Status))
255 {
256 DPRINT1("CSR: %s: NtListenPort(SB) failed\n", __FUNCTION__);
257 break;
258 }
259 Status = NtAcceptConnectPort (& hConnectedPort,
260 hSbApiPortListen,
261 NULL,
262 TRUE,
263 NULL,
264 NULL);
265 if(!NT_SUCCESS(Status))
266 {
267 DPRINT1("CSR: %s: NtAcceptConnectPort() failed\n", __FUNCTION__);
268 break;
269 }
270 Status = NtCompleteConnectPort (hConnectedPort);
271 if(!NT_SUCCESS(Status))
272 {
273 DPRINT1("CSR: %s: NtCompleteConnectPort() failed\n", __FUNCTION__);
274 break;
275 }
276 /* TODO: create thread for the connected port */
277 }
278 NtClose (hSbApiPortListen);
279 NtTerminateThread (NtCurrentThread(), Status);
280 }
281
282 /* EOF */