Author: weiden
Date: Thu Nov 15 08:42:44 2007
New Revision: 30455
URL:
http://svn.reactos.org/svn/reactos?rev=30455&view=rev
Log:
Dereference callproc handles without a system call
Modified:
trunk/reactos/dll/win32/user32/include/user32.h
trunk/reactos/dll/win32/user32/include/user32p.h
trunk/reactos/dll/win32/user32/misc/dllmain.c
trunk/reactos/dll/win32/user32/misc/misc.c
trunk/reactos/dll/win32/user32/windows/message.c
trunk/reactos/subsystems/win32/win32k/include/object.h
trunk/reactos/subsystems/win32/win32k/ntuser/object.c
Modified: trunk/reactos/dll/win32/user32/include/user32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/u…
==============================================================================
--- trunk/reactos/dll/win32/user32/include/user32.h (original)
+++ trunk/reactos/dll/win32/user32/include/user32.h Thu Nov 15 08:42:44 2007
@@ -45,8 +45,9 @@
BOOL FASTCALL IsMetaFile(HDC);
extern PW32PROCESSINFO g_pi;
+extern PW32PROCESSINFO g_kpi;
-static PVOID __inline
+static __inline PVOID
SharedPtrToUser(PVOID Ptr)
{
ASSERT(Ptr != NULL);
@@ -55,7 +56,7 @@
return (PVOID)((ULONG_PTR)Ptr - g_pi->UserHeapDelta);
}
-static PVOID __inline
+static __inline PVOID
DesktopPtrToUser(PVOID Ptr)
{
PW32THREADINFO ti = GetW32ThreadInfo();
@@ -65,3 +66,13 @@
return (PVOID)((ULONG_PTR)Ptr - ti->DesktopHeapDelta);
}
+static __inline PVOID
+SharedPtrToKernel(PVOID Ptr)
+{
+ ASSERT(Ptr != NULL);
+ ASSERT(g_pi != NULL);
+ ASSERT(g_pi->UserHeapDelta != 0);
+ return (PVOID)((ULONG_PTR)Ptr + g_pi->UserHeapDelta);
+}
+
+PCALLPROC FASTCALL ValidateCallProc(HANDLE hCallProc);
Modified: trunk/reactos/dll/win32/user32/include/user32p.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/u…
==============================================================================
--- trunk/reactos/dll/win32/user32/include/user32p.h (original)
+++ trunk/reactos/dll/win32/user32/include/user32p.h Thu Nov 15 08:42:44 2007
@@ -200,7 +200,12 @@
typedef struct _USER_HANDLE_ENTRY
{
void *ptr; /* pointer to object */
- PW32THREADINFO pti; // pointer to Win32ThreadInfo
+ union
+ {
+ PVOID pi;
+ PW32THREADINFO pti; // pointer to Win32ThreadInfo
+ PW32PROCESSINFO ppi; // pointer to W32ProcessInfo
+ };
unsigned short type; /* object type (0 if free) */
unsigned short generation; /* generation counter */
} USER_HANDLE_ENTRY, * PUSER_HANDLE_ENTRY;
@@ -214,6 +219,7 @@
} USER_HANDLE_TABLE, * PUSER_HANDLE_TABLE;
extern PUSER_HANDLE_TABLE gHandleTable;
+extern PUSER_HANDLE_ENTRY gHandleEntries;
PUSER_HANDLE_ENTRY FASTCALL GetUser32Handle(HANDLE);
PVOID FASTCALL ValidateHandle(HANDLE, UINT);
Modified: trunk/reactos/dll/win32/user32/misc/dllmain.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/dllm…
==============================================================================
--- trunk/reactos/dll/win32/user32/misc/dllmain.c (original)
+++ trunk/reactos/dll/win32/user32/misc/dllmain.c Thu Nov 15 08:42:44 2007
@@ -5,7 +5,9 @@
static ULONG User32TlsIndex;
HINSTANCE User32Instance;
PUSER_HANDLE_TABLE gHandleTable = NULL;
-PW32PROCESSINFO g_pi = NULL;
+PUSER_HANDLE_ENTRY gHandleEntries = NULL;
+PW32PROCESSINFO g_pi = NULL; /* User Mode Pointer */
+PW32PROCESSINFO g_kpi = NULL; /* Kernel Mode Pointer */
PW32PROCESSINFO
GetW32ProcessInfo(VOID);
@@ -56,7 +58,9 @@
(PVOID)User32CallHookProcFromKernel;
g_pi = GetW32ProcessInfo();
+ g_kpi = SharedPtrToKernel(g_pi);
gHandleTable = SharedPtrToUser(g_pi->UserHandleTable);
+ gHandleEntries = SharedPtrToUser(gHandleTable->handles);
/* Allocate an index for user32 thread local data. */
User32TlsIndex = TlsAlloc();
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 Nov 15 08:42:44 2007
@@ -314,23 +314,23 @@
FASTCALL
GetUser32Handle(HANDLE handle)
{
- PUSER_HANDLE_TABLE ht = gHandleTable;
- USHORT generation;
-
- TRACE("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;
+ INT Index;
+ USHORT generation;
+
+ Index = (((UINT)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
+
+ if (Index < 0 || Index >= gHandleTable->nb_handles)
+ return NULL;
+
+ if (!gHandleEntries[Index].type || !gHandleEntries[Index].ptr)
+ return NULL;
+
+ generation = (UINT)handle >> 16;
+
+ if (generation == gHandleEntries[Index].generation || !generation || generation ==
0xffff)
+ return &gHandleEntries[Index];
+
+ return NULL;
}
/*
@@ -345,8 +345,8 @@
TRUE, /* VALIDATE_TYPE_MWPOS */
TRUE, /* VALIDATE_TYPE_HOOK */
FALSE, /* (not used) */
- FALSE, /* VALIDATE_TYPE_CALLPROC */
- FALSE, /* VALIDATE_TYPE_ACCEL */
+ TRUE, /* VALIDATE_TYPE_CALLPROC */
+ TRUE, /* VALIDATE_TYPE_ACCEL */
FALSE, /* (not used) */
FALSE, /* (not used) */
FALSE, /* (not used) */
@@ -361,6 +361,7 @@
ValidateHandle(HANDLE handle, UINT uType)
{
PVOID ret;
+ PUSER_HANDLE_ENTRY pEntry;
PW32CLIENTINFO ClientInfo = GetWin32ClientInfo();
ASSERT(uType <= VALIDATE_TYPE_MONITOR);
@@ -372,13 +373,13 @@
if (handle == ClientInfo->hWND) return ClientInfo->pvWND;
}
- PUSER_HANDLE_ENTRY pEntry = GetUser32Handle(handle);
+ pEntry = GetUser32Handle(handle);
if (pEntry && uType == 0)
uType = pEntry->type;
// Must have an entry and must be the same type!
- if ( (!pEntry) || (pEntry->type != uType) )
+ if ( (!pEntry) || (pEntry->type != uType) || !pEntry->ptr )
{
switch ( uType )
{ // Test (with wine too) confirms these results!
@@ -406,8 +407,6 @@
}
return NULL;
}
-
- if (!(NtUserValidateHandleSecure(handle, FALSE))) return NULL;
if (g_ObjectHeapTypeShared[uType])
ret = SharedPtrToUser(pEntry->ptr);
@@ -427,3 +426,17 @@
return ret;
}
+
+//
+// Validate callproc handle and return the pointer to the object.
+//
+PCALLPROC
+FASTCALL
+ValidateCallProc(HANDLE hCallProc)
+{
+ PCALLPROC CallProc = ValidateHandle(hCallProc, VALIDATE_TYPE_CALLPROC);
+ if (CallProc != NULL && CallProc->pi == g_kpi)
+ return CallProc;
+
+ return NULL;
+}
Modified: trunk/reactos/dll/win32/user32/windows/message.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/m…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/message.c (original)
+++ trunk/reactos/dll/win32/user32/windows/message.c Thu Nov 15 08:42:44 2007
@@ -1233,27 +1233,29 @@
WPARAM wParam,
LPARAM lParam)
{
- WNDPROC_INFO wpInfo;
-
- if (lpPrevWndFunc == NULL)
- {
- WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
- return 0;
- }
-
- if (!IsCallProcHandle(lpPrevWndFunc))
- return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
- else
- {
- if (NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
- &wpInfo))
- return IntCallWindowProcA(!wpInfo.IsUnicode, wpInfo.WindowProc,
- hWnd, Msg, wParam, lParam);
- else
- {
- WARN("CallWindowProcA: can not dereference WndProcHandle\n");
- return 0;
- }
+ PCALLPROC CallProc;
+
+ if (lpPrevWndFunc == NULL)
+ {
+ WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
+ return 0;
+ }
+
+ if (!IsCallProcHandle(lpPrevWndFunc))
+ return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
+ else
+ {
+ CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc);
+ if (CallProc != NULL)
+ {
+ return IntCallWindowProcA(!CallProc->Unicode, CallProc->WndProc,
+ hWnd, Msg, wParam, lParam);
+ }
+ else
+ {
+ WARN("CallWindowProcA: can not dereference WndProcHandle\n");
+ return 0;
+ }
}
}
@@ -1268,29 +1270,31 @@
WPARAM wParam,
LPARAM lParam)
{
- WNDPROC_INFO wpInfo;
-
- /* FIXME - can the first parameter be NULL? */
- if (lpPrevWndFunc == NULL)
- {
- WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
- return 0;
- }
-
- if (!IsCallProcHandle(lpPrevWndFunc))
- return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
- else
- {
- if (NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
- &wpInfo))
- return IntCallWindowProcW(!wpInfo.IsUnicode, wpInfo.WindowProc,
- hWnd, Msg, wParam, lParam);
- else
- {
- WARN("CallWindowProcW: can not dereference WndProcHandle\n");
- return 0;
- }
- }
+ PCALLPROC CallProc;
+
+ /* FIXME - can the first parameter be NULL? */
+ if (lpPrevWndFunc == NULL)
+ {
+ WARN("CallWindowProcA: lpPrevWndFunc == NULL!\n");
+ return 0;
+ }
+
+ if (!IsCallProcHandle(lpPrevWndFunc))
+ return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
+ else
+ {
+ CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc);
+ if (CallProc != NULL)
+ {
+ return IntCallWindowProcW(!CallProc->Unicode, CallProc->WndProc,
+ hWnd, Msg, wParam, lParam);
+ }
+ else
+ {
+ WARN("CallWindowProcW: can not dereference WndProcHandle\n");
+ return 0;
+ }
+ }
}
Modified: trunk/reactos/subsystems/win32/win32k/include/object.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/object.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/object.h Thu Nov 15 08:42:44 2007
@@ -20,7 +20,12 @@
typedef struct _USER_HANDLE_ENTRY
{
void *ptr; /* pointer to object */
- PW32THREADINFO pti; // pointer to Win32ThreadInfo
+ union
+ {
+ PVOID pi;
+ PW32THREADINFO pti; // pointer to Win32ThreadInfo
+ PW32PROCESSINFO ppi; // pointer to W32ProcessInfo
+ };
unsigned short type; /* object type (0 if free) */
unsigned short generation; /* generation counter */
} USER_HANDLE_ENTRY, * PUSER_HANDLE_ENTRY;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/object.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/object.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/object.c Thu Nov 15 08:42:44 2007
@@ -108,12 +108,43 @@
ret = entry->ptr;
entry->ptr = ht->freelist;
entry->type = 0;
- entry->pti = 0;
+ entry->pi = NULL;
ht->freelist = entry;
usedHandles--;
return ret;
+}
+
+static __inline PVOID
+UserHandleOwnerByType(USER_OBJECT_TYPE type)
+{
+ PVOID pi;
+
+ switch (type)
+ {
+ case otWindow:
+ pi = GetW32ThreadInfo();
+ break;
+
+ case otMenu:
+ case otCursorIcon:
+ case otHook:
+ case otCallProc:
+ case otAccel:
+ pi = GetW32ProcessInfo();
+ break;
+
+ case otMonitor:
+ pi = NULL; /* System */
+ break;
+
+ default:
+ pi = NULL;
+ break;
+ }
+
+ return pi;
}
/* allocate a user handle for a given object */
@@ -124,8 +155,7 @@
return 0;
entry->ptr = object;
entry->type = type;
- entry->pti = GetW32ThreadInfo();
- if (entry->pti->pi->UserHandleTable == NULL) GetW32ProcessInfo();
+ entry->pi = UserHandleOwnerByType(type);
if (++entry->generation >= 0xffff)
entry->generation = 1;
return entry_to_handle(ht, entry );