xref: /reactos/win32ss/user/winsrv/usersrv/init.c (revision c2c66aff)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS User API Server DLL
4  * FILE:            win32ss/user/winsrv/usersrv/init.c
5  * PURPOSE:         Initialization
6  * PROGRAMMERS:     Dmitry Philippov (shedon@mail.ru)
7  *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include "usersrv.h"
13 
14 #include "api.h"
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 /* GLOBALS ********************************************************************/
20 
21 HINSTANCE UserServerDllInstance = NULL;
22 
23 /* Handles for Power and Media events. Used by both usersrv and win32k. */
24 HANDLE ghPowerRequestEvent;
25 HANDLE ghMediaRequestEvent;
26 
27 /* Copy of CSR Port handle for win32k */
28 HANDLE CsrApiPort = NULL;
29 
30 /* Memory */
31 HANDLE UserServerHeap = NULL;   // Our own heap.
32 
33 // Windows Server 2003 table from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_2k3
34 PCSR_API_ROUTINE UserServerApiDispatchTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] =
35 {
36     SrvExitWindowsEx,
37     SrvEndTask,
38     SrvLogon,
39     SrvRegisterServicesProcess, // Not present in Win7
40     SrvActivateDebugger,
41     SrvGetThreadConsoleDesktop, // Not present in Win7
42     SrvDeviceEvent,
43     SrvRegisterLogonProcess,    // Not present in Win7
44     SrvCreateSystemThreads,
45     SrvRecordShutdownReason,
46     // SrvCancelShutdown,              // Added in Vista
47     // SrvConsoleHandleOperation,      // Added in Win7
48     // SrvGetSetShutdownBlockReason,   // Added in Vista
49 };
50 
51 BOOLEAN UserServerApiServerValidTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] =
52 {
53     FALSE,   // SrvExitWindowsEx
54     FALSE,   // SrvEndTask
55     FALSE,   // SrvLogon
56     FALSE,   // SrvRegisterServicesProcess
57     FALSE,   // SrvActivateDebugger
58     TRUE,    // SrvGetThreadConsoleDesktop
59     FALSE,   // SrvDeviceEvent
60     FALSE,   // SrvRegisterLogonProcess
61     FALSE,   // SrvCreateSystemThreads
62     FALSE,   // SrvRecordShutdownReason
63     // FALSE,   // SrvCancelShutdown
64     // FALSE,   // SrvConsoleHandleOperation
65     // FALSE,   // SrvGetSetShutdownBlockReason
66 };
67 
68 /*
69  * On Windows Server 2003, CSR Servers contain
70  * the API Names Table only in Debug Builds.
71  */
72 #ifdef CSR_DBG
73 PCHAR UserServerApiNameTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] =
74 {
75     "SrvExitWindowsEx",
76     "SrvEndTask",
77     "SrvLogon",
78     "SrvRegisterServicesProcess",
79     "SrvActivateDebugger",
80     "SrvGetThreadConsoleDesktop",
81     "SrvDeviceEvent",
82     "SrvRegisterLogonProcess",
83     "SrvCreateSystemThreads",
84     "SrvRecordShutdownReason",
85     // "SrvCancelShutdown",
86     // "SrvConsoleHandleOperation",
87     // "SrvGetSetShutdownBlockReason",
88 };
89 #endif
90 
91 /* FUNCTIONS ******************************************************************/
92 
93 // PUSER_SOUND_SENTRY. Used in basesrv.dll
94 BOOL NTAPI _UserSoundSentry(VOID)
95 {
96     // TODO: Do something.
97     return TRUE;
98 }
99 
100 ULONG
101 NTAPI
102 CreateSystemThreads(PVOID pParam)
103 {
104     NtUserCallOneParam((DWORD)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS);
105     RtlExitUserThread(0);
106     return 0;
107 }
108 
109 CSR_API(SrvCreateSystemThreads)
110 {
111     DPRINT1("%s not yet implemented\n", __FUNCTION__);
112     return STATUS_NOT_IMPLEMENTED;
113 }
114 
115 CSR_API(SrvActivateDebugger)
116 {
117     DPRINT1("%s not yet implemented\n", __FUNCTION__);
118     return STATUS_NOT_IMPLEMENTED;
119 }
120 
121 CSR_API(SrvGetThreadConsoleDesktop)
122 {
123     PUSER_GET_THREAD_CONSOLE_DESKTOP GetThreadConsoleDesktopRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.GetThreadConsoleDesktopRequest;
124 
125     DPRINT1("%s not yet implemented\n", __FUNCTION__);
126 
127     /* Return nothing for the moment... */
128     GetThreadConsoleDesktopRequest->ConsoleDesktop = NULL;
129 
130     /* Always succeeds */
131     return STATUS_SUCCESS;
132 }
133 
134 CSR_API(SrvDeviceEvent)
135 {
136     DPRINT1("%s not yet implemented\n", __FUNCTION__);
137     return STATUS_NOT_IMPLEMENTED;
138 }
139 
140 CSR_API(SrvLogon)
141 {
142     PUSER_LOGON LogonRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.LogonRequest;
143 
144     DPRINT1("We are logged %s\n", LogonRequest->IsLogon ? "on" : "off");
145 
146     /* Impersonate the caller in order to retrieve settings in its context */
147     if (!CsrImpersonateClient(NULL))
148         return STATUS_UNSUCCESSFUL;
149 
150     GetTimeouts(&ShutdownSettings);
151 
152     /* We are done */
153     CsrRevertToSelf();
154     return STATUS_SUCCESS;
155 }
156 
157 NTSTATUS
158 NTAPI
159 UserClientConnect(IN PCSR_PROCESS CsrProcess,
160                   IN OUT PVOID  ConnectionInfo,
161                   IN OUT PULONG ConnectionInfoLength)
162 {
163     NTSTATUS Status;
164     // PUSERCONNECT
165     PUSERSRV_API_CONNECTINFO ConnectInfo = (PUSERSRV_API_CONNECTINFO)ConnectionInfo;
166 
167     DPRINT("UserClientConnect\n");
168 
169     /* Check if we don't have an API port yet */
170     if (CsrApiPort == NULL)
171     {
172         /* Query the API port and save it globally */
173         CsrApiPort = CsrQueryApiPort();
174 
175         /* Inform win32k about the API port */
176         Status = NtUserSetInformationThread(NtCurrentThread(),
177                                             UserThreadCsrApiPort,
178                                             &CsrApiPort,
179                                             sizeof(CsrApiPort));
180         if (!NT_SUCCESS(Status))
181         {
182             return Status;
183         }
184     }
185 
186     /* Check connection info validity */
187     if ( ConnectionInfo       == NULL ||
188          ConnectionInfoLength == NULL ||
189         *ConnectionInfoLength != sizeof(*ConnectInfo) )
190     {
191         DPRINT1("USERSRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), expected %lu\n",
192                 ConnectionInfo,
193                 ConnectionInfoLength,
194                 ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1,
195                 sizeof(*ConnectInfo));
196 
197         return STATUS_INVALID_PARAMETER;
198     }
199 
200     /* Pass the request to win32k */
201     ConnectInfo->dwDispatchCount = 0; // gDispatchTableValues;
202     Status = NtUserProcessConnect(CsrProcess->ProcessHandle,
203                                   ConnectInfo,
204                                   *ConnectionInfoLength);
205 
206     return Status;
207 }
208 
209 CSR_SERVER_DLL_INIT(UserServerDllInitialization)
210 {
211     NTSTATUS Status;
212 
213     /* Initialize the memory */
214     UserServerHeap = RtlGetProcessHeap();
215 
216     /* Setup the DLL Object */
217     LoadedServerDll->ApiBase = USERSRV_FIRST_API_NUMBER;
218     LoadedServerDll->HighestApiSupported = UserpMaxApiNumber;
219     LoadedServerDll->DispatchTable = UserServerApiDispatchTable;
220     LoadedServerDll->ValidTable = UserServerApiServerValidTable;
221 #ifdef CSR_DBG
222     LoadedServerDll->NameTable = UserServerApiNameTable;
223 #endif
224     LoadedServerDll->SizeOfProcessData = 0;
225     LoadedServerDll->ConnectCallback = UserClientConnect;
226     LoadedServerDll->DisconnectCallback = NULL;
227     LoadedServerDll->HardErrorCallback = UserServerHardError;
228     LoadedServerDll->ShutdownProcessCallback = UserClientShutdown;
229 
230     UserServerDllInstance = LoadedServerDll->ServerHandle;
231 
232     /* Create the power request event */
233     Status = NtCreateEvent(&ghPowerRequestEvent,
234                            EVENT_ALL_ACCESS,
235                            NULL,
236                            SynchronizationEvent,
237                            FALSE);
238     if (!NT_SUCCESS(Status))
239     {
240         DPRINT1("Power request event creation failed with Status 0x%08x\n", Status);
241         return Status;
242     }
243 
244     /* Create the media request event */
245     Status = NtCreateEvent(&ghMediaRequestEvent,
246                            EVENT_ALL_ACCESS,
247                            NULL,
248                            SynchronizationEvent,
249                            FALSE);
250     if (!NT_SUCCESS(Status))
251     {
252         DPRINT1("Media request event creation failed with Status 0x%08x\n", Status);
253         return Status;
254     }
255 
256     /* Set the process creation notify routine for BASE */
257     BaseSetProcessCreateNotify(NtUserNotifyProcessCreate);
258 
259     /* Initialize the kernel mode subsystem */
260     Status = NtUserInitialize(USER_VERSION,
261                               ghPowerRequestEvent,
262                               ghMediaRequestEvent);
263     if (!NT_SUCCESS(Status))
264     {
265         DPRINT1("NtUserInitialize failed with Status 0x%08x\n", Status);
266         return Status;
267     }
268 
269 /*** From win32csr... See r54125 ***/
270     {
271         HANDLE ServerThread;
272         CLIENT_ID ClientId;
273         UINT i;
274 
275         /* Start the Raw Input Thread and the Desktop Thread */
276         for (i = 0; i < 2; ++i)
277         {
278             Status = RtlCreateUserThread(NtCurrentProcess(),
279                                          NULL, TRUE, 0, 0, 0,
280                                          CreateSystemThreads,
281                                          (PVOID)i, &ServerThread, &ClientId);
282             if (NT_SUCCESS(Status))
283             {
284                 NtResumeThread(ServerThread, NULL);
285                 NtClose(ServerThread);
286             }
287             else
288             {
289                 DPRINT1("Cannot start Raw Input Thread!\n");
290             }
291         }
292     }
293 /*** END - From win32csr... ***/
294 
295     /* All done */
296     return STATUS_SUCCESS;
297 }
298 
299 /* EOF */
300