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

View file

@ -50,7 +50,7 @@ typedef struct _SYSTEM_CURSORINFO
HCURSOR FASTCALL IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL ForceChange);
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);
VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process);

View file

@ -5,105 +5,127 @@
#include <win32k/bitmaps.h>
#include <win32k/pen.h>
typedef enum {
otUnknown = 0,
otClass,
#define FIRST_USER_HANDLE 0x0020 /* first possible value for low word of user handle */
#define LAST_USER_HANDLE 0xffef /* last possible value for low word of user handle */
#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,
otMenu,
otAcceleratorTable,
otCursorIcon,
otHookProc,
otMonitor
otAccel,
otCursor,
otHook,
otMonitor,
otClass //fixme: remove
} USER_OBJECT_TYPE;
typedef struct _USER_OBJECT_HEADER
/*
* Header for user object
*/
{
USER_OBJECT_TYPE Type;
LONG HandleCount;
// USER_OBJECT_TYPE Type;
LONG RefCount;
CSHORT Size;
BOOL destroyed;
HANDLE hSelf;
// CSHORT Size;
} USER_OBJECT_HEADER, *PUSER_OBJECT_HEADER;
typedef struct _USER_HANDLE
typedef struct _USER_REFERENCE_ENTRY
{
PVOID ObjectBody;
} USER_HANDLE, *PUSER_HANDLE;
#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;
SINGLE_LIST_ENTRY Entry;
PVOID obj;
} USER_REFERENCE_ENTRY, *PUSER_REFERENCE_ENTRY;
ULONG FASTCALL
ObmGetReferenceCount(
PVOID ObjectBody);
ULONG FASTCALL
ObmGetHandleCount(
PVOID ObjectBody);
#include <malloc.h>
VOID FASTCALL
ObmReferenceObject(
PVOID ObjectBody);
#define ASSERT_LAST_REF(_obj_) \
{ \
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
ObmReferenceObjectByPointer(
PVOID ObjectBody,
USER_OBJECT_TYPE ObjectType);
PVOID FASTCALL
ObmCreateObject(
PUSER_HANDLE_TABLE HandleTable,
PHANDLE Handle,
USER_OBJECT_TYPE ObjectType,
ULONG ObjectSize);
NTSTATUS FASTCALL
ObmCreateHandle(
PUSER_HANDLE_TABLE HandleTable,
PVOID ObjectBody,
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);
#define UserDerefObjectCo(_obj_) \
{ \
PW32THREAD t; \
PSINGLE_LIST_ENTRY e; \
PUSER_REFERENCE_ENTRY ref; \
\
ASSERT(_obj_); \
t = PsGetWin32Thread(); \
ASSERT(t); \
e = PopEntryList(&t->ReferencesList); \
ASSERT(e); \
ref = CONTAINING_RECORD(e, USER_REFERENCE_ENTRY, Entry); \
ASSERT(ref); \
\
ASSERT(_obj_ == ref->obj); \
ObmDereferenceObject(_obj_); \
\
}
VOID INTERNAL_CALL InitGdiObjectHandleTable (VOID);

View file

@ -1,18 +1,52 @@
#ifndef _WIN32K_USERFUNCS_H
#define _WIN32K_USERFUNCS_H
//currently unused
#define ASSERT_REFS(obj) ASSERT(ObmGetReferenceCount(obj) >= 2)
#define UserReferenceWindowObjectCo(o) IntReferenceWindowObject(o)
#define UserDereferenceWindowObjectCo(o) IntReleaseWindowObject(o)
#define ASSERT_REFS_CO(obj) \
{ \
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 UserDereferenceAccelObjectCo(o) IntReleaseWindowObject(o)
#define DUMP_REFS(obj) DPRINT1("obj 0x%x, refs %i\n",obj, USER_BODY_TO_HEADER(obj)->RefCount)
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 ***************/
HWINSTA FASTCALL UserGetProcessWindowStation(VOID);
@ -25,7 +59,7 @@ UserAcquireOrReleaseInputOwnership(BOOLEAN Release);
/*************** WINPOS.C ***************/
BOOL FASTCALL
UserGetClientOrigin(HWND hWnd, LPPOINT Point);
UserGetClientOrigin(PWINDOW_OBJECT Window, LPPOINT Point);
/*************** FOCUS.C ***************/
@ -81,7 +115,7 @@ UserPostMessage(HWND Wnd,
/*************** PAINTING.C ***************/
BOOL FASTCALL UserValidateRgn(HWND hWnd, HRGN hRgn);
BOOL FASTCALL co_UserValidateRgn(PWINDOW_OBJECT Window, HRGN hRgn);
/*************** WINDOW.C ***************/

View file

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

View file

@ -123,14 +123,6 @@ typedef struct _WINDOW_OBJECT
#define IntIsBroadcastHwnd(hWnd) \
(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) \
(((WndObj->OwnerThread && WndObj->OwnerThread->Tcb.Win32Thread)) && \
@ -143,9 +135,6 @@ typedef struct _WINDOW_OBJECT
WndObj->OwnerThread->ThreadsProcess->UniqueProcessId
PWINDOW_OBJECT FASTCALL
IntGetProcessWindowObject(PW32THREAD Thread, HWND hWnd);
BOOL FASTCALL
IntIsWindow(HWND hWnd);

View file

@ -17,7 +17,7 @@
UINT
FASTCALL co_WinPosArrangeIconicWindows(PWINDOW_OBJECT parent);
BOOL FASTCALL
IntGetClientOrigin(HWND hWnd, LPPOINT Point);
IntGetClientOrigin(PWINDOW_OBJECT Window, LPPOINT Point);
LRESULT FASTCALL
co_WinPosGetNonClientSize(HWND Wnd, RECT* WindowRect, RECT* ClientRect);
UINT FASTCALL
@ -26,7 +26,7 @@ co_WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
UINT FASTCALL
co_WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos);
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);
BOOLEAN FASTCALL
co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd);

View file

@ -219,11 +219,14 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
}
else
{
PSINGLE_LIST_ENTRY e;
DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
Win32Thread->IsExiting = TRUE;
HOOK_DestroyThreadHooks(Thread);
UnregisterThreadHotKeys(Thread);
/* what if this co_ func crash in umode? what will clean us up then? */
co_DestroyThreadWindows(Thread);
IntBlockInput(Win32Thread, FALSE);
MsqDestroyMessageQueue(Win32Thread->MessageQueue);
@ -232,6 +235,17 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
{
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);

View file

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

View file

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

View file

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

View file

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

View file

@ -58,6 +58,26 @@ IntAllocHookTable(void)
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 */
STATIC FASTCALL PHOOK
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,
otHookProc, sizeof(HOOK));
Hook = ObmCreateObject(&gHandleTable, &Handle, otHook, sizeof(HOOK));
if (NULL == Hook)
{
return NULL;
@ -180,7 +199,7 @@ IntFreeHook(PHOOKTABLE Table, PHOOK Hook, PWINSTATION_OBJECT WinStaObj)
}
/* Close handle */
ObmCloseHandle(gHandleTable, Hook->Self);
ObmDeleteObject(Hook->Self, otHook);
}
/* remove a hook, freeing it if the chain is not in use */
@ -399,15 +418,22 @@ NtUserCallNextHookEx(
RETURN( FALSE);
}
Status = ObmReferenceObjectByHandle(gHandleTable, Hook,
otHookProc, (PVOID *) &HookObj);
//Status = ObmReferenceObjectByHandle(gHandleTable, Hook,
// otHookProc, (PVOID *) &HookObj);
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);
}
ASSERT(Hook == HookObj->Self);
if (NULL != HookObj->Thread && (HookObj->Thread != PsGetCurrentThread()))
@ -687,13 +713,13 @@ NtUserUnhookWindowsHookEx(
RETURN( FALSE);
}
Status = ObmReferenceObjectByHandle(gHandleTable, Hook,
otHookProc, (PVOID *) &HookObj);
if (! NT_SUCCESS(Status))
// Status = ObmReferenceObjectByHandle(gHandleTable, Hook,
// otHookProc, (PVOID *) &HookObj);
if (!(HookObj = IntGetHookObject(Hook)))
{
DPRINT1("Invalid handle passed to NtUserUnhookWindowsHookEx\n");
ObDereferenceObject(WinStaObj);
SetLastNtError(Status);
// SetLastNtError(Status);
RETURN( FALSE);
}
ASSERT(Hook == HookObj->Self);

