https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e56da4854fd3c93b3444e11bbbbdb219fa2f2559

commit e56da4854fd3c93b3444e11bbbbdb219fa2f2559
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Tue Dec 6 07:02:12 2022 +0100
Commit:     Timo Kreuzer <[email protected]>
CommitDate: Wed Jan 4 10:32:28 2023 +0100

    [WIN32K] Properly reference owner window
---
 win32ss/user/ntuser/ime.c    | 10 +++++-----
 win32ss/user/ntuser/window.c | 17 ++++++-----------
 win32ss/user/ntuser/window.h | 19 +++++++++++++++++++
 3 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/win32ss/user/ntuser/ime.c b/win32ss/user/ntuser/ime.c
index 5c15a2375dd..97021f0daca 100644
--- a/win32ss/user/ntuser/ime.c
+++ b/win32ss/user/ntuser/ime.c
@@ -1192,7 +1192,7 @@ VOID FASTCALL IntImeSetFutureOwner(PWND pImeWnd, PWND 
pwndOwner)
     pwndParent = pwndNode->spwndParent;
     if (!pwndParent || pwndOwner != pwndNode)
     {
-        pImeWnd->spwndOwner = pwndNode;
+        WndSetOwner(pImeWnd, pwndNode);
         return;
     }
 
@@ -1218,7 +1218,7 @@ VOID FASTCALL IntImeSetFutureOwner(PWND pImeWnd, PWND 
pwndOwner)
         }
     }
 
-    pImeWnd->spwndOwner = pwndNode;
+    WndSetOwner(pImeWnd, pwndNode);
 }
 
 // Get the last non-IME-like top-most window on the desktop.
@@ -1401,7 +1401,7 @@ NtUserSetImeOwnerWindow(HWND hImeWnd, HWND hwndFocus)
             }
         }
 
-        pImeWnd->spwndOwner = pwndTopLevel;
+        WndSetOwner(pImeWnd, pwndTopLevel);
         IntImeCheckTopmost(pImeWnd);
     }
     else
@@ -1413,7 +1413,7 @@ NtUserSetImeOwnerWindow(HWND hImeWnd, HWND hwndFocus)
         {
             if (pwndActive && ptiIme == pwndActive->head.pti && 
!IS_WND_IMELIKE(pwndActive))
             {
-                pImeWnd->spwndOwner = pwndActive;
+                WndSetOwner(pImeWnd, pwndActive);
             }
             else
             {
@@ -2127,7 +2127,7 @@ BOOL FASTCALL IntImeCanDestroyDefIME(PWND pImeWnd, PWND 
pwndTarget)
     if (pImeWnd->spwndOwner && pwndTarget != pImeWnd->spwndOwner)
         return FALSE;
 
-    pImeWnd->spwndOwner = NULL;
+    WndSetOwner(pImeWnd, NULL);
     return TRUE;
 }
 
diff --git a/win32ss/user/ntuser/window.c b/win32ss/user/ntuser/window.c
index e9026864d57..691b3f2996c 100644
--- a/win32ss/user/ntuser/window.c
+++ b/win32ss/user/ntuser/window.c
@@ -588,6 +588,7 @@ LRESULT co_UserFreeWindow(PWND Window,
    Window->style &= ~WS_VISIBLE;
    Window->head.pti->cVisWindows--;
 
+   WndSetOwner(Window, NULL);
 
    /* remove the window already at this point from the thread window list so we
       don't get into trouble when destroying the thread windows while we're 
still
@@ -662,7 +663,7 @@ LRESULT co_UserFreeWindow(PWND Window,
    if (ThreadData->spwndDefaultIme &&
        ThreadData->spwndDefaultIme->spwndOwner == Window)
    {
-      ThreadData->spwndDefaultIme->spwndOwner = NULL;
+      WndSetOwner(ThreadData->spwndDefaultIme, NULL);
    }
 
    if (IS_IMM_MODE() && Window == ThreadData->spwndDefaultIme)
@@ -1091,6 +1092,7 @@ IntProcessOwnerSwap(PWND Wnd, PWND WndNewOwner, PWND 
WndOldOwner)
    // FIXME: System Tray checks.
 }
 
+static
 HWND FASTCALL
 IntSetOwner(HWND hWnd, HWND hWndNewOwner)
 {
@@ -1119,14 +1121,7 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner)
 
    if (IntValidateOwnerDepth(Wnd, WndNewOwner))
    {
-      if (WndNewOwner)
-      {
-         Wnd->spwndOwner= WndNewOwner;
-      }
-      else
-      {
-         Wnd->spwndOwner = NULL;
-      }
+      WndSetOwner(Wnd, WndNewOwner);
    }
    else
    {
@@ -1869,7 +1864,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
     */
    /* Remember, pWnd->head is setup in object.c ... */
    pWnd->spwndParent = ParentWindow;
-   pWnd->spwndOwner = OwnerWindow;
+   WndSetOwner(pWnd, OwnerWindow);
    pWnd->fnid = 0;
    pWnd->spwndLastActive = pWnd;
    // Ramp up compatible version sets.
@@ -2825,7 +2820,7 @@ VOID FASTCALL IntDestroyOwnedWindows(PWND Window)
             continue;
         }
 
-        pWnd->spwndOwner = NULL;
+        WndSetOwner(pWnd, NULL);
         if (IntWndBelongsToThread(pWnd, PsGetCurrentThreadWin32Thread()))
         {
             UserRefObjectCo(pWnd, &Ref); // Temp HACK?
diff --git a/win32ss/user/ntuser/window.h b/win32ss/user/ntuser/window.h
index 036cd690954..0a463b75c16 100644
--- a/win32ss/user/ntuser/window.h
+++ b/win32ss/user/ntuser/window.h
@@ -124,4 +124,23 @@ BOOL FASTCALL IntBroadcastImeShowStatusChange(PWND 
pImeWnd, BOOL bShow);
 VOID FASTCALL IntNotifyImeShowStatus(PWND pImeWnd);
 VOID FASTCALL IntCheckImeShowStatusInThread(PWND pImeWnd);
 
+static inline
+VOID
+WndSetOwner(_Inout_ PWND pwnd, _In_opt_ PWND pwndOwner)
+{
+    /* First reference the new owner window */
+    if (pwndOwner != NULL)
+    {
+        UserReferenceObject(pwndOwner);
+    }
+
+    /* Now dereference the previous owner window */
+    if (pwnd->spwndOwner != NULL)
+    {
+        UserDereferenceObject(pwnd->spwndOwner);
+    }
+
+    pwnd->spwndOwner = pwndOwner;
+}
+
 /* EOF */

Reply via email to