mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
-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:
parent
b0bac13ce1
commit
a401832d5f
25 changed files with 905 additions and 965 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 ***************/
|
||||
|
|
|
@ -13,6 +13,8 @@ typedef struct _W32THREAD
|
|||
HANDLE hDesktop;
|
||||
DWORD MessagePumpHookValue;
|
||||
BOOLEAN IsExiting;
|
||||
SINGLE_LIST_ENTRY ReferencesList;
|
||||
|
||||
} W32THREAD, *PW32THREAD;
|
||||
|
||||
#include <poppack.h>
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
PACCELERATOR_TABLE Accel= UserGetObject(&gHandleTable, hAccel, otAccel);
|
||||
|
||||
ObmDereferenceObject(Accel);
|
||||
if (Accel)
|
||||
{
|
||||
ASSERT(USER_BODY_TO_HEADER(Accel)->RefCount >= 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
ObDereferenceObject(WinStaObject);
|
||||
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;
|
||||
|
|
|
@ -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,25 +73,26 @@ 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) {
|
||||
Parent = IntGetParent(Window);
|
||||
if (!Parent)
|
||||
|
||||
Owner = IntGetOwner(Window);
|
||||
if (!Owner)
|
||||
{
|
||||
Parent = IntGetParent(Window);
|
||||
if (!Parent)
|
||||
co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (LPARAM) hWnd);
|
||||
else
|
||||
else
|
||||
IntReleaseWindowObject(Parent);
|
||||
} else {
|
||||
IntReleaseWindowObject(Owner);
|
||||
}
|
||||
|
||||
IntReleaseWindowObject(Window);
|
||||
}
|
||||
else
|
||||
{
|
||||
IntReleaseWindowObject(Owner);
|
||||
}
|
||||
|
||||
IntReleaseWindowObject(Window);
|
||||
|
||||
/* FIXME: IntIsWindow */
|
||||
|
||||
co_IntPostOrSendMessage(hWnd, WM_NCACTIVATE, (WPARAM)(hWnd == UserGetForegroundWindow()), 0);
|
||||
|
@ -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);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
DPRINT1("Invalid handle passed to NtUserCallNextHookEx\n");
|
||||
SetLastNtError(Status);
|
||||
RETURN( 0);
|
||||
}
|
||||
|
||||
// if (! NT_SUCCESS(Status))
|
||||
// {
|
||||
// DPRINT1("Invalid handle passed to NtUserCallNextHookEx\n");
|
||||
// SetLastNtError(Status);
|
||||
// RETURN( 0);
|
||||
// }
|
||||
|
||||
if (!(HookObj = IntGetHookObject(Hook)))
|
||||
{
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
ASSERT(Hook == HookObj->Self);
|
||||
|
||||
if (NULL != HookObj->Thread && (HookObj->Thread != PsGetCurrentThread()))
|
||||
|
@ -670,7 +696,7 @@ NtUserUnhookWindowsHookEx(
|
|||
{
|
||||
PWINSTATION_OBJECT WinStaObj;
|
||||
PHOOK HookObj;
|
||||
NTSTATUS Status;
|
||||
NTSTATUS Status;
|
||||
DECLARE_RETURN(BOOL);
|
||||
|
||||
DPRINT("Enter NtUserUnhookWindowsHookEx\n");
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -115,18 +115,15 @@ CleanupMenuImpl(VOID)
|
|||
|
||||
PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu)
|
||||
{
|
||||
PMENU_OBJECT Menu;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = ObmReferenceObjectByHandle(gHandleTable,
|
||||
hMenu, otMenu, (PVOID*)&Menu);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
ObmDereferenceObject(Menu);
|
||||
return Menu;
|
||||
PMENU_OBJECT Menu = (PMENU_OBJECT)UserGetObject(&gHandleTable, hMenu, otMenu);
|
||||
if (!Menu)
|
||||
{
|
||||
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTSTATUS Status = ObmReferenceObjectByHandle(gHandleTable,
|
||||
hMenu, otMenu, (PVOID*)&MenuObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return MenuObject;
|
||||
PMENU_OBJECT Menu = UserGetMenuObject(hMenu);
|
||||
if (Menu)
|
||||
{
|
||||
ASSERT(USER_BODY_TO_HEADER(Menu)->RefCount >= 0);
|
||||
|
||||
USER_BODY_TO_HEADER(Menu)->RefCount++;
|
||||
}
|
||||
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;
|
||||
|
|
|
@ -507,8 +507,19 @@ 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);
|
||||
if(!WindowObject)
|
||||
|
@ -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;
|
||||
|
|
|
@ -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,17 +138,19 @@ 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)
|
||||
{
|
||||
/* FIXME: SetLastNtError( status ); ? */
|
||||
PMONITOR_OBJECT Monitor = (PMONITOR_OBJECT)UserGetObject(&gHandleTable, hMonitor, otMonitor);
|
||||
if (!Monitor)
|
||||
{
|
||||
SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return Monitor;
|
||||
}
|
||||
|
||||
ASSERT(USER_BODY_TO_HEADER(Monitor)->RefCount >= 0);
|
||||
|
||||
USER_BODY_TO_HEADER(Monitor)->RefCount++;
|
||||
|
||||
return Monitor;
|
||||
}
|
||||
|
||||
/* IntReleaseMonitorObject
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -50,15 +50,13 @@ 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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* 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)
|
||||
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle )
|
||||
{
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
inline static HANDLE entry_to_handle(PUSER_HANDLE_TABLE ht, PUSER_HANDLE_ENTRY ptr )
|
||||
{
|
||||
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)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Current = HandleTable->ListHead.Flink;
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
Current = Current->Flink;
|
||||
if (Current == &(HandleTable->ListHead))
|
||||
{
|
||||
DPRINT1("Invalid handle 0x%x\n", Handle);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Block = CONTAINING_RECORD(Current, USER_HANDLE_BLOCK, ListEntry);
|
||||
return &(Block->Handles[Index % HANDLE_BLOCK_ENTRIES]);
|
||||
int index = ptr - ht->handles;
|
||||
return (HANDLE)(((index << 1) + FIRST_USER_HANDLE) + (ptr->generation << 16));
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
ObmpCloseAllHandles(PUSER_HANDLE_TABLE HandleTable)
|
||||
inline static PUSER_HANDLE_ENTRY alloc_user_entry(PUSER_HANDLE_TABLE ht)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PUSER_HANDLE_BLOCK Current;
|
||||
PVOID ObjectBody;
|
||||
ULONG i;
|
||||
PUSER_HANDLE_ENTRY entry;
|
||||
|
||||
CurrentEntry = HandleTable->ListHead.Flink;
|
||||
|
||||
while (CurrentEntry != &HandleTable->ListHead)
|
||||
if (ht->freelist)
|
||||
{
|
||||
Current = CONTAINING_RECORD(CurrentEntry, USER_HANDLE_BLOCK, ListEntry);
|
||||
|
||||
for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
|
||||
{
|
||||
ObjectBody = Current->Handles[i].ObjectBody;
|
||||
|
||||
if (ObjectBody != NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
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 FASTCALL
|
||||
ObmpDeleteHandleTable(PUSER_HANDLE_TABLE HandleTable)
|
||||
VOID UserInitHandleTable(PUSER_HANDLE_TABLE ht, PVOID mem, ULONG bytes)
|
||||
{
|
||||
PUSER_HANDLE_BLOCK Current;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
|
||||
ObmpCloseAllHandles(HandleTable);
|
||||
|
||||
CurrentEntry = RemoveHeadList(&HandleTable->ListHead);
|
||||
|
||||
while (CurrentEntry != &HandleTable->ListHead)
|
||||
{
|
||||
Current = CONTAINING_RECORD(CurrentEntry,
|
||||
USER_HANDLE_BLOCK,
|
||||
ListEntry);
|
||||
|
||||
ExFreePool(Current);
|
||||
|
||||
CurrentEntry = RemoveHeadList(&HandleTable->ListHead);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/* get the full handle (32bit) for a possibly truncated (16bit) handle */
|
||||
HANDLE get_user_full_handle(PUSER_HANDLE_TABLE ht, HANDLE handle )
|
||||
{
|
||||
PUSER_HANDLE_ENTRY entry;
|
||||
|
||||
if ((unsigned int)handle >> 16) return handle;
|
||||
if (!(entry = handle_to_entry(ht, handle ))) return handle;
|
||||
return entry_to_handle( ht, entry );
|
||||
}
|
||||
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
PUSER_HANDLE_ENTRY entry;
|
||||
|
||||
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 )
|
||||
{
|
||||
PUSER_HANDLE_ENTRY entry;
|
||||
|
||||
if (!(entry = handle_to_entry( ht, handle )))
|
||||
{
|
||||
SetLastNtError( STATUS_INVALID_HANDLE );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
PUSER_HANDLE_ENTRY entry;
|
||||
|
||||
if (!*handle) entry = ht->handles;
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
if (ObjectBody != NULL)
|
||||
{
|
||||
ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
|
||||
ObjectHeader->HandleCount--;
|
||||
ObmReferenceObjectByPointer(ObjectBody, otUnknown);
|
||||
Entry->ObjectBody = NULL;
|
||||
}
|
||||
|
||||
return ObjectBody;
|
||||
RtlZeroMemory(hdr, size + sizeof(USER_OBJECT_HEADER));
|
||||
hdr->hSelf = hi;
|
||||
hdr->RefCount++; //temp hack!
|
||||
|
||||
if (h) *h = hi;
|
||||
return USER_HEADER_TO_BODY(hdr);
|
||||
}
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
ObmpInitializeObject(PUSER_HANDLE_TABLE HandleTable,
|
||||
PUSER_OBJECT_HEADER ObjectHeader,
|
||||
PHANDLE Handle,
|
||||
USER_OBJECT_TYPE ObjectType,
|
||||
ULONG ObjectSize)
|
||||
BOOL FASTCALL
|
||||
ObmDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
|
||||
{
|
||||
DWORD Status = STATUS_SUCCESS;
|
||||
|
||||
ObjectHeader->Type = ObjectType;
|
||||
ObjectHeader->HandleCount = 0;
|
||||
ObjectHeader->RefCount = 1;
|
||||
ObjectHeader->Size = ObjectSize;
|
||||
|
||||
if (Handle != NULL)
|
||||
{
|
||||
Status = ObmCreateHandle(HandleTable,
|
||||
USER_HEADER_TO_BODY(ObjectHeader),
|
||||
Handle);
|
||||
}
|
||||
|
||||
return Status;
|
||||
PUSER_OBJECT_HEADER hdr;
|
||||
PVOID body = UserGetObject(&gHandleTable, h, type);
|
||||
if (!body) return FALSE;
|
||||
|
||||
hdr = USER_BODY_TO_HEADER(body);
|
||||
ASSERT(hdr->RefCount >= 0);
|
||||
|
||||
hdr->destroyed = TRUE;
|
||||
if (hdr->RefCount == 0)
|
||||
{
|
||||
UserFreeHandle(&gHandleTable, h);
|
||||
|
||||
memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
|
||||
|
||||
ExFreePool(hdr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// DPRINT1("info: something not destroyed bcause refs still left, inuse %i\n",usedHandles);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
ULONG FASTCALL
|
||||
ObmGetReferenceCount(PVOID ObjectBody)
|
||||
VOID FASTCALL ObmReferenceObject(PVOID obj)
|
||||
{
|
||||
PUSER_OBJECT_HEADER ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
|
||||
|
||||
return ObjectHeader->RefCount;
|
||||
PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
|
||||
|
||||
ASSERT(hdr->RefCount >= 0);
|
||||
|
||||
hdr->RefCount++;
|
||||
}
|
||||
|
||||
ULONG FASTCALL
|
||||
ObmGetHandleCount(PVOID ObjectBody)
|
||||
|
||||
BOOL FASTCALL ObmDereferenceObject(PVOID obj)
|
||||
{
|
||||
PUSER_OBJECT_HEADER ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
|
||||
|
||||
return ObjectHeader->HandleCount;
|
||||
PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
|
||||
|
||||
ASSERT(hdr->RefCount >= 1);
|
||||
|
||||
hdr->RefCount--;
|
||||
|
||||
if (hdr->RefCount == 0 && hdr->destroyed)
|
||||
{
|
||||
// DPRINT1("info: something destroyed bcaise of deref, in use=%i\n",usedHandles);
|
||||
|
||||
UserFreeHandle(&gHandleTable, hdr->hSelf);
|
||||
|
||||
memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
|
||||
|
||||
ExFreePool(hdr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
ObmReferenceObject(PVOID ObjectBody)
|
||||
/*
|
||||
* FUNCTION: Increments a given object's reference count and performs
|
||||
* retention checks
|
||||
* ARGUMENTS:
|
||||
* ObjectBody = Body of the object
|
||||
*/
|
||||
|
||||
|
||||
BOOL FASTCALL ObmCreateHandleTable()
|
||||
{
|
||||
PUSER_OBJECT_HEADER ObjectHeader;
|
||||
|
||||
PVOID mem;
|
||||
|
||||
if (!ObjectBody)
|
||||
{
|
||||
DPRINT1("Cannot Reference NULL!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
|
||||
|
||||
ObjectHeader->RefCount++;
|
||||
|
||||
ObmpPerformRetentionChecks(ObjectHeader);
|
||||
//FIXME: dont alloc all at once! must be mapped into umode also...
|
||||
mem = ExAllocatePool(PagedPool, sizeof(USER_HANDLE_ENTRY) * 1024);
|
||||
if (!mem)
|
||||
{
|
||||
DPRINT1("Failed creating handle table\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//FIXME: make auto growable
|
||||
UserInitHandleTable(&gHandleTable, mem, sizeof(USER_HANDLE_ENTRY) * 1024);
|
||||
|
||||
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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
IntGetClientOrigin(hWnd, &ClientOrigin);
|
||||
PWINDOW_OBJECT Wnd;
|
||||
|
||||
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);
|
||||
|
||||
UserDerefObjectCo(CaretWnd);
|
||||
}
|
||||
|
||||
IntReleaseWindowObject(Window);
|
||||
|
||||
RETURN( Result);
|
||||
|
||||
CLEANUP:
|
||||
if (Window) UserDerefObjectCo(Window);
|
||||
|
||||
DPRINT("Leave NtUserScrollWindowEx, ret=%i\n",_ret_);
|
||||
UserLeave();
|
||||
END_CLEANUP;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -106,12 +103,15 @@ UserGetClientOrigin(HWND hWnd, LPPOINT Point)
|
|||
BOOL STDCALL
|
||||
NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
|
||||
{
|
||||
DECLARE_RETURN(BOOL);
|
||||
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,10 +125,12 @@ 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))
|
||||
{
|
||||
|
@ -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,12 +1562,12 @@ 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;
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue