- DispatchMessage does not allow pointers to be passed forward so need to check for non synchronous messages. Added the same check for the other functions in User32 leaving the rest to be checked in Win32k.
- Add the timer callback validation check.

svn path=/trunk/; revision=51676
This commit is contained in:
James Tabor 2011-05-11 19:59:03 +00:00
parent 585c628014
commit 537a1dcc7f

View file

@ -13,6 +13,81 @@
#include <wine/debug.h> #include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(user32); WINE_DEFAULT_DEBUG_CHANNEL(user32);
/* From wine: */
/* flag for messages that contain pointers */
/* 32 messages per entry, messages 0..31 map to bits 0..31 */
#define SET(msg) (1 << ((msg) & 31))
static const unsigned int message_pointer_flags[] =
{
/* 0x00 - 0x1f */
SET(WM_CREATE) | SET(WM_SETTEXT) | SET(WM_GETTEXT) |
SET(WM_WININICHANGE) | SET(WM_DEVMODECHANGE),
/* 0x20 - 0x3f */
SET(WM_GETMINMAXINFO) | SET(WM_DRAWITEM) | SET(WM_MEASUREITEM) | SET(WM_DELETEITEM) |
SET(WM_COMPAREITEM),
/* 0x40 - 0x5f */
SET(WM_WINDOWPOSCHANGING) | SET(WM_WINDOWPOSCHANGED) | SET(WM_COPYDATA) |
SET(WM_COPYGLOBALDATA) | SET(WM_NOTIFY) | SET(WM_HELP),
/* 0x60 - 0x7f */
SET(WM_STYLECHANGING) | SET(WM_STYLECHANGED),
/* 0x80 - 0x9f */
SET(WM_NCCREATE) | SET(WM_NCCALCSIZE) | SET(WM_GETDLGCODE),
/* 0xa0 - 0xbf */
SET(EM_GETSEL) | SET(EM_GETRECT) | SET(EM_SETRECT) | SET(EM_SETRECTNP),
/* 0xc0 - 0xdf */
SET(EM_REPLACESEL) | SET(EM_GETLINE) | SET(EM_SETTABSTOPS),
/* 0xe0 - 0xff */
SET(SBM_GETRANGE) | SET(SBM_SETSCROLLINFO) | SET(SBM_GETSCROLLINFO) | SET(SBM_GETSCROLLBARINFO),
/* 0x100 - 0x11f */
0,
/* 0x120 - 0x13f */
0,
/* 0x140 - 0x15f */
SET(CB_GETEDITSEL) | SET(CB_ADDSTRING) | SET(CB_DIR) | SET(CB_GETLBTEXT) |
SET(CB_INSERTSTRING) | SET(CB_FINDSTRING) | SET(CB_SELECTSTRING) |
SET(CB_GETDROPPEDCONTROLRECT) | SET(CB_FINDSTRINGEXACT),
/* 0x160 - 0x17f */
0,
/* 0x180 - 0x19f */
SET(LB_ADDSTRING) | SET(LB_INSERTSTRING) | SET(LB_GETTEXT) | SET(LB_SELECTSTRING) |
SET(LB_DIR) | SET(LB_FINDSTRING) |
SET(LB_GETSELITEMS) | SET(LB_SETTABSTOPS) | SET(LB_ADDFILE) | SET(LB_GETITEMRECT),
/* 0x1a0 - 0x1bf */
SET(LB_FINDSTRINGEXACT),
/* 0x1c0 - 0x1df */
0,
/* 0x1e0 - 0x1ff */
0,
/* 0x200 - 0x21f */
SET(WM_NEXTMENU) | SET(WM_SIZING) | SET(WM_MOVING) | SET(WM_DEVICECHANGE),
/* 0x220 - 0x23f */
SET(WM_MDICREATE) | SET(WM_MDIGETACTIVE) | SET(WM_DROPOBJECT) |
SET(WM_QUERYDROPOBJECT) | SET(WM_DRAGLOOP) | SET(WM_DRAGSELECT) | SET(WM_DRAGMOVE),
/* 0x240 - 0x25f */
0,
/* 0x260 - 0x27f */
0,
/* 0x280 - 0x29f */
0,
/* 0x2a0 - 0x2bf */
0,
/* 0x2c0 - 0x2df */
0,
/* 0x2e0 - 0x2ff */
0,
/* 0x300 - 0x31f */
SET(WM_ASKCBFORMATNAME)
};
/* check whether a given message type includes pointers */
static inline int is_pointer_message( UINT message )
{
if (message >= 8*sizeof(message_pointer_flags)) return FALSE;
return (message_pointer_flags[message / 32] & SET(message)) != 0;
}
/* DDE message exchange /* DDE message exchange
* *
* - Session initialization * - Session initialization
@ -1500,6 +1575,12 @@ DispatchMessageA(CONST MSG *lpmsg)
else else
Wnd = NULL; Wnd = NULL;
if (is_pointer_message(lpmsg->message))
{
SetLastError( ERROR_MESSAGE_SYNC_ONLY );
return 0;
}
if ((lpmsg->message == WM_TIMER || lpmsg->message == WM_SYSTIMER) && lpmsg->lParam != 0) if ((lpmsg->message == WM_TIMER || lpmsg->message == WM_SYSTIMER) && lpmsg->lParam != 0)
{ {
WNDPROC WndProc = (WNDPROC)lpmsg->lParam; WNDPROC WndProc = (WNDPROC)lpmsg->lParam;
@ -1507,6 +1588,8 @@ DispatchMessageA(CONST MSG *lpmsg)
if ( lpmsg->message == WM_SYSTIMER ) if ( lpmsg->message == WM_SYSTIMER )
return NtUserDispatchMessage( (PMSG)lpmsg ); return NtUserDispatchMessage( (PMSG)lpmsg );
if (!NtUserValidateTimerCallback(lpmsg->hwnd, lpmsg->wParam, lpmsg->lParam)) return 0;
_SEH2_TRY // wine does this. Hint: Prevents call to another thread.... _SEH2_TRY // wine does this. Hint: Prevents call to another thread....
{ {
Ret = WndProc(lpmsg->hwnd, Ret = WndProc(lpmsg->hwnd,
@ -1572,6 +1655,12 @@ DispatchMessageW(CONST MSG *lpmsg)
else else
Wnd = NULL; Wnd = NULL;
if (is_pointer_message(lpmsg->message))
{
SetLastError( ERROR_MESSAGE_SYNC_ONLY );
return 0;
}
if ((lpmsg->message == WM_TIMER || lpmsg->message == WM_SYSTIMER) && lpmsg->lParam != 0) if ((lpmsg->message == WM_TIMER || lpmsg->message == WM_SYSTIMER) && lpmsg->lParam != 0)
{ {
WNDPROC WndProc = (WNDPROC)lpmsg->lParam; WNDPROC WndProc = (WNDPROC)lpmsg->lParam;
@ -1579,6 +1668,8 @@ DispatchMessageW(CONST MSG *lpmsg)
if ( lpmsg->message == WM_SYSTIMER ) if ( lpmsg->message == WM_SYSTIMER )
return NtUserDispatchMessage( (PMSG) lpmsg ); return NtUserDispatchMessage( (PMSG) lpmsg );
if (!NtUserValidateTimerCallback(lpmsg->hwnd, lpmsg->wParam, lpmsg->lParam)) return 0;
_SEH2_TRY _SEH2_TRY
{ {
Ret = WndProc(lpmsg->hwnd, Ret = WndProc(lpmsg->hwnd,
@ -2032,6 +2123,12 @@ SendMessageCallbackA(
MSG AnsiMsg, UcMsg; MSG AnsiMsg, UcMsg;
CALL_BACK_INFO CallBackInfo; CALL_BACK_INFO CallBackInfo;
if (is_pointer_message(Msg))
{
SetLastError( ERROR_MESSAGE_SYNC_ONLY );
return FALSE;
}
CallBackInfo.CallBack = lpCallBack; CallBackInfo.CallBack = lpCallBack;
CallBackInfo.Context = dwData; CallBackInfo.Context = dwData;
@ -2073,6 +2170,12 @@ SendMessageCallbackW(
{ {
CALL_BACK_INFO CallBackInfo; CALL_BACK_INFO CallBackInfo;
if (is_pointer_message(Msg))
{
SetLastError( ERROR_MESSAGE_SYNC_ONLY );
return FALSE;
}
CallBackInfo.CallBack = lpCallBack; CallBackInfo.CallBack = lpCallBack;
CallBackInfo.Context = dwData; CallBackInfo.Context = dwData;
@ -2237,6 +2340,12 @@ SendNotifyMessageA(
BOOL Ret; BOOL Ret;
MSG AnsiMsg, UcMsg; MSG AnsiMsg, UcMsg;
if (is_pointer_message(Msg))
{
SetLastError( ERROR_MESSAGE_SYNC_ONLY );
return FALSE;
}
AnsiMsg.hwnd = hWnd; AnsiMsg.hwnd = hWnd;
AnsiMsg.message = Msg; AnsiMsg.message = Msg;
AnsiMsg.wParam = wParam; AnsiMsg.wParam = wParam;
@ -2266,6 +2375,12 @@ SendNotifyMessageW(
MSG UMMsg, KMMsg; MSG UMMsg, KMMsg;
LRESULT Result; LRESULT Result;
if (is_pointer_message(Msg))
{
SetLastError( ERROR_MESSAGE_SYNC_ONLY );
return FALSE;
}
UMMsg.hwnd = hWnd; UMMsg.hwnd = hWnd;
UMMsg.message = Msg; UMMsg.message = Msg;
UMMsg.wParam = wParam; UMMsg.wParam = wParam;