[0.4.7][WIN32K:NTUSER] Properly fix IntSendChildNCPaint() & IntLinkWindow()
authorJoachim Henze <Joachim.Henze@reactos.org>
Wed, 23 Dec 2020 01:23:59 +0000 (02:23 +0100)
committerJoachim Henze <Joachim.Henze@reactos.org>
Wed, 23 Dec 2020 01:23:59 +0000 (02:23 +0100)
Hack has been introduced in IntSendChildNCPaint() in r73532 == 6d7fcc4
to attempt to pseudo-fix CORE-12071 and CORE-12085 while breaking other stuff,
amongst which CORE-14763 is one of the latest manifestations, and re-enable the correct original code.

This fixes painting hangs under diverse situations,
while CORE-12071 and CORE-12085 remain fixed.

When it was hanging like CORE-14763, we could not even ACPI shutdown anymore.

fixed by porting back:
0.4.10-dev-324-g 25004bb5b424960358fda4ba9d8438246c0bef9e
0.4.10-dev-323-g ee0511b49db6197897386df44078c8048a49c821
0.4.10-dev-322-g 4d057cf6267bcbe7be3253fa3caa59f5b1feeb87

win32ss/user/ntuser/painting.c
win32ss/user/ntuser/window.c
win32ss/user/ntuser/winpos.c

index 49528e5..3f17402 100644 (file)
@@ -366,38 +366,16 @@ IntSendNCPaint(PWND pWnd, HRGN hRgn)
 VOID FASTCALL
 IntSendChildNCPaint(PWND pWnd)
 {
-   PWND Child;
-   HWND *List, *phWnd;
-
-   List = IntWinListChildren(UserGetDesktopWindow());
-   if ( List )
-   {
-      for (phWnd = List; *phWnd; ++phWnd)
-      {
-          Child = ValidateHwndNoErr(*phWnd);
-          if ( Child && Child->hrgnUpdate == NULL && Child->state & WNDS_SENDNCPAINT)
-          {
-             USER_REFERENCE_ENTRY Ref;
-             UserRefObjectCo(Child, &Ref);
-             IntSendNCPaint(Child, HRGN_WINDOW);
-             UserDerefObjectCo(Child);
-          }
-      }
-      ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
-   }
-/* FIXME : Use snap shot mode until window death is fixed while surfing menus! Fix CORE-12085 and CORE-12071.
-   pWnd = pWnd->spwndChild;
-   while(pWnd)
-   {
-      if (pWnd->hrgnUpdate == NULL && pWnd->state & WNDS_SENDNCPAINT)
-      {
-         USER_REFERENCE_ENTRY Ref;
-         UserRefObjectCo(pWnd, &Ref);
-         IntSendNCPaint(pWnd, HRGN_WINDOW);
-         UserDerefObjectCo(pWnd);
-      }
-      pWnd = pWnd->spwndNext;
-   }*/
+    for (pWnd = pWnd->spwndChild; pWnd; pWnd = pWnd->spwndNext)
+    {
+        if ((pWnd->hrgnUpdate == NULL) && (pWnd->state & WNDS_SENDNCPAINT))
+        {
+            USER_REFERENCE_ENTRY Ref;
+            UserRefObjectCo(pWnd, &Ref);
+            IntSendNCPaint(pWnd, HRGN_WINDOW);
+            UserDerefObjectCo(pWnd);
+        }
+    }
 }
 
 /*
index f58175a..389d969 100644 (file)
@@ -894,32 +894,41 @@ IntIsChildWindow(PWND Parent, PWND BaseWindow)
 }
 ////
 
-/*
-   Link the window into siblings list
-   children and parent are kept in place.
-*/
+/* Link the window into siblings list. Children and parent are kept in place. */
 VOID FASTCALL
 IntLinkWindow(
-   PWND Wnd,
-   PWND WndInsertAfter /* set to NULL if top sibling */
+    PWND Wnd,
+    PWND WndInsertAfter /* Set to NULL if top sibling */
 )
 {
-  if ((Wnd->spwndPrev = WndInsertAfter))
-   {
-      /* link after WndInsertAfter */
-      if ((Wnd->spwndNext = WndInsertAfter->spwndNext))
-         Wnd->spwndNext->spwndPrev = Wnd;
+    if (Wnd == WndInsertAfter)
+    {
+        ERR("IntLinkWindow -- Trying to link window 0x%p to itself!!\n", Wnd);
+        return;
+    }
 
-      Wnd->spwndPrev->spwndNext = Wnd;
-   }
-   else
-   {
-      /* link at top */
-     if ((Wnd->spwndNext = Wnd->spwndParent->spwndChild))
-         Wnd->spwndNext->spwndPrev = Wnd;
+    Wnd->spwndPrev = WndInsertAfter;
+    if (Wnd->spwndPrev)
+    {
+        /* Link after WndInsertAfter */
+        ASSERT(Wnd != WndInsertAfter->spwndNext);
+        Wnd->spwndNext = WndInsertAfter->spwndNext;
+        if (Wnd->spwndNext)
+            Wnd->spwndNext->spwndPrev = Wnd;
+
+        ASSERT(Wnd != Wnd->spwndPrev);
+        Wnd->spwndPrev->spwndNext = Wnd;
+    }
+    else
+    {
+        /* Link at the top */
+        ASSERT(Wnd != Wnd->spwndParent->spwndChild);
+        Wnd->spwndNext = Wnd->spwndParent->spwndChild;
+        if (Wnd->spwndNext)
+            Wnd->spwndNext->spwndPrev = Wnd;
 
-     Wnd->spwndParent->spwndChild = Wnd;
-   }
+        Wnd->spwndParent->spwndChild = Wnd;
+    }
 }
 
 /*
@@ -929,8 +938,8 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
 {
     if (hWndPrev == HWND_NOTOPMOST)
     {
-        if (!(Wnd->ExStyle & WS_EX_TOPMOST) &&
-            (Wnd->ExStyle2 & WS_EX2_LINKED)) return;  /* nothing to do */
+        if (!(Wnd->ExStyle & WS_EX_TOPMOST) && (Wnd->ExStyle2 & WS_EX2_LINKED))
+            return;  /* nothing to do */
         Wnd->ExStyle &= ~WS_EX_TOPMOST;
         hWndPrev = HWND_TOP;  /* fallback to the HWND_TOP case */
     }
