-replace user object/handle manager with the one from wine. its simpler, faster and more correct.

-convert dozens of functions to take pointers as args, not handles
-attempt to simplify/correct refcounting
-remove much useless refcounting
-make callout refcounts auto undoable (ei. if the thread crash in umode during callback)
-misc formatting/naming changes

svn path=/trunk/; revision=17728
This commit is contained in:
Gunnar Dalsnes 2005-09-07 20:59:26 +00:00
parent b0bac13ce1
commit a401832d5f
25 changed files with 905 additions and 965 deletions

View file

@ -197,7 +197,7 @@ WNDOBJ*
STDCALL STDCALL
EngCreateWnd( EngCreateWnd(
SURFOBJ *pso, SURFOBJ *pso,
HWND hwnd, HWND hWnd,
WNDOBJCHANGEPROC pfn, WNDOBJCHANGEPROC pfn,
FLONG fl, FLONG fl,
int iPixelFormat) int iPixelFormat)
@ -209,7 +209,7 @@ EngCreateWnd(
DECLARE_RETURN(WNDOBJ*); DECLARE_RETURN(WNDOBJ*);
DPRINT("EngCreateWnd: pso = 0x%x, hwnd = 0x%x, pfn = 0x%x, fl = 0x%x, pixfmt = %d\n", DPRINT("EngCreateWnd: pso = 0x%x, hwnd = 0x%x, pfn = 0x%x, fl = 0x%x, pixfmt = %d\n",
pso, hwnd, pfn, fl, iPixelFormat); pso, hWnd, pfn, fl, iPixelFormat);
calledFromUser = UserIsEntered(); calledFromUser = UserIsEntered();
if (!calledFromUser){ if (!calledFromUser){
@ -217,7 +217,7 @@ EngCreateWnd(
} }
/* Get window object */ /* Get window object */
Window = IntGetWindowObject(hwnd); Window = UserGetWindowObject(hWnd);
if (Window == NULL) if (Window == NULL)
{ {
RETURN( NULL); RETURN( NULL);
@ -227,7 +227,6 @@ EngCreateWnd(
WndObjInt = EngAllocMem(0, sizeof (WNDGDI), TAG_WNDOBJ); WndObjInt = EngAllocMem(0, sizeof (WNDGDI), TAG_WNDOBJ);
if (WndObjInt == NULL) if (WndObjInt == NULL)
{ {
IntReleaseWindowObject(Window);
DPRINT1("Failed to allocate memory for a WND structure!\n"); DPRINT1("Failed to allocate memory for a WND structure!\n");
RETURN( NULL); RETURN( NULL);
} }
@ -236,7 +235,6 @@ EngCreateWnd(
WndObjInt->ClientClipObj = NULL; WndObjInt->ClientClipObj = NULL;
if (!IntEngWndUpdateClipObj(WndObjInt, Window)) if (!IntEngWndUpdateClipObj(WndObjInt, Window))
{ {
IntReleaseWindowObject(Window);
EngFreeMem(WndObjInt); EngFreeMem(WndObjInt);
RETURN( NULL); RETURN( NULL);
} }
@ -247,7 +245,7 @@ EngCreateWnd(
WndObjUser->pvConsumer = NULL; WndObjUser->pvConsumer = NULL;
/* Fill internal object */ /* Fill internal object */
WndObjInt->Hwnd = hwnd; WndObjInt->Hwnd = hWnd;
WndObjInt->ChangeProc = pfn; WndObjInt->ChangeProc = pfn;
WndObjInt->Flags = fl; WndObjInt->Flags = fl;
WndObjInt->PixelFormat = iPixelFormat; WndObjInt->PixelFormat = iPixelFormat;
@ -255,9 +253,6 @@ EngCreateWnd(
/* associate object with window */ /* associate object with window */
InsertTailList(&Window->WndObjListHead, &WndObjInt->ListEntry); InsertTailList(&Window->WndObjListHead, &WndObjInt->ListEntry);
/* release resources */
IntReleaseWindowObject(Window);
DPRINT("EngCreateWnd: SUCCESS!\n"); DPRINT("EngCreateWnd: SUCCESS!\n");
RETURN( WndObjUser); RETURN( WndObjUser);

View file

@ -50,7 +50,7 @@ typedef struct _SYSTEM_CURSORINFO
HCURSOR FASTCALL IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL ForceChange); HCURSOR FASTCALL IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL ForceChange);
BOOL FASTCALL IntSetupCurIconHandles(PWINSTATION_OBJECT WinStaObject); BOOL FASTCALL IntSetupCurIconHandles(PWINSTATION_OBJECT WinStaObject);
PCURICON_OBJECT FASTCALL IntGetCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle); PCURICON_OBJECT FASTCALL IntGetCurIconObject(HANDLE Handle);
PCURICON_OBJECT FASTCALL IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject); PCURICON_OBJECT FASTCALL IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject);
VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process); VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process);

View file

@ -5,105 +5,127 @@
#include <win32k/bitmaps.h> #include <win32k/bitmaps.h>
#include <win32k/pen.h> #include <win32k/pen.h>
typedef enum { #define FIRST_USER_HANDLE 0x0020 /* first possible value for low word of user handle */
otUnknown = 0, #define LAST_USER_HANDLE 0xffef /* last possible value for low word of user handle */
otClass,
#define USER_HEADER_TO_BODY(ObjectHeader) \
((PVOID)(((PUSER_OBJECT_HEADER)ObjectHeader) + 1))
#define USER_BODY_TO_HEADER(ObjectBody) \
((PUSER_OBJECT_HEADER)(((PUSER_OBJECT_HEADER)ObjectBody) - 1))
typedef struct _USER_HANDLE_ENTRY
{
void *ptr; /* pointer to object */
unsigned short type; /* object type (0 if free) */
unsigned short generation; /* generation counter */
} USER_HANDLE_ENTRY, * PUSER_HANDLE_ENTRY;
typedef struct _USER_HANDLE_TABLE
{
PUSER_HANDLE_ENTRY handles;
PUSER_HANDLE_ENTRY freelist;
int nb_handles;
int allocated_handles;
} USER_HANDLE_TABLE, * PUSER_HANDLE_TABLE;
typedef enum _USER_OBJECT_TYPE
{
otFree = 0,
otWindow, otWindow,
otMenu, otMenu,
otAcceleratorTable, otAccel,
otCursorIcon, otCursor,
otHookProc, otHook,
otMonitor otMonitor,
otClass //fixme: remove
} USER_OBJECT_TYPE; } USER_OBJECT_TYPE;
typedef struct _USER_OBJECT_HEADER typedef struct _USER_OBJECT_HEADER
/* /*
* Header for user object * Header for user object
*/ */
{ {
USER_OBJECT_TYPE Type; // USER_OBJECT_TYPE Type;
LONG HandleCount;
LONG RefCount; LONG RefCount;
CSHORT Size; BOOL destroyed;
HANDLE hSelf;
// CSHORT Size;
} USER_OBJECT_HEADER, *PUSER_OBJECT_HEADER; } USER_OBJECT_HEADER, *PUSER_OBJECT_HEADER;
typedef struct _USER_HANDLE
typedef struct _USER_REFERENCE_ENTRY
{ {
PVOID ObjectBody; SINGLE_LIST_ENTRY Entry;
} USER_HANDLE, *PUSER_HANDLE; PVOID obj;
} USER_REFERENCE_ENTRY, *PUSER_REFERENCE_ENTRY;
#define HANDLE_BLOCK_ENTRIES ((PAGE_SIZE-sizeof(LIST_ENTRY))/sizeof(USER_HANDLE))
typedef struct _USER_HANDLE_BLOCK
{
LIST_ENTRY ListEntry;
USER_HANDLE Handles[HANDLE_BLOCK_ENTRIES];
} USER_HANDLE_BLOCK, *PUSER_HANDLE_BLOCK;
typedef struct _USER_HANDLE_TABLE
{
LIST_ENTRY ListHead;
} USER_HANDLE_TABLE, *PUSER_HANDLE_TABLE;
ULONG FASTCALL
ObmGetReferenceCount(
PVOID ObjectBody);
ULONG FASTCALL #include <malloc.h>
ObmGetHandleCount(
PVOID ObjectBody);
VOID FASTCALL #define ASSERT_LAST_REF(_obj_) \
ObmReferenceObject( { \
PVOID ObjectBody); PW32THREAD t; \
PSINGLE_LIST_ENTRY e; \
PUSER_REFERENCE_ENTRY ref; \
\
ASSERT(_obj_); \
t = PsGetWin32Thread(); \
ASSERT(t); \
e = t->ReferencesList.Next; \
ASSERT(e); \
ref = CONTAINING_RECORD(e, USER_REFERENCE_ENTRY, Entry); \
ASSERT(ref); \
\
ASSERT(_obj_ == ref->obj); \
\
}
#define UserRefObjectCo(_obj_) \
{ \
PW32THREAD t; \
PUSER_REFERENCE_ENTRY ref; \
\
ASSERT(_obj_); \
t = PsGetWin32Thread(); \
ASSERT(t); \
ref = (PUSER_REFERENCE_ENTRY)_alloca(sizeof(USER_REFERENCE_ENTRY)); \
ASSERT(ref); \
ref->obj = _obj_; \
ObmReferenceObject(_obj_); \
\
PushEntryList(&t->ReferencesList, &ref->Entry); \
\
}
VOID FASTCALL
ObmDereferenceObject(
PVOID ObjectBody);
NTSTATUS FASTCALL #define UserDerefObjectCo(_obj_) \
ObmReferenceObjectByPointer( { \
PVOID ObjectBody, PW32THREAD t; \
USER_OBJECT_TYPE ObjectType); PSINGLE_LIST_ENTRY e; \
PUSER_REFERENCE_ENTRY ref; \
PVOID FASTCALL \
ObmCreateObject( ASSERT(_obj_); \
PUSER_HANDLE_TABLE HandleTable, t = PsGetWin32Thread(); \
PHANDLE Handle, ASSERT(t); \
USER_OBJECT_TYPE ObjectType, e = PopEntryList(&t->ReferencesList); \
ULONG ObjectSize); ASSERT(e); \
ref = CONTAINING_RECORD(e, USER_REFERENCE_ENTRY, Entry); \
NTSTATUS FASTCALL ASSERT(ref); \
ObmCreateHandle( \
PUSER_HANDLE_TABLE HandleTable, ASSERT(_obj_ == ref->obj); \
PVOID ObjectBody, ObmDereferenceObject(_obj_); \
PHANDLE HandleReturn); \
}
NTSTATUS FASTCALL
ObmReferenceObjectByHandle(
PUSER_HANDLE_TABLE HandleTable,
HANDLE Handle,
USER_OBJECT_TYPE ObjectType,
PVOID* Object);
NTSTATUS FASTCALL
ObmCloseHandle(
PUSER_HANDLE_TABLE HandleTable,
HANDLE Handle);
VOID FASTCALL
ObmInitializeHandleTable(
PUSER_HANDLE_TABLE HandleTable);
VOID FASTCALL
ObmFreeHandleTable(
PUSER_HANDLE_TABLE HandleTable);
PUSER_HANDLE_TABLE FASTCALL
ObmCreateHandleTable(VOID);
VOID FASTCALL ObmDestroyHandleTable (PUSER_HANDLE_TABLE HandleTable);
VOID INTERNAL_CALL InitGdiObjectHandleTable (VOID); VOID INTERNAL_CALL InitGdiObjectHandleTable (VOID);

View file

@ -1,18 +1,52 @@
#ifndef _WIN32K_USERFUNCS_H #ifndef _WIN32K_USERFUNCS_H
#define _WIN32K_USERFUNCS_H #define _WIN32K_USERFUNCS_H
//currently unused
#define ASSERT_REFS(obj) ASSERT(ObmGetReferenceCount(obj) >= 2)
#define UserReferenceWindowObjectCo(o) IntReferenceWindowObject(o) #define ASSERT_REFS_CO(obj) \
#define UserDereferenceWindowObjectCo(o) IntReleaseWindowObject(o) { \
LONG ref = USER_BODY_TO_HEADER(obj)->RefCount;\
if (!(ref >= 1)){ \
DPRINT1("obj 0x%x, refs %i\n", obj, ref); \
ASSERT(FALSE); \
} \
}
#define UserReferenceAccelObjectCo(o) IntReferenceWindowObject(o) #define DUMP_REFS(obj) DPRINT1("obj 0x%x, refs %i\n",obj, USER_BODY_TO_HEADER(obj)->RefCount)
#define UserDereferenceAccelObjectCo(o) IntReleaseWindowObject(o)
extern PUSER_HANDLE_TABLE gHandleTable;
VOID FASTCALL ObmReferenceObject(PVOID obj);
BOOL FASTCALL ObmDereferenceObject(PVOID obj);
#define IntReferenceWindowObject(o) ObmReferenceObject(o)
VOID FASTCALL IntReleaseWindowObject(PWINDOW_OBJECT Window);
PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd);
PVOID FASTCALL
ObmCreateObject(PUSER_HANDLE_TABLE ht, HANDLE* h,USER_OBJECT_TYPE type , ULONG size);
BOOL FASTCALL
ObmDeleteObject(HANDLE h, USER_OBJECT_TYPE type );
//#define UserRefObjectCo(o) ObmReferenceObject(o)
//#define UserDerefObjectCo(o) ObmDereferenceObject(o)
BOOL FASTCALL ObmCreateHandleTable();
extern USER_HANDLE_TABLE gHandleTable;
/******************** HANDLE.C ***************/
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle );
VOID UserInitHandleTable(PUSER_HANDLE_TABLE ht, PVOID mem, ULONG bytes);
HANDLE UserAllocHandle(PUSER_HANDLE_TABLE ht, PVOID object, USER_OBJECT_TYPE type );
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, USER_OBJECT_TYPE type );
PVOID UserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle );
PVOID UserGetNextHandle(PUSER_HANDLE_TABLE ht, HANDLE* handle, USER_OBJECT_TYPE type );
/*************** WINSTA.C ***************/ /*************** WINSTA.C ***************/
HWINSTA FASTCALL UserGetProcessWindowStation(VOID); HWINSTA FASTCALL UserGetProcessWindowStation(VOID);
@ -25,7 +59,7 @@ UserAcquireOrReleaseInputOwnership(BOOLEAN Release);
/*************** WINPOS.C ***************/ /*************** WINPOS.C ***************/
BOOL FASTCALL BOOL FASTCALL
UserGetClientOrigin(HWND hWnd, LPPOINT Point); UserGetClientOrigin(PWINDOW_OBJECT Window, LPPOINT Point);
/*************** FOCUS.C ***************/ /*************** FOCUS.C ***************/
@ -81,7 +115,7 @@ UserPostMessage(HWND Wnd,
/*************** PAINTING.C ***************/ /*************** PAINTING.C ***************/
BOOL FASTCALL UserValidateRgn(HWND hWnd, HRGN hRgn); BOOL FASTCALL co_UserValidateRgn(PWINDOW_OBJECT Window, HRGN hRgn);
/*************** WINDOW.C ***************/ /*************** WINDOW.C ***************/

View file

@ -13,6 +13,8 @@ typedef struct _W32THREAD
HANDLE hDesktop; HANDLE hDesktop;
DWORD MessagePumpHookValue; DWORD MessagePumpHookValue;
BOOLEAN IsExiting; BOOLEAN IsExiting;
SINGLE_LIST_ENTRY ReferencesList;
} W32THREAD, *PW32THREAD; } W32THREAD, *PW32THREAD;
#include <poppack.h> #include <poppack.h>

View file

