[USERSRV] Hard-error improvements 3/7
[reactos.git] / win32ss / user / winsrv / usersrv / init.c
index 8949e60..8ee21e6 100644 (file)
 
 HINSTANCE UserServerDllInstance = NULL;
 
+/* Handles for Power and Media events. Used by both usersrv and win32k. */
+HANDLE ghPowerRequestEvent;
+HANDLE ghMediaRequestEvent;
+
+/* Copy of CSR Port handle for win32k */
+HANDLE CsrApiPort = NULL;
+
 /* Memory */
 HANDLE UserServerHeap = NULL;   // Our own heap.
 
@@ -83,19 +90,24 @@ PCHAR UserServerApiNameTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] =
 
 /* FUNCTIONS ******************************************************************/
 
-// PUSER_SOUND_SENTRY. Used in basesrv.dll
-BOOL WINAPI _UserSoundSentry(VOID)
+BOOL CALLBACK
+FindTopLevelWnd(
+    IN HWND hWnd,
+    IN LPARAM lParam)
 {
-    // TODO: Do something.
+    if (GetWindow(hWnd, GW_OWNER) == NULL)
+    {
+        *(HWND*)lParam = hWnd;
+        return FALSE;
+    }
     return TRUE;
 }
 
-// From win32ss/user/win32csr/dllmain.c
-VOID
-WINAPI
-PrivateCsrssManualGuiCheck(LONG Check)
+// PUSER_SOUND_SENTRY. Used in basesrv.dll
+BOOL NTAPI _UserSoundSentry(VOID)
 {
-    NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK);
+    // TODO: Do something.
+    return TRUE;
 }
 
 ULONG
@@ -103,7 +115,7 @@ NTAPI
 CreateSystemThreads(PVOID pParam)
 {
     NtUserCallOneParam((DWORD)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS);
-    DPRINT1("This thread should not terminate!\n");
+    RtlExitUserThread(0);
     return 0;
 }
 
@@ -121,8 +133,15 @@ CSR_API(SrvActivateDebugger)
 
 CSR_API(SrvGetThreadConsoleDesktop)
 {
+    PUSER_GET_THREAD_CONSOLE_DESKTOP GetThreadConsoleDesktopRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.GetThreadConsoleDesktopRequest;
+
     DPRINT1("%s not yet implemented\n", __FUNCTION__);
-    return STATUS_NOT_IMPLEMENTED;
+
+    /* Return nothing for the moment... */
+    GetThreadConsoleDesktopRequest->ConsoleDesktop = NULL;
+
+    /* Always succeeds */
+    return STATUS_SUCCESS;
 }
 
 CSR_API(SrvDeviceEvent)
@@ -131,22 +150,82 @@ CSR_API(SrvDeviceEvent)
     return STATUS_NOT_IMPLEMENTED;
 }
 
