xref: /reactos/win32ss/user/winsrv/usersrv/init.c (revision f04935d8)
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 BOOL CALLBACK
94 FindTopLevelWnd(
95     IN HWND hWnd,
96     IN LPARAM lParam)
97 {
98     if (GetWindow(hWnd, GW_OWNER) == NULL)
99     {
100         *(HWND*)lParam = hWnd;
101         return FALSE;
102     }
103     return TRUE;
104 }
105 
106 // PUSER_SOUND_SENTRY. Used in basesrv.dll
107 BOOL NTAPI _UserSoundSentry(VOID)
108 {
109     // TODO: Do something.
110     return TRUE;
111 }
112 
113 ULONG
114 NTAPI
115 CreateSystemThreads(PVOID pParam)
116 {
117     NtUserCallOneParam((DWORD_PTR)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS);
118     RtlExitUserThread(0);
119     return 0;
120 }
121 
122 CSR_API(SrvCreateSystemThreads)
123 {
124     NTSTATUS Status = CsrExecServerThread(CreateSystemThreads, 0);
125     if (!NT_SUCCESS(Status))
126     {
127         DPRINT1("Cannot start system thread!\n");
128     }
129 
130     return Status;
131 }
132 
133 CSR_API(SrvActivateDebugger)
134 {
135     DPRINT1("%s not yet implemented\n", __FUNCTION__);
136     return STATUS_NOT_IMPLEMENTED;
137 }
138 
139 CSR_API(SrvGetThreadConsoleDesktop)
140 {
141     PUSER_GET_THREAD_CONSOLE_DESKTOP GetThreadConsoleDesktopRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.GetThreadConsoleDesktopRequest;
142 
143     DPRINT1("%s not yet implemented\n", __FUNCTION__);
144 
145     /* Return nothing for the moment... */
146     GetThreadConsoleDesktopRequest->ConsoleDesktop = NULL;
147 
148     /* Always succeeds */
149     return STATUS_SUCCESS;
150 }
151 
152 CSR_API(SrvDeviceEvent)
153 {
154     DPRINT1("%s not yet implemented\n", __FUNCTION__);
155     return STATUS_NOT_IMPLEMENTED;
156 }
157 
158 CSR_API(SrvLogon)
159 {
160     PUSER_LOGON LogonRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.LogonRequest;
161 
162     DPRINT1("We are logged %s\n", LogonRequest->IsLogon ? "on" : "off");
163 
164     /* Impersonate the caller in order to retrieve settings in its context */
165     if (!CsrImpersonateClient(NULL))
166         return STATUS_UNSUCCESSFUL;
167 
168     GetTimeouts(&ShutdownSettings);
169 
170     /* We are done */
171     CsrRevertToSelf();
172     return STATUS_SUCCESS;
173 }
174 
175 NTSTATUS
176 NTAPI
177 UserClientConnect(IN PCSR_PROCESS CsrProcess,
178                   IN OUT PVOID  ConnectionInfo,
179                   IN OUT PULONG ConnectionInfoLength)
180 {
181     NTSTATUS Status;
182     // PUSERCONNECT
183     PUSERSRV_API_CONNECTINFO ConnectInfo = (PUSERSRV_API_CONNECTINFO)ConnectionInfo;
184 
185     DPRINT("UserClientConnect\n");
186 
187     /* Check if we don't have an API port yet */
188     if (CsrApiPort == NULL)
189     {
190         /* Query the API port and save it globally */
191         CsrApiPort = CsrQueryApiPort();
192 
193         /* Inform win32k about the API port */
194         Status = NtUserSetInformationThread(NtCurrentThread(),
195                                             UserThreadCsrApiPort,
196                                             &CsrApiPort,
197                                             sizeof(CsrApiPort));
198         if (!NT_SUCCESS(Status))
199         {
200             return Status;
201         }
202     }
203 
204     /* Check connection info validity */
205     if ( ConnectionInfo       == NULL ||
206          ConnectionInfoLength == NULL ||
207         *ConnectionInfoLength != sizeof(*ConnectInfo) )
208     {
209         DPRINT1("USERSRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), expected %lu\n",
210                 ConnectionInfo,
211                 ConnectionInfoLength,
212                 ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1,
213                 sizeof(*ConnectInfo));
214 
215         return STATUS_INVALID_PARAMETER;
216     }
217 
218     /* Pass the request to win32k */
219     ConnectInfo->dwDispatchCount = 0; // gDispatchTableValues;
220     Status = NtUserProcessConnect(CsrProcess->ProcessHandle,
221                                   ConnectInfo,
222                                   *ConnectionInfoLength);
223 
224     return Status;
225 }
226 
227 CSR_SERVER_DLL_INIT(UserServerDllInitialization)
228 {
229     NTSTATUS Status;
230 
231     /* Initialize the memory */
232     UserServerHeap = RtlGetProcessHeap();
233 
234     /* Setup the DLL Object */
235     LoadedServerDll->ApiBase = USERSRV_FIRST_API_NUMBER;
236     LoadedServerDll->HighestApiSupported = UserpMaxApiNumber;
237     LoadedServerDll->DispatchTable = UserServerApiDispatchTable;
238     LoadedServerDll->ValidTable = UserServerApiServerValidTable;
239 #ifdef CSR_DBG
240     LoadedServerDll->NameTable = UserServerApiNameTable;
241 #endif
242     LoadedServerDll->SizeOfProcessData = 0;
243     LoadedServerDll->ConnectCallback = UserClientConnect;
244     LoadedServerDll->DisconnectCallback = NULL;
245     LoadedServerDll->HardErrorCallback = UserServerHardError;
246     LoadedServerDll->ShutdownProcessCallback = UserClientShutdown;
247 
248     UserServerDllInstance = LoadedServerDll->ServerHandle;
249 
250     /* Create the power request event */
251     Status = NtCreateEvent(&ghPowerRequestEvent,
252                            EVENT_ALL_ACCESS,
253                            NULL,
254                            SynchronizationEvent,
255                            FALSE);
256     if (!NT_SUCCESS(Status))
257     {
258         DPRINT1("Power request event creation failed with Status 0x%08x\n", Status);
259         return Status;
260     }
261 
262     /* Create the media request event */
263     Status = NtCreateEvent(&ghMediaRequestEvent,
264                            EVENT_ALL_ACCESS,
265                            NULL,
266                            SynchronizationEvent,
267                            FALSE);
268     if (!NT_SUCCESS(Status))
269     {
270         DPRINT1("Media request event creation failed with Status 0x%08x\n", Status);
271         return Status;
272     }
273 
274     /* Set the process creation notify routine for BASE */
275     BaseSetProcessCreateNotify(NtUserNotifyProcessCreate);
276 
277     /* Initialize the hard errors cache */
278     UserInitHardErrorsCache();
279 
280     /* Initialize the kernel mode subsystem */
281     Status = NtUserInitialize(USER_VERSION,
282                               ghPowerRequestEvent,
283                               ghMediaRequestEvent);
284     if (!NT_SUCCESS(Status))
285     {
286         DPRINT1("NtUserInitialize failed with Status 0x%08x\n", Status);
287         return Status;
288     }
289 
290     /* All done */
291     return STATUS_SUCCESS;
292 }
293 
294 /* EOF */
295