@ -123,14 +123,6 @@ typedef struct _WINDOW_OBJECT
#define IntIsBroadcastHwnd(hWnd) \ #define IntIsBroadcastHwnd(hWnd) \
(hWnd == HWND_BROADCAST || hWnd == HWND_TOPMOST) (hWnd == HWND_BROADCAST || hWnd == HWND_TOPMOST)
#define IntGetWindowObject(hWnd) \
IntGetProcessWindowObject(PsGetWin32Thread(), hWnd)
#define IntReferenceWindowObject(WndObj) \
ObmReferenceObjectByPointer(WndObj, otWindow)
#define IntReleaseWindowObject(WndObj) \
ObmDereferenceObject(WndObj)
#define IntWndBelongsToThread(WndObj, W32Thread) \ #define IntWndBelongsToThread(WndObj, W32Thread) \
(((WndObj->OwnerThread && WndObj->OwnerThread->Tcb.Win32Thread)) && \ (((WndObj->OwnerThread && WndObj->OwnerThread->Tcb.Win32Thread)) && \
@ -143,9 +135,6 @@ typedef struct _WINDOW_OBJECT
WndObj->OwnerThread->ThreadsProcess->UniqueProcessId WndObj->OwnerThread->ThreadsProcess->UniqueProcessId
PWINDOW_OBJECT FASTCALL
IntGetProcessWindowObject(PW32THREAD Thread, HWND hWnd);
BOOL FASTCALL BOOL FASTCALL
IntIsWindow(HWND hWnd); IntIsWindow(HWND hWnd);

View file

@ -17,7 +17,7 @@
UINT UINT
FASTCALL co_WinPosArrangeIconicWindows(PWINDOW_OBJECT parent); FASTCALL co_WinPosArrangeIconicWindows(PWINDOW_OBJECT parent);
BOOL FASTCALL BOOL FASTCALL
IntGetClientOrigin(HWND hWnd, LPPOINT Point); IntGetClientOrigin(PWINDOW_OBJECT Window, LPPOINT Point);
LRESULT FASTCALL LRESULT FASTCALL
co_WinPosGetNonClientSize(HWND Wnd, RECT* WindowRect, RECT* ClientRect); co_WinPosGetNonClientSize(HWND Wnd, RECT* WindowRect, RECT* ClientRect);
UINT FASTCALL UINT FASTCALL
@ -26,7 +26,7 @@ co_WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
UINT FASTCALL UINT FASTCALL
co_WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos); co_WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos);
BOOLEAN FASTCALL BOOLEAN FASTCALL
co_WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx, co_WinPosSetWindowPos(PWINDOW_OBJECT Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
INT cy, UINT flags); INT cy, UINT flags);
BOOLEAN FASTCALL BOOLEAN FASTCALL
co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd); co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd);

View file

@ -219,11 +219,14 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
} }
else else
{ {
PSINGLE_LIST_ENTRY e;
DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql()); DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
Win32Thread->IsExiting = TRUE; Win32Thread->IsExiting = TRUE;
HOOK_DestroyThreadHooks(Thread); HOOK_DestroyThreadHooks(Thread);
UnregisterThreadHotKeys(Thread); UnregisterThreadHotKeys(Thread);
/* what if this co_ func crash in umode? what will clean us up then? */
co_DestroyThreadWindows(Thread); co_DestroyThreadWindows(Thread);
IntBlockInput(Win32Thread, FALSE); IntBlockInput(Win32Thread, FALSE);
MsqDestroyMessageQueue(Win32Thread->MessageQueue); MsqDestroyMessageQueue(Win32Thread->MessageQueue);
@ -232,6 +235,17 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
{ {
ObDereferenceObject(Win32Thread->Desktop); ObDereferenceObject(Win32Thread->Desktop);
} }
/* cleanup user object references stack */
e = PopEntryList(&Win32Thread->ReferencesList);
while (e)
{
PUSER_REFERENCE_ENTRY ref = CONTAINING_RECORD(e, USER_REFERENCE_ENTRY, Entry);
DPRINT1("thread clean: remove reference obj 0x%x\n",ref->obj);
ObmDereferenceObject(ref->obj);
e = PopEntryList(&Win32Thread->ReferencesList);
}
} }
RETURN( STATUS_SUCCESS); RETURN( STATUS_SUCCESS);

View file

@ -70,21 +70,19 @@ CleanupAcceleratorImpl(VOID)
static static
PACCELERATOR_TABLE FASTCALL UserGetAccelObjectNoRef(HACCEL hAccel) PACCELERATOR_TABLE FASTCALL UserGetAccelObject(HACCEL hAccel)
{ {
PACCELERATOR_TABLE Accel=NULL; PACCELERATOR_TABLE Accel= UserGetObject(&gHandleTable, hAccel, otAccel);
NTSTATUS Status = ObmReferenceObjectByHandle(gHandleTable,
hAccel,
otAcceleratorTable,
(PVOID*)&Accel);
if (!NT_SUCCESS(Status)) if (Accel)
{
ASSERT(USER_BODY_TO_HEADER(Accel)->RefCount >= 0);
}
else
{ {
SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE); SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE);
return NULL;
} }
ObmDereferenceObject(Accel);
return Accel; return Accel;
} }
@ -118,7 +116,7 @@ NtUserCopyAcceleratorTable(
RETURN(0); RETURN(0);
} }
if (!(Accel = UserGetAccelObjectNoRef(hAccel))) if (!(Accel = UserGetAccelObject(hAccel)))
{ {
ObDereferenceObject(WindowStation); ObDereferenceObject(WindowStation);
RETURN(0); RETURN(0);
@ -177,11 +175,7 @@ NtUserCreateAcceleratorTable(
RETURN( FALSE ); RETURN( FALSE );
} }
Accel = ObmCreateObject( Accel = ObmCreateObject(&gHandleTable, (PHANDLE)&hAccel, otAccel, sizeof(ACCELERATOR_TABLE));
gHandleTable,
(PHANDLE)&hAccel,
otAcceleratorTable,
sizeof(ACCELERATOR_TABLE));
if (Accel == NULL) if (Accel == NULL)
{ {
@ -196,7 +190,7 @@ NtUserCreateAcceleratorTable(
Accel->Table = ExAllocatePoolWithTag(PagedPool, EntriesCount * sizeof(ACCEL), TAG_ACCEL); Accel->Table = ExAllocatePoolWithTag(PagedPool, EntriesCount * sizeof(ACCEL), TAG_ACCEL);
if (Accel->Table == NULL) if (Accel->Table == NULL)
{ {
ObmCloseHandle(gHandleTable, hAccel); ObmDeleteObject(hAccel, otAccel);
ObDereferenceObject(WindowStation); ObDereferenceObject(WindowStation);
SetLastNtError(Status); SetLastNtError(Status);
RETURN( (HACCEL) 0); RETURN( (HACCEL) 0);
@ -206,7 +200,7 @@ NtUserCreateAcceleratorTable(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ExFreePool(Accel->Table); ExFreePool(Accel->Table);
ObmCloseHandle(gHandleTable, hAccel); ObmDeleteObject(hAccel, otAccel);
ObDereferenceObject(WindowStation); ObDereferenceObject(WindowStation);
SetLastNtError(Status); SetLastNtError(Status);
RETURN((HACCEL) 0); RETURN((HACCEL) 0);
@ -258,13 +252,13 @@ NtUserDestroyAcceleratorTable(
RETURN( FALSE); RETURN( FALSE);
} }
if (!(Accel = UserGetAccelObjectNoRef(hAccel))) if (!(Accel = UserGetAccelObject(hAccel)))
{ {
ObDereferenceObject(WindowStation); ObDereferenceObject(WindowStation);
RETURN( FALSE); RETURN( FALSE);
} }
ObmCloseHandle(gHandleTable, hAccel); ObmDeleteObject(hAccel, otAccel);
if (Accel->Table != NULL) if (Accel->Table != NULL)
{ {
@ -294,7 +288,7 @@ co_IntTranslateAccelerator(
{ {
UINT mesg = 0; UINT mesg = 0;
ASSERT_REFS(Window); ASSERT_REFS_CO(Window);
DPRINT("IntTranslateAccelerator(hwnd %x, message %x, wParam %x, lParam %x, fVirt %d, key %x, cmd %x)\n", DPRINT("IntTranslateAccelerator(hwnd %x, message %x, wParam %x, lParam %x, fVirt %d, key %x, cmd %x)\n",
Window->hSelf, message, wParam, lParam, fVirt, key, cmd); Window->hSelf, message, wParam, lParam, fVirt, key, cmd);
@ -509,19 +503,19 @@ NtUserTranslateAccelerator(
RETURN( 0); RETURN( 0);
} }
if (!(Accel = UserGetAccelObjectNoRef(hAccel))) if (!(Accel = UserGetAccelObject(hAccel)))
{ {
RETURN( 0); RETURN( 0);
} }
UserReferenceAccelObjectCo(Accel); UserRefObjectCo(Accel);
if (!(Window = UserGetWindowObject(hWnd))) if (!(Window = UserGetWindowObject(hWnd)))
{ {
RETURN( 0); RETURN( 0);
} }
UserReferenceWindowObjectCo(Window); UserRefObjectCo(Window);
/* FIXME: Associate AcceleratorTable with the current thread */ /* FIXME: Associate AcceleratorTable with the current thread */
@ -546,8 +540,8 @@ NtUserTranslateAccelerator(
CLEANUP: CLEANUP:
if (Window) UserReferenceWindowObjectCo(Window); if (Window) UserDerefObjectCo(Window);
if (Accel) UserReferenceAccelObjectCo(Accel); if (Accel) UserDerefObjectCo(Accel);
if (WindowStation) ObDereferenceObject(WindowStation); if (WindowStation) ObDereferenceObject(WindowStation);

View file

@ -299,7 +299,7 @@ IntCreateClass(
} }
objectSize = sizeof(WNDCLASS_OBJECT) + lpwcx->cbClsExtra; objectSize = sizeof(WNDCLASS_OBJECT) + lpwcx->cbClsExtra;
ClassObject = ObmCreateObject(NULL, NULL, otClass, objectSize); ClassObject = ObmCreateObject(&gHandleTable, NULL, otClass, objectSize);
if (ClassObject == 0) if (ClassObject == 0)
{ {
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
@ -538,21 +538,17 @@ DWORD STDCALL
NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi) NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi)
{ {
PWINDOW_OBJECT Window; PWINDOW_OBJECT Window;
LONG Ret;
DECLARE_RETURN(DWORD); DECLARE_RETURN(DWORD);
DPRINT("Enter NtUserGetClassLong\n"); DPRINT("Enter NtUserGetClassLong\n");
UserEnterExclusive(); UserEnterExclusive();
Window = IntGetWindowObject(hWnd); if (!(Window = UserGetWindowObject(hWnd)))
if (Window == NULL)
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
RETURN(0); RETURN(0);
} }
Ret = IntGetClassLong(Window, Offset, Ansi);
IntReleaseWindowObject(Window); RETURN(IntGetClassLong(Window, Offset, Ansi));
RETURN(Ret);
CLEANUP: CLEANUP:
DPRINT("Leave NtUserGetClassLong, ret=%i\n",_ret_); DPRINT("Leave NtUserGetClassLong, ret=%i\n",_ret_);
@ -565,6 +561,8 @@ co_IntSetClassLong(PWINDOW_OBJECT Window, ULONG Offset, LONG dwNewLong, BOOL Ans
{ {
PWINDOW_OBJECT Parent, Owner; PWINDOW_OBJECT Parent, Owner;
ASSERT_REFS_CO(Window);
if ((int)Offset >= 0) if ((int)Offset >= 0)
{ {
DPRINT("SetClassLong(%x, %d, %x)\n", Window->hSelf, Offset, dwNewLong); DPRINT("SetClassLong(%x, %d, %x)\n", Window->hSelf, Offset, dwNewLong);
@ -669,14 +667,18 @@ NtUserSetClassLong(HWND hWnd,
DPRINT("Enter NtUserSetClassLong\n"); DPRINT("Enter NtUserSetClassLong\n");
UserEnterExclusive(); UserEnterExclusive();
if (!(Window = IntGetWindowObject(hWnd))) if (!(Window = UserGetWindowObject(hWnd)))
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
RETURN(0); RETURN(0);
} }
UserRefObjectCo(Window);
Ret = IntGetClassLong(Window, Offset, Ansi); Ret = IntGetClassLong(Window, Offset, Ansi);
co_IntSetClassLong(Window, Offset, dwNewLong, Ansi); co_IntSetClassLong(Window, Offset, dwNewLong, Ansi);
IntReleaseWindowObject(Window);
UserDerefObjectCo(Window);
RETURN(Ret); RETURN(Ret);
CLEANUP: CLEANUP:

View file

@ -71,19 +71,34 @@ IntGetCursorLocation(PWINSTATION_OBJECT WinStaObject, POINT *loc)
return TRUE; return TRUE;
} }
PCURICON_OBJECT FASTCALL
IntGetCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle)
{
PCURICON_OBJECT Object;
NTSTATUS Status;
Status = ObmReferenceObjectByHandle(gHandleTable,
Handle, otCursorIcon, (PVOID*)&Object);
if (!NT_SUCCESS(Status)) /* temp hack */
PCURICON_OBJECT FASTCALL UserGetCurIconObject(HANDLE hWnd)
{ {
PCURICON_OBJECT Window = (PCURICON_OBJECT)UserGetObject(&gHandleTable, hWnd, otCursor);
if (!Window)
{
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
return NULL; return NULL;
} }
return Object;
ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
return Window;
}
PCURICON_OBJECT FASTCALL
IntGetCurIconObject(HANDLE Handle)
{
PCURICON_OBJECT ci = UserGetCurIconObject(Handle);
if (ci)
{
ASSERT(USER_BODY_TO_HEADER(ci)->RefCount >= 0);
USER_BODY_TO_HEADER(ci)->RefCount++;
}
return ci;
} }
#define COLORCURSORS_ALLOWED FALSE #define COLORCURSORS_ALLOWED FALSE
@ -362,7 +377,9 @@ IntFindExistingCurIconObject(PWINSTATION_OBJECT WinStaObject, HMODULE hModule,
{ {
Object = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry); Object = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry);
CurrentEntry = CurrentEntry->Flink; CurrentEntry = CurrentEntry->Flink;
if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon)))
// if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon))) //<- huh????
ObmReferenceObject( Object);
{ {
if((Object->hModule == hModule) && (Object->hRsrc == hRsrc)) if((Object->hModule == hModule) && (Object->hRsrc == hRsrc))
{ {
@ -380,6 +397,7 @@ IntFindExistingCurIconObject(PWINSTATION_OBJECT WinStaObject, HMODULE hModule,
} }
} }
ObmDereferenceObject(Object); ObmDereferenceObject(Object);
} }
return NULL; return NULL;
@ -391,7 +409,7 @@ IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject)
PCURICON_OBJECT Object; PCURICON_OBJECT Object;
HANDLE Handle; HANDLE Handle;
Object = ObmCreateObject(gHandleTable, &Handle, otCursorIcon, sizeof(CURICON_OBJECT)); Object = ObmCreateObject(&gHandleTable, &Handle, otCursor, sizeof(CURICON_OBJECT));
if(!Object) if(!Object)
{ {
@ -405,7 +423,7 @@ IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject)
if (! ReferenceCurIconByProcess(Object)) if (! ReferenceCurIconByProcess(Object))
{ {
DPRINT1("Failed to add process\n"); DPRINT1("Failed to add process\n");
ObmCloseHandle(gHandleTable, Handle); ObmDeleteObject(Handle, otCursor);
ObmDereferenceObject(Object); ObmDereferenceObject(Object);
return NULL; return NULL;
} }
@ -483,7 +501,7 @@ IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT Object,
bmpMask = Object->IconInfo.hbmMask; bmpMask = Object->IconInfo.hbmMask;
bmpColor = Object->IconInfo.hbmColor; bmpColor = Object->IconInfo.hbmColor;
Ret = NT_SUCCESS(ObmCloseHandle(gHandleTable, Object->Self)); Ret = ObmDeleteObject(Object->Self, otCursor);
/* delete bitmaps */ /* delete bitmaps */
if(bmpMask) if(bmpMask)
@ -520,7 +538,10 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process)
{ {
Object = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry); Object = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry);
CurrentEntry = CurrentEntry->Flink; CurrentEntry = CurrentEntry->Flink;
if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon)))
ObmReferenceObject(Object);
// if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon)))
{ {
ProcessEntry = Object->ProcessList.Flink; ProcessEntry = Object->ProcessList.Flink;
while (ProcessEntry != &Object->ProcessList) while (ProcessEntry != &Object->ProcessList)
@ -537,6 +558,8 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process)
ObmDereferenceObject(Object); ObmDereferenceObject(Object);
} }
} }
ObDereferenceObject(WinStaObject); ObDereferenceObject(WinStaObject);
@ -646,7 +669,7 @@ NtUserGetCursorIconInfo(
RETURN( FALSE); RETURN( FALSE);
} }
CurIconObject = IntGetCurIconObject(WinStaObject, Handle); CurIconObject = IntGetCurIconObject(Handle);
if(CurIconObject) if(CurIconObject)
{ {
if(IconInfo) if(IconInfo)
@ -712,7 +735,7 @@ NtUserGetCursorIconSize(
RETURN( FALSE); RETURN( FALSE);
} }
CurIconObject = IntGetCurIconObject(WinStaObject, Handle); CurIconObject = IntGetCurIconObject(Handle);
if(CurIconObject) if(CurIconObject)
{ {
/* Copy fields */ /* Copy fields */
@ -929,7 +952,6 @@ NtUserDestroyCursorIcon(
{ {
PWINSTATION_OBJECT WinStaObject; PWINSTATION_OBJECT WinStaObject;
PCURICON_OBJECT Object; PCURICON_OBJECT Object;
NTSTATUS Status;
DECLARE_RETURN(BOOL); DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserDestroyCursorIcon\n"); DPRINT("Enter NtUserDestroyCursorIcon\n");
@ -941,13 +963,18 @@ NtUserDestroyCursorIcon(
RETURN( FALSE); RETURN( FALSE);
} }
Status = ObmReferenceObjectByHandle(gHandleTable, Handle, otCursorIcon, (PVOID*)&Object); if (!(Object = IntGetCurIconObject(Handle)))
if(!NT_SUCCESS(Status))
{ {
ObDereferenceObject(WinStaObject); ObDereferenceObject(WinStaObject);
SetLastNtError(Status);
RETURN(FALSE); RETURN(FALSE);
} }
// Status = ObmReferenceObjectByHandle(gHandleTable, Handle, otCursorIcon, (PVOID*)&Object);
// if(!NT_SUCCESS(Status))
// {
// ObDereferenceObject(WinStaObject);
// SetLastNtError(Status);
// RETURN( FALSE);
// }
if(IntDestroyCurIconObject(WinStaObject, Object, FALSE)) if(IntDestroyCurIconObject(WinStaObject, Object, FALSE))
{ {
@ -1098,7 +1125,7 @@ NtUserSetCursor(
RETURN( (HCURSOR)0); RETURN( (HCURSOR)0);
} }
CurIconObject = IntGetCurIconObject(WinStaObject, hCursor); CurIconObject = IntGetCurIconObject(hCursor);
if(CurIconObject) if(CurIconObject)
{ {
OldCursor = IntSetCursor(WinStaObject, CurIconObject, FALSE); OldCursor = IntSetCursor(WinStaObject, CurIconObject, FALSE);
@ -1142,7 +1169,7 @@ NtUserSetCursorIconContents(
RETURN( FALSE); RETURN( FALSE);
} }
CurIconObject = IntGetCurIconObject(WinStaObject, Handle); CurIconObject = IntGetCurIconObject(Handle);
if(CurIconObject) if(CurIconObject)
{ {
/* Copy fields */ /* Copy fields */
@ -1222,7 +1249,7 @@ NtUserSetCursorIconData(
RETURN( FALSE); RETURN( FALSE);
} }
CurIconObject = IntGetCurIconObject(WinStaObject, Handle); CurIconObject = IntGetCurIconObject(Handle);
if(CurIconObject) if(CurIconObject)
{ {
CurIconObject->hModule = hModule; CurIconObject->hModule = hModule;
@ -1338,7 +1365,7 @@ NtUserDrawIconEx(
RETURN( FALSE); RETURN( FALSE);
} }
CurIconObject = IntGetCurIconObject(WinStaObject, hIcon); CurIconObject = IntGetCurIconObject(hIcon);
if(CurIconObject) if(CurIconObject)
{ {
hbmMask = CurIconObject->IconInfo.hbmMask; hbmMask = CurIconObject->IconInfo.hbmMask;

View file

@ -63,7 +63,7 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate)
{ {
PWINDOW_OBJECT Window, Owner, Parent; PWINDOW_OBJECT Window, Owner, Parent;
if (hWnd) if (hWnd && (Window = IntGetWindowObject(hWnd)))
{ {
/* Send palette messages */ /* Send palette messages */
if (co_IntPostOrSendMessage(hWnd, WM_QUERYNEWPALETTE, 0, 0)) if (co_IntPostOrSendMessage(hWnd, WM_QUERYNEWPALETTE, 0, 0))
@ -73,24 +73,25 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate)
} }
if (UserGetWindow(hWnd, GW_HWNDPREV) != NULL) if (UserGetWindow(hWnd, GW_HWNDPREV) != NULL)
co_WinPosSetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
Window = IntGetWindowObject(hWnd);
if (Window) {
Owner = IntGetOwner(Window); Owner = IntGetOwner(Window);
if (!Owner) { if (!Owner)
{
Parent = IntGetParent(Window); Parent = IntGetParent(Window);
if (!Parent) if (!Parent)
co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (LPARAM) hWnd); co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (LPARAM) hWnd);
else else
IntReleaseWindowObject(Parent); IntReleaseWindowObject(Parent);
} else { }
else
{
IntReleaseWindowObject(Owner); IntReleaseWindowObject(Owner);
} }
IntReleaseWindowObject(Window); IntReleaseWindowObject(Window);
}
/* FIXME: IntIsWindow */ /* FIXME: IntIsWindow */
@ -154,6 +155,8 @@ co_IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window, PWINDOW_OBJECT FocusWin
HWND hWndFocusPrev = NULL; HWND hWndFocusPrev = NULL;
PUSER_MESSAGE_QUEUE PrevForegroundQueue; PUSER_MESSAGE_QUEUE PrevForegroundQueue;
ASSERT_REFS_CO(Window);
DPRINT("IntSetForegroundAndFocusWindow(%x, %x, %s)\n", hWnd, hWndFocus, MouseActivate ? "TRUE" : "FALSE"); DPRINT("IntSetForegroundAndFocusWindow(%x, %x, %s)\n", hWnd, hWndFocus, MouseActivate ? "TRUE" : "FALSE");
DPRINT("(%wZ)\n", &Window->WindowName); DPRINT("(%wZ)\n", &Window->WindowName);
@ -214,6 +217,8 @@ co_IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window, PWINDOW_OBJECT FocusWin
BOOL FASTCALL BOOL FASTCALL
co_IntSetForegroundWindow(PWINDOW_OBJECT Window) co_IntSetForegroundWindow(PWINDOW_OBJECT Window)
{ {
ASSERT_REFS_CO(Window);
return co_IntSetForegroundAndFocusWindow(Window, Window, FALSE); return co_IntSetForegroundAndFocusWindow(Window, Window, FALSE);
} }
@ -223,6 +228,8 @@ co_IntMouseActivateWindow(PWINDOW_OBJECT Window)
HWND Top; HWND Top;
PWINDOW_OBJECT TopWindow; PWINDOW_OBJECT TopWindow;
ASSERT_REFS_CO(Window);
if(Window->Style & WS_DISABLED) if(Window->Style & WS_DISABLED)
{ {
BOOL Ret; BOOL Ret;
@ -269,12 +276,14 @@ co_IntMouseActivateWindow(PWINDOW_OBJECT Window)
} }
HWND FASTCALL HWND FASTCALL
co_IntSetActiveWindow(PWINDOW_OBJECT Window) co_IntSetActiveWindow(PWINDOW_OBJECT Window OPTIONAL)
{ {
PUSER_MESSAGE_QUEUE ThreadQueue; PUSER_MESSAGE_QUEUE ThreadQueue;
HWND hWndPrev; HWND hWndPrev;
HWND hWnd = 0; HWND hWnd = 0;
if (Window) ASSERT_REFS_CO(Window);
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue; ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
ASSERT(ThreadQueue != 0); ASSERT(ThreadQueue != 0);
@ -404,10 +413,8 @@ NtUserSetActiveWindow(HWND hWnd)
PUSER_MESSAGE_QUEUE ThreadQueue; PUSER_MESSAGE_QUEUE ThreadQueue;
HWND hWndPrev; HWND hWndPrev;
Window = IntGetWindowObject(hWnd); if (!(Window = UserGetWindowObject(hWnd)))
if (Window == NULL)
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
RETURN( 0); RETURN( 0);
} }
@ -417,13 +424,13 @@ NtUserSetActiveWindow(HWND hWnd)
if (Window->MessageQueue != ThreadQueue) if (Window->MessageQueue != ThreadQueue)
{ {
IntReleaseWindowObject(Window);
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
RETURN( 0); RETURN( 0);
} }
UserRefObjectCo(Window);
hWndPrev = co_IntSetActiveWindow(Window); hWndPrev = co_IntSetActiveWindow(Window);
IntReleaseWindowObject(Window); UserDerefObjectCo(Window);
RETURN( hWndPrev); RETURN( hWndPrev);
} }
@ -474,14 +481,15 @@ NtUserSetCapture(HWND hWnd)
UserEnterExclusive(); UserEnterExclusive();
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue; ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
if((Window = IntGetWindowObject(hWnd)))
if((Window = UserGetWindowObject(hWnd)))
{ {
if(Window->MessageQueue != ThreadQueue) if(Window->MessageQueue != ThreadQueue)
{ {
IntReleaseWindowObject(Window);
RETURN(NULL); RETURN(NULL);
} }
} }
hWndPrev = MsqSetStateWindow(ThreadQueue, MSQ_STATE_CAPTURE, hWnd); hWndPrev = MsqSetStateWindow(ThreadQueue, MSQ_STATE_CAPTURE, hWnd);
/* also remove other windows if not capturing anymore */ /* also remove other windows if not capturing anymore */
@ -512,10 +520,8 @@ HWND FASTCALL UserSetFocus(HWND hWnd)
PUSER_MESSAGE_QUEUE ThreadQueue; PUSER_MESSAGE_QUEUE ThreadQueue;
HWND hWndPrev, hWndTop; HWND hWndPrev, hWndTop;
Window = IntGetWindowObject(hWnd); if (!(Window = UserGetWindowObject(hWnd)))
if (Window == NULL)
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return( 0); return( 0);
} }
@ -523,13 +529,11 @@ HWND FASTCALL UserSetFocus(HWND hWnd)
if (Window->Style & (WS_MINIMIZE | WS_DISABLED)) if (Window->Style & (WS_MINIMIZE | WS_DISABLED))
{ {
IntReleaseWindowObject(Window);
return( (ThreadQueue ? ThreadQueue->FocusWindow : 0)); return( (ThreadQueue ? ThreadQueue->FocusWindow : 0));
} }
if (Window->MessageQueue != ThreadQueue) if (Window->MessageQueue != ThreadQueue)
{ {
IntReleaseWindowObject(Window);
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return( 0); return( 0);
} }
@ -543,7 +547,6 @@ HWND FASTCALL UserSetFocus(HWND hWnd)
} }
hWndPrev = co_IntSetFocusWindow(hWnd); hWndPrev = co_IntSetFocusWindow(hWnd);
IntReleaseWindowObject(Window);
return( hWndPrev); return( hWndPrev);
} }

View file

@ -58,6 +58,26 @@ IntAllocHookTable(void)
return Table; return Table;
} }
PHOOK FASTCALL IntGetHookObject(HHOOK hWnd)
{
PHOOK Window = (PHOOK)UserGetObject(&gHandleTable, hWnd, otHook);
if (!Window)
{
SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE);
return NULL;
}
ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
USER_BODY_TO_HEADER(Window)->RefCount++;
return Window;
}
/* create a new hook and add it to the specified table */ /* create a new hook and add it to the specified table */
STATIC FASTCALL PHOOK STATIC FASTCALL PHOOK
IntAddHook(PETHREAD Thread, int HookId, BOOLEAN Global, PWINSTATION_OBJECT WinStaObj) IntAddHook(PETHREAD Thread, int HookId, BOOLEAN Global, PWINSTATION_OBJECT WinStaObj)
@ -83,8 +103,7 @@ IntAddHook(PETHREAD Thread, int HookId, BOOLEAN Global, PWINSTATION_OBJECT WinSt
} }
} }
Hook = ObmCreateObject(gHandleTable, &Handle, Hook = ObmCreateObject(&gHandleTable, &Handle, otHook, sizeof(HOOK));
otHookProc, sizeof(HOOK));
if (NULL == Hook) if (NULL == Hook)
{ {
return NULL; return NULL;
@ -180,7 +199,7 @@ IntFreeHook(PHOOKTABLE Table, PHOOK Hook, PWINSTATION_OBJECT WinStaObj)
} }
/* Close handle */ /* Close handle */
ObmCloseHandle(gHandleTable, Hook->Self); ObmDeleteObject(Hook->Self, otHook);
} }
/* remove a hook, freeing it if the chain is not in use */ /* remove a hook, freeing it if the chain is not in use */
@ -399,15 +418,22 @@ NtUserCallNextHookEx(
RETURN( FALSE); RETURN( FALSE);
} }
Status = ObmReferenceObjectByHandle(gHandleTable, Hook, //Status = ObmReferenceObjectByHandle(gHandleTable, Hook,
otHookProc, (PVOID *) &HookObj); // otHookProc, (PVOID *) &HookObj);
ObDereferenceObject(WinStaObj); ObDereferenceObject(WinStaObj);
if (! NT_SUCCESS(Status))
// if (! NT_SUCCESS(Status))
// {
// DPRINT1("Invalid handle passed to NtUserCallNextHookEx\n");
// SetLastNtError(Status);
// RETURN( 0);
// }
if (!(HookObj = IntGetHookObject(Hook)))
{ {
DPRINT1("Invalid handle passed to NtUserCallNextHookEx\n");
SetLastNtError(Status);
RETURN(0); RETURN(0);
} }
ASSERT(Hook == HookObj->Self); ASSERT(Hook == HookObj->Self);
if (NULL != HookObj->Thread && (HookObj->Thread != PsGetCurrentThread())) if (NULL != HookObj->Thread && (HookObj->Thread != PsGetCurrentThread()))
@ -687,13 +713,13 @@ NtUserUnhookWindowsHookEx(
RETURN( FALSE); RETURN( FALSE);
} }
Status = ObmReferenceObjectByHandle(gHandleTable, Hook, // Status = ObmReferenceObjectByHandle(gHandleTable, Hook,
otHookProc, (PVOID *) &HookObj); // otHookProc, (PVOID *) &HookObj);
if (! NT_SUCCESS(Status)) if (!(HookObj = IntGetHookObject(Hook)))
{ {
DPRINT1("Invalid handle passed to NtUserUnhookWindowsHookEx\n"); DPRINT1("Invalid handle passed to NtUserUnhookWindowsHookEx\n");
ObDereferenceObject(WinStaObj); ObDereferenceObject(WinStaObj);
SetLastNtError(Status); // SetLastNtError(Status);
RETURN( FALSE); RETURN( FALSE);
} }
ASSERT(Hook == HookObj->Self); ASSERT(Hook == HookObj->Self);

View file

