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