diff --git a/win32ss/user/ntuser/focus.c b/win32ss/user/ntuser/focus.c index 07cc78c4f08..3b11d47d5f4 100644 --- a/win32ss/user/ntuser/focus.c +++ b/win32ss/user/ntuser/focus.c @@ -242,7 +242,7 @@ IntDeactivateWindow(PTHREADINFO pti, HANDLE tid) if ( pti->MessageQueue->spwndActive ) { pwndPrev = pti->MessageQueue->spwndActive; - ptiPrev = pwndPrev->head.pti; + ptiPrev = pwndPrev->head.pti; if (!co_IntSendDeactivateMessages(UserHMGetHandle(pwndPrev), 0, TRUE)) { @@ -403,7 +403,7 @@ IntActivateWindow(PWND Wnd, PTHREADINFO pti, HANDLE tid, DWORD Type) { Wnd = pmq->spwndActive; // Use active window from current queue. - UserRefObjectCo(Wnd, &Ref); + UserRefObjectCo(Wnd, &Ref); co_IntSendMessage( UserHMGetHandle(Wnd), WM_NCACTIVATE, TRUE, 0); @@ -433,7 +433,7 @@ co_IntMakeWindowActive(PWND Window) { spwndOwner = spwndOwner->spwndOwner; } - spwndOwner->spwndLastActive = Window; + WndSetLastActive(spwndOwner, Window); return TRUE; } ERR("MakeWindowActive Failed!\n"); @@ -830,7 +830,7 @@ co_IntSetForegroundMessageQueue( MsqPostMessage(ptiPrev, &Msg, FALSE, QS_EVENT, POSTEVENT_DAW, (LONG_PTR)tid); } } - + pumqChg = NULL; if ( ptiChg && !(ptiChg->TIF_flags & TIF_INCLEANUP) ) { diff --git a/win32ss/user/ntuser/window.c b/win32ss/user/ntuser/window.c index e587c73a58d..fe05bafac66 100644 --- a/win32ss/user/ntuser/window.c +++ b/win32ss/user/ntuser/window.c @@ -593,8 +593,6 @@ 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 in co_UserFreeWindow() */ @@ -733,6 +731,12 @@ LRESULT co_UserFreeWindow(PWND Window, ASSERT(Window->PropListItems==0); } + /* Kill any reference to linked windows. Prev & Next are taken care of in IntUnlinkWindow */ + WndSetOwner(Window, NULL); + WndSetParent(Window, NULL); + WndSetChild(Window, NULL); + WndSetLastActive(Window, NULL); + UserReferenceObject(Window); UserMarkObjectDestroy(Window); @@ -948,27 +952,27 @@ IntLinkWindow( return; } - Wnd->spwndPrev = WndInsertAfter; + WndSetPrev(Wnd, WndInsertAfter); if (Wnd->spwndPrev) { /* Link after WndInsertAfter */ ASSERT(Wnd != WndInsertAfter->spwndNext); - Wnd->spwndNext = WndInsertAfter->spwndNext; + WndSetNext(Wnd, WndInsertAfter->spwndNext); if (Wnd->spwndNext) - Wnd->spwndNext->spwndPrev = Wnd; + WndSetPrev(Wnd->spwndNext, Wnd); ASSERT(Wnd != Wnd->spwndPrev); - Wnd->spwndPrev->spwndNext = Wnd; + WndSetNext(Wnd->spwndPrev, Wnd); } else { /* Link at the top */ ASSERT(Wnd != Wnd->spwndParent->spwndChild); - Wnd->spwndNext = Wnd->spwndParent->spwndChild; + WndSetNext(Wnd, Wnd->spwndParent->spwndChild); if (Wnd->spwndNext) - Wnd->spwndNext->spwndPrev = Wnd; + WndSetPrev(Wnd->spwndNext, Wnd); - Wnd->spwndParent->spwndChild = Wnd; + WndSetChild(Wnd->spwndParent, Wnd); } } @@ -1220,7 +1224,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent) Wnd->ExStyle2 &= ~WS_EX2_LINKED; /* Set the new parent */ - Wnd->spwndParent = WndNewParent; + WndSetParent(Wnd, WndNewParent); if ( Wnd->style & WS_CHILD && Wnd->spwndOwner && @@ -1352,15 +1356,16 @@ IntUnlinkWindow(PWND Wnd) ASSERT(Wnd != Wnd->spwndPrev); if (Wnd->spwndNext) - Wnd->spwndNext->spwndPrev = Wnd->spwndPrev; + WndSetPrev(Wnd->spwndNext, Wnd->spwndPrev); if (Wnd->spwndPrev) - Wnd->spwndPrev->spwndNext = Wnd->spwndNext; + WndSetNext(Wnd->spwndPrev, Wnd->spwndNext); if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd) - Wnd->spwndParent->spwndChild = Wnd->spwndNext; + WndSetChild(Wnd->spwndParent, Wnd->spwndNext); - Wnd->spwndPrev = Wnd->spwndNext = NULL; + WndSetPrev(Wnd, NULL); + WndSetNext(Wnd, NULL); } // Win: ExpandWindowList @@ -1876,10 +1881,10 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, * Fill out the structure describing it. */ /* Remember, pWnd->head is setup in object.c ... */ - pWnd->spwndParent = ParentWindow; + WndSetParent(pWnd, ParentWindow); WndSetOwner(pWnd, OwnerWindow); pWnd->fnid = 0; - pWnd->spwndLastActive = pWnd; + WndSetLastActive(pWnd, pWnd); // Ramp up compatible version sets. if ( dwVer >= WINVER_WIN31 ) { @@ -2932,7 +2937,7 @@ BOOLEAN co_UserDestroyWindow(PVOID Object) pwndTemp = pwndTemp->spwndOwner; if (pwndTemp->spwndLastActive == Window) - pwndTemp->spwndLastActive = Window->spwndOwner; + WndSetLastActive(pwndTemp, Window->spwndOwner); } if (Window->spwndParent && IntIsWindow(UserHMGetHandle(Window))) diff --git a/win32ss/user/ntuser/window.h b/win32ss/user/ntuser/window.h index fa0387f30d3..a6c60a6354c 100644 --- a/win32ss/user/ntuser/window.h +++ b/win32ss/user/ntuser/window.h @@ -125,23 +125,66 @@ BOOL FASTCALL IntBroadcastImeShowStatusChange(PWND pImeWnd, BOOL bShow); VOID FASTCALL IntNotifyImeShowStatus(PWND pImeWnd); VOID FASTCALL IntCheckImeShowStatusInThread(PWND pImeWnd); +static inline +VOID +ReplaceWndPtr(_Inout_ PWND* ppwnd, _In_opt_ PWND pwndNew) +{ + /* First reference the new one */ + if (pwndNew != NULL) + { + UserReferenceObject(pwndNew); + } + + /* Then dereference the previous one */ + if (*ppwnd != NULL) + { + UserDereferenceObject(*ppwnd); + } + + /* And set */ + *ppwnd = pwndNew; +} + static inline VOID WndSetOwner(_Inout_ PWND pwnd, _In_opt_ PWND pwndOwner) { - /* First reference the new owner window */ - if (pwndOwner != NULL) - { - UserReferenceObject(pwndOwner); - } + ReplaceWndPtr(&pwnd->spwndOwner, pwndOwner); +} - /* Now dereference the previous owner window */ - if (pwnd->spwndOwner != NULL) - { - UserDereferenceObject(pwnd->spwndOwner); - } +static inline +VOID +WndSetParent(_Inout_ PWND pwnd, _In_opt_ PWND pwndParent) +{ + ReplaceWndPtr(&pwnd->spwndParent, pwndParent); +} - pwnd->spwndOwner = pwndOwner; +static inline +VOID +WndSetChild(_Inout_ PWND pwnd, _In_opt_ PWND pwndChild) +{ + ReplaceWndPtr(&pwnd->spwndChild, pwndChild); +} + +static inline +VOID +WndSetNext(_Inout_ PWND pwnd, _In_opt_ PWND pwndNext) +{ + ReplaceWndPtr(&pwnd->spwndNext, pwndNext); +} + +static inline +VOID +WndSetPrev(_Inout_ PWND pwnd, _In_opt_ PWND pwndPrev) +{ + ReplaceWndPtr(&pwnd->spwndPrev, pwndPrev); +} + +static inline +VOID +WndSetLastActive(_Inout_ PWND pwnd, _In_opt_ PWND pwndLastActive) +{ + ReplaceWndPtr(&pwnd->spwndLastActive, pwndLastActive); } /* EOF */