update for HEAD-2003050101
[reactos.git] / subsys / csrss / api / wapi.c
1 /* $Id$
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 <windows.h>
15 #include <ntdll/rtl.h>
16 #include <csrss/csrss.h>
17 #include <debug.h>
18
19 #include "api.h"
20
21 /* GLOBALS *******************************************************************/
22
23 HANDLE CsrssApiHeap;
24
25 /* FUNCTIONS *****************************************************************/
26
27 typedef NTSTATUS (*CsrFunc)( PCSRSS_PROCESS_DATA, PCSRSS_API_REQUEST, PCSRSS_API_REPLY );
28
29 static const CsrFunc CsrFuncs[] = {
30    CsrCreateProcess,
31    CsrTerminateProcess,
32    CsrWriteConsole,
33    CsrReadConsole,
34    CsrAllocConsole,
35    CsrFreeConsole,
36    CsrConnectProcess,
37    CsrGetScreenBufferInfo,
38    CsrSetCursor,
39    CsrFillOutputChar,
40    CsrReadInputEvent,
41    CsrWriteConsoleOutputChar,
42    CsrWriteConsoleOutputAttrib,
43    CsrFillOutputAttrib,
44    CsrGetCursorInfo,
45    CsrSetCursorInfo,
46    CsrSetTextAttrib,
47    CsrGetConsoleMode,
48    CsrSetConsoleMode,
49    CsrCreateScreenBuffer,
50    CsrSetScreenBuffer,
51    CsrSetTitle,
52    CsrGetTitle,
53    CsrWriteConsoleOutput,
54    CsrFlushInputBuffer,
55    CsrScrollConsoleScreenBuffer,
56    CsrReadConsoleOutputChar,
57    CsrReadConsoleOutputAttrib,
58    CsrGetNumberOfConsoleInputEvents,
59    CsrRegisterServicesProcess,
60    CsrExitReactos,
61    CsrGetShutdownParameters,
62    CsrSetShutdownParameters,
63    CsrPeekConsoleInput,
64    CsrReadConsoleOutput,
65    CsrWriteConsoleInput,
66    CsrGetInputHandle,
67    CsrGetOutputHandle,
68    CsrCloseHandle,
69    CsrVerifyHandle,
70    CsrDuplicateHandle,
71    0 };
72
73 static void Thread_Api2(HANDLE ServerPort)
74 {
75    NTSTATUS Status;
76    LPC_MAX_MESSAGE LpcReply;
77    LPC_MAX_MESSAGE LpcRequest;
78    PCSRSS_API_REQUEST Request;
79    PCSRSS_PROCESS_DATA ProcessData;
80    PCSRSS_API_REPLY Reply;
81    
82    Reply = NULL;
83    
84    for (;;)
85      {
86         Status = NtReplyWaitReceivePort(ServerPort,
87                                         0,
88                                         &Reply->Header,
89                                         &LpcRequest.Header);
90         if ( !NT_SUCCESS( Status ) )
91           {
92              DisplayString(L"CSR: NtReplyWaitReceivePort failed\n");
93           }
94         
95         if ( LpcRequest.Header.MessageType == LPC_PORT_CLOSED )
96
97           {
98              CsrFreeProcessData( (ULONG)LpcRequest.Header.Cid.UniqueProcess );
99              NtClose(ServerPort);
100              NtTerminateThread(NtCurrentThread(), STATUS_SUCCESS);
101              continue;
102           }
103         
104         Request = (PCSRSS_API_REQUEST)&LpcRequest;
105         Reply = (PCSRSS_API_REPLY)&LpcReply;
106         
107         ProcessData = CsrGetProcessData(
108                                   (ULONG)LpcRequest.Header.Cid.UniqueProcess);
109         
110 //      DisplayString(L"CSR: Received request\n");
111         if( Request->Type >= (sizeof( CsrFuncs ) / sizeof( CsrFunc )) - 1 )
112             Reply->Status = STATUS_INVALID_SYSTEM_SERVICE;
113         else CsrFuncs[ Request->Type ]( ProcessData, Request, Reply );
114      }
115 }
116
117 /**********************************************************************
118  * NAME
119  *      Thread_Api
120  *
121  * DESCRIPTION
122  *      Handle connection requests from clients to the port
123  *      "\Windows\ApiPort".
124  */
125 void Thread_Api(PVOID PortHandle)
126 {
127    NTSTATUS Status;
128    LPC_MAX_MESSAGE Request;
129    HANDLE ServerPort;
130    HANDLE ServerThread;
131    PCSRSS_PROCESS_DATA ProcessData;
132    
133    CsrInitProcessData();
134    
135    for (;;)
136      {
137        LPC_SECTION_READ LpcRead;
138
139         Status = NtListenPort(PortHandle, &Request.Header);
140         if (!NT_SUCCESS(Status))
141           {
142              DisplayString(L"CSR: NtListenPort() failed\n");
143              NtTerminateThread(NtCurrentThread(), Status);
144           }
145         
146         Status = NtAcceptConnectPort(&ServerPort,
147                                      PortHandle,
148                                      NULL,
149                                      1,
150                                      0,
151                                      &LpcRead);
152         if (!NT_SUCCESS(Status))
153           {
154              DisplayString(L"CSR: NtAcceptConnectPort() failed\n");
155              NtTerminateThread(NtCurrentThread(), Status);
156           }
157
158         ProcessData = CsrGetProcessData((ULONG)Request.Header.Cid.UniqueProcess);
159         ProcessData->CsrSectionViewBase = LpcRead.ViewBase;
160         ProcessData->CsrSectionViewSize = LpcRead.ViewSize;
161         
162         Status = NtCompleteConnectPort(ServerPort);
163         if (!NT_SUCCESS(Status))
164           {
165              DisplayString(L"CSR: NtCompleteConnectPort() failed\n");
166              NtTerminateThread(NtCurrentThread(), Status);
167           }
168         
169         Status = RtlCreateUserThread(NtCurrentProcess(),
170                                      NULL,
171                                      FALSE,
172                                      0,
173                                      NULL,
174                                      NULL,
175                                      (PTHREAD_START_ROUTINE)Thread_Api2,
176                                      ServerPort,
177                                      &ServerThread,
178                                      NULL);
179         if (!NT_SUCCESS(Status))
180           {
181              DisplayString(L"CSR: Unable to create server thread\n");
182              NtClose(ServerPort);
183              NtTerminateThread(NtCurrentThread(), Status);
184           }
185         NtClose(ServerThread);
186      }
187 }
188
189 /* EOF */