View file

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

View file

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

View file

@ -507,7 +507,18 @@ NtUserCallTwoParam(
RETURN( 0);
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:
WindowObject = IntGetWindowObject((HWND)Param1);
@ -724,7 +735,7 @@ NtUserCallHwndLock(
MenuObject->MenuInfo.WndOwner = hWnd;
MenuObject->MenuInfo.Height = 0;
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 );
Ret = TRUE;
break;

View file

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

View file

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

View file

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

View file

@ -1,32 +1,25 @@
/*
* ReactOS W32 Subsystem
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
* Server-side USER handles
*
* This program is free software; you can redistribute it and/or modify
* 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.
* Copyright (C) 2001 Alexandre Julliard
*
* 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
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* INCLUDES ******************************************************************/
#include <w32k.h>
@ -34,479 +27,277 @@
#define NDEBUG
#include <debug.h>
#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))
int usedHandles=0;
USER_HANDLE_TABLE gHandleTable;
PUSER_HANDLE_TABLE gHandleTable = NULL;
/* 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)
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE 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;
}
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;
if (Current == &(HandleTable->ListHead))
PUSER_HANDLE_ENTRY entry;
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 entry->ptr;
}
Block = CONTAINING_RECORD(Current, USER_HANDLE_BLOCK, ListEntry);
return &(Block->Handles[Index % HANDLE_BLOCK_ENTRIES]);
}
VOID FASTCALL
ObmpCloseAllHandles(PUSER_HANDLE_TABLE HandleTable)
/* get the full handle (32bit) for a possibly truncated (16bit) handle */
HANDLE get_user_full_handle(PUSER_HANDLE_TABLE ht, HANDLE handle )
{
PLIST_ENTRY CurrentEntry;
PUSER_HANDLE_BLOCK Current;
PVOID ObjectBody;
ULONG i;
PUSER_HANDLE_ENTRY entry;
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);
ObmReferenceObjectByPointer(ObjectBody, otUnknown);
ObjectHeader->HandleCount--;
Current->Handles[i].ObjectBody = NULL;
ObmDereferenceObject(ObjectBody);
CurrentEntry = &HandleTable->ListHead;
break;
}
SetLastNtError( STATUS_INVALID_HANDLE );
return NULL;
}
CurrentEntry = CurrentEntry->Flink;
return free_user_entry(ht, entry );
}
}
VOID FASTCALL
ObmpDeleteHandleTable(PUSER_HANDLE_TABLE HandleTable)
/* 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 )
{
PUSER_HANDLE_BLOCK Current;
PLIST_ENTRY CurrentEntry;
PUSER_HANDLE_ENTRY entry;
ObmpCloseAllHandles(HandleTable);
CurrentEntry = RemoveHeadList(&HandleTable->ListHead);
while (CurrentEntry != &HandleTable->ListHead)
if (!*handle) entry = ht->handles;
else
{
Current = CONTAINING_RECORD(CurrentEntry,
USER_HANDLE_BLOCK,
ListEntry);
ExFreePool(Current);
CurrentEntry = RemoveHeadList(&HandleTable->ListHead);
int index = (((unsigned int)*handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
if (index < 0 || index >= ht->nb_handles) return NULL;
entry = ht->handles + index + 1; /* start from the next one */
}
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
ObmpDeleteHandle(PUSER_HANDLE_TABLE HandleTable,
HANDLE Handle)
ObmCreateObject(PUSER_HANDLE_TABLE ht, HANDLE* h,USER_OBJECT_TYPE type , ULONG size)
{
PUSER_OBJECT_HEADER ObjectHeader;
PUSER_HANDLE Entry;
PVOID ObjectBody;
Entry = ObmpGetObjectByHandle(HandleTable, Handle);
if (Entry == NULL)
{
DPRINT1("Invalid handle\n");
HANDLE hi;
PUSER_OBJECT_HEADER hdr = ExAllocatePool(PagedPool, size + sizeof(USER_OBJECT_HEADER));
if (!hdr) return NULL;
hi = UserAllocHandle(ht, USER_HEADER_TO_BODY(hdr), type );
if (!hi){
ExFreePool(hdr);
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);
ObjectHeader->HandleCount--;
ObmReferenceObjectByPointer(ObjectBody, otUnknown);
Entry->ObjectBody = NULL;
}
PUSER_OBJECT_HEADER hdr;
PVOID body = UserGetObject(&gHandleTable, h, type);
if (!body) return FALSE;
return ObjectBody;
}
hdr = USER_BODY_TO_HEADER(body);
ASSERT(hdr->RefCount >= 0);
NTSTATUS FASTCALL
ObmpInitializeObject(PUSER_HANDLE_TABLE HandleTable,
PUSER_OBJECT_HEADER ObjectHeader,
PHANDLE Handle,
USER_OBJECT_TYPE ObjectType,
ULONG ObjectSize)
hdr->destroyed = TRUE;
if (hdr->RefCount == 0)
{
DWORD Status = STATUS_SUCCESS;
UserFreeHandle(&gHandleTable, h);
ObjectHeader->Type = ObjectType;
ObjectHeader->HandleCount = 0;
ObjectHeader->RefCount = 1;
ObjectHeader->Size = ObjectSize;
memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
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,
USER_HEADER_TO_BODY(ObjectHeader),
Handle);
}
PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
return Status;
ASSERT(hdr->RefCount >= 0);
hdr->RefCount++;
}
ULONG FASTCALL
ObmGetReferenceCount(PVOID ObjectBody)
BOOL FASTCALL ObmDereferenceObject(PVOID obj)
{
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
ObmGetHandleCount(PVOID ObjectBody)
hdr->RefCount--;
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
ObmReferenceObject(PVOID ObjectBody)
/*
* FUNCTION: Increments a given object's reference count and performs
* retention checks
* ARGUMENTS:
* ObjectBody = Body of the object
*/
return FALSE;
}
BOOL FASTCALL ObmCreateHandleTable()
{
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");
return;
DPRINT1("Failed creating handle table\n");
return FALSE;
}
ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
//FIXME: make auto growable
UserInitHandleTable(&gHandleTable, mem, sizeof(USER_HANDLE_ENTRY) * 1024);
ObjectHeader->RefCount++;
ObmpPerformRetentionChecks(ObjectHeader);
return TRUE;
}
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
HWND FASTCALL
co_IntFixCaret(HWND hWnd, LPRECT lprc, UINT flags)
co_IntFixCaret(PWINDOW_OBJECT Window, LPRECT lprc, UINT flags)
{
PDESKTOP_OBJECT Desktop;
PTHRDCARETINFO CaretInfo;
HWND hWndCaret;
PWINDOW_OBJECT WndCaret;
ASSERT_REFS_CO(Window);
Desktop = PsGetCurrentThread()->Tcb.Win32Thread->Desktop;
CaretInfo = ((PUSER_MESSAGE_QUEUE)Desktop->ActiveMessageQueue)->CaretInfo;
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;
RECT rcCaret;
pt.x = CaretInfo->Pos.x;
pt.y = CaretInfo->Pos.y;
IntGetClientOrigin(hWndCaret, &FromOffset);
IntGetClientOrigin(hWnd, &ToOffset);
IntGetClientOrigin(WndCaret, &FromOffset);
IntGetClientOrigin(Window, &ToOffset);
Offset.x = FromOffset.x - ToOffset.x;
Offset.y = FromOffset.y - ToOffset.y;
rcCaret.left = pt.x;
@ -843,15 +849,9 @@ NtUserInvalidateRgn(HWND hWnd, HRGN Rgn, BOOL Erase)
BOOL FASTCALL
UserValidateRgn(HWND hWnd, HRGN hRgn)
co_UserValidateRgn(PWINDOW_OBJECT Window, HRGN hRgn)
{
PWINDOW_OBJECT Window;
BOOL ret;
if (!(Window = IntGetWindowObject(hWnd))) return FALSE;
ret = co_UserRedrawWindow(Window, NULL, hRgn, RDW_VALIDATE | RDW_NOCHILDREN);
IntReleaseWindowObject(Window);//temp hack
return ret;
return co_UserRedrawWindow(Window, NULL, hRgn, RDW_VALIDATE | RDW_NOCHILDREN);
}
/*
@ -885,16 +885,11 @@ NtUserUpdateWindow(HWND hWnd)
INT FASTCALL
co_UserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
co_UserGetUpdateRgn(PWINDOW_OBJECT Window, HRGN hRgn, BOOL bErase)
{
PWINDOW_OBJECT Window;
int RegionType;
if (!(Window = IntGetWindowObject(hWnd)))
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return ERROR;
}
ASSERT_REFS_CO(Window);
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);
}
IntReleaseWindowObject(Window);
return RegionType;
}
/*
@ -929,11 +922,22 @@ INT STDCALL
NtUserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
{
DECLARE_RETURN(INT);
PWINDOW_OBJECT Window;
INT ret;
DPRINT("Enter NtUserGetUpdateRgn\n");
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:
DPRINT("Leave NtUserGetUpdateRgn, ret=%i\n",_ret_);
@ -962,9 +966,8 @@ NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
DPRINT("Enter NtUserGetUpdateRect\n");
UserEnterExclusive();
if (!(Window = IntGetWindowObject(hWnd)))
if (!(Window = UserGetWindowObject(hWnd)))
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
RETURN( ERROR);
}
@ -985,11 +988,11 @@ NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
if (bErase && Rect.left < Rect.right && Rect.top < Rect.bottom)
{
UserRefObjectCo(Window);
co_UserRedrawWindow(Window, NULL, NULL, RDW_ERASENOW | RDW_NOCHILDREN);
UserDerefObjectCo(Window);
}
IntReleaseWindowObject(Window);
if (UnsafeRect != NULL)
{
Status = MmCopyToCaller(UnsafeRect, &Rect, sizeof(RECT));
@ -1027,9 +1030,8 @@ NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate,
DPRINT("Enter NtUserRedrawWindow\n");
UserEnterExclusive();
if (!(Wnd = IntGetWindowObject(hWnd ? hWnd : IntGetDesktopWindow())))
if (!(Wnd = UserGetWindowObject(hWnd ? hWnd : IntGetDesktopWindow())))
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
RETURN( FALSE);
}
@ -1041,23 +1043,24 @@ NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate,
if (!NT_SUCCESS(Status))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
IntReleaseWindowObject(Wnd);
RETURN( FALSE);
}
}
UserRefObjectCo(Wnd);
Status = co_UserRedrawWindow(Wnd, NULL == lprcUpdate ? NULL : &SafeUpdateRect,
hrgnUpdate, flags);
UserDerefObjectCo(Wnd);
if (!NT_SUCCESS(Status))
{
/* IntRedrawWindow fails only in case that flags are invalid */
SetLastWin32Error(ERROR_INVALID_PARAMETER);
IntReleaseWindowObject(Wnd);
RETURN( FALSE);
}
IntReleaseWindowObject(Wnd);
RETURN( TRUE);
CLEANUP:
@ -1208,7 +1211,7 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
{
RECT rc, cliprc, caretrc, rect, clipRect;
INT Result;
PWINDOW_OBJECT Window, CaretWnd;
PWINDOW_OBJECT Window = NULL, CaretWnd;
HDC hDC;
HRGN hrgnTemp;
HWND hwndCaret;
@ -1220,14 +1223,16 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
DPRINT("Enter NtUserScrollWindowEx\n");
UserEnterExclusive();
Window = IntGetWindowObject(hWnd);
Window = UserGetWindowObject(hWnd);
if (!Window || !IntIsWindowDrawable(Window))
{
IntReleaseWindowObject(Window);
Window = NULL; /* prevent deref at cleanup */
RETURN( ERROR);
}
UserRefObjectCo(Window);
IntGetClientRect(Window, &rc);
if (NULL != UnsafeRect)
{
Status = MmCopyFromCaller(&rect, UnsafeRect, sizeof(RECT));
@ -1259,7 +1264,7 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
}
caretrc = rc;
hwndCaret = co_IntFixCaret(hWnd, &caretrc, flags);
hwndCaret = co_IntFixCaret(Window, &caretrc, flags);
if (hrgnUpdate)
bOwnRgn = FALSE;
@ -1279,7 +1284,7 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
*/
hrgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
Result = co_UserGetUpdateRgn(hWnd, hrgnTemp, FALSE);
Result = co_UserGetUpdateRgn(Window, hrgnTemp, FALSE);
if (Result != NULLREGION)
{
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);
NtGdiDeleteObject(hrgnClip);
}
NtGdiDeleteObject(hrgnTemp);
if (flags & SW_SCROLLCHILDREN)
@ -1298,23 +1304,28 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
int i;
RECT r, dummy;
POINT ClientOrigin;
PWINDOW_OBJECT WindowObject;
PWINDOW_OBJECT Wnd;
IntGetClientOrigin(hWnd, &ClientOrigin);
IntGetClientOrigin(Window, &ClientOrigin);
for (i = 0; List[i]; i++)
{
WindowObject = IntGetWindowObject(List[i]);
if (!WindowObject) continue;
r = WindowObject->WindowRect;
if (!(Wnd = UserGetWindowObject(List[i]))) continue;
r = Wnd->WindowRect;
r.left -= ClientOrigin.x;
r.top -= ClientOrigin.y;
r.right -= ClientOrigin.x;
r.bottom -= ClientOrigin.y;
IntReleaseWindowObject(WindowObject);
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_NOREDRAW);
UserDerefObjectCo(Wnd);
}
}
ExFreePool(List);
}
@ -1328,18 +1339,21 @@ NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *UnsafeRect,
if (bOwnRgn && hrgnUpdate)
NtGdiDeleteObject(hrgnUpdate);
if ((CaretWnd = IntGetWindowObject(hwndCaret)))
if ((CaretWnd = UserGetWindowObject(hwndCaret)))
{
UserRefObjectCo(CaretWnd);
co_IntSetCaretPos(caretrc.left + dx, caretrc.top + dy);
co_UserShowCaret(CaretWnd);
IntReleaseWindowObject(CaretWnd);
}
IntReleaseWindowObject(Window);
UserDerefObjectCo(CaretWnd);
}
RETURN( Result);
CLEANUP:
if (Window) UserDerefObjectCo(Window);
DPRINT("Leave NtUserScrollWindowEx, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;

View file

@ -198,7 +198,7 @@ co_IntGetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPSCROLLINFO lpsi)
UINT Mask;
LPSCROLLINFO psi;
ASSERT_REFS(Window);
ASSERT_REFS_CO(Window);
if(!SBID_IS_VALID(nBar))
{
@ -260,7 +260,7 @@ co_IntSetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bR
/* UINT new_flags;*/
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))
{
@ -411,7 +411,7 @@ co_IntGetScrollBarInfo(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi
PSCROLLBARINFO sbi;
LPSCROLLINFO psi;
ASSERT_REFS(Window);
ASSERT_REFS_CO(Window);
Bar = SBOBJ_TO_SBID(idObject);
@ -447,7 +447,7 @@ co_IntCreateScrollBars(PWINDOW_OBJECT Window)
ULONG Size, s;
INT i;
ASSERT_REFS(Window);
ASSERT_REFS_CO(Window);
if(Window->Scroll)
{
@ -563,9 +563,9 @@ NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
RETURN(FALSE);
}
UserReferenceWindowObjectCo(Window);
UserRefObjectCo(Window);
Ret = co_IntGetScrollBarInfo(Window, idObject, &sbi);
UserDereferenceWindowObjectCo(Window);
UserDerefObjectCo(Window);
Status = MmCopyToCaller(psbi, &sbi, sizeof(SCROLLBARINFO));
if(!NT_SUCCESS(Status))
@ -618,9 +618,9 @@ NtUserGetScrollInfo(HWND hWnd, int fnBar, LPSCROLLINFO lpsi)
RETURN(FALSE);
}
UserReferenceWindowObjectCo(Window);
UserRefObjectCo(Window);
Ret = co_IntGetScrollInfo(Window, fnBar, &psi);
UserDereferenceWindowObjectCo(Window);
UserDerefObjectCo(Window);
Status = MmCopyToCaller(lpsi, &psi, sz);
if(!NT_SUCCESS(Status))
@ -657,7 +657,7 @@ NtUserEnableScrollBar(
{
RETURN(FALSE);
}
UserReferenceWindowObjectCo(Window);
UserRefObjectCo(Window);
if(wSBflags == SB_CTL)
{
@ -709,7 +709,7 @@ NtUserEnableScrollBar(
RETURN( TRUE);
CLEANUP:
if (Window) UserDereferenceWindowObjectCo(Window);
if (Window) UserDerefObjectCo(Window);
DPRINT("Leave NtUserEnableScrollBar, ret=%i\n",_ret_);
UserLeave();
@ -738,7 +738,7 @@ NtUserSetScrollBarInfo(
{
RETURN( FALSE);
}
UserReferenceWindowObjectCo(Window);
UserRefObjectCo(Window);
Obj = SBOBJ_TO_SBID(idObject);
if(!SBID_IS_VALID(Obj))
@ -770,7 +770,7 @@ NtUserSetScrollBarInfo(
RETURN(TRUE);
CLEANUP:
if (Window) UserDereferenceWindowObjectCo(Window);
if (Window) UserDerefObjectCo(Window);
DPRINT("Leave NtUserSetScrollBarInfo, ret=%i\n",_ret_);
UserLeave();
@ -797,7 +797,7 @@ NtUserSetScrollInfo(
{
RETURN( 0);
}
UserReferenceWindowObjectCo(Window);
UserRefObjectCo(Window);
Status = MmCopyFromCaller(&ScrollInfo, lpsi, sizeof(SCROLLINFO) - sizeof(ScrollInfo.nTrackPos));
if(!NT_SUCCESS(Status))
@ -809,7 +809,7 @@ NtUserSetScrollInfo(
RETURN(co_IntSetScrollInfo(Window, fnBar, &ScrollInfo, bRedraw));
CLEANUP:
if (Window) UserDereferenceWindowObjectCo(Window);
if (Window) UserDerefObjectCo(Window);
DPRINT("Leave NtUserSetScrollInfo, ret=%i\n",_ret_);
UserLeave();
@ -823,7 +823,7 @@ co_UserShowScrollBar(PWINDOW_OBJECT Window, int wBar, DWORD bShow)
{
DWORD Style, OldStyle;
ASSERT_REFS(Window);
ASSERT_REFS_CO(Window);
switch(wBar)
{
@ -873,7 +873,7 @@ co_UserShowScrollBar(PWINDOW_OBJECT Window, int wBar, DWORD bShow)
if(Window->Style & WS_VISIBLE)
{
/* 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);
}
}
@ -897,9 +897,9 @@ NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow)
RETURN(0);
}
UserReferenceWindowObjectCo(Window);
UserRefObjectCo(Window);
ret = co_UserShowScrollBar(Window, wBar, bShow);
UserDereferenceWindowObjectCo(Window);
UserDerefObjectCo(Window);
RETURN(ret);

View file

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

View file

@ -75,15 +75,45 @@ CleanupWindowImpl(VOID)
/* 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 */
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);
if (w) IntReleaseWindowObject(w);
return w;
ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
return Window;
}
@ -115,29 +145,7 @@ IntIsWindow(HWND hWnd)
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
@ -423,7 +431,7 @@ static LRESULT co_IntDestroyWindow(PWINDOW_OBJECT Window,
IntUnlinkWindow(Window);
IntReferenceWindowObject(Window);
ObmCloseHandle(gHandleTable, Window->hSelf);
ObmDeleteObject(Window->hSelf, otWindow);
IntDestroyScrollBars(Window);
@ -922,6 +930,8 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
ASSERT(Wnd);
ASSERT(WndNewParent);
ASSERT_REFS_CO(Wnd);
ASSERT_REFS_CO(WndNewParent);
hWnd = Wnd->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
* 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
| (WasVisible ? SWP_SHOWWINDOW : 0));
@ -1392,8 +1402,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
{
PWINSTATION_OBJECT WinSta;
PWNDCLASS_OBJECT Class;
PWINDOW_OBJECT Window;
PWINDOW_OBJECT ParentWindow, OwnerWindow;
PWINDOW_OBJECT Window = NULL;
PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
HWND ParentWindowHandle;
HWND OwnerWindowHandle;
PMENU_OBJECT SystemMenu;
@ -1410,7 +1420,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
LRESULT Result;
BOOL MenuChanged;
BOOL ClassFound;
DECLARE_RETURN(HWND);
BOOL HasOwner;
ParentWindowHandle = PsGetWin32Thread()->Desktop->DesktopWindow;
@ -1433,12 +1443,14 @@ co_IntCreateWindowEx(DWORD dwExStyle,
}
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)
{
ParentWindow = IntGetWindowObject(ParentWindowHandle);
ParentWindow = UserGetWindowObject(ParentWindowHandle);
if (ParentWindow) UserRefObjectCo(ParentWindow);
}
else
{
@ -1459,31 +1471,25 @@ co_IntCreateWindowEx(DWORD dwExStyle,
{
DPRINT1("Class %wZ not found\n", ClassName);
}
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS);
return((HWND)0);
RETURN((HWND)0);
}
/* Check the window station. */
if (PsGetWin32Thread()->Desktop == NULL)
{
ClassDereferenceObject(Class);
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
DPRINT("Thread is not attached to a desktop! Cannot create window!\n");
return (HWND)0;
RETURN( (HWND)0);
}
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
/* Create the window object. */
Window = (PWINDOW_OBJECT)
ObmCreateObject(gHandleTable, &Handle,
ObmCreateObject(&gHandleTable, &Handle,
otWindow, sizeof(WINDOW_OBJECT) + Class->cbWndExtra
);
@ -1492,13 +1498,13 @@ co_IntCreateWindowEx(DWORD dwExStyle,
{
ObDereferenceObject(WinSta);
ClassDereferenceObject(Class);
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
return (HWND)0;
RETURN( (HWND)0);
}
UserRefObjectCo(Window);
ObDereferenceObject(WinSta);
if (NULL == PsGetWin32Thread()->Desktop->DesktopWindow)
@ -1588,7 +1594,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
ClassDereferenceObject(Class);
DPRINT1("Failed to allocate mem for window name\n");
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
RETURN( NULL);
}
RtlCopyMemory(Window->WindowName.Buffer, WindowName->Buffer, WindowName->MaximumLength);
}
@ -1666,17 +1672,13 @@ co_IntCreateWindowEx(DWORD dwExStyle,
CbtCreate.hwndInsertAfter = HWND_TOP;
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 allocated DCE */
ClassDereferenceObject(Class);
DPRINT1("CBT-hook returned !0\n");
return (HWND) NULL;
RETURN( (HWND) NULL);
}
x = Cs.x;
@ -1815,12 +1817,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
if (!Result)
{
/* FIXME: Cleanup. */
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
DPRINT("IntCreateWindowEx(): NCCREATE message failed.\n");
return((HWND)0);
RETURN((HWND)0);
}
/* Calculate the non-client size. */
@ -1884,13 +1882,9 @@ co_IntCreateWindowEx(DWORD dwExStyle,
if (Result == (LRESULT)-1)
{
/* FIXME: Cleanup. */
if (NULL != ParentWindow)
{
IntReleaseWindowObject(ParentWindow);
}
ClassDereferenceObject(Class);
DPRINT("IntCreateWindowEx(): send CREATE message failed.\n");
return((HWND)0);
RETURN((HWND)0);
}
/* Send move and size messages. */
@ -1946,7 +1940,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
SWP_NOZORDER | SWP_FRAMECHANGED;
DPRINT("IntCreateWindow(): About to minimize/maximize\n");
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);
}
@ -1968,13 +1962,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
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 */
if (Window->Style & WS_VSCROLL)
{
@ -1991,12 +1978,15 @@ co_IntCreateWindowEx(DWORD dwExStyle,
co_WinPosShowWindow(Window, dwShowMode);
}
//faxme: temp hack
UserDereferenceWindowObjectCo(Window);
DPRINT("IntCreateWindow(): = %X\n", Handle);
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
@ -2100,7 +2090,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
{
BOOLEAN isChild;
ASSERT_REFS(Window);
ASSERT_REFS_CO(Window);
if (Window == NULL)
{
@ -3021,11 +3011,17 @@ BOOL STDCALL
NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
{
PWINSTATION_OBJECT WinStaObject;
PWINDOW_OBJECT WndShell;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserSetShellWindowEx\n");
UserEnterExclusive();
if (!(WndShell = UserGetWindowObject(hwndShell)))
{
RETURN(FALSE);
}
NTSTATUS Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
KernelMode,
0,
@ -3072,11 +3068,14 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
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->ShellListView = hwndListView;
UserDerefObjectCo(WndShell);
ObDereferenceObject(WinStaObject);
RETURN( TRUE);
@ -3982,24 +3981,23 @@ NtUserSetMenu(
DPRINT("Enter NtUserSetMenu\n");
UserEnterExclusive();
if (!(Window = IntGetWindowObject(hWnd)))
if (!(Window = UserGetWindowObject(hWnd)))
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
RETURN( FALSE);
}
if (! IntSetMenu(Window, Menu, &Changed))
{
IntReleaseWindowObject(Window);
RETURN( FALSE);
}
IntReleaseWindowObject(Window);
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);
UserDerefObjectCo(Window);
}
RETURN( TRUE);
@ -4060,7 +4058,7 @@ NtUserSetWindowPlacement(HWND hWnd,
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.right - Safepl.rcNormalPosition.left,
Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top,
@ -4100,11 +4098,22 @@ NtUserSetWindowPos(
UINT uFlags)
{
DECLARE_RETURN(BOOL);
PWINDOW_OBJECT Window;
BOOL ret;
DPRINT("Enter NtUserSetWindowPos\n");
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:
DPRINT("Leave NtUserSetWindowPos, ret=%i\n",_ret_);
@ -4263,9 +4272,9 @@ NtUserShowWindow(HWND hWnd, LONG nCmdShow)
RETURN(FALSE);
}
UserReferenceWindowObjectCo(Window);
UserRefObjectCo(Window);
ret = co_WinPosShowWindow(Window, nCmdShow);
UserReferenceWindowObjectCo(Window);
UserDerefObjectCo(Window);
RETURN(ret);

View file

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