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;
LIST_ENTRY ListEntry;
PCHAR ExtraData;
/* list of windows */
FAST_MUTEX ClassWindowsListLock;
LIST_ENTRY ClassWindowsListHead;
} WNDCLASS_OBJECT, *PWNDCLASS_OBJECT;
NTSTATUS FASTCALL
@ -37,10 +40,19 @@ NTSTATUS FASTCALL
CleanupClassImpl(VOID);
#define IntLockProcessClasses(W32Process) \
ExAcquireFastMutex(&W32Process->ClassListLock)
ExAcquireFastMutex(&(W32Process)->ClassListLock)
#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
ClassReferenceClassByAtom(

View file

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

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* 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
* PROJECT: ReactOS kernel
@ -366,6 +366,9 @@ IntCreateClass(
ClassObject->ExtraData = NULL;
}
InitializeListHead(&ClassObject->ClassWindowsListHead);
ExInitializeFastMutex(&ClassObject->ClassWindowsListLock);
return(ClassObject);
}
@ -690,34 +693,42 @@ NtUserUnregisterClass(
if (!ClassReferenceClassByNameOrAtom(&Class, ClassNameOrAtom, hInstance))
{
ObDereferenceObject(WinStaObject);
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
return FALSE;
}
if (Class->hInstance && Class->hInstance != hInstance)
{
ObmDereferenceObject(Class);
ClassDereferenceObject(Class);
ObDereferenceObject(WinStaObject);
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
return FALSE;
}
if (ObmGetReferenceCount(Class) > 2)
IntLockClassWindows(Class);
if (!IsListEmpty(&Class->ClassWindowsListHead))
{
IntUnLockClassWindows(Class);
/* Dereference the ClassReferenceClassByNameOrAtom() call */
ObmDereferenceObject(Class);
ObDereferenceObject(WinStaObject);
SetLastWin32Error(ERROR_CLASS_HAS_WINDOWS);
return FALSE;
}
IntUnLockClassWindows(Class);
/* Dereference the ClassReferenceClassByNameOrAtom() call */
ObmDereferenceObject(Class);
ClassDereferenceObject(Class);
RemoveEntryList(&Class->ListEntry);
RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Class->Atom);
ObDereferenceObject(WinStaObject);
/* Free the object */
ObmDereferenceObject(Class);
ClassDereferenceObject(Class);
ObDereferenceObject(WinStaObject);
return TRUE;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* 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
* PROJECT: ReactOS kernel
@ -387,7 +387,13 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
/* don't remove the WINDOWSTATUS_DESTROYING bit */
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;
if(Window->WindowRegion)
@ -1509,7 +1515,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
&WinStaObject);
if (!NT_SUCCESS(Status))
{
ObmDereferenceObject(ClassObject);
ClassDereferenceObject(ClassObject);
RtlFreeUnicodeString(&WindowName);
if (NULL != ParentWindow)
{
@ -1530,7 +1536,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
if (!WindowObject)
{
ObDereferenceObject(WinStaObject);
ObmDereferenceObject(ClassObject);
ClassDereferenceObject(ClassObject);
RtlFreeUnicodeString(&WindowName);
if (NULL != ParentWindow)
{
@ -1551,6 +1557,10 @@ NtUserCreateWindowEx(DWORD dwExStyle,
* Fill out the structure describing it.
*/
WindowObject->Class = ClassObject;
IntLockClassWindows(ClassObject);
InsertTailList(&ClassObject->ClassWindowsListHead, &WindowObject->ClassListEntry);
IntUnLockClassWindows(ClassObject);
WindowObject->ExStyle = dwExStyle;
WindowObject->Style = dwStyle & ~WS_VISIBLE;
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 allocated DCE */
ClassDereferenceObject(ClassObject);
DPRINT1("CBT-hook returned !0\n");
return (HWND) NULL;
}
@ -1907,6 +1918,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
{
IntReleaseWindowObject(ParentWindow);
}
ClassDereferenceObject(ClassObject);
DPRINT("NtUserCreateWindowEx(): send CREATE message failed.\n");
return((HWND)0);
}
@ -2463,6 +2475,8 @@ NtUserFindWindowEx(HWND hwndParent,
}
#endif
ClassDereferenceObject(ClassObject);
Cleanup:
if(ClassName.Length > 0 && ClassName.Buffer)
ExFreePool(ClassName.Buffer);