fixed missing class dereferencings and store a list of windows in the class object

svn path=/trunk/; revision=9505
This commit is contained in:
Thomas Bluemel 2004-05-27 11:47:42 +00:00
parent ae85951413
commit 94c04c2051
4 changed files with 51 additions and 12 deletions

View file

@ -28,6 +28,9 @@ typedef struct _WNDCLASS_OBJECT
BOOL Global; BOOL Global;
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
PCHAR ExtraData; PCHAR ExtraData;
/* list of windows */
FAST_MUTEX ClassWindowsListLock;
LIST_ENTRY ClassWindowsListHead;
} WNDCLASS_OBJECT, *PWNDCLASS_OBJECT; } WNDCLASS_OBJECT, *PWNDCLASS_OBJECT;
NTSTATUS FASTCALL NTSTATUS FASTCALL
@ -37,10 +40,19 @@ NTSTATUS FASTCALL
CleanupClassImpl(VOID); CleanupClassImpl(VOID);
#define IntLockProcessClasses(W32Process) \ #define IntLockProcessClasses(W32Process) \
ExAcquireFastMutex(&W32Process->ClassListLock) ExAcquireFastMutex(&(W32Process)->ClassListLock)
#define IntUnLockProcessClasses(W32Process) \ #define IntUnLockProcessClasses(W32Process) \
ExReleaseFastMutex(&W32Process->ClassListLock) ExReleaseFastMutex(&(W32Process)->ClassListLock)
#define IntLockClassWindows(ClassObj) \
ExAcquireFastMutex(&(ClassObj)->ClassWindowsListLock)
#define IntUnLockClassWindows(ClassObj) \
ExReleaseFastMutex(&(ClassObj)->ClassWindowsListLock)
#define ClassDereferenceObject(ClassObj) \
ObmDereferenceObject(ClassObj)
BOOL FASTCALL BOOL FASTCALL
ClassReferenceClassByAtom( ClassReferenceClassByAtom(

View file

@ -30,6 +30,8 @@ typedef struct _WINDOW_OBJECT
{ {
/* Pointer to the window class. */ /* Pointer to the window class. */
PWNDCLASS_OBJECT Class; PWNDCLASS_OBJECT Class;
/* entry in the window list of the class object */
LIST_ENTRY ClassListEntry;
/* Extended style. */ /* Extended style. */
DWORD ExStyle; DWORD ExStyle;
/* Window name. */ /* Window name. */

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: class.c,v 1.56 2004/05/23 14:04:58 weiden Exp $ /* $Id: class.c,v 1.57 2004/05/27 11:47:42 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -366,6 +366,9 @@ IntCreateClass(
ClassObject->ExtraData = NULL; ClassObject->ExtraData = NULL;
} }
InitializeListHead(&ClassObject->ClassWindowsListHead);
ExInitializeFastMutex(&ClassObject->ClassWindowsListLock);
return(ClassObject); return(ClassObject);
} }
@ -690,34 +693,42 @@ NtUserUnregisterClass(
if (!ClassReferenceClassByNameOrAtom(&Class, ClassNameOrAtom, hInstance)) if (!ClassReferenceClassByNameOrAtom(&Class, ClassNameOrAtom, hInstance))
{ {
ObDereferenceObject(WinStaObject);
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST); SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
return FALSE; return FALSE;
} }
if (Class->hInstance && Class->hInstance != hInstance) if (Class->hInstance && Class->hInstance != hInstance)
{ {
ObmDereferenceObject(Class); ClassDereferenceObject(Class);
ObDereferenceObject(WinStaObject);
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST); SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
return FALSE; return FALSE;
} }
if (ObmGetReferenceCount(Class) > 2) IntLockClassWindows(Class);
if (!IsListEmpty(&Class->ClassWindowsListHead))
{ {
IntUnLockClassWindows(Class);
/* Dereference the ClassReferenceClassByNameOrAtom() call */
ObmDereferenceObject(Class); ObmDereferenceObject(Class);
ObDereferenceObject(WinStaObject);
SetLastWin32Error(ERROR_CLASS_HAS_WINDOWS); SetLastWin32Error(ERROR_CLASS_HAS_WINDOWS);
return FALSE; return FALSE;
} }
IntUnLockClassWindows(Class);
/* Dereference the ClassReferenceClassByNameOrAtom() call */ /* Dereference the ClassReferenceClassByNameOrAtom() call */
ObmDereferenceObject(Class); ClassDereferenceObject(Class);
RemoveEntryList(&Class->ListEntry); RemoveEntryList(&Class->ListEntry);
RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Class->Atom); RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Class->Atom);
ObDereferenceObject(WinStaObject);
/* Free the object */ /* Free the object */
ObmDereferenceObject(Class); ClassDereferenceObject(Class);
ObDereferenceObject(WinStaObject);
return TRUE; return TRUE;
} }

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.235 2004/05/19 19:16:47 weiden Exp $ /* $Id: window.c,v 1.236 2004/05/27 11:47:42 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -387,7 +387,13 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
/* don't remove the WINDOWSTATUS_DESTROYING bit */ /* don't remove the WINDOWSTATUS_DESTROYING bit */
IntUnLockThreadWindows(Window->OwnerThread->Win32Thread); IntUnLockThreadWindows(Window->OwnerThread->Win32Thread);
ObmDereferenceObject(Window->Class); /* remove the window from the class object */
IntLockClassWindows(Window->Class);
RemoveEntryList(&Window->ClassListEntry);
IntUnLockClassWindows(Window->Class);
/* dereference the class */
ClassDereferenceObject(Window->Class);
Window->Class = NULL; Window->Class = NULL;
if(Window->WindowRegion) if(Window->WindowRegion)
@ -1509,7 +1515,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
&WinStaObject); &WinStaObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ObmDereferenceObject(ClassObject); ClassDereferenceObject(ClassObject);
RtlFreeUnicodeString(&WindowName); RtlFreeUnicodeString(&WindowName);
if (NULL != ParentWindow) if (NULL != ParentWindow)
{ {
@ -1530,7 +1536,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
if (!WindowObject) if (!WindowObject)
{ {
ObDereferenceObject(WinStaObject); ObDereferenceObject(WinStaObject);
ObmDereferenceObject(ClassObject); ClassDereferenceObject(ClassObject);
RtlFreeUnicodeString(&WindowName); RtlFreeUnicodeString(&WindowName);
if (NULL != ParentWindow) if (NULL != ParentWindow)
{ {
@ -1551,6 +1557,10 @@ NtUserCreateWindowEx(DWORD dwExStyle,
* Fill out the structure describing it. * Fill out the structure describing it.
*/ */
WindowObject->Class = ClassObject; WindowObject->Class = ClassObject;
IntLockClassWindows(ClassObject);
InsertTailList(&ClassObject->ClassWindowsListHead, &WindowObject->ClassListEntry);
IntUnLockClassWindows(ClassObject);
WindowObject->ExStyle = dwExStyle; WindowObject->ExStyle = dwExStyle;
WindowObject->Style = dwStyle & ~WS_VISIBLE; WindowObject->Style = dwStyle & ~WS_VISIBLE;
DPRINT("1: Style is now %lx\n", WindowObject->Style); DPRINT("1: Style is now %lx\n", WindowObject->Style);
@ -1690,6 +1700,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
/* FIXME - Delete window object and remove it from the thread windows list */ /* FIXME - Delete window object and remove it from the thread windows list */
/* FIXME - delete allocated DCE */ /* FIXME - delete allocated DCE */
ClassDereferenceObject(ClassObject);
DPRINT1("CBT-hook returned !0\n"); DPRINT1("CBT-hook returned !0\n");
return (HWND) NULL; return (HWND) NULL;
} }
@ -1907,6 +1918,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
{ {
IntReleaseWindowObject(ParentWindow); IntReleaseWindowObject(ParentWindow);
} }
ClassDereferenceObject(ClassObject);
DPRINT("NtUserCreateWindowEx(): send CREATE message failed.\n"); DPRINT("NtUserCreateWindowEx(): send CREATE message failed.\n");
return((HWND)0); return((HWND)0);
} }
@ -2463,6 +2475,8 @@ NtUserFindWindowEx(HWND hwndParent,
} }
#endif #endif
ClassDereferenceObject(ClassObject);
Cleanup: Cleanup:
if(ClassName.Length > 0 && ClassName.Buffer) if(ClassName.Length > 0 && ClassName.Buffer)
ExFreePool(ClassName.Buffer); ExFreePool(ClassName.Buffer);