added tests for StretchBlt, PatBlt and BitBlt by Damon Chandler
[reactos.git] / posix / server / port / api.c
1 /* $Id: api.c,v 1.1 2002/04/10 21:30:22 ea Exp $
2 *
3 * PROJECT : ReactOS / POSIX+ Environment Subsystem Server
4 * FILE : reactos/subsys/psx/server/port/api.c
5 * DESCRIPTION: \POSIX+\ApiPort LPC port logic.
6 * DATE : 2001-04-04
7 * AUTHOR : Emanuele Aliberti <eal@users.sf.net>
8 *
9 * --------------------------------------------------------------------
10 *
11 * This software is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of the
14 * License, or (at your option) any later version.
15 *
16 * This software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this software; see the file COPYING. If not, write
23 * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
24 * MA 02139, USA.
25 *
26 * --------------------------------------------------------------------
27 */
28 #include <psxss.h>
29 #include <psx/lpcproto.h>
30 #include "utils.h"
31
32 /**********************************************************************
33 * ProcessConnectionRequest/ PRIVATE
34 *
35 * DESCRIPTION
36 * This is called when a PSX process attaches to PSXDLL.DLL.
37 */
38 PRIVATE NTSTATUS STDCALL
39 ProcessConnectionRequest (PLPC_MAX_MESSAGE pRequest)
40 {
41 PPSX_CONNECT_PORT_DATA pConnectData = (PPSX_CONNECT_PORT_DATA) & pRequest->Data;
42 NTSTATUS Status;
43 HANDLE hConnectedPort;
44 ULONG ulPortIdentifier;
45
46 debug_print (L"PSXSS: ->"__FUNCTION__);
47 /* Check if the caller is a process */
48 Status = PsxCheckConnectionRequest (
49 pConnectData,
50 PSX_CONNECTION_TYPE_PROCESS
51 );
52 if (!NT_SUCCESS(Status))
53 {
54 Status = NtAcceptConnectPort (
55 & hConnectedPort,
56 NULL,
57 & pRequest->Header,
58 FALSE, /* reject connection request */
59 NULL,
60 NULL
61 );
62 if (!NT_SUCCESS(Status))
63 {
64 debug_print(
65 L"PSXSS: "__FUNCTION__": NtAcceptConnectPort failed with status=%08x",
66 Status
67 );
68 }
69 return STATUS_UNSUCCESSFUL;
70 }
71 /* OK, accept the connection */
72 Status = NtAcceptConnectPort (
73 & hConnectedPort,
74 & ulPortIdentifier,
75 & pRequest->Header,
76 TRUE, /* accept connection request */
77 NULL,
78 NULL
79 );
80 if (!NT_SUCCESS(Status))
81 {
82 debug_print(L"PSXSS: "__FUNCTION__": NtAcceptConnectPort failed with status=%08x", Status);
83 return Status;
84 }
85 Status = PsxCreateProcess (pRequest,hConnectedPort,ulPortIdentifier);
86 if (!NT_SUCCESS(Status))
87 {
88 debug_print(L"PSXSS: "__FUNCTION__": PsxCreateProcess failed with status=%08x", Status);
89 return Status;
90 }
91 Status = NtCompleteConnectPort (hConnectedPort);
92 if (!NT_SUCCESS(Status))
93 {
94 debug_print(L"PSXSS: "__FUNCTION__": NtCompleteConnectPort failed with status=%08x", Status);
95 return Status;
96 }
97 debug_print (L"PSXSS: <-"__FUNCTION__);
98 return STATUS_SUCCESS;
99 }
100 /**********************************************************************
101 * ProcessRequest/ PRIVATE
102 *
103 * DESCRIPTION
104 * This is the actual POSIX system calls dispatcher.
105 */
106 PRIVATE NTSTATUS STDCALL
107 ProcessRequest (PPSX_MAX_MESSAGE pRequest)
108 {
109 debug_print (L"PSXSS: ->"__FUNCTION__);
110
111 if (pRequest->PsxHeader.Procedure < PSX_SYSCALL_APIPORT_COUNT)
112 {
113 pRequest->PsxHeader.Status =
114 SystemCall [pRequest->PsxHeader.Procedure] (pRequest);
115 }
116 else
117 {
118 pRequest->PsxHeader.Status = STATUS_INVALID_SYSTEM_SERVICE;
119 }
120 return STATUS_SUCCESS;
121 }
122 /**********************************************************************
123 * ApiPortListener/1
124 *
125 * DESCRIPTION
126 * The thread to process messages from the \POSIX+\ApiPort
127 * LPC port. Mostly used by PSXDLL.DLL.
128 */
129 VOID STDCALL
130 ApiPortListener (PVOID pArg)
131 {
132 ULONG ulIndex = (ULONG) pArg;
133 NTSTATUS Status;
134 LPC_TYPE RequestType;
135 ULONG PortIdentifier;
136 PSX_MAX_MESSAGE Request;
137 PPSX_MAX_MESSAGE Reply = NULL;
138 BOOL NullReply = FALSE;
139
140 debug_print (L"PSXSS: ->"__FUNCTION__" pArg=%d", ulIndex);
141
142 while (TRUE)
143 {
144 Reply = NULL;
145 NullReply = FALSE;
146 while (!NullReply)
147 {
148 Status = NtReplyWaitReceivePort (
149 Server.Port[ulIndex].hObject,
150 0,
151 (PLPC_MESSAGE) Reply,
152 (PLPC_MESSAGE) & Request
153 );
154 if (!NT_SUCCESS(Status))
155 {
156 break;
157 }
158 RequestType = PORT_MESSAGE_TYPE(Request);
159 switch (RequestType)
160 {
161 case LPC_CONNECTION_REQUEST:
162 ProcessConnectionRequest ((PLPC_MAX_MESSAGE) & Request);
163 NullReply = TRUE;
164 continue;
165 case LPC_CLIENT_DIED:
166 case LPC_PORT_CLOSED:
167 case LPC_DEBUG_EVENT:
168 case LPC_ERROR_EVENT:
169 case LPC_EXCEPTION:
170 NullReply = TRUE;
171 continue;
172 default:
173 if (RequestType != LPC_REQUEST)
174 {
175 NullReply = TRUE;
176 continue;
177 }
178 }
179 Reply = & Request;
180 Reply->PsxHeader.Status = ProcessRequest (& Request);
181 NullReply = FALSE;
182 }
183 if ((STATUS_INVALID_HANDLE == Status) ||
184 (STATUS_OBJECT_TYPE_MISMATCH == Status))
185 {
186 break;
187 }
188 }
189 #ifdef __PSXSS_ON_W32__
190 TerminateThread(GetCurrentThread(),Status);
191 #else
192 NtTerminateThread(NtCurrentThread(),Status);
193 #endif
194 }
195 /* EOF */