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