mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
fixed missing class dereferencings and store a list of windows in the class object
svn path=/trunk/; revision=9505
This commit is contained in:
parent
ae85951413
commit
94c04c2051
4 changed files with 51 additions and 12 deletions
|
@ -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(
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue