Author: jimtabor Date: Thu Sep 20 18:26:43 2007 New Revision: 29121
URL: http://svn.reactos.org/svn/reactos?rev=29121&view=rev Log: 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.
Modified: trunk/reactos/dll/win32/user32/include/user32p.h trunk/reactos/dll/win32/user32/misc/dllmain.c trunk/reactos/dll/win32/user32/misc/misc.c
Modified: trunk/reactos/dll/win32/user32/include/user32p.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/us... ============================================================================== --- trunk/reactos/dll/win32/user32/include/user32p.h (original) +++ trunk/reactos/dll/win32/user32/include/user32p.h Thu Sep 20 18:26:43 2007 @@ -130,12 +130,14 @@ /* 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 { @@ -145,7 +147,7 @@ } USER32_THREAD_DATA, *PUSER32_THREAD_DATA;
PUSER32_THREAD_DATA User32GetThreadData(); - + DEVMODEW * STDCALL GdiConvertToDevmodeW(DEVMODEA *dm); @@ -163,6 +165,7 @@ #define SPY_RESULT_OK 0x0001 #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); @@ -172,5 +175,48 @@ 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 */
Modified: trunk/reactos/dll/win32/user32/misc/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/dllma... ============================================================================== --- trunk/reactos/dll/win32/user32/misc/dllmain.c (original) +++ trunk/reactos/dll/win32/user32/misc/dllmain.c Thu Sep 20 18:26:43 2007 @@ -4,6 +4,8 @@
static ULONG User32TlsIndex; HINSTANCE User32Instance; +PUSER_HANDLE_TABLE gHandleTable = NULL; +
PUSER32_THREAD_DATA User32GetThreadData() @@ -49,7 +51,11 @@ (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)
Modified: trunk/reactos/dll/win32/user32/misc/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/misc.... ============================================================================== --- trunk/reactos/dll/win32/user32/misc/misc.c (original) +++ trunk/reactos/dll/win32/user32/misc/misc.c Thu Sep 20 18:26:43 2007 @@ -268,3 +268,78 @@
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; +} + +