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