@ -376,14 +376,8 @@ IntKeyboardSendWinKeyMsg()
{ {
PWINDOW_OBJECT Window; PWINDOW_OBJECT Window;
MSG Mesg; MSG Mesg;
NTSTATUS Status;
Status = ObmReferenceObjectByHandle(gHandleTable, if (!(Window = IntGetWindowObject(InputWindowStation->ShellWindow)))
InputWindowStation->ShellWindow,
otWindow,
(PVOID *)&Window);
if (!NT_SUCCESS(Status))
{ {
DPRINT1("Couldn't find window to send Windows key message!\n"); DPRINT1("Couldn't find window to send Windows key message!\n");
return; return;
@ -895,7 +889,6 @@ IntMouseInput(MOUSEINPUT *mi)
SURFOBJ *SurfObj; SURFOBJ *SurfObj;
PDC dc; PDC dc;
PWINDOW_OBJECT DesktopWindow; PWINDOW_OBJECT DesktopWindow;
NTSTATUS Status;
#if 1 #if 1
HDC hDC; HDC hDC;
@ -947,9 +940,9 @@ IntMouseInput(MOUSEINPUT *mi)
MousePos.y += mi->dy; MousePos.y += mi->dy;
} }
Status = ObmReferenceObjectByHandle(gHandleTable, DesktopWindow = IntGetWindowObject(WinSta->ActiveDesktop->DesktopWindow);
WinSta->ActiveDesktop->DesktopWindow, otWindow, (PVOID*)&DesktopWindow);
if (NT_SUCCESS(Status)) if (DesktopWindow)
{ {
if(MousePos.x >= DesktopWindow->ClientRect.right) if(MousePos.x >= DesktopWindow->ClientRect.right)
MousePos.x = DesktopWindow->ClientRect.right - 1; MousePos.x = DesktopWindow->ClientRect.right - 1;

View file

@ -115,17 +115,14 @@ CleanupMenuImpl(VOID)
PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu) PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu)
{ {
PMENU_OBJECT Menu; PMENU_OBJECT Menu = (PMENU_OBJECT)UserGetObject(&gHandleTable, hMenu, otMenu);
NTSTATUS Status; if (!Menu)
Status = ObmReferenceObjectByHandle(gHandleTable,
hMenu, otMenu, (PVOID*)&Menu);
if (!NT_SUCCESS(Status))
{ {
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE); SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
return NULL; return NULL;
} }
ObmDereferenceObject(Menu);
ASSERT(USER_BODY_TO_HEADER(Menu)->RefCount >= 0);
return Menu; return Menu;
} }
@ -170,21 +167,14 @@ DumpMenuItemList(PMENU_ITEM MenuItem)
PMENU_OBJECT FASTCALL PMENU_OBJECT FASTCALL
IntGetMenuObject(HMENU hMenu) IntGetMenuObject(HMENU hMenu)
{ {
PMENU_OBJECT MenuObject; PMENU_OBJECT Menu = UserGetMenuObject(hMenu);
PW32THREAD W32Thread = PsGetWin32Thread(); if (Menu)
if(!W32Thread)
{ {
return NULL; ASSERT(USER_BODY_TO_HEADER(Menu)->RefCount >= 0);
}
NTSTATUS Status = ObmReferenceObjectByHandle(gHandleTable, USER_BODY_TO_HEADER(Menu)->RefCount++;
hMenu, otMenu, (PVOID*)&MenuObject);
if (!NT_SUCCESS(Status))
{
return NULL;
} }
return MenuObject; return Menu;
} }
BOOL FASTCALL BOOL FASTCALL
@ -279,7 +269,7 @@ IntDestroyMenuObject(PMENU_OBJECT Menu,
NULL); NULL);
if(NT_SUCCESS(Status)) if(NT_SUCCESS(Status))
{ {
ObmCloseHandle(gHandleTable, Menu->MenuInfo.Self); ObmDeleteObject(Menu->MenuInfo.Self, otMenu);
ObDereferenceObject(WindowStation); ObDereferenceObject(WindowStation);
return TRUE; return TRUE;
} }
@ -293,7 +283,7 @@ IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
PMENU_OBJECT Menu; PMENU_OBJECT Menu;
Menu = (PMENU_OBJECT)ObmCreateObject( Menu = (PMENU_OBJECT)ObmCreateObject(
gHandleTable, Handle, &gHandleTable, Handle,
otMenu, sizeof(MENU_OBJECT)); otMenu, sizeof(MENU_OBJECT));
if(!Menu) if(!Menu)
@ -402,7 +392,7 @@ IntCloneMenu(PMENU_OBJECT Source)
return NULL; return NULL;
Menu = (PMENU_OBJECT)ObmCreateObject( Menu = (PMENU_OBJECT)ObmCreateObject(
gHandleTable, &hMenu, &gHandleTable, &hMenu,
otMenu, sizeof(MENU_OBJECT)); otMenu, sizeof(MENU_OBJECT));
if(!Menu) if(!Menu)
@ -1692,6 +1682,7 @@ NtUserGetMenuItemRect(
ULONG i; ULONG i;
NTSTATUS Status; NTSTATUS Status;
PMENU_OBJECT Menu; PMENU_OBJECT Menu;
PWINDOW_OBJECT ReferenceWnd;
DECLARE_RETURN(BOOL); DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserGetMenuItemRect\n"); DPRINT("Enter NtUserGetMenuItemRect\n");
@ -1718,7 +1709,11 @@ NtUserGetMenuItemRect(
*lpRect = mii.Rect; *lpRect = mii.Rect;
lpPoints = (LPPOINT)lpRect; lpPoints = (LPPOINT)lpRect;
if(!UserGetClientOrigin(referenceHwnd, &FromOffset)) RETURN( FALSE); ReferenceWnd = UserGetWindowObject(referenceHwnd);
if (!ReferenceWnd || !UserGetClientOrigin(ReferenceWnd, &FromOffset))
{
RETURN( FALSE);
}
XMove = FromOffset.x; XMove = FromOffset.x;
YMove = FromOffset.y; YMove = FromOffset.y;

View file

@ -507,7 +507,18 @@ NtUserCallTwoParam(
RETURN( 0); RETURN( 0);
case TWOPARAM_ROUTINE_VALIDATERGN: case TWOPARAM_ROUTINE_VALIDATERGN:
RETURN( (DWORD)UserValidateRgn((HWND) Param1, (HRGN) Param2)); {
PWINDOW_OBJECT Window = UserGetWindowObject((HWND) Param1);
BOOL ret;
if (!Window) RETURN(FALSE);
UserRefObjectCo(Window);
ret = co_UserValidateRgn(Window, (HRGN) Param2);
UserDerefObjectCo(Window);
RETURN((DWORD) ret);
}
case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID: case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID:
WindowObject = IntGetWindowObject((HWND)Param1); WindowObject = IntGetWindowObject((HWND)Param1);
@ -724,7 +735,7 @@ NtUserCallHwndLock(
MenuObject->MenuInfo.WndOwner = hWnd; MenuObject->MenuInfo.WndOwner = hWnd;
MenuObject->MenuInfo.Height = 0; MenuObject->MenuInfo.Height = 0;
IntReleaseMenuObject(MenuObject); IntReleaseMenuObject(MenuObject);
co_WinPosSetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
Ret = TRUE; Ret = TRUE;
break; break;

View file

@ -91,7 +91,7 @@ IntCreateMonitorObject()
HANDLE Handle; HANDLE Handle;
PMONITOR_OBJECT Monitor; PMONITOR_OBJECT Monitor;
Monitor = ObmCreateObject(gHandleTable, &Handle, otMonitor, sizeof (MONITOR_OBJECT)); Monitor = ObmCreateObject(&gHandleTable, &Handle, otMonitor, sizeof (MONITOR_OBJECT));
if (Monitor == NULL) if (Monitor == NULL)
{ {
return NULL; return NULL;
@ -138,16 +138,18 @@ static
PMONITOR_OBJECT PMONITOR_OBJECT
IntGetMonitorObject(IN HMONITOR hMonitor) IntGetMonitorObject(IN HMONITOR hMonitor)
{ {
PMONITOR_OBJECT Monitor;
NTSTATUS Status;
Status = ObmReferenceObjectByHandle(gHandleTable, hMonitor, otMonitor, (PVOID *)&Monitor); PMONITOR_OBJECT Monitor = (PMONITOR_OBJECT)UserGetObject(&gHandleTable, hMonitor, otMonitor);
if (!NT_SUCCESS(Status) || Monitor == NULL) if (!Monitor)
{ {
/* FIXME: SetLastNtError( status ); ? */ SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);
return NULL; return NULL;
} }
ASSERT(USER_BODY_TO_HEADER(Monitor)->RefCount >= 0);
USER_BODY_TO_HEADER(Monitor)->RefCount++;
return Monitor; return Monitor;
} }

View file

@ -733,9 +733,8 @@ MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
} }
WinSta = Win32Thread->Desktop->WindowStation; WinSta = Win32Thread->Desktop->WindowStation;
Status = ObmReferenceObjectByHandle(gHandleTable, Window = IntGetWindowObject(hWnd);
hWnd, otWindow, (PVOID*)&Window); if (!Window)
if (!NT_SUCCESS(Status))
{ {
ObDereferenceObject ((PETHREAD)Thread); ObDereferenceObject ((PETHREAD)Thread);
return; return;

View file

@ -50,16 +50,14 @@ NTSTATUS FASTCALL InitUserImpl(VOID)
// DPRINT("Enter InitUserImpl\n"); // DPRINT("Enter InitUserImpl\n");
// ExInitializeResourceLite(&UserLock); // ExInitializeResourceLite(&UserLock);
ExInitializeFastMutex(&UserLock);
gHandleTable = ObmCreateHandleTable(); if (!ObmCreateHandleTable())
if (!gHandleTable)
{ {
DPRINT("Failed creating handle table\n"); DPRINT1("Failed creating handle table\n");
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
ExInitializeFastMutex(&UserLock);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -1,32 +1,25 @@
/* /*
* ReactOS W32 Subsystem * Server-side USER handles
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
* *
* This program is free software; you can redistribute it and/or modify * Copyright (C) 2001 Alexandre Julliard
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* GNU General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU Lesser General Public
* along with this program; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: User object manager
* FILE: subsys/win32k/misc/object.c
* PROGRAMMERS: David Welch (welch@cwcom.net)
* Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
* 06-06-2001 CSH Ported kernel object manager
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include <w32k.h> #include <w32k.h>
@ -34,479 +27,277 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#define USER_HEADER_TO_BODY(ObjectHeader) \ int usedHandles=0;
((PVOID)(((PUSER_OBJECT_HEADER)ObjectHeader) + 1)) USER_HANDLE_TABLE gHandleTable;
#define USER_BODY_TO_HEADER(ObjectBody) \
((PUSER_OBJECT_HEADER)(((PUSER_OBJECT_HEADER)ObjectBody) - 1))
PUSER_HANDLE_TABLE gHandleTable = NULL; PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle )
/* FUNCTIONS *****************************************************************/
VOID FASTCALL
ObmpPerformRetentionChecks(PUSER_OBJECT_HEADER ObjectHeader)
{
if (ObjectHeader->RefCount < 0)
{
DPRINT1("ObjectHeader 0x%X has invalid reference count (%d)\n",
ObjectHeader, ObjectHeader->RefCount);
ASSERT(FALSE);
}
if (ObjectHeader->HandleCount < 0)
{
DPRINT1("Object 0x%X has invalid handle count (%d)\n",
ObjectHeader, ObjectHeader->HandleCount);
}
if ((ObjectHeader->RefCount == 0) && (ObjectHeader->HandleCount == 0))
{
ExFreePool(ObjectHeader);
}
}
PUSER_HANDLE FASTCALL
ObmpGetObjectByHandle(PUSER_HANDLE_TABLE HandleTable,
HANDLE Handle)
/*
* FUNCTION: Get the data structure for a handle
* ARGUMENTS:
* HandleTable = Table to search
* Handle = Handle to get data structure for
* RETURNS:
* Pointer to the data structure identified by the handle on success,
* NULL on failure
*/
{
ULONG Index = (((ULONG)Handle) >> 2) - 1;
ULONG Count = Index / HANDLE_BLOCK_ENTRIES;
PUSER_HANDLE_BLOCK Block = NULL;
PLIST_ENTRY Current;
ULONG i;
if (NULL == Handle)
{ {
unsigned short generation;
int index = (((unsigned int)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
if (index < 0 || index >= ht->nb_handles) return NULL;
if (!ht->handles[index].type) return NULL;
generation = (unsigned int)handle >> 16;
if (generation == ht->handles[index].generation || !generation || generation == 0xffff)
return &ht->handles[index];
return NULL; return NULL;
} }
Current = HandleTable->ListHead.Flink; inline static HANDLE entry_to_handle(PUSER_HANDLE_TABLE ht, PUSER_HANDLE_ENTRY ptr )
{
int index = ptr - ht->handles;
return (HANDLE)(((index << 1) + FIRST_USER_HANDLE) + (ptr->generation << 16));
}
for (i = 0; i < Count; i++) inline static PUSER_HANDLE_ENTRY alloc_user_entry(PUSER_HANDLE_TABLE ht)
{ {
Current = Current->Flink; PUSER_HANDLE_ENTRY entry;
if (Current == &(HandleTable->ListHead))
if (ht->freelist)
{ {
DPRINT1("Invalid handle 0x%x\n", Handle); entry = ht->freelist;
ht->freelist = entry->ptr;
usedHandles++;
return entry;
}
if (ht->nb_handles >= ht->allocated_handles) /* need to grow the array */
{
DPRINT1("Out of user handles!\n");
return NULL;
#if 0
struct user_handle *new_handles;
/* grow array by 50% (but at minimum 32 entries) */
int growth = max( 32, allocated_handles / 2 );
int new_size = min( allocated_handles + growth, (LAST_USER_HANDLE-FIRST_USER_HANDLE+1) >> 1 );
if (new_size <= allocated_handles) return NULL;
if (!(new_handles = realloc( handles, new_size * sizeof(*handles) )))
return NULL;
handles = new_handles;
allocated_handles = new_size;
#endif
}
entry = &ht->handles[ht->nb_handles++];
entry->generation = 1;
usedHandles++;
return entry;
}
VOID UserInitHandleTable(PUSER_HANDLE_TABLE ht, PVOID mem, ULONG bytes)
{
ht->freelist = NULL;
ht->handles = mem;
ht->nb_handles = 0;
ht->allocated_handles = bytes / sizeof(USER_HANDLE_ENTRY);
}
inline static void *free_user_entry(PUSER_HANDLE_TABLE ht, PUSER_HANDLE_ENTRY entry)
{
void *ret;
ret = entry->ptr;
entry->ptr = ht->freelist;
entry->type = 0;
ht->freelist = entry;
usedHandles--;
return ret;
}
/* allocate a user handle for a given object */
HANDLE UserAllocHandle(PUSER_HANDLE_TABLE ht, PVOID object, USER_OBJECT_TYPE type )
{
PUSER_HANDLE_ENTRY entry = alloc_user_entry(ht);
if (!entry) return 0;
entry->ptr = object;
entry->type = type;
if (++entry->generation >= 0xffff) entry->generation = 1;
return entry_to_handle(ht, entry );
}
/* return a pointer to a user object from its handle */
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, USER_OBJECT_TYPE type )
{
PUSER_HANDLE_ENTRY entry;
ASSERT(ht);
if (!(entry = handle_to_entry(ht, handle )) || entry->type != type)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL; return NULL;
} }
return entry->ptr;
} }
Block = CONTAINING_RECORD(Current, USER_HANDLE_BLOCK, ListEntry);
return &(Block->Handles[Index % HANDLE_BLOCK_ENTRIES]);
}
VOID FASTCALL /* get the full handle (32bit) for a possibly truncated (16bit) handle */
ObmpCloseAllHandles(PUSER_HANDLE_TABLE HandleTable) HANDLE get_user_full_handle(PUSER_HANDLE_TABLE ht, HANDLE handle )
{ {
PLIST_ENTRY CurrentEntry; PUSER_HANDLE_ENTRY entry;
PUSER_HANDLE_BLOCK Current;
PVOID ObjectBody;
ULONG i;
CurrentEntry = HandleTable->ListHead.Flink; if ((unsigned int)handle >> 16) return handle;
if (!(entry = handle_to_entry(ht, handle ))) return handle;
return entry_to_handle( ht, entry );
}
while (CurrentEntry != &HandleTable->ListHead)
/* same as get_user_object plus set the handle to the full 32-bit value */
void *get_user_object_handle(PUSER_HANDLE_TABLE ht, HANDLE* handle, USER_OBJECT_TYPE type )
{ {
Current = CONTAINING_RECORD(CurrentEntry, USER_HANDLE_BLOCK, ListEntry); PUSER_HANDLE_ENTRY entry;
for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) if (!(entry = handle_to_entry(ht, *handle )) || entry->type != type) return NULL;
*handle = entry_to_handle( ht, entry );
return entry->ptr;
}
/* free a user handle and return a pointer to the object */
PVOID UserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle )
{ {
ObjectBody = Current->Handles[i].ObjectBody; PUSER_HANDLE_ENTRY entry;
if (ObjectBody != NULL) if (!(entry = handle_to_entry( ht, handle )))
{ {
PUSER_OBJECT_HEADER ObjectHeader = USER_BODY_TO_HEADER(ObjectBody); SetLastNtError( STATUS_INVALID_HANDLE );
return NULL;
ObmReferenceObjectByPointer(ObjectBody, otUnknown);
ObjectHeader->HandleCount--;
Current->Handles[i].ObjectBody = NULL;
ObmDereferenceObject(ObjectBody);
CurrentEntry = &HandleTable->ListHead;
break;
}
} }
CurrentEntry = CurrentEntry->Flink; return free_user_entry(ht, entry );
} }
} /* return the next user handle after 'handle' that is of a given type */
PVOID UserGetNextHandle(PUSER_HANDLE_TABLE ht, HANDLE* handle, USER_OBJECT_TYPE type )
VOID FASTCALL
ObmpDeleteHandleTable(PUSER_HANDLE_TABLE HandleTable)
{ {
PUSER_HANDLE_BLOCK Current; PUSER_HANDLE_ENTRY entry;
PLIST_ENTRY CurrentEntry;
ObmpCloseAllHandles(HandleTable); if (!*handle) entry = ht->handles;
else
CurrentEntry = RemoveHeadList(&HandleTable->ListHead);
while (CurrentEntry != &HandleTable->ListHead)
{ {
Current = CONTAINING_RECORD(CurrentEntry, int index = (((unsigned int)*handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
USER_HANDLE_BLOCK, if (index < 0 || index >= ht->nb_handles) return NULL;
ListEntry); entry = ht->handles + index + 1; /* start from the next one */
ExFreePool(Current);
CurrentEntry = RemoveHeadList(&HandleTable->ListHead);
} }
while (entry < ht->handles + ht->nb_handles)
{
if (!type || entry->type == type)
{
*handle = entry_to_handle(ht, entry );
return entry->ptr;
} }
entry++;
}
return NULL;
}
PVOID FASTCALL PVOID FASTCALL
ObmpDeleteHandle(PUSER_HANDLE_TABLE HandleTable, ObmCreateObject(PUSER_HANDLE_TABLE ht, HANDLE* h,USER_OBJECT_TYPE type , ULONG size)
HANDLE Handle)
{ {
PUSER_OBJECT_HEADER ObjectHeader;
PUSER_HANDLE Entry;
PVOID ObjectBody;
Entry = ObmpGetObjectByHandle(HandleTable, Handle); HANDLE hi;
if (Entry == NULL) PUSER_OBJECT_HEADER hdr = ExAllocatePool(PagedPool, size + sizeof(USER_OBJECT_HEADER));
{ if (!hdr) return NULL;
DPRINT1("Invalid handle\n");
hi = UserAllocHandle(ht, USER_HEADER_TO_BODY(hdr), type );
if (!hi){
ExFreePool(hdr);
return NULL; return NULL;
} }
ObjectBody = Entry->ObjectBody; RtlZeroMemory(hdr, size + sizeof(USER_OBJECT_HEADER));
hdr->hSelf = hi;
hdr->RefCount++; //temp hack!
if (ObjectBody != NULL) if (h) *h = hi;
return USER_HEADER_TO_BODY(hdr);
}
BOOL FASTCALL
ObmDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
{ {
ObjectHeader = USER_BODY_TO_HEADER(ObjectBody); PUSER_OBJECT_HEADER hdr;
ObjectHeader->HandleCount--; PVOID body = UserGetObject(&gHandleTable, h, type);
ObmReferenceObjectByPointer(ObjectBody, otUnknown); if (!body) return FALSE;
Entry->ObjectBody = NULL;
}
return ObjectBody; hdr = USER_BODY_TO_HEADER(body);
} ASSERT(hdr->RefCount >= 0);
NTSTATUS FASTCALL hdr->destroyed = TRUE;
ObmpInitializeObject(PUSER_HANDLE_TABLE HandleTable, if (hdr->RefCount == 0)
PUSER_OBJECT_HEADER ObjectHeader,
PHANDLE Handle,
USER_OBJECT_TYPE ObjectType,
ULONG ObjectSize)
{ {
DWORD Status = STATUS_SUCCESS; UserFreeHandle(&gHandleTable, h);
ObjectHeader->Type = ObjectType; memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
ObjectHeader->HandleCount = 0;
ObjectHeader->RefCount = 1;
ObjectHeader->Size = ObjectSize;
if (Handle != NULL) ExFreePool(hdr);
return TRUE;
}
// DPRINT1("info: something not destroyed bcause refs still left, inuse %i\n",usedHandles);
return FALSE;
}
VOID FASTCALL ObmReferenceObject(PVOID obj)
{ {
Status = ObmCreateHandle(HandleTable, PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
USER_HEADER_TO_BODY(ObjectHeader),
Handle);
}
return Status; ASSERT(hdr->RefCount >= 0);
hdr->RefCount++;
} }
ULONG FASTCALL BOOL FASTCALL ObmDereferenceObject(PVOID obj)
ObmGetReferenceCount(PVOID ObjectBody)
{ {
PUSER_OBJECT_HEADER ObjectHeader = USER_BODY_TO_HEADER(ObjectBody); PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
return ObjectHeader->RefCount; ASSERT(hdr->RefCount >= 1);
}
ULONG FASTCALL hdr->RefCount--;
ObmGetHandleCount(PVOID ObjectBody)
if (hdr->RefCount == 0 && hdr->destroyed)
{ {
PUSER_OBJECT_HEADER ObjectHeader = USER_BODY_TO_HEADER(ObjectBody); // DPRINT1("info: something destroyed bcaise of deref, in use=%i\n",usedHandles);
return ObjectHeader->HandleCount; UserFreeHandle(&gHandleTable, hdr->hSelf);
memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
ExFreePool(hdr);
return TRUE;
} }
VOID FASTCALL return FALSE;
ObmReferenceObject(PVOID ObjectBody) }
/*
* FUNCTION: Increments a given object's reference count and performs
* retention checks
* ARGUMENTS: BOOL FASTCALL ObmCreateHandleTable()
* ObjectBody = Body of the object
*/
{ {
PUSER_OBJECT_HEADER ObjectHeader;
if (!ObjectBody) PVOID mem;
//FIXME: dont alloc all at once! must be mapped into umode also...
mem = ExAllocatePool(PagedPool, sizeof(USER_HANDLE_ENTRY) * 1024);
if (!mem)
{ {
DPRINT1("Cannot Reference NULL!\n"); DPRINT1("Failed creating handle table\n");
return; return FALSE;
} }
ObjectHeader = USER_BODY_TO_HEADER(ObjectBody); //FIXME: make auto growable
UserInitHandleTable(&gHandleTable, mem, sizeof(USER_HANDLE_ENTRY) * 1024);
ObjectHeader->RefCount++; return TRUE;
ObmpPerformRetentionChecks(ObjectHeader);
} }
VOID FASTCALL
ObmDereferenceObject(PVOID ObjectBody)
/*
* FUNCTION: Decrements a given object's reference count and performs
* retention checks
* ARGUMENTS:
* ObjectBody = Body of the object
*/
{
PUSER_OBJECT_HEADER ObjectHeader;
if (!ObjectBody)
{
DPRINT1("Cannot Dereference NULL!\n");
return;
}
ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
ObjectHeader->RefCount--;
ObmpPerformRetentionChecks(ObjectHeader);
}
NTSTATUS FASTCALL
ObmReferenceObjectByPointer(PVOID ObjectBody,
USER_OBJECT_TYPE ObjectType)
/*
* FUNCTION: Increments the pointer reference count for a given object
* ARGUMENTS:
* ObjectBody = Object's body
* ObjectType = Object type
* RETURNS: Status
*/
{
PUSER_OBJECT_HEADER ObjectHeader;
ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
if ((ObjectType != otUnknown) && (ObjectHeader->Type != ObjectType))
{
return STATUS_INVALID_PARAMETER;
}
ObjectHeader->RefCount++;
return STATUS_SUCCESS;
}
PVOID FASTCALL
ObmCreateObject(PUSER_HANDLE_TABLE HandleTable,
PHANDLE Handle,
USER_OBJECT_TYPE ObjectType,
ULONG ObjectSize)
{
PUSER_OBJECT_HEADER ObjectHeader;
PVOID ObjectBody;
DWORD Status;
ObjectHeader = (PUSER_OBJECT_HEADER)ExAllocatePool(PagedPool,
ObjectSize + sizeof(USER_OBJECT_HEADER));
if (!ObjectHeader)
{
return NULL;
}
ObjectBody = USER_HEADER_TO_BODY(ObjectHeader);
RtlZeroMemory(ObjectBody, ObjectSize);
Status = ObmpInitializeObject(HandleTable,
ObjectHeader,
Handle,
ObjectType,
ObjectSize);
if (!NT_SUCCESS(Status))
{
ExFreePool(ObjectHeader);
return NULL;
}
return ObjectBody;
}
NTSTATUS FASTCALL
ObmCreateHandle(PUSER_HANDLE_TABLE HandleTable,
PVOID ObjectBody,
PHANDLE HandleReturn)
/*
* FUNCTION: Add a handle referencing an object
* ARGUMENTS:
* HandleTable = Table to put handle in
* ObjectBody = Object body that the handle should refer to
* RETURNS: The created handle
*/
{
PUSER_HANDLE_BLOCK NewBlock;
PLIST_ENTRY Current;
ULONG Handle;
ULONG i;
if (ObjectBody != NULL)
{
USER_BODY_TO_HEADER(ObjectBody)->HandleCount++;
}
Handle = 1;
Current = HandleTable->ListHead.Flink;
/*
* Scan through the currently allocated Handle blocks looking for a free
* slot
*/
while (Current != &(HandleTable->ListHead))
{
PUSER_HANDLE_BLOCK Block =
CONTAINING_RECORD(Current, USER_HANDLE_BLOCK, ListEntry);
for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
{
if (!Block->Handles[i].ObjectBody)
{
Block->Handles[i].ObjectBody = ObjectBody;
*HandleReturn = (HANDLE)((Handle + i) << 2);
return STATUS_SUCCESS;
}
}
Handle = Handle + HANDLE_BLOCK_ENTRIES;
Current = Current->Flink;
}
/*
* Add a new Handle block to the end of the list
*/
NewBlock = (PUSER_HANDLE_BLOCK)ExAllocatePool(PagedPool,
sizeof(USER_HANDLE_BLOCK));
if (!NewBlock)
{
DPRINT1("Unable to allocate new handle block\n");
*HandleReturn = (PHANDLE)NULL;
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(NewBlock, sizeof(USER_HANDLE_BLOCK));
NewBlock->Handles[0].ObjectBody = ObjectBody;
InsertTailList(&HandleTable->ListHead, &NewBlock->ListEntry);
*HandleReturn = (HANDLE)(Handle << 2);
return STATUS_SUCCESS;
}
NTSTATUS FASTCALL
ObmReferenceObjectByHandle(PUSER_HANDLE_TABLE HandleTable,
HANDLE Handle,
USER_OBJECT_TYPE ObjectType,
PVOID* Object)
/*
* FUNCTION: Increments the reference count for an object and returns a
* pointer to its body
* ARGUMENTS:
* HandleTable = Table to search
* Handle = Handle for the object
* ObjectType = Type of object
* Object (OUT) = Points to the object body on return
* RETURNS: Status
*/
{
PUSER_OBJECT_HEADER ObjectHeader;
PUSER_HANDLE UserHandle;
PVOID ObjectBody;
UserHandle = ObmpGetObjectByHandle(HandleTable, Handle);
if ((UserHandle == NULL) || (UserHandle->ObjectBody == NULL))
{
return STATUS_UNSUCCESSFUL;
}
ObjectBody = UserHandle->ObjectBody;
ObmReferenceObjectByPointer(ObjectBody, ObjectType);
ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
if ((ObjectType != otUnknown) && (ObjectHeader->Type != ObjectType))
{
DPRINT1("Object type mismatch 0x%x 0x%x\n", ObjectType, ObjectHeader->Type);
ObmDereferenceObject(ObjectBody);
return STATUS_UNSUCCESSFUL;
}
*Object = ObjectBody;
return STATUS_SUCCESS;
}
NTSTATUS FASTCALL
ObmCloseHandle(PUSER_HANDLE_TABLE HandleTable,
HANDLE Handle)
{
PVOID ObjectBody;
ObjectBody = ObmpDeleteHandle(HandleTable, Handle);
if (ObjectBody == NULL)
{
return STATUS_UNSUCCESSFUL;
}
ObmDereferenceObject(ObjectBody);
return STATUS_SUCCESS;
}
VOID FASTCALL
ObmInitializeHandleTable(PUSER_HANDLE_TABLE HandleTable)
{
InitializeListHead(&HandleTable->ListHead);
}
VOID FASTCALL
ObmFreeHandleTable(PUSER_HANDLE_TABLE HandleTable)
{
ObmpDeleteHandleTable(HandleTable);
}
PUSER_HANDLE_TABLE FASTCALL
ObmCreateHandleTable(VOID)
{
PUSER_HANDLE_TABLE HandleTable;
HandleTable = (PUSER_HANDLE_TABLE)ExAllocatePool(PagedPool,
sizeof(USER_HANDLE_TABLE));
if (!HandleTable)
{
DPRINT1("Unable to create handle table\n");
return NULL;
}
ObmInitializeHandleTable(HandleTable);
return HandleTable;
}
VOID FASTCALL
ObmDestroyHandleTable(PUSER_HANDLE_TABLE HandleTable)
{
ObmFreeHandleTable(HandleTable);
ExFreePool(HandleTable);
}
/* EOF */

View file

@ -625,25 +625,31 @@ IntGetPaintMessage(HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax,
static static
HWND FASTCALL HWND FASTCALL
co_IntFixCaret(HWND hWnd, LPRECT lprc, UINT flags) co_IntFixCaret(PWINDOW_OBJECT Window, LPRECT lprc, UINT flags)
{ {
PDESKTOP_OBJECT Desktop; PDESKTOP_OBJECT Desktop;
PTHRDCARETINFO CaretInfo; PTHRDCARETINFO CaretInfo;
HWND hWndCaret; HWND hWndCaret;
PWINDOW_OBJECT WndCaret;
ASSERT_REFS_CO(Window);
Desktop = PsGetCurrentThread()->Tcb.Win32Thread->Desktop; Desktop = PsGetCurrentThread()->Tcb.Win32Thread->Desktop;
CaretInfo = ((PUSER_MESSAGE_QUEUE)Desktop->ActiveMessageQueue)->CaretInfo; CaretInfo = ((PUSER_MESSAGE_QUEUE)Desktop->ActiveMessageQueue)->CaretInfo;
hWndCaret = CaretInfo->hWnd; hWndCaret = CaretInfo->hWnd;
if (hWndCaret == hWnd ||
((flags & SW_SCROLLCHILDREN) && IntIsChildWindow(hWnd, hWndCaret))) WndCaret = UserGetWindowObject(hWndCaret);
if (WndCaret == Window ||
((flags & SW_SCROLLCHILDREN) && IntIsChildWindow(Window->hSelf, hWndCaret)))
{ {
POINT pt, FromOffset, ToOffset, Offset; POINT pt, FromOffset, ToOffset, Offset;
RECT rcCaret; RECT rcCaret;
pt.x = CaretInfo->Pos.x; pt.x = CaretInfo->Pos.x;
pt.y = CaretInfo->Pos.y; pt.y = CaretInfo->Pos.y;
IntGetClientOrigin(hWndCaret, &FromOffset); IntGetClientOrigin(WndCaret, &FromOffset);
IntGetClientOrigin(hWnd, &ToOffset); IntGetClientOrigin(Window, &ToOffset);
Offset.x = FromOffset.x - ToOffset.x; Offset.x = FromOffset.x - ToOffset.x;
Offset.y = FromOffset.y - ToOffset.y; Offset.y = FromOffset.y - ToOffset.y;
rcCaret.left = pt.x; rcCaret.left = pt.x;
@ -843,15 +849,9 @@ NtUserInvalidateRgn(HWND hWnd, HRGN Rgn, BOOL Erase)
BOOL FASTCALL BOOL FASTCALL
UserValidateRgn(HWND hWnd, HRGN hRgn) co_UserValidateRgn(PWINDOW_OBJECT Window, HRGN hRgn)
{ {
PWINDOW_OBJECT Window; return co_UserRedrawWindow(Window, NULL, hRgn, RDW_VALIDATE | RDW_NOCHILDREN);
BOOL ret;
if (!(Window = IntGetWindowObject(hWnd))) return FALSE;
ret = co_UserRedrawWindow(Window, NULL, hRgn, RDW_VALIDATE | RDW_NOCHILDREN);
IntReleaseWindowObject(Window);//temp hack
return ret;
} }
/* /*
@ -885,16 +885,11 @@ NtUserUpdateWindow(HWND hWnd)
INT FASTCALL INT FASTCALL
co_UserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase) co_UserGetUpdateRgn(PWINDOW_OBJECT Window, HRGN hRgn, BOOL bErase)
{ {
PWINDOW_OBJECT Window;
int RegionType; int RegionType;
if (!(Window = IntGetWindowObject(hWnd))) ASSERT_REFS_CO(Window);
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return ERROR;
}
if (Window->UpdateRegion == NULL) if (Window->UpdateRegion == NULL)
{ {
@ -914,8 +909,6 @@ co_UserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
co_UserRedrawWindow(Window, NULL, NULL, RDW_ERASENOW | RDW_NOCHILDREN); co_UserRedrawWindow(Window, NULL, NULL, RDW_ERASENOW | RDW_NOCHILDREN);
} }
IntReleaseWindowObject(Window);
return RegionType; return RegionType;
} }
/* /*
@ -929,11 +922,22 @@ INT STDCALL
NtUserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase) NtUserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
{ {
DECLARE_RETURN(INT); DECLARE_RETURN(INT);
PWINDOW_OBJECT Window;
INT ret;
DPRINT("Enter NtUserGetUpdateRgn\n"); DPRINT("Enter NtUserGetUpdateRgn\n");
UserEnterExclusive(); UserEnterExclusive();
RETURN(co_UserGetUpdateRgn(hWnd, hRgn, bErase)); if (!(Window = UserGetWindowObject(hWnd)))
{
RETURN(ERROR);
}
UserRefObjectCo(Window);
ret = co_UserGetUpdateRgn(Window, hRgn, bErase);
UserDerefObjectCo(Window);
RETURN(ret);
CLEANUP: CLEANUP:
DPRINT("Leave NtUserGetUpdateRgn, ret=%i\n",_ret_); DPRINT("Leave NtUserGetUpdateRgn, ret=%i\n",_ret_);
@ -962,9 +966,8 @@ NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
DPRINT("Enter NtUserGetUpdateRect\n"); DPRINT("Enter NtUserGetUpdateRect\n");
UserEnterExclusive(); UserEnterExclusive();
if (!(Window = IntGetWindowObject(hWnd))) if (!(Window = UserGetWindowObject(hWnd)))
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
RETURN( ERROR); RETURN( ERROR);
} }
@ -985,11 +988,11 @@ NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
if (bErase && Rect.left < Rect.right && Rect.top < Rect.bottom) if (bErase && Rect.left < Rect.right && Rect.top < Rect.bottom)
{ {
UserRefObjectCo(Window);
co_UserRedrawWindow(Window, NULL, NULL, RDW_ERASENOW | RDW_NOCHILDREN); co_UserRedrawWindow(Window, NULL, NULL, RDW_ERASENOW | RDW_NOCHILDREN);
UserDerefObjectCo(Window);
} }
IntReleaseWindowObject(Window);
if (UnsafeRect != NULL) if (UnsafeRect != NULL)
{ {
Status = MmCopyToCaller(UnsafeRect, &Rect, sizeof(RECT)); Status = MmCopyToCaller(UnsafeRect, &Rect, sizeof(RECT));
@ -1027,9 +1030,8 @@ NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate,
DPRINT("Enter NtUserRedrawWindow\n"); DPRINT("Enter NtUserRedrawWindow\n");
UserEnterExclusive(); UserEnterExclusive();
if (!(Wnd = IntGetWindowObject(hWnd ? hWnd : IntGetDesktopWindow()))) if (!(Wnd = UserGetWindowObject(hWnd ? hWnd : IntGetDesktopWindow())))
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
RETURN( FALSE); RETURN( FALSE);
} }
@ -1041,23 +1043,24 @@ NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
SetLastWin32Error(ERROR_INVALID_PARAMETER); SetLastWin32Error(ERROR_INVALID_PARAMETER);
IntReleaseWindowObject(Wnd);
RETURN( FALSE); RETURN( FALSE);
} }
} }
UserRefObjectCo(Wnd);
Status = co_UserRedrawWindow(Wnd, NULL == lprcUpdate ? NULL : &SafeUpdateRect, Status = co_UserRedrawWindow(Wnd, NULL == lprcUpdate ? NULL : &SafeUpdateRect,
hrgnUpdate, flags); hrgnUpdate, flags);
UserDerefObjectCo(Wnd);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* IntRedrawWindow fails only in case that flags are invalid */ /* IntRedrawWindow fails only in case that flags are invalid */
SetLastWin32Error(ERROR_INVALID_PARAMETER); SetLastWin32Error(ERROR_INVALID_PARAMETER);
IntReleaseWindowObject(Wnd);
RETURN( FALSE); RETURN( FALSE);
} }
IntReleaseWindowObject(Wnd);
RETURN( TRUE); RETURN( TRUE);
CLEANUP: CLEANUP:
@ -1208,7 +1211,7 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
{ {
RECT rc, cliprc, caretrc, rect, clipRect; RECT rc, cliprc, caretrc, rect, clipRect;
INT Result; INT Result;
PWINDOW_OBJECT Window, CaretWnd; PWINDOW_OBJECT Window = NULL, CaretWnd;
HDC hDC; HDC hDC;
HRGN hrgnTemp; HRGN hrgnTemp;
HWND hwndCaret; HWND hwndCaret;
@ -1220,14 +1223,16 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
DPRINT("Enter NtUserScrollWindowEx\n"); DPRINT("Enter NtUserScrollWindowEx\n");
UserEnterExclusive(); UserEnterExclusive();
Window = IntGetWindowObject(hWnd); Window = UserGetWindowObject(hWnd);
if (!Window || !IntIsWindowDrawable(Window)) if (!Window || !IntIsWindowDrawable(Window))
{ {
IntReleaseWindowObject(Window); Window = NULL; /* prevent deref at cleanup */
RETURN( ERROR); RETURN( ERROR);
} }
UserRefObjectCo(Window);
IntGetClientRect(Window, &rc); IntGetClientRect(Window, &rc);
if (NULL != UnsafeRect) if (NULL != UnsafeRect)
{ {
Status = MmCopyFromCaller(&rect, UnsafeRect, sizeof(RECT)); Status = MmCopyFromCaller(&rect, UnsafeRect, sizeof(RECT));
@ -1259,7 +1264,7 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
} }
caretrc = rc; caretrc = rc;
hwndCaret = co_IntFixCaret(hWnd, &caretrc, flags); hwndCaret = co_IntFixCaret(Window, &caretrc, flags);
if (hrgnUpdate) if (hrgnUpdate)
bOwnRgn = FALSE; bOwnRgn = FALSE;
@ -1279,7 +1284,7 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
*/ */
hrgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0); hrgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
Result = co_UserGetUpdateRgn(hWnd, hrgnTemp, FALSE); Result = co_UserGetUpdateRgn(Window, hrgnTemp, FALSE);
if (Result != NULLREGION) if (Result != NULLREGION)
{ {
HRGN hrgnClip = UnsafeIntCreateRectRgnIndirect(&cliprc); HRGN hrgnClip = UnsafeIntCreateRectRgnIndirect(&cliprc);
@ -1288,6 +1293,7 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
co_UserRedrawWindow(Window, NULL, hrgnTemp, RDW_INVALIDATE | RDW_ERASE); co_UserRedrawWindow(Window, NULL, hrgnTemp, RDW_INVALIDATE | RDW_ERASE);
NtGdiDeleteObject(hrgnClip); NtGdiDeleteObject(hrgnClip);
} }
NtGdiDeleteObject(hrgnTemp); NtGdiDeleteObject(hrgnTemp);
if (flags & SW_SCROLLCHILDREN) if (flags & SW_SCROLLCHILDREN)
@ -1298,23 +1304,28 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
int i; int i;
RECT r, dummy; RECT r, dummy;
POINT ClientOrigin; POINT ClientOrigin;
PWINDOW_OBJECT WindowObject; PWINDOW_OBJECT Wnd;
IntGetClientOrigin(hWnd, &ClientOrigin); IntGetClientOrigin(Window, &ClientOrigin);
for (i = 0; List[i]; i++) for (i = 0; List[i]; i++)
{ {
WindowObject = IntGetWindowObject(List[i]); if (!(Wnd = UserGetWindowObject(List[i]))) continue;
if (!WindowObject) continue;
r = WindowObject->WindowRect; r = Wnd->WindowRect;
r.left -= ClientOrigin.x; r.left -= ClientOrigin.x;
r.top -= ClientOrigin.y; r.top -= ClientOrigin.y;
r.right -= ClientOrigin.x; r.right -= ClientOrigin.x;
r.bottom -= ClientOrigin.y; r.bottom -= ClientOrigin.y;
IntReleaseWindowObject(WindowObject);
if (! UnsafeRect || IntGdiIntersectRect(&dummy, &r, &rc)) if (! UnsafeRect || IntGdiIntersectRect(&dummy, &r, &rc))
co_WinPosSetWindowPos(List[i], 0, r.left + dx, r.top + dy, 0, 0, {
UserRefObjectCo(Wnd);
co_WinPosSetWindowPos(Wnd, 0, r.left + dx, r.top + dy, 0, 0,
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE |
SWP_NOREDRAW); SWP_NOREDRAW);
UserDerefObjectCo(Wnd);
}
} }
ExFreePool(List); ExFreePool(List);
} }
@ -1328,18 +1339,21 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
if (bOwnRgn && hrgnUpdate) if (bOwnRgn && hrgnUpdate)
NtGdiDeleteObject(hrgnUpdate); NtGdiDeleteObject(hrgnUpdate);
if ((CaretWnd = IntGetWindowObject(hwndCaret))) if ((CaretWnd = UserGetWindowObject(hwndCaret)))
{ {
UserRefObjectCo(CaretWnd);
co_IntSetCaretPos(caretrc.left + dx, caretrc.top + dy); co_IntSetCaretPos(caretrc.left + dx, caretrc.top + dy);
co_UserShowCaret(CaretWnd); co_UserShowCaret(CaretWnd);
IntReleaseWindowObject(CaretWnd);
}
IntReleaseWindowObject(Window); UserDerefObjectCo(CaretWnd);
}
RETURN( Result); RETURN( Result);
CLEANUP: CLEANUP:
if (Window) UserDerefObjectCo(Window);
DPRINT("Leave NtUserScrollWindowEx, ret=%i\n",_ret_); DPRINT("Leave NtUserScrollWindowEx, ret=%i\n",_ret_);
UserLeave(); UserLeave();
END_CLEANUP; END_CLEANUP;

View file

@ -198,7 +198,7 @@ co_IntGetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPSCROLLINFO lpsi)
UINT Mask; UINT Mask;
LPSCROLLINFO psi; LPSCROLLINFO psi;
ASSERT_REFS(Window); ASSERT_REFS_CO(Window);
if(!SBID_IS_VALID(nBar)) if(!SBID_IS_VALID(nBar))
{ {
@ -260,7 +260,7 @@ co_IntSetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bR
/* UINT new_flags;*/ /* UINT new_flags;*/
BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't change */ BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't change */
ASSERT_REFS(Window); ASSERT_REFS_CO(Window);
if(!SBID_IS_VALID(nBar)) if(!SBID_IS_VALID(nBar))
{ {
@ -411,7 +411,7 @@ co_IntGetScrollBarInfo(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi
PSCROLLBARINFO sbi; PSCROLLBARINFO sbi;
LPSCROLLINFO psi; LPSCROLLINFO psi;
ASSERT_REFS(Window); ASSERT_REFS_CO(Window);
Bar = SBOBJ_TO_SBID(idObject); Bar = SBOBJ_TO_SBID(idObject);
@ -447,7 +447,7 @@ co_IntCreateScrollBars(PWINDOW_OBJECT Window)
ULONG Size, s; ULONG Size, s;
INT i; INT i;
ASSERT_REFS(Window); ASSERT_REFS_CO(Window);
if(Window->Scroll) if(Window->Scroll)
{ {
@ -563,9 +563,9 @@ NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
RETURN(FALSE); RETURN(FALSE);
} }
UserReferenceWindowObjectCo(Window); UserRefObjectCo(Window);
Ret = co_IntGetScrollBarInfo(Window, idObject, &sbi); Ret = co_IntGetScrollBarInfo(Window, idObject, &sbi);
UserDereferenceWindowObjectCo(Window); UserDerefObjectCo(Window);
Status = MmCopyToCaller(psbi, &sbi, sizeof(SCROLLBARINFO)); Status = MmCopyToCaller(psbi, &sbi, sizeof(SCROLLBARINFO));
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
@ -618,9 +618,9 @@ NtUserGetScrollInfo(HWND hWnd, int fnBar, LPSCROLLINFO lpsi)
RETURN(FALSE); RETURN(FALSE);
} }
UserReferenceWindowObjectCo(Window); UserRefObjectCo(Window);
Ret = co_IntGetScrollInfo(Window, fnBar, &psi); Ret = co_IntGetScrollInfo(Window, fnBar, &psi);
UserDereferenceWindowObjectCo(Window); UserDerefObjectCo(Window);
Status = MmCopyToCaller(lpsi, &psi, sz); Status = MmCopyToCaller(lpsi, &psi, sz);
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
@ -657,7 +657,7 @@ NtUserEnableScrollBar(
{ {
RETURN(FALSE); RETURN(FALSE);
} }
UserReferenceWindowObjectCo(Window); UserRefObjectCo(Window);
if(wSBflags == SB_CTL) if(wSBflags == SB_CTL)
{ {
@ -709,7 +709,7 @@ NtUserEnableScrollBar(
RETURN( TRUE); RETURN( TRUE);
CLEANUP: CLEANUP:
if (Window) UserDereferenceWindowObjectCo(Window); if (Window) UserDerefObjectCo(Window);
DPRINT("Leave NtUserEnableScrollBar, ret=%i\n",_ret_); DPRINT("Leave NtUserEnableScrollBar, ret=%i\n",_ret_);
UserLeave(); UserLeave();
@ -738,7 +738,7 @@ NtUserSetScrollBarInfo(
{ {
RETURN( FALSE); RETURN( FALSE);
} }
UserReferenceWindowObjectCo(Window); UserRefObjectCo(Window);
Obj = SBOBJ_TO_SBID(idObject); Obj = SBOBJ_TO_SBID(idObject);
if(!SBID_IS_VALID(Obj)) if(!SBID_IS_VALID(Obj))
@ -770,7 +770,7 @@ NtUserSetScrollBarInfo(
RETURN(TRUE); RETURN(TRUE);
CLEANUP: CLEANUP:
if (Window) UserDereferenceWindowObjectCo(Window); if (Window) UserDerefObjectCo(Window);
DPRINT("Leave NtUserSetScrollBarInfo, ret=%i\n",_ret_); DPRINT("Leave NtUserSetScrollBarInfo, ret=%i\n",_ret_);
UserLeave(); UserLeave();
@ -797,7 +797,7 @@ NtUserSetScrollInfo(
{ {
RETURN( 0); RETURN( 0);
} }
UserReferenceWindowObjectCo(Window); UserRefObjectCo(Window);
Status = MmCopyFromCaller(&ScrollInfo, lpsi, sizeof(SCROLLINFO) - sizeof(ScrollInfo.nTrackPos)); Status = MmCopyFromCaller(&ScrollInfo, lpsi, sizeof(SCROLLINFO) - sizeof(ScrollInfo.nTrackPos));
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
@ -809,7 +809,7 @@ NtUserSetScrollInfo(
RETURN(co_IntSetScrollInfo(Window, fnBar, &ScrollInfo, bRedraw)); RETURN(co_IntSetScrollInfo(Window, fnBar, &ScrollInfo, bRedraw));
CLEANUP: CLEANUP:
if (Window) UserDereferenceWindowObjectCo(Window); if (Window) UserDerefObjectCo(Window);
DPRINT("Leave NtUserSetScrollInfo, ret=%i\n",_ret_); DPRINT("Leave NtUserSetScrollInfo, ret=%i\n",_ret_);
UserLeave(); UserLeave();
@ -823,7 +823,7 @@ co_UserShowScrollBar(PWINDOW_OBJECT Window, int wBar, DWORD bShow)
{ {
DWORD Style, OldStyle; DWORD Style, OldStyle;
ASSERT_REFS(Window); ASSERT_REFS_CO(Window);
switch(wBar) switch(wBar)
{ {
@ -873,7 +873,7 @@ co_UserShowScrollBar(PWINDOW_OBJECT Window, int wBar, DWORD bShow)
if(Window->Style & WS_VISIBLE) if(Window->Style & WS_VISIBLE)
{ {
/* Frame has been changed, let the window redraw itself */ /* Frame has been changed, let the window redraw itself */
co_WinPosSetWindowPos(Window->hSelf, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
} }
} }
@ -897,9 +897,9 @@ NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow)
RETURN(0); RETURN(0);
} }
UserReferenceWindowObjectCo(Window); UserRefObjectCo(Window);
ret = co_UserShowScrollBar(Window, wBar, bShow); ret = co_UserShowScrollBar(Window, wBar, bShow);
UserDereferenceWindowObjectCo(Window); UserDerefObjectCo(Window);
RETURN(ret); RETURN(ret);

View file

@ -158,7 +158,7 @@ co_VIS_WindowLayoutChanged(
HRGN Temp; HRGN Temp;
PWINDOW_OBJECT Parent; PWINDOW_OBJECT Parent;
ASSERT_REFS(Window); ASSERT_REFS_CO(Window);
Temp = NtGdiCreateRectRgn(0, 0, 0, 0); Temp = NtGdiCreateRectRgn(0, 0, 0, 0);
NtGdiCombineRgn(Temp, NewlyExposed, NULL, RGN_COPY); NtGdiCombineRgn(Temp, NewlyExposed, NULL, RGN_COPY);
@ -170,11 +170,11 @@ co_VIS_WindowLayoutChanged(
Window->WindowRect.left - Parent->ClientRect.left, Window->WindowRect.left - Parent->ClientRect.left,
Window->WindowRect.top - Parent->ClientRect.top); Window->WindowRect.top - Parent->ClientRect.top);
UserReferenceWindowObjectCo(Parent); UserRefObjectCo(Parent);
co_UserRedrawWindow(Parent, NULL, Temp, co_UserRedrawWindow(Parent, NULL, Temp,
RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_INVALIDATE |
RDW_ALLCHILDREN); RDW_ALLCHILDREN);
UserDereferenceWindowObjectCo(Parent); UserDerefObjectCo(Parent);
} }
NtGdiDeleteObject(Temp); NtGdiDeleteObject(Temp);
} }

View file

@ -75,15 +75,45 @@ CleanupWindowImpl(VOID)
/* HELPER FUNCTIONS ***********************************************************/ /* HELPER FUNCTIONS ***********************************************************/
VOID FASTCALL IntReleaseWindowObject(PWINDOW_OBJECT Window)
{
ASSERT(Window);
ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 1);
USER_BODY_TO_HEADER(Window)->RefCount--;
if (USER_BODY_TO_HEADER(Window)->RefCount == 0 && USER_BODY_TO_HEADER(Window)->destroyed)
{
}
}
PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
{
PWINDOW_OBJECT Window = UserGetWindowObject(hWnd);
if (Window)
{
ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
USER_BODY_TO_HEADER(Window)->RefCount++;
}
return Window;
}
/* temp hack */ /* temp hack */
PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd) PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
{ {
PWINDOW_OBJECT Window = (PWINDOW_OBJECT)UserGetObject(&gHandleTable, hWnd, otWindow);
if (!Window)
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return NULL;
}
PWINDOW_OBJECT w = IntGetWindowObject(hWnd); ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
if (w) IntReleaseWindowObject(w); return Window;
return w;
} }
@ -115,29 +145,7 @@ IntIsWindow(HWND hWnd)
return TRUE; return TRUE;
} }
/*
* IntGetProcessWindowObject
*
* Get window object from handle of specified process.
*/
PWINDOW_OBJECT FASTCALL
IntGetProcessWindowObject(PW32THREAD Thread, HWND hWnd)
{
PWINDOW_OBJECT Window;
NTSTATUS Status;
if(Thread->Desktop != NULL)
{
Status = ObmReferenceObjectByHandle(gHandleTable,
hWnd, otWindow, (PVOID*)&Window);
if (NT_SUCCESS(Status))
{
return Window;
}
}
return NULL;
}
PWINDOW_OBJECT FASTCALL PWINDOW_OBJECT FASTCALL
@ -423,7 +431,7 @@ static LRESULT co_IntDestroyWindow(PWINDOW_OBJECT Window,
IntUnlinkWindow(Window); IntUnlinkWindow(Window);
IntReferenceWindowObject(Window); IntReferenceWindowObject(Window);
ObmCloseHandle(gHandleTable, Window->hSelf); ObmDeleteObject(Window->hSelf, otWindow);
IntDestroyScrollBars(Window); IntDestroyScrollBars(Window);
@ -922,6 +930,8 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
ASSERT(Wnd); ASSERT(Wnd);
ASSERT(WndNewParent); ASSERT(WndNewParent);
ASSERT_REFS_CO(Wnd);
ASSERT_REFS_CO(WndNewParent);
hWnd = Wnd->hSelf; hWnd = Wnd->hSelf;
hWndNewParent = WndNewParent->hSelf; hWndNewParent = WndNewParent->hSelf;
@ -983,7 +993,7 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
* in the z-order and send the expected WM_WINDOWPOSCHANGING and * in the z-order and send the expected WM_WINDOWPOSCHANGING and
* WM_WINDOWPOSCHANGED notification messages. * WM_WINDOWPOSCHANGED notification messages.
*/ */
co_WinPosSetWindowPos(hWnd, (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST), co_WinPosSetWindowPos(Wnd, (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE
| (WasVisible ? SWP_SHOWWINDOW : 0)); | (WasVisible ? SWP_SHOWWINDOW : 0));
@ -1392,8 +1402,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
{ {
PWINSTATION_OBJECT WinSta; PWINSTATION_OBJECT WinSta;
PWNDCLASS_OBJECT Class; PWNDCLASS_OBJECT Class;
PWINDOW_OBJECT Window; PWINDOW_OBJECT Window = NULL;
PWINDOW_OBJECT ParentWindow, OwnerWindow; PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
HWND ParentWindowHandle; HWND ParentWindowHandle;
HWND OwnerWindowHandle; HWND OwnerWindowHandle;
PMENU_OBJECT SystemMenu; PMENU_OBJECT SystemMenu;
@ -1410,7 +1420,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
LRESULT Result; LRESULT Result;
BOOL MenuChanged; BOOL MenuChanged;
BOOL ClassFound; BOOL ClassFound;
DECLARE_RETURN(HWND);
BOOL HasOwner; BOOL HasOwner;
ParentWindowHandle = PsGetWin32Thread()->Desktop->DesktopWindow; ParentWindowHandle = PsGetWin32Thread()->Desktop->DesktopWindow;
@ -1433,12 +1443,14 @@ co_IntCreateWindowEx(DWORD dwExStyle,
} }
else if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD) else if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD)
{ {
return (HWND)0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */ RETURN( (HWND)0); /* WS_CHILD needs a parent, but WS_POPUP doesn't */
} }
if (NULL != ParentWindowHandle) if (NULL != ParentWindowHandle)
{ {
ParentWindow = IntGetWindowObject(ParentWindowHandle); ParentWindow = UserGetWindowObject(ParentWindowHandle);
if (ParentWindow) UserRefObjectCo(ParentWindow);
} }
else else
{ {
@ -1459,31 +1471,25 @@ co_IntCreateWindowEx(DWORD dwExStyle,
{ {
DPRINT1("Class %wZ not found\n", ClassName); DPRINT1("Class %wZ not found\n", ClassName);
} }
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS); SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS);
return((HWND)0); RETURN((HWND)0);
} }
/* Check the window station. */ /* Check the window station. */
if (PsGetWin32Thread()->Desktop == NULL) if (PsGetWin32Thread()->Desktop == NULL)
{ {
ClassDereferenceObject(Class); ClassDereferenceObject(Class);
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
DPRINT("Thread is not attached to a desktop! Cannot create window!\n"); DPRINT("Thread is not attached to a desktop! Cannot create window!\n");
return (HWND)0; RETURN( (HWND)0);
} }
WinSta = PsGetWin32Thread()->Desktop->WindowStation; WinSta = PsGetWin32Thread()->Desktop->WindowStation;
ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0); ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
/* Create the window object. */ /* Create the window object. */
Window = (PWINDOW_OBJECT) Window = (PWINDOW_OBJECT)
ObmCreateObject(gHandleTable, &Handle, ObmCreateObject(&gHandleTable, &Handle,
otWindow, sizeof(WINDOW_OBJECT) + Class->cbWndExtra otWindow, sizeof(WINDOW_OBJECT) + Class->cbWndExtra
); );
@ -1492,13 +1498,13 @@ co_IntCreateWindowEx(DWORD dwExStyle,
{ {
ObDereferenceObject(WinSta); ObDereferenceObject(WinSta);
ClassDereferenceObject(Class); ClassDereferenceObject(Class);
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
return (HWND)0; RETURN( (HWND)0);
} }
UserRefObjectCo(Window);
ObDereferenceObject(WinSta); ObDereferenceObject(WinSta);
if (NULL == PsGetWin32Thread()->Desktop->DesktopWindow) if (NULL == PsGetWin32Thread()->Desktop->DesktopWindow)
@ -1588,7 +1594,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
ClassDereferenceObject(Class); ClassDereferenceObject(Class);
DPRINT1("Failed to allocate mem for window name\n"); DPRINT1("Failed to allocate mem for window name\n");
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return NULL; RETURN( NULL);
} }
RtlCopyMemory(Window->WindowName.Buffer, WindowName->Buffer, WindowName->MaximumLength); RtlCopyMemory(Window->WindowName.Buffer, WindowName->Buffer, WindowName->MaximumLength);
} }
@ -1666,17 +1672,13 @@ co_IntCreateWindowEx(DWORD dwExStyle,
CbtCreate.hwndInsertAfter = HWND_TOP; CbtCreate.hwndInsertAfter = HWND_TOP;
if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) Handle, (LPARAM) &CbtCreate)) if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) Handle, (LPARAM) &CbtCreate))
{ {
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
/* 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(Class); ClassDereferenceObject(Class);
DPRINT1("CBT-hook returned !0\n"); DPRINT1("CBT-hook returned !0\n");
return (HWND) NULL; RETURN( (HWND) NULL);
} }
x = Cs.x; x = Cs.x;
@ -1815,12 +1817,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
if (!Result) if (!Result)
{ {
/* FIXME: Cleanup. */ /* FIXME: Cleanup. */
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
DPRINT("IntCreateWindowEx(): NCCREATE message failed.\n"); DPRINT("IntCreateWindowEx(): NCCREATE message failed.\n");
return((HWND)0); RETURN((HWND)0);
} }
/* Calculate the non-client size. */ /* Calculate the non-client size. */
@ -1884,13 +1882,9 @@ co_IntCreateWindowEx(DWORD dwExStyle,
if (Result == (LRESULT)-1) if (Result == (LRESULT)-1)
{ {
/* FIXME: Cleanup. */ /* FIXME: Cleanup. */
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
ClassDereferenceObject(Class); ClassDereferenceObject(Class);
DPRINT("IntCreateWindowEx(): send CREATE message failed.\n"); DPRINT("IntCreateWindowEx(): send CREATE message failed.\n");
return((HWND)0); RETURN((HWND)0);
} }
/* Send move and size messages. */ /* Send move and size messages. */
@ -1946,7 +1940,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
SWP_NOZORDER | SWP_FRAMECHANGED; SWP_NOZORDER | SWP_FRAMECHANGED;
DPRINT("IntCreateWindow(): About to minimize/maximize\n"); DPRINT("IntCreateWindow(): About to minimize/maximize\n");
DPRINT("%d,%d %dx%d\n", NewPos.left, NewPos.top, NewPos.right, NewPos.bottom); DPRINT("%d,%d %dx%d\n", NewPos.left, NewPos.top, NewPos.right, NewPos.bottom);
co_WinPosSetWindowPos(Window->hSelf, 0, NewPos.left, NewPos.top, co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top,
NewPos.right, NewPos.bottom, SwFlag); NewPos.right, NewPos.bottom, SwFlag);
} }
@ -1968,13 +1962,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
DPRINT("Not sending CREATED notify, %x %d\n", ParentWindow, HasOwner); DPRINT("Not sending CREATED notify, %x %d\n", ParentWindow, HasOwner);
} }
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
//faxme:temp hack
UserReferenceWindowObjectCo(Window);
/* Initialize and show the window's scrollbars */ /* Initialize and show the window's scrollbars */
if (Window->Style & WS_VSCROLL) if (Window->Style & WS_VSCROLL)
{ {
@ -1991,12 +1978,15 @@ co_IntCreateWindowEx(DWORD dwExStyle,
co_WinPosShowWindow(Window, dwShowMode); co_WinPosShowWindow(Window, dwShowMode);
} }
//faxme: temp hack
UserDereferenceWindowObjectCo(Window);
DPRINT("IntCreateWindow(): = %X\n", Handle); DPRINT("IntCreateWindow(): = %X\n", Handle);
DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu); DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu);
return((HWND)Handle); RETURN((HWND)Handle);
CLEANUP:
if (Window) UserDerefObjectCo(Window);
if (ParentWindow) UserDerefObjectCo(ParentWindow);
END_CLEANUP;
} }
HWND STDCALL HWND STDCALL
@ -2100,7 +2090,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
{ {
BOOLEAN isChild; BOOLEAN isChild;
ASSERT_REFS(Window); ASSERT_REFS_CO(Window);
if (Window == NULL) if (Window == NULL)
{ {
@ -3021,11 +3011,17 @@ BOOL STDCALL
NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView) NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
{ {
PWINSTATION_OBJECT WinStaObject; PWINSTATION_OBJECT WinStaObject;
PWINDOW_OBJECT WndShell;
DECLARE_RETURN(BOOL); DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserSetShellWindowEx\n"); DPRINT("Enter NtUserSetShellWindowEx\n");
UserEnterExclusive(); UserEnterExclusive();
if (!(WndShell = UserGetWindowObject(hwndShell)))
{
RETURN(FALSE);
}
NTSTATUS Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, NTSTATUS Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
KernelMode, KernelMode,
0, 0,
@ -3072,11 +3068,14 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
RETURN( FALSE); RETURN( FALSE);
} }
co_WinPosSetWindowPos(hwndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); UserRefObjectCo(WndShell);
co_WinPosSetWindowPos(WndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
WinStaObject->ShellWindow = hwndShell; WinStaObject->ShellWindow = hwndShell;
WinStaObject->ShellListView = hwndListView; WinStaObject->ShellListView = hwndListView;
UserDerefObjectCo(WndShell);
ObDereferenceObject(WinStaObject); ObDereferenceObject(WinStaObject);
RETURN( TRUE); RETURN( TRUE);
@ -3982,24 +3981,23 @@ NtUserSetMenu(
DPRINT("Enter NtUserSetMenu\n"); DPRINT("Enter NtUserSetMenu\n");
UserEnterExclusive(); UserEnterExclusive();
if (!(Window = IntGetWindowObject(hWnd))) if (!(Window = UserGetWindowObject(hWnd)))
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
RETURN( FALSE); RETURN( FALSE);
} }
if (! IntSetMenu(Window, Menu, &Changed)) if (! IntSetMenu(Window, Menu, &Changed))
{ {
IntReleaseWindowObject(Window);
RETURN( FALSE); RETURN( FALSE);
} }
IntReleaseWindowObject(Window);
if (Changed && Repaint) if (Changed && Repaint)
{ {
co_WinPosSetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | UserRefObjectCo(Window);
co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED); SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
UserDerefObjectCo(Window);
} }
RETURN( TRUE); RETURN( TRUE);
@ -4060,7 +4058,7 @@ NtUserSetWindowPlacement(HWND hWnd,
if ((Window->Style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0) if ((Window->Style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
{ {
co_WinPosSetWindowPos(Window->hSelf, NULL, co_WinPosSetWindowPos(Window, NULL,
Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top, Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top,
Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left,
Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top, Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top,
@ -4100,11 +4098,22 @@ NtUserSetWindowPos(
UINT uFlags) UINT uFlags)
{ {
DECLARE_RETURN(BOOL); DECLARE_RETURN(BOOL);
PWINDOW_OBJECT Window;
BOOL ret;
DPRINT("Enter NtUserSetWindowPos\n"); DPRINT("Enter NtUserSetWindowPos\n");
UserEnterExclusive(); UserEnterExclusive();
RETURN( co_WinPosSetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags)); if (!(Window = UserGetWindowObject(hWnd)))
{
RETURN(FALSE);
}
UserRefObjectCo(Window);
ret = co_WinPosSetWindowPos(Window, hWndInsertAfter, X, Y, cx, cy, uFlags);
UserDerefObjectCo(Window);
RETURN(ret);
CLEANUP: CLEANUP:
DPRINT("Leave NtUserSetWindowPos, ret=%i\n",_ret_); DPRINT("Leave NtUserSetWindowPos, ret=%i\n",_ret_);
@ -4263,9 +4272,9 @@ NtUserShowWindow(HWND hWnd, LONG nCmdShow)
RETURN(FALSE); RETURN(FALSE);
} }
UserReferenceWindowObjectCo(Window); UserRefObjectCo(Window);
ret = co_WinPosShowWindow(Window, nCmdShow); ret = co_WinPosShowWindow(Window, nCmdShow);
UserReferenceWindowObjectCo(Window); UserDerefObjectCo(Window);
RETURN(ret); RETURN(ret);

View file

@ -50,11 +50,9 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
BOOL FASTCALL BOOL FASTCALL
IntGetClientOrigin(HWND hWnd, LPPOINT Point) IntGetClientOrigin(PWINDOW_OBJECT Window OPTIONAL, LPPOINT Point)
{ {
PWINDOW_OBJECT Window; Window = Window ? Window : UserGetWindowObject(IntGetDesktopWindow());
Window = IntGetWindowObject((hWnd ? hWnd : IntGetDesktopWindow()));
if (Window == NULL) if (Window == NULL)
{ {
Point->x = Point->y = 0; Point->x = Point->y = 0;
@ -63,7 +61,6 @@ IntGetClientOrigin(HWND hWnd, LPPOINT Point)
Point->x = Window->ClientRect.left; Point->x = Window->ClientRect.left;
Point->y = Window->ClientRect.top; Point->y = Window->ClientRect.top;
IntReleaseWindowObject(Window);
return TRUE; return TRUE;
} }
@ -71,7 +68,7 @@ IntGetClientOrigin(HWND hWnd, LPPOINT Point)
BOOL FASTCALL BOOL FASTCALL
UserGetClientOrigin(HWND hWnd, LPPOINT Point) UserGetClientOrigin(PWINDOW_OBJECT Window, LPPOINT Point)
{ {
BOOL Ret; BOOL Ret;
POINT pt; POINT pt;
@ -83,7 +80,7 @@ UserGetClientOrigin(HWND hWnd, LPPOINT Point)
return FALSE; return FALSE;
} }
Ret = IntGetClientOrigin(hWnd, &pt); Ret = IntGetClientOrigin(Window, &pt);
if(!Ret) if(!Ret)
{ {
@ -107,11 +104,14 @@ BOOL STDCALL
NtUserGetClientOrigin(HWND hWnd, LPPOINT Point) NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
{ {
DECLARE_RETURN(BOOL); DECLARE_RETURN(BOOL);
PWINDOW_OBJECT Window;
DPRINT("Enter NtUserGetClientOrigin\n"); DPRINT("Enter NtUserGetClientOrigin\n");
UserEnterShared(); UserEnterShared();
RETURN(UserGetClientOrigin(hWnd, Point)); if (!(Window = UserGetWindowObject(hWnd))) RETURN(FALSE);
RETURN(UserGetClientOrigin(Window, Point));
CLEANUP: CLEANUP:
DPRINT("Leave NtUserGetClientOrigin, ret=%i\n",_ret_); DPRINT("Leave NtUserGetClientOrigin, ret=%i\n",_ret_);
@ -125,11 +125,13 @@ CLEANUP:
* Activates window other than pWnd. * Activates window other than pWnd.
*/ */
VOID FASTCALL VOID FASTCALL
co_WinPosActivateOtherWindow(PWINDOW_OBJECT Window) co_WinPosActivateOtherWindow(PWINDOW_OBJECT Window OPTIONAL)
{ {
PWINDOW_OBJECT Wnd, Old; PWINDOW_OBJECT Wnd, Old;
HWND Fg; HWND Fg;
if (Window) ASSERT_REFS_CO(Window);
if (!Window || IntIsDesktopWindow(Window)) if (!Window || IntIsDesktopWindow(Window))
{ {
IntSetFocusMessageQueue(NULL); IntSetFocusMessageQueue(NULL);
@ -142,21 +144,17 @@ co_WinPosActivateOtherWindow(PWINDOW_OBJECT Window)
for(;;) for(;;)
{ {
Old = Wnd; Old = Wnd;
Wnd = IntGetParentObject(Wnd); Wnd = Wnd->Parent;
if(IntIsDesktopWindow(Wnd)) if(IntIsDesktopWindow(Wnd))
{ {
IntReleaseWindowObject(Wnd);
Wnd = Old; Wnd = Old;
break; break;
} }
IntReleaseWindowObject(Old);
} }
if ((Wnd->Style & (WS_DISABLED | WS_VISIBLE)) == WS_VISIBLE && if ((Wnd->Style & (WS_DISABLED | WS_VISIBLE)) == WS_VISIBLE &&
(Wnd->Style & (WS_POPUP | WS_CHILD)) != WS_CHILD) (Wnd->Style & (WS_POPUP | WS_CHILD)) != WS_CHILD)
goto done; goto done;
IntReleaseWindowObject(Wnd);
} }
/* Pick a next top-level window. */ /* Pick a next top-level window. */
@ -164,36 +162,37 @@ co_WinPosActivateOtherWindow(PWINDOW_OBJECT Window)
Wnd = Window; Wnd = Window;
while (Wnd != NULL) while (Wnd != NULL)
{ {
Old = Wnd; if (Wnd->NextSibling == NULL)
if (Old->NextSibling == NULL)
{ {
Wnd = NULL; Wnd = NULL;
if (Old != Window)
IntReleaseWindowObject(Old);
break; break;
} }
Wnd = IntGetWindowObject(Old->NextSibling->hSelf);
if (Old != Window) Wnd = Wnd->NextSibling;
IntReleaseWindowObject(Old);
if ((Wnd->Style & (WS_DISABLED | WS_VISIBLE)) == WS_VISIBLE && if ((Wnd->Style & (WS_DISABLED | WS_VISIBLE)) == WS_VISIBLE &&
(Wnd->Style & (WS_POPUP | WS_CHILD)) != WS_CHILD) (Wnd->Style & (WS_POPUP | WS_CHILD)) != WS_CHILD)
break; break;
} }
done: done:
if (Wnd) UserRefObjectCo(Wnd);
Fg = UserGetForegroundWindow(); Fg = UserGetForegroundWindow();
if (Wnd && (!Fg || Window->hSelf == Fg)) if (Wnd && (!Fg || Window->hSelf == Fg))
{ {
if (co_IntSetForegroundWindow(Wnd)) if (co_IntSetForegroundWindow(Wnd))
{ {
IntReleaseWindowObject(Wnd); UserDerefObjectCo(Wnd);
return; return;
} }
} }
if (!co_IntSetActiveWindow(Wnd)) if (!co_IntSetActiveWindow(Wnd))
co_IntSetActiveWindow(0); co_IntSetActiveWindow(0);
if (Wnd)
IntReleaseWindowObject(Wnd); if (Wnd) UserDerefObjectCo(Wnd);
} }
@ -206,6 +205,8 @@ co_WinPosArrangeIconicWindows(PWINDOW_OBJECT parent)
INT i, x, y, xspacing, yspacing; INT i, x, y, xspacing, yspacing;
HWND *List = IntWinListChildren(parent); HWND *List = IntWinListChildren(parent);
ASSERT_REFS_CO(parent);
IntGetClientRect( parent, &rectParent ); IntGetClientRect( parent, &rectParent );
x = rectParent.left; x = rectParent.left;
y = rectParent.bottom; y = rectParent.bottom;
@ -217,13 +218,22 @@ co_WinPosArrangeIconicWindows(PWINDOW_OBJECT parent)
for( i = 0; List[i]; i++) for( i = 0; List[i]; i++)
{ {
PWINDOW_OBJECT WndChild;
hwndChild = List[i]; hwndChild = List[i];
if (!(WndChild = UserGetWindowObject(List[i]))) continue;
if((UserGetWindowLong( hwndChild, GWL_STYLE, FALSE) & WS_MINIMIZE) != 0 ) if((UserGetWindowLong( hwndChild, GWL_STYLE, FALSE) & WS_MINIMIZE) != 0 )
{ {
co_WinPosSetWindowPos( hwndChild, 0, x + UserGetSystemMetrics(SM_CXBORDER), UserRefObjectCo(WndChild);
co_WinPosSetWindowPos(WndChild, 0, x + UserGetSystemMetrics(SM_CXBORDER),
y - yspacing - UserGetSystemMetrics(SM_CYBORDER) y - yspacing - UserGetSystemMetrics(SM_CYBORDER)
, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); , 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
UserDerefObjectCo(WndChild);
if (x <= rectParent.right - xspacing) x += xspacing; if (x <= rectParent.right - xspacing) x += xspacing;
else else
{ {
@ -300,6 +310,8 @@ co_WinPosMinMaximize(PWINDOW_OBJECT Window, UINT ShowFlag, RECT* NewPos)
PINTERNALPOS InternalPos; PINTERNALPOS InternalPos;
UINT SwpFlags = 0; UINT SwpFlags = 0;
ASSERT_REFS_CO(Window);
Size.x = Window->WindowRect.left; Size.x = Window->WindowRect.left;
Size.y = Window->WindowRect.top; Size.y = Window->WindowRect.top;
InternalPos = WinPosInitInternalPos(Window, &Size, &Window->WindowRect); InternalPos = WinPosInitInternalPos(Window, &Size, &Window->WindowRect);
@ -674,13 +686,23 @@ WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
{ {
for (i = 0; List[i]; i++) for (i = 0; List[i]; i++)
{ {
PWINDOW_OBJECT Wnd;
if (List[i] == hWnd) if (List[i] == hWnd)
break; break;
if (!(Wnd = UserGetWindowObject(List[i]))) continue;
if ((UserGetWindowLong(List[i], GWL_STYLE, FALSE) & WS_POPUP) && if ((UserGetWindowLong(List[i], GWL_STYLE, FALSE) & WS_POPUP) &&
UserGetWindow(List[i], GW_OWNER) == hWnd) UserGetWindow(List[i], GW_OWNER) == hWnd)
{ {
co_WinPosSetWindowPos(List[i], hWndInsertAfter, 0, 0, 0, 0, UserRefObjectCo(Wnd);
co_WinPosSetWindowPos(Wnd, hWndInsertAfter, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
UserDerefObjectCo(Wnd);
hWndInsertAfter = List[i]; hWndInsertAfter = List[i];
} }
} }
@ -828,10 +850,16 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window)
/* x and y are always screen relative */ /* x and y are always screen relative */
BOOLEAN FASTCALL BOOLEAN FASTCALL
co_WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx, co_WinPosSetWindowPos(
INT cy, UINT flags) PWINDOW_OBJECT Window,
HWND WndInsertAfter,
INT x,
INT y,
INT cx,
INT cy,
UINT flags
)
{ {
PWINDOW_OBJECT Window;
WINDOWPOS WinPos; WINDOWPOS WinPos;
RECT NewWindowRect; RECT NewWindowRect;
RECT NewClientRect; RECT NewClientRect;
@ -848,26 +876,20 @@ co_WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
RECT CopyRect; RECT CopyRect;
RECT TempRect; RECT TempRect;
/* FIXME: Get current active window from active queue. */ ASSERT_REFS_CO(Window);
Window = IntGetWindowObject(Wnd); /* FIXME: Get current active window from active queue. */
if (!Window)
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return FALSE;
}
/* /*
* Only allow CSRSS to mess with the desktop window * Only allow CSRSS to mess with the desktop window
*/ */
if (Wnd == IntGetDesktopWindow() && if (Window->hSelf == IntGetDesktopWindow() &&
Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess()) Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
{ {
IntReleaseWindowObject(Window);
return FALSE; return FALSE;
} }
WinPos.hwnd = Wnd; WinPos.hwnd = Window->hSelf;
WinPos.hwndInsertAfter = WndInsertAfter; WinPos.hwndInsertAfter = WndInsertAfter;
WinPos.x = x; WinPos.x = x;
WinPos.y = y; WinPos.y = y;
@ -880,7 +902,6 @@ co_WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
/* Fix up the flags. */ /* Fix up the flags. */
if (!WinPosFixupFlags(&WinPos, Window)) if (!WinPosFixupFlags(&WinPos, Window))
{ {
IntReleaseWindowObject(Window);
SetLastWin32Error(ERROR_INVALID_PARAMETER); SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@ -888,7 +909,6 @@ co_WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
/* Does the window still exist? */ /* Does the window still exist? */
if (!IntIsWindow(WinPos.hwnd)) if (!IntIsWindow(WinPos.hwnd))
{ {
IntReleaseWindowObject(Window);
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return FALSE; return FALSE;
} }
@ -1217,8 +1237,6 @@ co_WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
co_IntSendMessage(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos); co_IntSendMessage(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos);
IntReleaseWindowObject(Window);
return TRUE; return TRUE;
} }
@ -1244,7 +1262,7 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
BOOLEAN ShowFlag; BOOLEAN ShowFlag;
// HRGN VisibleRgn; // HRGN VisibleRgn;
ASSERT_REFS(Window); ASSERT_REFS_CO(Window);
WasVisible = (Window->Style & WS_VISIBLE) != 0; WasVisible = (Window->Style & WS_VISIBLE) != 0;
@ -1343,7 +1361,7 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
Swp |= SWP_NOACTIVATE | SWP_NOZORDER; Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
} }
co_WinPosSetWindowPos(Window->hSelf, 0 != (Window->ExStyle & WS_EX_TOPMOST) co_WinPosSetWindowPos(Window, 0 != (Window->ExStyle & WS_EX_TOPMOST)
? HWND_TOPMOST : HWND_TOP, ? HWND_TOPMOST : HWND_TOP,
NewPos.left, NewPos.top, NewPos.right, NewPos.bottom, LOWORD(Swp)); NewPos.left, NewPos.top, NewPos.right, NewPos.bottom, LOWORD(Swp));
@ -1418,7 +1436,7 @@ co_WinPosSearchChildren(
PWINDOW_OBJECT Current; PWINDOW_OBJECT Current;
HWND *List, *phWnd; HWND *List, *phWnd;
ASSERT_REFS(ScopeWin); ASSERT_REFS_CO(ScopeWin);
if ((List = IntWinListChildren(ScopeWin))) if ((List = IntWinListChildren(ScopeWin)))
{ {
@ -1495,6 +1513,8 @@ co_WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, PUSER_MESSAGE_QUEUE OnlyHitTes
POINT Point = *WinPoint; POINT Point = *WinPoint;
USHORT HitTest; USHORT HitTest;
ASSERT_REFS_CO(ScopeWin);
*Window = NULL; *Window = NULL;
if(!ScopeWin) if(!ScopeWin)
@ -1528,13 +1548,13 @@ co_WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, PUSER_MESSAGE_QUEUE OnlyHitTes
BOOL BOOL
STDCALL STDCALL
NtUserGetMinMaxInfo( NtUserGetMinMaxInfo(
HWND hwnd, HWND hWnd,
MINMAXINFO *MinMaxInfo, MINMAXINFO *MinMaxInfo,
BOOL SendMessage) BOOL SendMessage)
{ {
POINT Size; POINT Size;
PINTERNALPOS InternalPos; PINTERNALPOS InternalPos;
PWINDOW_OBJECT Window; PWINDOW_OBJECT Window = NULL;
MINMAXINFO SafeMinMax; MINMAXINFO SafeMinMax;
NTSTATUS Status; NTSTATUS Status;
DECLARE_RETURN(BOOL); DECLARE_RETURN(BOOL);
@ -1542,13 +1562,13 @@ NtUserGetMinMaxInfo(
DPRINT("Enter NtUserGetMinMaxInfo\n"); DPRINT("Enter NtUserGetMinMaxInfo\n");
UserEnterExclusive(); UserEnterExclusive();
Window = IntGetWindowObject(hwnd); if(!(Window = UserGetWindowObject(hWnd)))
if(!Window)
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
RETURN( FALSE); RETURN( FALSE);
} }
UserRefObjectCo(Window);
Size.x = Window->WindowRect.left; Size.x = Window->WindowRect.left;
Size.y = Window->WindowRect.top; Size.y = Window->WindowRect.top;
InternalPos = WinPosInitInternalPos(Window, &Size, InternalPos = WinPosInitInternalPos(Window, &Size,
@ -1567,18 +1587,18 @@ NtUserGetMinMaxInfo(
Status = MmCopyToCaller(MinMaxInfo, &SafeMinMax, sizeof(MINMAXINFO)); Status = MmCopyToCaller(MinMaxInfo, &SafeMinMax, sizeof(MINMAXINFO));
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
{ {
IntReleaseWindowObject(Window);
SetLastNtError(Status); SetLastNtError(Status);
RETURN( FALSE); RETURN( FALSE);
} }
IntReleaseWindowObject(Window);
RETURN( TRUE); RETURN( TRUE);
} }
IntReleaseWindowObject(Window);
RETURN( FALSE); RETURN( FALSE);
CLEANUP: CLEANUP:
if (Window) UserDerefObjectCo(Window);
DPRINT("Leave NtUserGetMinMaxInfo, ret=%i\n",_ret_); DPRINT("Leave NtUserGetMinMaxInfo, ret=%i\n",_ret_);
UserLeave(); UserLeave();
END_CLEANUP; END_CLEANUP;