xref: /reactos/win32ss/user/winsrv/usersrv/init.c (revision 8540ab04)
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     DPRINT1("%s not yet implemented\n", __FUNCTION__);
125     return STATUS_NOT_IMPLEMENTED;
126 }
127 
128 CSR_API(SrvActivateDebugger)
129 {
130     DPRINT1("%s not yet implemented\n", __FUNCTION__);
131     return STATUS_NOT_IMPLEMENTED;
132 }
133 
134 CSR_API(SrvGetThreadConsoleDesktop)
135 {
136     PUSER_GET_THREAD_CONSOLE_DESKTOP GetThreadConsoleDesktopRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.GetThreadConsoleDesktopRequest;
137 
138     DPRINT1("%s not yet implemented\n", __FUNCTION__);
139 
140     /* Return nothing for the moment... */
141     GetThreadConsoleDesktopRequest->ConsoleDesktop = NULL;
142 
143     /* Always succeeds */
144     return STATUS_SUCCESS;
145 }
146 
147 CSR_API(SrvDeviceEvent)
148 {
149     DPRINT1("%s not yet implemented\n", __FUNCTION__);
150     return STATUS_NOT_IMPLEMENTED;
151 }
152 
153 CSR_API(SrvLogon)
154 {
155     PUSER_LOGON LogonRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.LogonRequest;
156 
157     DPRINT1("We are logged %s\n", LogonRequest->IsLogon ? "on" : "off");
158 
159     /* Impersonate the caller in order to retrieve settings in its context */
160     if (!CsrImpersonateClient(NULL))
161         return STATUS_UNSUCCESSFUL;
162 
163     GetTimeouts(&ShutdownSettings);
164 
165     /* We are done */
166     CsrRevertToSelf();
167     return STATUS_SUCCESS;
168 }
169 
170 NTSTATUS
171 NTAPI
172 UserClientConnect(IN PCSR_PROCESS CsrProcess,
173                   IN OUT PVOID  ConnectionInfo,
174                   IN OUT PULONG ConnectionInfoLength)
175 {
176     NTSTATUS Status;
177     // PUSERCONNECT
178     PUSERSRV_API_CONNECTINFO ConnectInfo = (PUSERSRV_API_CONNECTINFO)ConnectionInfo;
179 
180     DPRINT("UserClientConnect\n");
181 
182     /* Check if we don't have an API port yet */
183     if (CsrApiPort == NULL)
184     {
185         /* Query the API port and save it globally */
186         CsrApiPort = CsrQueryApiPort();
187 
188         /* Inform win32k about the API port */
189         Status = NtUserSetInformationThread(NtCurrentThread(),
190                                             UserThreadCsrApiPort,
191                                             &CsrApiPort,
192                                             sizeof(CsrApiPort));
193         if (!NT_SUCCESS(Status))
194         {
195             return Status;
196         }
197     }
198 
199     /* Check connection info validity */
200     if ( ConnectionInfo       == NULL ||
201          ConnectionInfoLength == NULL ||
202         *ConnectionInfoLength != sizeof(*ConnectInfo) )
203     {
204         DPRINT1("USERSRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), expected %lu\n",
205                 ConnectionInfo,
206                 ConnectionInfoLength,
207                 ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1,
208                 sizeof(*ConnectInfo));
209 
210         return STATUS_INVALID_PARAMETER;
211     }
212 
213     /* Pass the request to win32k */
214     ConnectInfo->dwDispatchCount = 0; // gDispatchTableValues;
215     Status = NtUserProcessConnect(CsrProcess->ProcessHandle,
216                                   ConnectInfo,
217                                   *ConnectionInfoLength);
218 
219     return Status;
220 }
221 
222 CSR_SERVER_DLL_INIT(UserServerDllInitialization)
223 {
224     NTSTATUS Status;
225 
226     /* Initialize the memory */
227     UserServerHeap = RtlGetProcessHeap();
228 
229     /* Setup the DLL Object */
230     LoadedServerDll->ApiBase = USERSRV_FIRST_API_NUMBER;
231     LoadedServerDll->HighestApiSupported = UserpMaxApiNumber;
232     LoadedServerDll->DispatchTable = UserServerApiDispatchTable;
233     LoadedServerDll->ValidTable = UserServerApiServerValidTable;
234 #ifdef CSR_DBG
235     LoadedServerDll->NameTable = UserServerApiNameTable;
236 #endif
237     LoadedServerDll->SizeOfProcessData = 0;
238     LoadedServerDll->ConnectCallback = UserClientConnect;
239     LoadedServerDll->DisconnectCallback = NULL;
240     LoadedServerDll->HardErrorCallback = UserServerHardError;
241     LoadedServerDll->ShutdownProcessCallback = UserClientShutdown;
242 
243     UserServerDllInstance = LoadedServerDll->ServerHandle;
244 
245     /* Create the power request event */
246     Status = NtCreateEvent(&ghPowerRequestEvent,
247                            EVENT_ALL_ACCESS,
248                            NULL,
249                            SynchronizationEvent,
250                            FALSE);
251     if (!NT_SUCCESS(Status))
252     {
253         DPRINT1("Power request event creation failed with Status 0x%08x\n", Status);
254         return Status;
255     }
256 
257     /* Create the media request event */
258     Status = NtCreateEvent(&ghMediaRequestEvent,
259                            EVENT_ALL_ACCESS,
260                            NULL,
261                            SynchronizationEvent,
262                            FALSE);
263     if (!NT_SUCCESS(Status))
264     {
265         DPRINT1("Media request event creation failed with Status 0x%08x\n", Status);
266         return Status;
267     }
268 
269     /* Set the process creation notify routine for BASE */
270     BaseSetProcessCreateNotify(NtUserNotifyProcessCreate);
271 
272     /* Initialize the hard errors cache */
273     UserInitHardErrorsCache();
274 
275     /* Initialize the kernel mode subsystem */
276     Status = NtUserInitialize(USER_VERSION,
277                               ghPowerRequestEvent,
278                               ghMediaRequestEvent);
279     if (!NT_SUCCESS(Status))
280     {
281         DPRINT1("NtUserInitialize failed with Status 0x%08x\n", Status);
282         return Status;
283     }
284 
285 /*** From win32csr... See r54125 ***/
286     {
287         HANDLE ServerThread;
288         CLIENT_ID ClientId;
289         UINT i;
290 
291         /* Start the Raw Input Thread and the Desktop Thread */
292         for (i = 0; i < 2; ++i)
293         {
294             Status = RtlCreateUserThread(NtCurrentProcess(),
295                                          NULL,
296                                          TRUE,
297                                          0,
298                                          0,
299                                          0,
300                                          CreateSystemThreads,
301                                          UlongToPtr(i),
302                                          &ServerThread,
303                                          &ClientId);
304             if (NT_SUCCESS(Status))
305             {
306                 NtResumeThread(ServerThread, NULL);
307                 NtClose(ServerThread);
308             }
309             else
310             {
311                 DPRINT1("Cannot start Raw Input Thread!\n");
312             }
313         }
314     }
315 /*** END - From win32csr... ***/
316 
317     /* All done */
318     return STATUS_SUCCESS;
319 }
320 
321 /* EOF */
322