Commit 0ad2db66 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Pack messages sent directly from win32u.

Instead of leaking kernel pointers.
parent 894d728b
......@@ -47,6 +47,18 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
#define MAX_PACK_COUNT 4
/* info about the message currently being received by the current thread */
struct received_message_info
{
UINT type;
MSG msg;
UINT flags; /* InSendMessageEx return flags */
LRESULT result;
struct received_message_info *prev;
};
#define MSG_CLIENT_MESSAGE 0xff
struct packed_hook_extra_info
{
user_handle_t handle;
......@@ -1030,6 +1042,117 @@ static void unpack_reply( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
}
/***********************************************************************
* copy_reply
*
* Copy a message reply received from client.
*/
static void copy_reply( LRESULT result, HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
WPARAM wparam_src, LPARAM lparam_src )
{
size_t copy_size = 0;
switch(message)
{
case WM_NCCREATE:
case WM_CREATE:
{
CREATESTRUCTW *dst = (CREATESTRUCTW *)lparam;
CREATESTRUCTW *src = (CREATESTRUCTW *)lparam_src;
dst->lpCreateParams = src->lpCreateParams;
dst->hInstance = src->hInstance;
dst->hMenu = src->hMenu;
dst->hwndParent = src->hwndParent;
dst->cy = src->cy;
dst->cx = src->cx;
dst->y = src->y;
dst->x = src->x;
dst->style = src->style;
dst->dwExStyle = src->dwExStyle;
/* don't allow changing name and class pointers */
}
return;
case WM_GETTEXT:
case CB_GETLBTEXT:
case LB_GETTEXT:
copy_size = (result + 1) * sizeof(WCHAR);
break;
case WM_GETMINMAXINFO:
copy_size = sizeof(MINMAXINFO);
break;
case WM_MEASUREITEM:
copy_size = sizeof(MEASUREITEMSTRUCT);
break;
case WM_WINDOWPOSCHANGING:
case WM_WINDOWPOSCHANGED:
copy_size = sizeof(WINDOWPOS);
break;
case WM_STYLECHANGING:
copy_size = sizeof(STYLESTRUCT);
break;
case WM_GETDLGCODE:
if (lparam) copy_size = sizeof(MSG);
break;
case SBM_GETSCROLLINFO:
copy_size = sizeof(SCROLLINFO);
break;
case SBM_GETSCROLLBARINFO:
copy_size = sizeof(SCROLLBARINFO);
break;
case EM_GETRECT:
case LB_GETITEMRECT:
case CB_GETDROPPEDCONTROLRECT:
case WM_SIZING:
case WM_MOVING:
copy_size = sizeof(RECT);
break;
case EM_GETLINE:
{
WORD *ptr = (WORD *)lparam;
copy_size = ptr[-1] * sizeof(WCHAR);
break;
}
case LB_GETSELITEMS:
copy_size = wparam * sizeof(UINT);
break;
case WM_MDIGETACTIVE:
if (lparam) copy_size = sizeof(BOOL);
break;
case WM_NCCALCSIZE:
if (wparam)
{
NCCALCSIZE_PARAMS *dst = (NCCALCSIZE_PARAMS *)lparam;
NCCALCSIZE_PARAMS *src = (NCCALCSIZE_PARAMS *)lparam_src;
dst->rgrc[0] = src->rgrc[0];
dst->rgrc[1] = src->rgrc[1];
dst->rgrc[2] = src->rgrc[2];
*dst->lppos = *src->lppos;
return;
}
copy_size = sizeof(RECT);
break;
case EM_GETSEL:
case SBM_GETRANGE:
case CB_GETEDITSEL:
if (wparam) *(DWORD *)wparam = *(DWORD *)wparam_src;
if (lparam) copy_size = sizeof(DWORD);
break;
case WM_NEXTMENU:
copy_size = sizeof(MDINEXTMENU);
break;
case WM_MDICREATE:
copy_size = sizeof(MDICREATESTRUCTW);
break;
case WM_ASKCBFORMATNAME:
copy_size = (lstrlenW((WCHAR *)lparam) + 1) * sizeof(WCHAR);
break;
default:
return;
}
if (copy_size) memcpy( (void *)lparam, (void *)lparam_src, copy_size );
}
/***********************************************************************
* reply_message
*
* Send a reply to a sent message.
......@@ -1074,6 +1197,7 @@ BOOL reply_message_result( LRESULT result )
struct user_thread_info *thread_info = get_user_thread_info();
struct received_message_info *info = thread_info->receive_info;
while (info && info->type == MSG_CLIENT_MESSAGE) info = info->prev;
if (!info) return FALSE;
reply_message( info, result, NULL );
return TRUE;
......@@ -1092,6 +1216,13 @@ static BOOL reply_winproc_result( LRESULT result, HWND hwnd, UINT message, WPARA
if (!info) return FALSE;
if (info->type == MSG_CLIENT_MESSAGE)
{
copy_reply( result, hwnd, message, info->msg.wParam, info->msg.lParam, wparam, lparam );
info->result = result;
return TRUE;
}
msg.hwnd = hwnd;
msg.message = message;
msg.wParam = wparam;
......@@ -1221,8 +1352,12 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
return 0;
}
params->needs_unpack = needs_unpack;
if (size) memcpy( params + 1, buffer, size );
if (needs_unpack)
{
params->needs_unpack = TRUE;
params->ansi = FALSE;
if (size) memcpy( params + 1, buffer, size );
}
/* first the WH_CALLWNDPROC hook */
cwp.lParam = lparam;
......@@ -2608,6 +2743,7 @@ static BOOL broadcast_message( struct send_message_info *info, DWORD_PTR *res_pt
switch(info->type)
{
case MSG_UNICODE:
case MSG_OTHER_PROCESS:
send_message_timeout( list[i], info->msg, info->wparam, info->lparam,
info->flags, info->timeout, FALSE );
break;
......@@ -2641,6 +2777,48 @@ static BOOL broadcast_message( struct send_message_info *info, DWORD_PTR *res_pt
return TRUE;
}
static BOOL process_packed_message( struct send_message_info *info, LRESULT *res_ptr, BOOL ansi )
{
struct user_thread_info *thread_info = get_user_thread_info();
struct received_message_info receive_info;
struct packed_message data;
size_t buffer_size = 0, i;
void *buffer = NULL;
char *ptr;
pack_message( info->hwnd, info->msg, info->wparam, info->lparam, &data );
if (data.count == -1) return FALSE;
for (i = 0; i < data.count; i++) buffer_size += data.size[i];
if (!(buffer = malloc( buffer_size ))) return FALSE;
for (ptr = buffer, i = 0; i < data.count; i++)
{
memcpy( ptr, data.data[i], data.size[i] );
ptr += data.size[i];
}
receive_info.type = MSG_CLIENT_MESSAGE;
receive_info.msg.hwnd = info->hwnd;
receive_info.msg.message = info->msg;
receive_info.msg.wParam = info->wparam;
receive_info.msg.lParam = info->lparam;
receive_info.flags = 0;
receive_info.prev = thread_info->receive_info;
receive_info.result = 0;
thread_info->receive_info = &receive_info;
*res_ptr = call_window_proc( info->hwnd, info->msg, info->wparam, info->lparam,
!ansi, TRUE, info->wm_char, TRUE, buffer, buffer_size );
if (thread_info->receive_info == &receive_info)
{
thread_info->receive_info = receive_info.prev;
*res_ptr = receive_info.result;
}
free( buffer );
return TRUE;
}
/***********************************************************************
* process_message
*
......@@ -2652,7 +2830,7 @@ static BOOL process_message( struct send_message_info *info, DWORD_PTR *res_ptr,
INPUT_MESSAGE_SOURCE prev_source = thread_info->msg_source;
DWORD dest_pid;
BOOL ret;
LRESULT result;
LRESULT result = 0;
if (is_broadcast( info->hwnd )) return broadcast_message( info, res_ptr );
......@@ -2672,7 +2850,13 @@ static BOOL process_message( struct send_message_info *info, DWORD_PTR *res_ptr,
thread_info->msg_source = msg_source_unavailable;
spy_enter_message( SPY_SENDMESSAGE, info->hwnd, info->msg, info->wparam, info->lparam );
if (info->dest_tid == GetCurrentThreadId())
if (info->dest_tid != GetCurrentThreadId())
{
if (dest_pid != GetCurrentProcessId() && (info->type == MSG_ASCII || info->type == MSG_UNICODE))
info->type = MSG_OTHER_PROCESS;
ret = send_inter_thread_message( info, &result );
}
else if (info->type != MSG_OTHER_PROCESS)
{
result = call_window_proc( info->hwnd, info->msg, info->wparam, info->lparam,
!ansi, TRUE, info->wm_char, FALSE, NULL, 0 );
......@@ -2682,9 +2866,7 @@ static BOOL process_message( struct send_message_info *info, DWORD_PTR *res_ptr,
}
else
{
if (dest_pid != GetCurrentProcessId() && (info->type == MSG_ASCII || info->type == MSG_UNICODE))
info->type = MSG_OTHER_PROCESS;
ret = send_inter_thread_message( info, &result );
ret = process_packed_message( info, &result, ansi );
}
spy_exit_message( SPY_RESULT_OK, info->hwnd, info->msg, result, info->wparam, info->lparam );
......@@ -2831,8 +3013,26 @@ static LRESULT send_client_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
UINT flags, UINT timeout, BOOL ansi )
{
struct send_message_info info;
DWORD_PTR res = 0;
send_client_message( hwnd, msg, wparam, lparam, flags, timeout, &res, ansi );
if (!is_pointer_message( msg, wparam ))
{
send_client_message( hwnd, msg, wparam, lparam, flags, timeout, &res, ansi );
return res;
}
info.type = MSG_OTHER_PROCESS;
info.hwnd = hwnd;
info.msg = msg;
info.wparam = wparam;
info.lparam = lparam;
info.flags = flags;
info.timeout = timeout;
info.wm_char = WMCHAR_MAP_SENDMESSAGETIMEOUT;
info.params = NULL;
process_message( &info, &res, ansi );
return res;
}
......
......@@ -209,15 +209,6 @@ struct scroll_bar_win_data
#define WINSWITCH_CLASS_ATOM MAKEINTATOM(32771) /* WinSwitch */
#define ICONTITLE_CLASS_ATOM MAKEINTATOM(32772) /* IconTitle */
/* info about the message currently being received by the current thread */
struct received_message_info
{
UINT type;
MSG msg;
UINT flags; /* InSendMessageEx return flags */
struct received_message_info *prev;
};
extern const char *debugstr_msg_name( UINT msg, HWND hwnd ) DECLSPEC_HIDDEN;
extern const char *debugstr_vkey_name( WPARAM wParam ) DECLSPEC_HIDDEN;
extern void spy_enter_message( INT flag, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment