From 0e53a7424f7fb9be9b3cdfa08e8404e965da8cee Mon Sep 17 00:00:00 2001 From: Rex Jolliff Date: Fri, 6 Jul 2001 00:05:05 +0000 Subject: [PATCH] added object handling routines for user objects in win32k.sys svn path=/trunk/; revision=2039 --- reactos/include/win32k/ntuser.h | 10 +- reactos/include/win32k/userobj.h | 46 +++++++++ reactos/lib/user32/windows/window.c | 28 +++--- reactos/subsys/win32k/makefile | 4 +- reactos/subsys/win32k/ntuser/class.c | 62 +++++++----- reactos/subsys/win32k/ntuser/userobj.c | 125 +++++++++++++++++++++++++ reactos/subsys/win32k/ntuser/window.c | 73 +++++++++++---- 7 files changed, 282 insertions(+), 66 deletions(-) create mode 100644 reactos/include/win32k/userobj.h create mode 100644 reactos/subsys/win32k/ntuser/userobj.c diff --git a/reactos/include/win32k/ntuser.h b/reactos/include/win32k/ntuser.h index b375509db04..e7ac9e8335a 100644 --- a/reactos/include/win32k/ntuser.h +++ b/reactos/include/win32k/ntuser.h @@ -484,13 +484,13 @@ NtUserFindExistingCursorIcon( DWORD Unknown1, DWORD Unknown2); -DWORD +HWND STDCALL NtUserFindWindowEx( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, + HWND hwndParent, + HWND hwndChildAfter, + PUNICODE_STRING ucClassName, + PUNICODE_STRING ucWindowName, DWORD Unknown4); DWORD diff --git a/reactos/include/win32k/userobj.h b/reactos/include/win32k/userobj.h new file mode 100644 index 00000000000..caf219345a5 --- /dev/null +++ b/reactos/include/win32k/userobj.h @@ -0,0 +1,46 @@ +/* $Id: userobj.h,v 1.1 2001/07/06 00:05:05 rex Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: USER Object manager interface definition + * FILE: include/win32k/userobj.h + * PROGRAMER: Rex Jolliff (rex@lvcablemodem.com) + * + */ + +#ifndef __WIN32K_USEROBJ_H +#define __WIN32K_USEROBJ_H + +#include + +#define UO_CLASS_MAGIC 0x5141 +#define UO_WINDOW_MAGIC 0x5142 +#define UO_MAGIC_DONTCARE 0xffff + +#define USER_OBJECT_TAG (ULONG)(('W'<<0) + ('3'<<8) + ('2'<<16) + ('U'<<24)) + +typedef struct tag_USER_OBJECT_HEADER +{ + WORD magic; + DWORD referenceCount; + LIST_ENTRY listEntry; + FAST_MUTEX mutex; +} USER_OBJECT_HEADER, *PUSER_OBJECT_HEADER; + +typedef PVOID PUSER_OBJECT; +typedef HANDLE HUSEROBJ; + +#define UserObjectHeaderToBody(header) ((PUSER_OBJECT)(((PCHAR)header)+sizeof(USER_OBJECT_HEADER))) +#define UserObjectBodyToHeader(body) ((PUSER_OBJECT_HEADER)(((PCHAR)body)-sizeof(USER_OBJECT_HEADER))) +#define UserObjectHeaderToHandle(header) ((HUSEROBJ)header) +#define UserObjectHandleToHeader(handle) ((HUSEROBJ)handle) + +PUSER_OBJECT USEROBJ_AllocObject (WORD size, WORD magic); +BOOL USEROBJ_FreeObject (PUSER_OBJECT object, WORD magic); +HUSEROBJ USEROBJ_PtrToHandle (PUSER_OBJECT object, WORD magic); +PUSER_OBJECT USEROBJ_HandleToPtr (HUSEROBJ object, WORD magic); +BOOL USEROBJ_LockObject (HUSEROBJ Obj); +BOOL USEROBJ_UnlockObject (HUSEROBJ Obj); + +#endif + diff --git a/reactos/lib/user32/windows/window.c b/reactos/lib/user32/windows/window.c index 18a9b9a82b0..dad7d800ff8 100644 --- a/reactos/lib/user32/windows/window.c +++ b/reactos/lib/user32/windows/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.1 2001/06/12 17:50:27 chorns Exp $ +/* $Id: window.c,v 1.2 2001/07/06 00:05:05 rex Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -321,11 +321,11 @@ EnumWindows( HWND STDCALL -FindWindowA( - LPCSTR lpClassName, - LPCSTR lpWindowName) +FindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName) { - return (HWND)0; + //FIXME: FindWindow does not search children, but FindWindowEx does. + // what should we do about this? + return FindWindowExA (NULL, NULL, lpClassName, lpWindowName); } HWND @@ -339,6 +339,15 @@ FindWindowExA( return (HWND)0; } +HWND +STDCALL +FindWindowW(LPCWSTR lpClassName, LPCWSTR lpWindowName) +{ + //FIXME: FindWindow does not search children, but FindWindowEx does. + // what should we do about this? + return FindWindowExW (NULL, NULL, lpClassName, lpWindowName); +} + HWND STDCALL FindWindowExW( @@ -350,15 +359,6 @@ FindWindowExW( return (HWND)0; } -HWND -STDCALL -FindWindowW( - LPCWSTR lpClassName, - LPCWSTR lpWindowName) -{ - return (HWND)0; -} - WINBOOL STDCALL GetAltTabInfo( diff --git a/reactos/subsys/win32k/makefile b/reactos/subsys/win32k/makefile index 3f65515d9c7..c9d652782aa 100644 --- a/reactos/subsys/win32k/makefile +++ b/reactos/subsys/win32k/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.35 2001/07/04 20:40:24 chorns Exp $ +# $Id: makefile,v 1.36 2001/07/06 00:05:05 rex Exp $ # # WIN32K.SYS build spec # @@ -21,7 +21,7 @@ MISC_OBJECTS = misc/driver.o misc/error.o misc/math.o misc/object.o LDR_OBJECTS = ldr/loader.o NTUSER_OBJECTS = ntuser/class.o ntuser/guicheck.o ntuser/hook.o \ ntuser/message.o ntuser/msgqueue.o ntuser/stubs.o \ - ntuser/window.o ntuser/winsta.o + ntuser/userobj.o ntuser/window.o ntuser/winsta.o OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \ objects/color.o objects/coord.o objects/dc.o \ objects/fillshap.o objects/gdiobj.o objects/icm.o \ diff --git a/reactos/subsys/win32k/ntuser/class.c b/reactos/subsys/win32k/ntuser/class.c index 0570d97731e..d7bc69d8929 100644 --- a/reactos/subsys/win32k/ntuser/class.c +++ b/reactos/subsys/win32k/ntuser/class.c @@ -1,4 +1,4 @@ -/* $Id: class.c,v 1.1 2001/06/12 17:50:29 chorns Exp $ +/* $Id: class.c,v 1.2 2001/07/06 00:05:05 rex Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -10,35 +10,31 @@ */ #include #include +#include #include #include -#include #include #define NDEBUG #include - /* List of system classes */ -LIST_ENTRY SystemClassListHead; -FAST_MUTEX SystemClassListLock; - +static LIST_ENTRY SystemClassListHead; +static FAST_MUTEX SystemClassListLock; NTSTATUS InitClassImpl(VOID) { + ExInitializeFastMutex(&SystemClassListLock); InitializeListHead(&SystemClassListHead); - //ExInitializeFastMutex(&SystemClassListLock); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } NTSTATUS CleanupClassImpl(VOID) { - //ExReleaseFastMutex(&SystemClassListLock); - - return STATUS_SUCCESS; + return STATUS_SUCCESS; } @@ -51,6 +47,7 @@ CliFindClassByName( PWNDCLASS_OBJECT Current; PLIST_ENTRY CurrentEntry; + ExAcquireFastMutexUnsafe (&SystemClassListLock); CurrentEntry = ListHead->Flink; while (CurrentEntry != ListHead) { @@ -59,14 +56,15 @@ CliFindClassByName( if (_wcsicmp(ClassName, Current->Class.lpszClassName) == 0) { *Class = Current; - ObmReferenceObject(Current); - return STATUS_SUCCESS; + ExReleaseFastMutexUnsafe (&SystemClassListLock); + return STATUS_SUCCESS; } CurrentEntry = CurrentEntry->Flink; } + ExReleaseFastMutexUnsafe (&SystemClassListLock); - return STATUS_NOT_FOUND; + return STATUS_NOT_FOUND; } NTSTATUS @@ -256,6 +254,8 @@ NtUserRegisterClassExWOW( PWNDCLASS_OBJECT ClassObject; NTSTATUS Status; RTL_ATOM Atom; + WORD objectSize; + LPTSTR namePtr; DPRINT("About to open window station handle (0x%X)\n", PROCESS_WINDOW_STATION()); @@ -281,26 +281,38 @@ NtUserRegisterClassExWOW( DPRINT("Failed adding class name (%wS) to atom table\n", lpwcx->lpszClassName); SetLastNtError(Status); - return (RTL_ATOM)0; + + return (RTL_ATOM) 0; } - ClassObject = ObmCreateObject( - WinStaObject->HandleTable, - NULL, - otClass, - sizeof(WNDCLASS_OBJECT)); - if (!ClassObject) + objectSize = sizeof(WNDCLASS_OBJECT) + + (lpwcx->lpszMenuName != 0 ? wcslen (lpwcx->lpszMenuName) + 1 : 0) + + wcslen (lpwcx->lpszClassName) + 1; + ClassObject = USEROBJ_AllocObject (objectSize, UO_CLASS_MAGIC); + if (ClassObject == 0) { RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Atom); ObDereferenceObject(WinStaObject); DPRINT("Failed creating window class object\n"); SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - return (ATOM)0; + + return (RTL_ATOM) 0; } - if (ClassObject->Class.style & CS_GLOBALCLASS) + ClassObject->Class = *lpwcx; + ClassObject->Unicode = bUnicodeClass; + namePtr = (LPTSTR)(((PCHAR)ClassObject) + sizeof (WNDCLASS_OBJECT)); + if (lpwcx->lpszMenuName != 0) + { + ClassObject->Class.lpszMenuName = namePtr; + wcscpy (namePtr, lpwcx->lpszMenuName); + namePtr += wcslen (lpwcx->lpszMenuName + 1); + } + ClassObject->Class.lpszClassName = namePtr; + wcscpy (namePtr, lpwcx->lpszClassName); + + if (lpwcx->style & CS_GLOBALCLASS) { - /* FIXME: Put on global list */ InsertTailList(&SystemClassListHead, &ClassObject->ListEntry); } else @@ -311,7 +323,7 @@ NtUserRegisterClassExWOW( ObDereferenceObject(WinStaObject); - return (RTL_ATOM)0; + return Atom; } DWORD diff --git a/reactos/subsys/win32k/ntuser/userobj.c b/reactos/subsys/win32k/ntuser/userobj.c new file mode 100644 index 00000000000..006e9ed5a00 --- /dev/null +++ b/reactos/subsys/win32k/ntuser/userobj.c @@ -0,0 +1,125 @@ +/* $Id: userobj.c,v 1.1 2001/07/06 00:05:05 rex Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: USER Object manager interface definition + * FILE: subsys/win32k/ntuser/userobj.c + * PROGRAMER: Rex Jolliff (rex@lvcablemodem.com) + * + */ + +#undef WIN32_LEAN_AND_MEAN +#include +#define NDEBUG +#include +#include +#include + +static LIST_ENTRY UserObjectList; + +PUSER_OBJECT USEROBJ_AllocObject (WORD size, WORD magic) +{ + PUSER_OBJECT_HEADER newObject; + + newObject = ExAllocatePoolWithTag(PagedPool, + size + sizeof (USER_OBJECT_HEADER), + USER_OBJECT_TAG); + if (newObject == 0) + { + return 0; + } + RtlZeroMemory(newObject, size + sizeof (USER_OBJECT_HEADER)); + + newObject->magic = magic; + ExInitializeFastMutex (&newObject->mutex); + InsertTailList (&UserObjectList, &newObject->listEntry); + + return UserObjectHeaderToBody (newObject); +} + +BOOL USEROBJ_FreeObject (PUSER_OBJECT object, WORD magic) +{ + PUSER_OBJECT_HEADER objectHeader; + + if (object == NULL) + { + return FALSE; + } + objectHeader = UserObjectBodyToHeader (object); + if (objectHeader->magic != magic) + { + return FALSE; + } + RemoveEntryList (&objectHeader->listEntry); + ExFreePool (objectHeader); + + return TRUE; +} + +HUSEROBJ USEROBJ_PtrToHandle (PUSER_OBJECT object, WORD magic) +{ + PUSER_OBJECT_HEADER objectHeader; + + if (object == 0) + { + return 0; + } + objectHeader = UserObjectBodyToHeader (object); + if (objectHeader->magic != magic) + { + return 0; + } + + return UserObjectHeaderToHandle(objectHeader); +} + +PUSER_OBJECT USEROBJ_HandleToPtr (HUSEROBJ handle, WORD magic) +{ + PUSER_OBJECT_HEADER objectHeader; + + if (handle == 0) + { + return 0; + } + objectHeader = UserObjectHandleToHeader (handle); + if ((objectHeader->magic != magic) && + (magic != UO_MAGIC_DONTCARE)) + { + return 0; + } + + return UserObjectHeaderToBody (objectHeader); +} + +BOOL USEROBJ_LockObject (HUSEROBJ objectHandle) +{ + PUSER_OBJECT_HEADER objectHeader; + + if (objectHandle == 0) + { + return FALSE; + } + objectHeader = UserObjectHandleToHeader (objectHandle); + + ExAcquireFastMutexUnsafe (&objectHeader->mutex); + + return TRUE; +} + +BOOL USEROBJ_UnlockObject (HUSEROBJ objectHandle) +{ + PUSER_OBJECT_HEADER objectHeader; + + if (objectHandle == 0) + { + return FALSE; + } + objectHeader = UserObjectHandleToHeader (objectHandle); + + ExReleaseFastMutexUnsafe (&objectHeader->mutex); + + return TRUE; +} + + + diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 42e4ca04ec9..badc31927dc 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.1 2001/06/12 17:50:29 chorns Exp $ +/* $Id: window.c,v 1.2 2001/07/06 00:05:05 rex Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -10,11 +10,11 @@ */ #include #include +#include #include #include #include #include -#include #include #define NDEBUG @@ -22,15 +22,15 @@ /* List of windows created by the process */ -LIST_ENTRY WindowListHead; -FAST_MUTEX WindowListLock; +static LIST_ENTRY WindowListHead; +static FAST_MUTEX WindowListLock; NTSTATUS InitWindowImpl(VOID) { + ExInitializeFastMutex(&WindowListLock); InitializeListHead(&WindowListHead); - //ExInitializeFastMutex(&WindowListLock); return STATUS_SUCCESS; } @@ -122,12 +122,10 @@ NtUserCreateWindowEx( return (HWND)0; } - WindowObject = ObmCreateObject( - WinStaObject->HandleTable, - &Handle, - otWindow, - sizeof(WINDOW_OBJECT)); - if (!WindowObject) { + WindowObject = (PWINDOW_OBJECT) USEROBJ_AllocObject (sizeof (WINDOW_OBJECT), + UO_WINDOW_MAGIC); + if (!WindowObject) + { ObDereferenceObject(WinStaObject); ObmDereferenceObject(ClassObject); RtlFreeUnicodeString(&WindowName); @@ -151,8 +149,9 @@ NtUserCreateWindowEx( RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer); - //FIXME: Grab lock - InsertTailList(&WindowListHead, &WindowObject->ListEntry); + ExAcquireFastMutexUnsafe (&WindowListLock); + InsertTailList (&WindowListHead, &WindowObject->ListEntry); + ExReleaseFastMutexUnsafe (&WindowListLock); return (HWND)Handle; } @@ -208,18 +207,52 @@ NtUserFillWindow( return 0; } -DWORD +HWND STDCALL NtUserFindWindowEx( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, + HWND hwndParent, + HWND hwndChildAfter, + PUNICODE_STRING ucClassName, + PUNICODE_STRING ucWindowName, DWORD Unknown4) { - UNIMPLEMENTED + NTSTATUS status; + HWND windowHandle; + PWINDOW_OBJECT windowObject; + PLIST_ENTRY currentEntry; + PWNDCLASS_OBJECT classObject; + + GuiCheck(); - return 0; + status = ClassReferenceClassByNameOrAtom(&classObject, ucClassName->Buffer); + if (!NT_SUCCESS(status)) + { + return (HWND)0; + } + + ExAcquireFastMutexUnsafe (&WindowListLock); + currentEntry = WindowListHead.Flink; + while (currentEntry != &WindowListHead) + { + windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT, ListEntry); + + if (classObject == windowObject->Class && + RtlCompareUnicodeString (ucWindowName, &windowObject->WindowName, TRUE) == 0) + { + windowHandle = (HWND) UserObjectHeaderToHandle ( + UserObjectBodyToHeader (windowObject)); + ExReleaseFastMutexUnsafe (&WindowListLock); + ObDereferenceObject (classObject); + + return windowHandle; + } + currentEntry = currentEntry->Flink; + } + ExReleaseFastMutexUnsafe (&WindowListLock); + + ObDereferenceObject (classObject); + + return (HWND)0; } DWORD