4d19d35f8779bfa72e0f0d66994992da674a6ab4
[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    CsrHardwareStateProperty,
72    0 };
73
74 static void Thread_Api2(HANDLE ServerPort)
75 {
76    NTSTATUS Status;
77    LPC_MAX_MESSAGE LpcReply;
78    LPC_MAX_MESSAGE LpcRequest;
79    PCSRSS_API_REQUEST Request;
80    PCSRSS_PROCESS_DATA ProcessData;
81    PCSRSS_API_REPLY Reply;
82    
83    Reply = NULL;
84    
85    for (;;)
86      {
87         Status = NtReplyWaitReceivePort(ServerPort,
88                                         0,
89                                         &Reply->Header,
90                                         &LpcRequest.Header);
91         if ( !NT_SUCCESS( Status ) )
92           {
93              DisplayString(L"CSR: NtReplyWaitReceivePort failed\n");
94           }
95         
96         if ( LpcRequest.Header.MessageType == LPC_PORT_CLOSED )
97
98           {
99              CsrFreeProcessData( (ULONG)LpcRequest.Header.ClientId.UniqueProcess );
100              NtClose(ServerPort);
101              NtTerminateThread(NtCurrentThread(), STATUS_SUCCESS);
102              continue;
103           }
104         
105         Request = (PCSRSS_API_REQUEST)&LpcRequest;
106         Reply = (PCSRSS_API_REPLY)&LpcReply;
107         
108         ProcessData = CsrGetProcessData(
109                                   (ULONG)LpcRequest.Header.ClientId.UniqueProcess);
110         
111 //      DisplayString(L"CSR: Received request\n");
112         if( Request->Type >= (sizeof( CsrFuncs ) / sizeof( CsrFunc )) - 1 )
113             Reply->Status = STATUS_INVALID_SYSTEM_SERVICE;
114         else CsrFuncs[ Request->Type ]( ProcessData, Request, Reply );
115      }
116 }
117
118 /**********************************************************************
119  * NAME
120  *      Thread_Api
121  *
122  * DESCRIPTION
123  *      Handle connection requests from clients to the port
124  *      "\Windows\ApiPort".
125  */
126 void Thread_Api(PVOID PortHandle)
127 {
128    NTSTATUS Status;
129    LPC_MAX_MESSAGE Request;
130    HANDLE ServerPort;
131    HANDLE ServerThread;
132    PCSRSS_PROCESS_DATA ProcessData;
133    
134    CsrInitProcessData();
135    
136    for (;;)
137      {
138        LPC_SECTION_READ LpcRead;
139
140         Status = NtListenPort(PortHandle, &Request.Header);
141         if (!NT_SUCCESS(Status))
142           {
143              DisplayString(L"CSR: NtListenPort() failed\n");
144              NtTerminateThread(NtCurrentThread(), Status);
145           }
146         
147         Status = NtAcceptConnectPort(&ServerPort,
148                                      PortHandle,
149                                      NULL,
150                                      1,
151                                      0,
152                                      &LpcRead);
153         if (!NT_SUCCESS(Status))
154           {
155              DisplayString(L"CSR: NtAcceptConnectPort() failed\n");
156              NtTerminateThread(NtCurrentThread(), Status);
157           }
158
159         ProcessData = CsrGetProcessData((ULONG)Request.Header.ClientId.UniqueProcess);
160         ProcessData->CsrSectionViewBase = LpcRead.ViewBase;
161         ProcessData->CsrSectionViewSize = LpcRead.ViewSize;
162         
163         Status = NtCompleteConnectPort(ServerPort);
164         if (!NT_SUCCESS(Status))
165           {
166              DisplayString(L"CSR: NtCompleteConnectPort() failed\n");
167              NtTerminateThread(NtCurrentThread(), Status);
168           }
169         
170         Status = RtlCreateUserThread(NtCurrentProcess(),
171                                      NULL,
172                                      FALSE,
173                                      0,
174                                      NULL,
175                                      NULL,
176                                      (PTHREAD_START_ROUTINE)Thread_Api2,
177                                      ServerPort,
178                                      &ServerThread,
179                                      NULL);
180         if (!NT_SUCCESS(Status))
181           {
182              DisplayString(L"CSR: Unable to create server thread\n");
183              NtClose(ServerPort);
184              NtTerminateThread(NtCurrentThread(), Status);
185           }
186         NtClose(ServerThread);
187      }
188 }
189
190 /* EOF */