From 08bf20fb83bf3f3700f3b95d2f18c0b07ead1542 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Thu, 20 Sep 2007 14:26:43 +0000 Subject: [PATCH] User32: - Implement ValidateHandle. - Copied handle_to_entry and header information from win32k. Yes I know, duplication etc. Just for now. - Add tested validation object types and as per revision 29105. Those object types now match. - In dllmain.c, the gHandleTable pointer is set from Win32k GetW32ProcessInfo. - Tested it, failed. The pointer does match with win32k gHandleTable. svn path=/trunk/; revision=29121 --- reactos/dll/win32/user32/include/user32p.h | 50 ++++++++++++++- reactos/dll/win32/user32/misc/dllmain.c | 8 ++- reactos/dll/win32/user32/misc/misc.c | 75 ++++++++++++++++++++++ 3 files changed, 130 insertions(+), 3 deletions(-) diff --git a/reactos/dll/win32/user32/include/user32p.h b/reactos/dll/win32/user32/include/user32p.h index edc2ab1d693..d413fc8db0b 100644 --- a/reactos/dll/win32/user32/include/user32p.h +++ b/reactos/dll/win32/user32/include/user32p.h @@ -130,13 +130,15 @@ /* Internal Thread Data */ extern HINSTANCE User32Instance; +/* Critical Section*/ +extern RTL_CRITICAL_SECTION User32Crit; + typedef struct _USER32_TRACKINGLIST { TRACKMOUSEEVENT tme; POINT pos; /* center of hover rectangle */ UINT_PTR timer; } USER32_TRACKINGLIST,*PUSER32_TRACKINGLIST; - typedef struct _USER32_THREAD_DATA { MSG LastMessage; @@ -145,7 +147,7 @@ typedef struct _USER32_THREAD_DATA } USER32_THREAD_DATA, *PUSER32_THREAD_DATA; PUSER32_THREAD_DATA User32GetThreadData(); - + DEVMODEW * STDCALL GdiConvertToDevmodeW(DEVMODEA *dm); @@ -164,6 +166,7 @@ VOID DeleteFrameBrushes(VOID); #define SPY_RESULT_INVALIDHWND 0x0003 #define SPY_RESULT_DEFWND 0x0005 + extern const char *SPY_GetMsgName(UINT msg, HWND hWnd); extern const char *SPY_GetVKeyName(WPARAM wParam); extern void SPY_EnterMessage(INT iFlag, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); @@ -172,5 +175,48 @@ extern void SPY_ExitMessage(INT iFlag, HWND hwnd, UINT msg, extern int SPY_Init(void); +/* Validate window handle types */ +#define VALIDATE_TYPE_FREE 0 +#define VALIDATE_TYPE_WIN 1 +#define VALIDATE_TYPE_MENU 2 +#define VALIDATE_TYPE_CURSOR 3 +#define VALIDATE_TYPE_MWPOS 4 +#define VALIDATE_TYPE_HOOK 5 +#define VALIDATE_TYPE_CALLPROC 7 +#define VALIDATE_TYPE_ACCEL 8 +#define VALIDATE_TYPE_MONITOR 12 + +#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 NB_USER_HANDLES ((LAST_USER_HANDLE - FIRST_USER_HANDLE + 1) >> 1) +#define USER_HANDLE_TO_INDEX(hwnd) ((LOWORD(hwnd) - FIRST_USER_HANDLE) >> 1) + +#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 */ + PW32THREADINFO pti; // pointer to Win32ThreadInfo + 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; + +extern PUSER_HANDLE_TABLE gHandleTable; + +PUSER_HANDLE_ENTRY FASTCALL GetUser32Handle(HANDLE); +PVOID FASTCALL ValidateHandle(HANDLE, UINT); + #endif /* EOF */ diff --git a/reactos/dll/win32/user32/misc/dllmain.c b/reactos/dll/win32/user32/misc/dllmain.c index f37b36b66e9..6061cfdef51 100644 --- a/reactos/dll/win32/user32/misc/dllmain.c +++ b/reactos/dll/win32/user32/misc/dllmain.c @@ -4,6 +4,8 @@ static ULONG User32TlsIndex; HINSTANCE User32Instance; +PUSER_HANDLE_TABLE gHandleTable = NULL; + PUSER32_THREAD_DATA User32GetThreadData() @@ -49,7 +51,11 @@ Init(VOID) (PVOID)User32SetupDefaultCursors; NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_HOOKPROC] = (PVOID)User32CallHookProcFromKernel; - + { + PW32THREADINFO ti = (PW32THREADINFO)NtCurrentTeb()->Win32ThreadInfo; + PW32PROCESSINFO pi = ti->pi; + gHandleTable = (PUSER_HANDLE_TABLE) pi->UserHandleTable; + } /* Allocate an index for user32 thread local data. */ User32TlsIndex = TlsAlloc(); if (User32TlsIndex != TLS_OUT_OF_INDEXES) diff --git a/reactos/dll/win32/user32/misc/misc.c b/reactos/dll/win32/user32/misc/misc.c index c917cc0a6f8..7bd178afb6c 100644 --- a/reactos/dll/win32/user32/misc/misc.c +++ b/reactos/dll/win32/user32/misc/misc.c @@ -268,3 +268,78 @@ EndTask( return TRUE; } + +PUSER_HANDLE_ENTRY +FASTCALL +GetUser32Handle(HANDLE handle) +{ + PUSER_HANDLE_TABLE ht = gHandleTable; + USHORT generation; + + DPRINT1("Main Handle Table %x\n", ht); + + INT Index = (((UINT)handle & 0xffff) - FIRST_USER_HANDLE) >> 1; + + if (Index < 0 || Index >= ht->nb_handles) return NULL; + + if (!ht->handles[Index].type) return NULL; + + generation = (UINT)handle >> 16; + + if (generation == ht->handles[Index].generation || !generation || generation == 0xffff) + return &ht->handles[Index]; + + return NULL; +} + +// +// Validate Handle and return the pointer to the object. +// +PVOID +FASTCALL +ValidateHandle(HANDLE handle, UINT uType) +{ + PW32CLIENTINFO ClientInfo = GetWin32ClientInfo(); + + if (uType == VALIDATE_TYPE_WIN) + { + if (handle == ClientInfo->hWND) return ClientInfo->pvWND; + } + + PUSER_HANDLE_ENTRY pEntry = GetUser32Handle(handle); + +// Must have an entry and must be the same type! + if ( (!pEntry) || (pEntry->type != uType) ) + { + switch ( uType ) + { // Test (with wine too) confirms these results! + case VALIDATE_TYPE_WIN: + SetLastError(ERROR_INVALID_WINDOW_HANDLE); + break; + case VALIDATE_TYPE_MENU: + SetLastError(ERROR_INVALID_MENU_HANDLE); + break; + case VALIDATE_TYPE_CURSOR: + SetLastError(ERROR_INVALID_CURSOR_HANDLE); + break; + case VALIDATE_TYPE_MWPOS: + SetLastError(ERROR_INVALID_DWP_HANDLE); + break; + case VALIDATE_TYPE_HOOK: + SetLastError(ERROR_INVALID_HOOK_HANDLE); + break; + case VALIDATE_TYPE_ACCEL: + SetLastError(ERROR_INVALID_ACCEL_HANDLE); + break; + default: + SetLastError(ERROR_INVALID_HANDLE); + } + return NULL; + } + + if (!(NtUserValidateHandleSecure(handle, FALSE))) return NULL; + + return pEntry->ptr; +} + +