revert my previous patch
[reactos.git] / reactos / subsys / csrss / api / wapi.c
1 /* $Id: wapi.c,v 1.36 2004/06/27 12:21:32 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
139 CsrApiCallHandler(ProcessData, Request, Reply);
140 }
141 }
142
143 /**********************************************************************
144 * NAME
145 * Thread_Api
146 *
147 * DESCRIPTION
148 * Handle connection requests from clients to the port
149 * "\Windows\ApiPort".
150 */
151 void Thread_Api(PVOID PortHandle)
152 {
153 NTSTATUS Status;
154 LPC_MAX_MESSAGE Request;
155 HANDLE ServerPort;
156 HANDLE ServerThread;
157 PCSRSS_PROCESS_DATA ProcessData;
158
159 CsrInitProcessData();
160
161 for (;;)
162 {
163 LPC_SECTION_READ LpcRead;
164
165 Status = NtListenPort(PortHandle, &Request.Header);
166 if (!NT_SUCCESS(Status))
167 {
168 DPRINT1("CSR: NtListenPort() failed\n");
169 NtTerminateThread(NtCurrentThread(), Status);
170 }
171
172 Status = NtAcceptConnectPort(&ServerPort,
173 PortHandle,
174 NULL,
175 1,
176 0,
177 &LpcRead);
178 if (!NT_SUCCESS(Status))
179 {
180 DPRINT1("CSR: NtAcceptConnectPort() failed\n");
181 NtTerminateThread(NtCurrentThread(), Status);
182 }
183
184 ProcessData = CsrGetProcessData((ULONG)Request.Header.ClientId.UniqueProcess);
185 ProcessData->CsrSectionViewBase = LpcRead.ViewBase;
186 ProcessData->CsrSectionViewSize = LpcRead.ViewSize;
187
188 Status = NtCompleteConnectPort(ServerPort);
189 if (!NT_SUCCESS(Status))
190 {
191 DPRINT1("CSR: NtCompleteConnectPort() failed\n");
192 NtTerminateThread(NtCurrentThread(), Status);
193 }
194
195 Status = RtlCreateUserThread(NtCurrentProcess(),
196 NULL,
197 FALSE,
198 0,
199 NULL,
200 NULL,
201 (PTHREAD_START_ROUTINE)Thread_Api2,
202 ServerPort,
203 &ServerThread,
204 NULL);
205 if (!NT_SUCCESS(Status))
206 {
207 DPRINT1("CSR: Unable to create server thread\n");
208 NtClose(ServerPort);
209 NtTerminateThread(NtCurrentThread(), Status);
210 }
211 NtClose(ServerThread);
212 }
213 }
214
215 /* EOF */