don't crash if requested process couldn't be found
[reactos.git] / reactos / subsys / csrss / api / wapi.c
1 /* $Id: wapi.c,v 1.35 2004/06/27 10:16:59 weiden Exp $
2 *
3 * reactos/subsys/csrss/api/wapi.c
4 *
5 * Initialize the CSRSS subsystem server process.
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
101 Thread_Api2(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 NtClose(ServerPort);
122 RtlRosExitUserThread(Status);
123 continue;
124 }
125
126 if (LpcRequest.Header.MessageType == LPC_PORT_CLOSED)
127 {
128 CsrFreeProcessData( (ULONG)LpcRequest.Header.ClientId.UniqueProcess );
129 NtClose(ServerPort);
130 RtlRosExitUserThread(STATUS_SUCCESS);
131 continue;
132 }
133
134 Request = (PCSRSS_API_REQUEST)&LpcRequest;
135 Reply = (PCSRSS_API_REPLY)&LpcReply;
136
137 ProcessData = CsrGetProcessData((ULONG)LpcRequest.Header.ClientId.UniqueProcess);
138 if (ProcessData == NULL)
139 {
140 DPRINT1("CSR: Unable to find process data for process 0x%x\n", (ULONG)LpcRequest.Header.ClientId.UniqueProcess);
141 NtClose(ServerPort);
142 continue;
143 }
144 CsrApiCallHandler(ProcessData, Request, Reply);
145 }
146 }
147
148 /**********************************************************************
149 * NAME
150 * Thread_Api
151 *
152 * DESCRIPTION
153 * Handle connection requests from clients to the port
154 * "\Windows\ApiPort".
155 */
156 void Thread_Api(PVOID PortHandle)
157 {
158 NTSTATUS Status;
159 LPC_MAX_MESSAGE Request;
160 HANDLE ServerPort;
161 HANDLE ServerThread;
162 PCSRSS_PROCESS_DATA ProcessData;
163
164 CsrInitProcessData();
165
166 for (;;)
167 {
168 LPC_SECTION_READ LpcRead;
169
170 Status = NtListenPort(PortHandle, &Request.Header);
171 if (!NT_SUCCESS(Status))
172 {
173 DPRINT1("CSR: NtListenPort() failed\n");
174 NtTerminateThread(NtCurrentThread(), Status);
175 }
176
177 Status = NtAcceptConnectPort(&ServerPort,
178 PortHandle,
179 NULL,
180 1,
181 0,
182 &LpcRead);
183 if (!NT_SUCCESS(Status))
184 {
185 DPRINT1("CSR: NtAcceptConnectPort() failed\n");
186 NtTerminateThread(NtCurrentThread(), Status);
187 }
188
189 ProcessData = CsrGetProcessData((ULONG)Request.Header.ClientId.UniqueProcess);
190 if (ProcessData == NULL)
191 {
192 DPRINT1("CSR: Unable to find process data for process 0x%x\n", (ULONG)Request.Header.ClientId.UniqueProcess);
193 NtClose(ServerPort);
194 continue;
195 }
196 ProcessData->CsrSectionViewBase = LpcRead.ViewBase;
197 ProcessData->CsrSectionViewSize = LpcRead.ViewSize;
198
199 Status = NtCompleteConnectPort(ServerPort);
200 if (!NT_SUCCESS(Status))
201 {
202 DPRINT1("CSR: NtCompleteConnectPort() failed\n");
203 NtTerminateThread(NtCurrentThread(), Status);
204 }
205
206 Status = RtlCreateUserThread(NtCurrentProcess(),
207 NULL,
208 FALSE,
209 0,
210 NULL,
211 NULL,
212 (PTHREAD_START_ROUTINE)Thread_Api2,
213 ServerPort,
214 &ServerThread,
215 NULL);
216 if (!NT_SUCCESS(Status))
217 {
218 DPRINT1("CSR: Unable to create server thread\n");
219 NtClose(ServerPort);
220 NtTerminateThread(NtCurrentThread(), Status);
221 }
222 NtClose(ServerThread);
223 }
224 }
225
226 /* EOF */