mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
On thread termination, destroy all windows owned by that thread
svn path=/trunk/; revision=4966
This commit is contained in:
parent
91e44fd859
commit
9aea24bfae
3 changed files with 63 additions and 25 deletions
|
@ -1,6 +1,8 @@
|
||||||
#ifndef __WIN32K_MISC_H
|
#ifndef __WIN32K_MISC_H
|
||||||
#define __WIN32K_MISC_H
|
#define __WIN32K_MISC_H
|
||||||
|
|
||||||
|
#include <internal/ps.h>
|
||||||
|
|
||||||
/* Process context in which miniport driver is opened/used */
|
/* Process context in which miniport driver is opened/used */
|
||||||
extern PEPROCESS W32kDeviceProcess;
|
extern PEPROCESS W32kDeviceProcess;
|
||||||
|
|
||||||
|
@ -8,4 +10,8 @@ BOOLEAN
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kInitialize (VOID);
|
W32kInitialize (VOID);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
DestroyThreadWindows(PETHREAD Thread);
|
||||||
|
|
||||||
#endif /* __WIN32K_MISC_H */
|
#endif /* __WIN32K_MISC_H */
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: dllmain.c,v 1.39 2003/06/20 16:25:13 ekohl Exp $
|
/* $Id: dllmain.c,v 1.40 2003/06/25 22:37:07 gvg Exp $
|
||||||
*
|
*
|
||||||
* Entry Point for win32k.sys
|
* Entry Point for win32k.sys
|
||||||
*/
|
*/
|
||||||
|
@ -145,7 +145,7 @@ W32kThreadCallback (struct _ETHREAD *Thread,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RemoveTimersThread(Thread->Cid.UniqueThread);
|
RemoveTimersThread(Thread->Cid.UniqueThread);
|
||||||
|
DestroyThreadWindows(Thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: window.c,v 1.57 2003/06/20 16:26:14 ekohl Exp $
|
/* $Id: window.c,v 1.58 2003/06/25 22:37:07 gvg Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -811,12 +811,11 @@ static void W32kSendDestroyMsg(HWND Wnd)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL W32kWndBelongsToCurrentThread(PWINDOW_OBJECT Window)
|
static BOOLEAN W32kWndBelongsToThread(PWINDOW_OBJECT Window, PW32THREAD ThreadData)
|
||||||
{
|
{
|
||||||
PW32THREAD ThreadData = PsGetWin32Thread();
|
|
||||||
PLIST_ENTRY Current;
|
PLIST_ENTRY Current;
|
||||||
PWINDOW_OBJECT ThreadWindow;
|
PWINDOW_OBJECT ThreadWindow;
|
||||||
BOOL Belongs = FALSE;
|
BOOLEAN Belongs = FALSE;
|
||||||
|
|
||||||
ExAcquireFastMutexUnsafe(&ThreadData->WindowListLock);
|
ExAcquireFastMutexUnsafe(&ThreadData->WindowListLock);
|
||||||
/* If there's no win32k thread data then this thread hasn't created any windows */
|
/* If there's no win32k thread data then this thread hasn't created any windows */
|
||||||
|
@ -881,14 +880,17 @@ static BOOL BuildChildWindowArray(PWINDOW_OBJECT Window, HWND **Children, unsign
|
||||||
*
|
*
|
||||||
* Destroy storage associated to a window. "Internals" p.358
|
* Destroy storage associated to a window. "Internals" p.358
|
||||||
*/
|
*/
|
||||||
static LRESULT W32kDestroyWindow(PWINDOW_OBJECT Window)
|
static LRESULT W32kDestroyWindow(PWINDOW_OBJECT Window,
|
||||||
|
PW32PROCESS ProcessData,
|
||||||
|
PW32THREAD ThreadData,
|
||||||
|
BOOLEAN SendMessages)
|
||||||
{
|
{
|
||||||
HWND *Children;
|
HWND *Children;
|
||||||
unsigned NumChildren;
|
unsigned NumChildren;
|
||||||
unsigned Index;
|
unsigned Index;
|
||||||
PWINDOW_OBJECT Child;
|
PWINDOW_OBJECT Child;
|
||||||
|
|
||||||
if (! W32kWndBelongsToCurrentThread(Window))
|
if (! W32kWndBelongsToThread(Window, ThreadData))
|
||||||
{
|
{
|
||||||
DPRINT1("Window doesn't belong to current thread\n");
|
DPRINT1("Window doesn't belong to current thread\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -904,9 +906,9 @@ static LRESULT W32kDestroyWindow(PWINDOW_OBJECT Window)
|
||||||
Child = W32kGetWindowObject(Children[Index - 1]);
|
Child = W32kGetWindowObject(Children[Index - 1]);
|
||||||
if (NULL != Child)
|
if (NULL != Child)
|
||||||
{
|
{
|
||||||
if (W32kWndBelongsToCurrentThread(Child))
|
if (W32kWndBelongsToThread(Child, ThreadData))
|
||||||
{
|
{
|
||||||
W32kDestroyWindow(Child);
|
W32kDestroyWindow(Child, ProcessData, ThreadData, SendMessages);
|
||||||
}
|
}
|
||||||
#if 0 /* FIXME */
|
#if 0 /* FIXME */
|
||||||
else
|
else
|
||||||
|
@ -921,18 +923,21 @@ static LRESULT W32kDestroyWindow(PWINDOW_OBJECT Window)
|
||||||
ExFreePool(Children);
|
ExFreePool(Children);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (SendMessages)
|
||||||
* Clear the update region to make sure no WM_PAINT messages will be
|
{
|
||||||
* generated for this window while processing the WM_NCDESTROY.
|
/*
|
||||||
*/
|
* Clear the update region to make sure no WM_PAINT messages will be
|
||||||
PaintRedrawWindow(Window->Self, NULL, 0,
|
* generated for this window while processing the WM_NCDESTROY.
|
||||||
RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_NOCHILDREN,
|
*/
|
||||||
0);
|
PaintRedrawWindow(Window->Self, NULL, 0,
|
||||||
|
RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_NOCHILDREN,
|
||||||
|
0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send the WM_NCDESTROY to the window being destroyed.
|
* Send the WM_NCDESTROY to the window being destroyed.
|
||||||
*/
|
*/
|
||||||
NtUserSendMessage(Window->Self, WM_NCDESTROY, 0, 0);
|
NtUserSendMessage(Window->Self, WM_NCDESTROY, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
|
/* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
|
||||||
|
|
||||||
|
@ -969,7 +974,7 @@ static LRESULT W32kDestroyWindow(PWINDOW_OBJECT Window)
|
||||||
RemoveEntryList(&Window->DesktopListEntry);
|
RemoveEntryList(&Window->DesktopListEntry);
|
||||||
RemoveEntryList(&Window->ThreadListEntry);
|
RemoveEntryList(&Window->ThreadListEntry);
|
||||||
Window->Class = NULL;
|
Window->Class = NULL;
|
||||||
ObmCloseHandle(PsGetWin32Process()->WindowStation->HandleTable, Window->Self);
|
ObmCloseHandle(ProcessData->WindowStation->HandleTable, Window->Self);
|
||||||
|
|
||||||
W32kGraphicsCheck(FALSE);
|
W32kGraphicsCheck(FALSE);
|
||||||
|
|
||||||
|
@ -988,8 +993,6 @@ NtUserDestroyWindow(HWND Wnd)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: check if window belongs to current thread */
|
|
||||||
|
|
||||||
/* Check for desktop window (has NULL parent) */
|
/* Check for desktop window (has NULL parent) */
|
||||||
if (NULL == Window->Parent)
|
if (NULL == Window->Parent)
|
||||||
{
|
{
|
||||||
|
@ -1112,11 +1115,40 @@ NtUserDestroyWindow(HWND Wnd)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Destroy the window storage */
|
/* Destroy the window storage */
|
||||||
W32kDestroyWindow(Window);
|
W32kDestroyWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID FASTCALL
|
||||||
|
DestroyThreadWindows(PETHREAD Thread)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY LastHead;
|
||||||
|
PW32PROCESS Win32Process;
|
||||||
|
PW32THREAD Win32Thread;
|
||||||
|
PWINDOW_OBJECT Window;
|
||||||
|
|
||||||
|
Win32Thread = Thread->Win32Thread;
|
||||||
|
Win32Process = Thread->ThreadsProcess->Win32Process;
|
||||||
|
ExAcquireFastMutexUnsafe(&Win32Thread->WindowListLock);
|
||||||
|
LastHead = NULL;
|
||||||
|
while (Win32Thread->WindowListHead.Flink != &(Win32Thread->WindowListHead) &&
|
||||||
|
Win32Thread->WindowListHead.Flink != LastHead)
|
||||||
|
{
|
||||||
|
LastHead = Win32Thread->WindowListHead.Flink;
|
||||||
|
Window = CONTAINING_RECORD(Win32Thread->WindowListHead.Flink, WINDOW_OBJECT, ThreadListEntry);
|
||||||
|
ExReleaseFastMutexUnsafe(&Win32Thread->WindowListLock);
|
||||||
|
W32kDestroyWindow(Window, Win32Process, Win32Thread, FALSE);
|
||||||
|
ExAcquireFastMutexUnsafe(&Win32Thread->WindowListLock);
|
||||||
|
}
|
||||||
|
if (Win32Thread->WindowListHead.Flink == LastHead)
|
||||||
|
{
|
||||||
|
/* Window at head of list was not removed, should never happen, infinite loop */
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
ExReleaseFastMutexUnsafe(&Win32Thread->WindowListLock);
|
||||||
|
}
|
||||||
|
|
||||||
DWORD STDCALL
|
DWORD STDCALL
|
||||||
NtUserEndDeferWindowPosEx(DWORD Unknown0,
|
NtUserEndDeferWindowPosEx(DWORD Unknown0,
|
||||||
DWORD Unknown1)
|
DWORD Unknown1)
|
||||||
|
|
Loading…
Reference in a new issue