[USERSRV] Hard-error improvements 3/7
[reactos.git] / win32ss / user / winsrv / usersrv / init.c
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)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, TRUE, 0, 0, 0,
296 CreateSystemThreads,
297 (PVOID)i, &ServerThread, &ClientId);
298 if (NT_SUCCESS(Status))
299 {
300 NtResumeThread(ServerThread, NULL);
301 NtClose(ServerThread);
302 }
303 else
304 {
305 DPRINT1("Cannot start Raw Input Thread!\n");
306 }
307 }
308 }
309 /*** END - From win32csr... ***/
310
311 /* All done */
312 return STATUS_SUCCESS;
313 }
314
315 /* EOF */