On thread termination, destroy all windows owned by that thread

svn path=/trunk/; revision=4966
This commit is contained in:
Gé van Geldorp 2003-06-25 22:37:07 +00:00
parent 91e44fd859
commit 9aea24bfae
3 changed files with 63 additions and 25 deletions

View file

@ -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 */

View file

@ -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;

View file

@ -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,6 +923,8 @@ 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 * Clear the update region to make sure no WM_PAINT messages will be
* generated for this window while processing the WM_NCDESTROY. * generated for this window while processing the WM_NCDESTROY.
@ -933,6 +937,7 @@ static LRESULT W32kDestroyWindow(PWINDOW_OBJECT Window)
* 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)