Fixes for problems with NtReplyWaitReceive and KeWaitForSingleObject
[reactos.git] / reactos / subsys / csrss / api / wapi.c
1 /* $Id: wapi.c,v 1.10 2001/01/18 15:00:09 dwelch 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 <ddk/ntddk.h>
14 #include <ntdll/rtl.h>
15 #include <csrss/csrss.h>
16
17 #include "api.h"
18
19 /* GLOBALS *******************************************************************/
20
21 HANDLE CsrssApiHeap;
22
23 /* FUNCTIONS *****************************************************************/
24
25 typedef NTSTATUS (*CsrFunc)( PCSRSS_PROCESS_DATA, PCSRSS_API_REQUEST, PCSRSS_API_REPLY );
26
27 static const CsrFunc CsrFuncs[] = {
28 CsrCreateProcess,
29 CsrTerminateProcess,
30 CsrWriteConsole,
31 CsrReadConsole,
32 CsrAllocConsole,
33 CsrFreeConsole,
34 CsrConnectProcess,
35 CsrGetScreenBufferInfo,
36 CsrSetCursor,
37 CsrFillOutputChar,
38 CsrReadInputEvent,
39 CsrWriteConsoleOutputChar,
40 CsrWriteConsoleOutputAttrib,
41 CsrFillOutputAttrib,
42 CsrGetCursorInfo,
43 CsrSetCursorInfo,
44 CsrSetTextAttrib,
45 CsrGetConsoleMode,
46 CsrSetConsoleMode,
47 0 };
48
49 static void Thread_Api2(HANDLE ServerPort)
50 {
51 NTSTATUS Status;
52 LPC_MAX_MESSAGE LpcReply;
53 LPC_MAX_MESSAGE LpcRequest;
54 PCSRSS_API_REQUEST Request;
55 PCSRSS_PROCESS_DATA ProcessData;
56 PCSRSS_API_REPLY Reply;
57
58 Reply = NULL;
59
60 for (;;)
61 {
62 Status = NtReplyWaitReceivePort(ServerPort,
63 0,
64 &Reply->Header,
65 &LpcRequest.Header);
66 if (!NT_SUCCESS(Status) &&
67 Status != STATUS_PORT_DISCONNECTED)
68 {
69 DisplayString(L"CSR: NtReplyWaitReceivePort failed\n");
70 }
71
72 if (LpcRequest.Header.MessageType == LPC_PORT_CLOSED ||
73 Status == STATUS_PORT_DISCONNECTED)
74 {
75 CsrFreeProcessData( LpcRequest.Header.Cid.UniqueProcess );
76 NtClose(ServerPort);
77 NtTerminateThread(NtCurrentThread(), STATUS_SUCCESS);
78 }
79
80 Request = (PCSRSS_API_REQUEST)&LpcRequest;
81 Reply = (PCSRSS_API_REPLY)&LpcReply;
82
83 ProcessData = CsrGetProcessData(
84 (ULONG)LpcRequest.Header.Cid.UniqueProcess);
85
86 // DisplayString(L"CSR: Received request\n");
87 if( Request->Type >= (sizeof( CsrFuncs ) / sizeof( CsrFunc )) - 1 )
88 Reply->Status = STATUS_INVALID_SYSTEM_SERVICE;
89 else CsrFuncs[ Request->Type ]( ProcessData, Request, Reply );
90 }
91 }
92
93 /**********************************************************************
94 * NAME
95 * Thread_Api
96 *
97 * DESCRIPTION
98 * Handle connection requests from clients to the port
99 * "\Windows\ApiPort".
100 */
101 void Thread_Api(PVOID PortHandle)
102 {
103 NTSTATUS Status;
104 LPC_MAX_MESSAGE Request;
105 HANDLE ServerPort;
106 HANDLE ServerThread;
107
108 CsrInitProcessData();
109
110 for (;;)
111 {
112 Status = NtListenPort(PortHandle, &Request.Header);
113 if (!NT_SUCCESS(Status))
114 {
115 DisplayString(L"CSR: NtListenPort() failed\n");
116 NtTerminateThread(NtCurrentThread(), Status);
117 }
118
119 Status = NtAcceptConnectPort(&ServerPort,
120 PortHandle,
121 NULL,
122 1,
123 0,
124 NULL);
125 if (!NT_SUCCESS(Status))
126 {
127 DisplayString(L"CSR: NtAcceptConnectPort() failed\n");
128 NtTerminateThread(NtCurrentThread(), Status);
129 }
130
131 Status = NtCompleteConnectPort(ServerPort);
132 if (!NT_SUCCESS(Status))
133 {
134 DisplayString(L"CSR: NtCompleteConnectPort() failed\n");
135 NtTerminateThread(NtCurrentThread(), Status);
136 }
137
138 Status = RtlCreateUserThread(NtCurrentProcess(),
139 NULL,
140 FALSE,
141 0,
142 NULL,
143 NULL,
144 (PTHREAD_START_ROUTINE)Thread_Api2,
145 ServerPort,
146 &ServerThread,
147 NULL);
148 if (!NT_SUCCESS(Status))
149 {
150 DisplayString(L"CSR: Unable to create server thread\n");
151 NtClose(ServerPort);
152 NtTerminateThread(NtCurrentThread(), Status);
153 }
154 NtClose(ServerThread);
155 }
156 }
157