@@ -943,8 +952,10 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
         PWND WndInsertAfter;
 
         WndInsertAfter = Wnd->spwndParent->spwndChild;
-        while( WndInsertAfter && WndInsertAfter->spwndNext)
+        while (WndInsertAfter && WndInsertAfter->spwndNext)
+        {
             WndInsertAfter = WndInsertAfter->spwndNext;
+        }
 
         IntLinkWindow(Wnd, WndInsertAfter);
         Wnd->ExStyle &= ~WS_EX_TOPMOST;
@@ -953,7 +964,6 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
     {
         /* Link in the top of the list */
         IntLinkWindow(Wnd, NULL);
-
         Wnd->ExStyle |= WS_EX_TOPMOST;
     }
     else if (hWndPrev == HWND_TOP)
@@ -967,7 +977,9 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
         {
             while (WndInsertBefore != NULL && WndInsertBefore->spwndNext != NULL)
             {
-                if (!(WndInsertBefore->ExStyle & WS_EX_TOPMOST)) break;
+                if (!(WndInsertBefore->ExStyle & WS_EX_TOPMOST))
+                    break;
+
                 if (WndInsertBefore == Wnd->spwndOwner)  /* keep it above owner */
                 {
                     Wnd->ExStyle |= WS_EX_TOPMOST;
@@ -986,13 +998,15 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
 
         WndInsertAfter = UserGetWindowObject(hWndPrev);
         /* Are we called with an erroneous handle */
-        if(WndInsertAfter == NULL)
+        if (WndInsertAfter == NULL)
         {
             /* Link in a default position */
             IntLinkHwnd(Wnd, HWND_TOP);
             return;
         }
 
+        if (Wnd == WndInsertAfter)
+            ERR("IntLinkHwnd -- Trying to link window 0x%p to itself!!\n", Wnd);
         IntLinkWindow(Wnd, WndInsertAfter);
 
         /* Fix the WS_EX_TOPMOST flag */
@@ -1002,8 +1016,8 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
         }
         else
         {
-            if(WndInsertAfter->spwndNext &&
-               WndInsertAfter->spwndNext->ExStyle & WS_EX_TOPMOST)
+            if (WndInsertAfter->spwndNext &&
+                (WndInsertAfter->spwndNext->ExStyle & WS_EX_TOPMOST))
             {
                 Wnd->ExStyle |= WS_EX_TOPMOST;
             }
@@ -1287,20 +1301,23 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
    return( hWndOldParent);
 }
 
-/* Unlink the window from siblings. children and parent are kept in place. */
+/* Unlink the window from siblings. Children and parent are kept in place. */
 VOID FASTCALL
 IntUnlinkWindow(PWND Wnd)
 {
-   if (Wnd->spwndNext)
-       Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
+    ASSERT(Wnd != Wnd->spwndNext);
+    ASSERT(Wnd != Wnd->spwndPrev);
+
+    if (Wnd->spwndNext)
+        Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
 
-   if (Wnd->spwndPrev)
-       Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
+    if (Wnd->spwndPrev)
+        Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
 
-   if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
-       Wnd->spwndParent->spwndChild = Wnd->spwndNext;
+    if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
+        Wnd->spwndParent->spwndChild = Wnd->spwndNext;
 
-   Wnd->spwndPrev = Wnd->spwndNext = NULL;
+    Wnd->spwndPrev = Wnd->spwndNext = NULL;
 }
 
 /* FUNCTIONS *****************************************************************/
index 13e7367..0c8c5b7 100644 (file)
@@ -30,8 +30,6 @@ DBG_DEFAULT_CHANNEL(UserWinpos);
 #define PLACE_MAX               0x0002
 #define PLACE_RECT              0x0004
 
-VOID FASTCALL IntLinkWindow(PWND Wnd,PWND WndInsertAfter);
-
 /* FUNCTIONS *****************************************************************/
 
 #if DBG