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