https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e56da4854fd3c93b3444e…
commit e56da4854fd3c93b3444e11bbbbdb219fa2f2559
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Tue Dec 6 07:02:12 2022 +0100
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
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 */