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