+CSR_API(SrvLogon)
+{
+    PUSER_LOGON LogonRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.LogonRequest;
+
+    DPRINT1("We are logged %s\n", LogonRequest->IsLogon ? "on" : "off");
+
+    /* Impersonate the caller in order to retrieve settings in its context */
+    if (!CsrImpersonateClient(NULL))
+        return STATUS_UNSUCCESSFUL;
+
+    GetTimeouts(&ShutdownSettings);
+
+    /* We are done */
+    CsrRevertToSelf();
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+UserClientConnect(IN PCSR_PROCESS CsrProcess,
+                  IN OUT PVOID  ConnectionInfo,
+                  IN OUT PULONG ConnectionInfoLength)
+{
+    NTSTATUS Status;
+    // PUSERCONNECT
+    PUSERSRV_API_CONNECTINFO ConnectInfo = (PUSERSRV_API_CONNECTINFO)ConnectionInfo;
+
+    DPRINT("UserClientConnect\n");
+
+    /* Check if we don't have an API port yet */
+    if (CsrApiPort == NULL)
+    {
+        /* Query the API port and save it globally */
+        CsrApiPort = CsrQueryApiPort();
+
+        /* Inform win32k about the API port */
+        Status = NtUserSetInformationThread(NtCurrentThread(),
+                                            UserThreadCsrApiPort,
+                                            &CsrApiPort,
+                                            sizeof(CsrApiPort));
+        if (!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
+    }
+
+    /* Check connection info validity */
+    if ( ConnectionInfo       == NULL ||
+         ConnectionInfoLength == NULL ||
+        *ConnectionInfoLength != sizeof(*ConnectInfo) )
+    {
+        DPRINT1("USERSRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), expected %lu\n",
+                ConnectionInfo,
+                ConnectionInfoLength,
+                ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1,
+                sizeof(*ConnectInfo));
+
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Pass the request to win32k */
+    ConnectInfo->dwDispatchCount = 0; // gDispatchTableValues;
+    Status = NtUserProcessConnect(CsrProcess->ProcessHandle,
+                                  ConnectInfo,
+                                  *ConnectionInfoLength);
+
+    return Status;
+}
+
 CSR_SERVER_DLL_INIT(UserServerDllInitialization)
 {
-/*** From win32csr... ***/
-    HANDLE ServerThread;
-    CLIENT_ID ClientId;
     NTSTATUS Status;
-    UINT i;
-/*** END - From win32csr... ***/
 
     /* Initialize the memory */
     UserServerHeap = RtlGetProcessHeap();
 
-    /* Initialize the video */
-    NtUserInitialize(0, NULL, NULL); //
-    PrivateCsrssManualGuiCheck(0);
-
     /* Setup the DLL Object */
     LoadedServerDll->ApiBase = USERSRV_FIRST_API_NUMBER;
     LoadedServerDll->HighestApiSupported = UserpMaxApiNumber;
@@ -156,28 +235,76 @@ CSR_SERVER_DLL_INIT(UserServerDllInitialization)
     LoadedServerDll->NameTable = UserServerApiNameTable;
 #endif
     LoadedServerDll->SizeOfProcessData = 0;
-    LoadedServerDll->ConnectCallback = NULL;
+    LoadedServerDll->ConnectCallback = UserClientConnect;
     LoadedServerDll->DisconnectCallback = NULL;
     LoadedServerDll->HardErrorCallback = UserServerHardError;
-    LoadedServerDll->ShutdownProcessCallback = NULL;
+    LoadedServerDll->ShutdownProcessCallback = UserClientShutdown;
 
     UserServerDllInstance = LoadedServerDll->ServerHandle;
 
+    /* Create the power request event */
+    Status = NtCreateEvent(&ghPowerRequestEvent,
+                           EVENT_ALL_ACCESS,
+                           NULL,
+                           SynchronizationEvent,
+                           FALSE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Power request event creation failed with Status 0x%08x\n", Status);
+        return Status;
+    }
+
+    /* Create the media request event */
+    Status = NtCreateEvent(&ghMediaRequestEvent,
+                           EVENT_ALL_ACCESS,
+                           NULL,
+                           SynchronizationEvent,
+                           FALSE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Media request event creation failed with Status 0x%08x\n", Status);
+        return Status;
+    }
+
+    /* Set the process creation notify routine for BASE */
+    BaseSetProcessCreateNotify(NtUserNotifyProcessCreate);
+
+    /* Initialize the hard errors cache */
+    UserInitHardErrorsCache();
+
+    /* Initialize the kernel mode subsystem */
+    Status = NtUserInitialize(USER_VERSION,
+                              ghPowerRequestEvent,
+                              ghMediaRequestEvent);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("NtUserInitialize failed with Status 0x%08x\n", Status);
+        return Status;
+    }
+
 /*** From win32csr... See r54125 ***/
-    /* Start the Raw Input Thread and the Desktop Thread */
-    for (i = 0; i < 2; ++i)
     {
-        Status = RtlCreateUserThread(NtCurrentProcess(),
-                                     NULL, TRUE, 0, 0, 0,
-                                     CreateSystemThreads,
-                                     (PVOID)i, &ServerThread, &ClientId);
-        if (NT_SUCCESS(Status))
+        HANDLE ServerThread;
+        CLIENT_ID ClientId;
+        UINT i;
+
+        /* Start the Raw Input Thread and the Desktop Thread */
+        for (i = 0; i < 2; ++i)
         {
-            NtResumeThread(ServerThread, NULL);
-            NtClose(ServerThread);
+            Status = RtlCreateUserThread(NtCurrentProcess(),
+                                         NULL, TRUE, 0, 0, 0,
+                                         CreateSystemThreads,
+                                         (PVOID)i, &ServerThread, &ClientId);
+            if (NT_SUCCESS(Status))
+            {
+                NtResumeThread(ServerThread, NULL);
+                NtClose(ServerThread);
+            }
+            else
+            {
+                DPRINT1("Cannot start Raw Input Thread!\n");
+            }
         }
-        else
-            DPRINT1("Cannot start Raw Input Thread!\n");
     }
 /*** END - From win32csr... ***/