user32: Move unpack_message call to User32CallWindowProc.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e72d463072
commit
2656d667a8
|
@ -290,14 +290,6 @@ static inline void push_string( struct packed_message *data, LPCWSTR str )
|
|||
push_data( data, str, (lstrlenW(str) + 1) * sizeof(WCHAR) );
|
||||
}
|
||||
|
||||
/* make sure that the buffer contains a valid null-terminated Unicode string */
|
||||
static inline BOOL check_string( LPCWSTR str, size_t size )
|
||||
{
|
||||
for (size /= sizeof(WCHAR); size; size--, str++)
|
||||
if (!*str) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* pack a pointer into a 32/64 portable format */
|
||||
static inline ULONGLONG pack_ptr( const void *ptr )
|
||||
{
|
||||
|
@ -311,22 +303,6 @@ static inline void *unpack_ptr( ULONGLONG ptr64 )
|
|||
return (void *)(ULONG_PTR)ptr64;
|
||||
}
|
||||
|
||||
/* make sure that there is space for 'size' bytes in buffer, growing it if needed */
|
||||
static inline void *get_buffer_space( void **buffer, size_t size )
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if (*buffer)
|
||||
{
|
||||
if (!(ret = HeapReAlloc( GetProcessHeap(), 0, *buffer, size )))
|
||||
HeapFree( GetProcessHeap(), 0, *buffer );
|
||||
}
|
||||
else ret = HeapAlloc( GetProcessHeap(), 0, size );
|
||||
|
||||
*buffer = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* check whether a combobox expects strings or ids in CB_ADDSTRING/CB_INSERTSTRING */
|
||||
static inline BOOL combobox_has_strings( HWND hwnd )
|
||||
{
|
||||
|
@ -938,7 +914,7 @@ static size_t pack_message( HWND hwnd, UINT message, WPARAM wparam, LPARAM lpara
|
|||
|
||||
|
||||
/***********************************************************************
|
||||
* unpack_message
|
||||
* unpack_message
|
||||
*
|
||||
* Unpack a message received from another process.
|
||||
*/
|
||||
|
@ -950,116 +926,6 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa
|
|||
|
||||
switch(message)
|
||||
{
|
||||
case WM_NCCREATE:
|
||||
case WM_CREATE:
|
||||
{
|
||||
CREATESTRUCTW cs;
|
||||
WCHAR *str = (WCHAR *)(&ps->cs + 1);
|
||||
if (size < sizeof(ps->cs)) return FALSE;
|
||||
size -= sizeof(ps->cs);
|
||||
cs.lpCreateParams = unpack_ptr( ps->cs.lpCreateParams );
|
||||
cs.hInstance = unpack_ptr( ps->cs.hInstance );
|
||||
cs.hMenu = wine_server_ptr_handle( ps->cs.hMenu );
|
||||
cs.hwndParent = wine_server_ptr_handle( ps->cs.hwndParent );
|
||||
cs.cy = ps->cs.cy;
|
||||
cs.cx = ps->cs.cx;
|
||||
cs.y = ps->cs.y;
|
||||
cs.x = ps->cs.x;
|
||||
cs.style = ps->cs.style;
|
||||
cs.dwExStyle = ps->cs.dwExStyle;
|
||||
cs.lpszName = unpack_ptr( ps->cs.lpszName );
|
||||
cs.lpszClass = unpack_ptr( ps->cs.lpszClass );
|
||||
if (ps->cs.lpszName >> 16)
|
||||
{
|
||||
if (!check_string( str, size )) return FALSE;
|
||||
cs.lpszName = str;
|
||||
size -= (lstrlenW(str) + 1) * sizeof(WCHAR);
|
||||
str += lstrlenW(str) + 1;
|
||||
}
|
||||
if (ps->cs.lpszClass >> 16)
|
||||
{
|
||||
if (!check_string( str, size )) return FALSE;
|
||||
cs.lpszClass = str;
|
||||
}
|
||||
memcpy( &ps->cs, &cs, sizeof(cs) );
|
||||
break;
|
||||
}
|
||||
case WM_GETTEXT:
|
||||
case WM_ASKCBFORMATNAME:
|
||||
if (!get_buffer_space( buffer, (*wparam * sizeof(WCHAR)) )) return FALSE;
|
||||
break;
|
||||
case WM_WININICHANGE:
|
||||
if (!*lparam) return TRUE;
|
||||
/* fall through */
|
||||
case WM_SETTEXT:
|
||||
case WM_DEVMODECHANGE:
|
||||
case CB_DIR:
|
||||
case LB_DIR:
|
||||
case LB_ADDFILE:
|
||||
case EM_REPLACESEL:
|
||||
if (!check_string( *buffer, size )) return FALSE;
|
||||
break;
|
||||
case WM_GETMINMAXINFO:
|
||||
minsize = sizeof(MINMAXINFO);
|
||||
break;
|
||||
case WM_DRAWITEM:
|
||||
{
|
||||
DRAWITEMSTRUCT dis;
|
||||
if (size < sizeof(ps->dis)) return FALSE;
|
||||
dis.CtlType = ps->dis.CtlType;
|
||||
dis.CtlID = ps->dis.CtlID;
|
||||
dis.itemID = ps->dis.itemID;
|
||||
dis.itemAction = ps->dis.itemAction;
|
||||
dis.itemState = ps->dis.itemState;
|
||||
dis.hwndItem = wine_server_ptr_handle( ps->dis.hwndItem );
|
||||
dis.hDC = wine_server_ptr_handle( ps->dis.hDC );
|
||||
dis.rcItem = ps->dis.rcItem;
|
||||
dis.itemData = (ULONG_PTR)unpack_ptr( ps->dis.itemData );
|
||||
memcpy( &ps->dis, &dis, sizeof(dis) );
|
||||
break;
|
||||
}
|
||||
case WM_MEASUREITEM:
|
||||
{
|
||||
MEASUREITEMSTRUCT mis;
|
||||
if (size < sizeof(ps->mis)) return FALSE;
|
||||
mis.CtlType = ps->mis.CtlType;
|
||||
mis.CtlID = ps->mis.CtlID;
|
||||
mis.itemID = ps->mis.itemID;
|
||||
mis.itemWidth = ps->mis.itemWidth;
|
||||
mis.itemHeight = ps->mis.itemHeight;
|
||||
mis.itemData = (ULONG_PTR)unpack_ptr( ps->mis.itemData );
|
||||
memcpy( &ps->mis, &mis, sizeof(mis) );
|
||||
break;
|
||||
}
|
||||
case WM_DELETEITEM:
|
||||
{
|
||||
DELETEITEMSTRUCT dls;
|
||||
if (size < sizeof(ps->dls)) return FALSE;
|
||||
dls.CtlType = ps->dls.CtlType;
|
||||
dls.CtlID = ps->dls.CtlID;
|
||||
dls.itemID = ps->dls.itemID;
|
||||
dls.hwndItem = wine_server_ptr_handle( ps->dls.hwndItem );
|
||||
dls.itemData = (ULONG_PTR)unpack_ptr( ps->dls.itemData );
|
||||
memcpy( &ps->dls, &dls, sizeof(dls) );
|
||||
break;
|
||||
}
|
||||
case WM_COMPAREITEM:
|
||||
{
|
||||
COMPAREITEMSTRUCT cis;
|
||||
if (size < sizeof(ps->cis)) return FALSE;
|
||||
cis.CtlType = ps->cis.CtlType;
|
||||
cis.CtlID = ps->cis.CtlID;
|
||||
cis.hwndItem = wine_server_ptr_handle( ps->cis.hwndItem );
|
||||
cis.itemID1 = ps->cis.itemID1;
|
||||
cis.itemData1 = (ULONG_PTR)unpack_ptr( ps->cis.itemData1 );
|
||||
cis.itemID2 = ps->cis.itemID2;
|
||||
cis.itemData2 = (ULONG_PTR)unpack_ptr( ps->cis.itemData2 );
|
||||
cis.dwLocaleId = ps->cis.dwLocaleId;
|
||||
memcpy( &ps->cis, &cis, sizeof(cis) );
|
||||
break;
|
||||
}
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
case WM_WINE_SETWINDOWPOS:
|
||||
{
|
||||
WINDOWPOS wp;
|
||||
|
@ -1074,210 +940,6 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa
|
|||
memcpy( &ps->wp, &wp, sizeof(wp) );
|
||||
break;
|
||||
}
|
||||
case WM_COPYDATA:
|
||||
{
|
||||
COPYDATASTRUCT cds;
|
||||
if (size < sizeof(ps->cds)) return FALSE;
|
||||
cds.dwData = (ULONG_PTR)unpack_ptr( ps->cds.dwData );
|
||||
if (ps->cds.lpData)
|
||||
{
|
||||
cds.cbData = ps->cds.cbData;
|
||||
cds.lpData = &ps->cds + 1;
|
||||
minsize = sizeof(ps->cds) + cds.cbData;
|
||||
}
|
||||
else
|
||||
{
|
||||
cds.cbData = 0;
|
||||
cds.lpData = 0;
|
||||
}
|
||||
memcpy( &ps->cds, &cds, sizeof(cds) );
|
||||
break;
|
||||
}
|
||||
case WM_NOTIFY:
|
||||
/* WM_NOTIFY cannot be sent across processes (MSDN) */
|
||||
return FALSE;
|
||||
case WM_HELP:
|
||||
{
|
||||
HELPINFO hi;
|
||||
if (size < sizeof(ps->hi)) return FALSE;
|
||||
hi.cbSize = sizeof(hi);
|
||||
hi.iContextType = ps->hi.iContextType;
|
||||
hi.iCtrlId = ps->hi.iCtrlId;
|
||||
hi.hItemHandle = wine_server_ptr_handle( ps->hi.hItemHandle );
|
||||
hi.dwContextId = (ULONG_PTR)unpack_ptr( ps->hi.dwContextId );
|
||||
hi.MousePos = ps->hi.MousePos;
|
||||
memcpy( &ps->hi, &hi, sizeof(hi) );
|
||||
break;
|
||||
}
|
||||
case WM_STYLECHANGING:
|
||||
case WM_STYLECHANGED:
|
||||
minsize = sizeof(STYLESTRUCT);
|
||||
break;
|
||||
case WM_NCCALCSIZE:
|
||||
if (!*wparam) minsize = sizeof(RECT);
|
||||
else
|
||||
{
|
||||
NCCALCSIZE_PARAMS ncp;
|
||||
WINDOWPOS wp;
|
||||
if (size < sizeof(ps->ncp)) return FALSE;
|
||||
ncp.rgrc[0] = ps->ncp.rgrc[0];
|
||||
ncp.rgrc[1] = ps->ncp.rgrc[1];
|
||||
ncp.rgrc[2] = ps->ncp.rgrc[2];
|
||||
wp.hwnd = wine_server_ptr_handle( ps->ncp.hwnd );
|
||||
wp.hwndInsertAfter = wine_server_ptr_handle( ps->ncp.hwndInsertAfter );
|
||||
wp.x = ps->ncp.x;
|
||||
wp.y = ps->ncp.y;
|
||||
wp.cx = ps->ncp.cx;
|
||||
wp.cy = ps->ncp.cy;
|
||||
wp.flags = ps->ncp.flags;
|
||||
ncp.lppos = (WINDOWPOS *)((NCCALCSIZE_PARAMS *)&ps->ncp + 1);
|
||||
memcpy( &ps->ncp, &ncp, sizeof(ncp) );
|
||||
*ncp.lppos = wp;
|
||||
}
|
||||
break;
|
||||
case WM_GETDLGCODE:
|
||||
if (*lparam)
|
||||
{
|
||||
MSG msg;
|
||||
if (size < sizeof(ps->msg)) return FALSE;
|
||||
msg.hwnd = wine_server_ptr_handle( ps->msg.hwnd );
|
||||
msg.message = ps->msg.message;
|
||||
msg.wParam = (ULONG_PTR)unpack_ptr( ps->msg.wParam );
|
||||
msg.lParam = (ULONG_PTR)unpack_ptr( ps->msg.lParam );
|
||||
msg.time = ps->msg.time;
|
||||
msg.pt = ps->msg.pt;
|
||||
memcpy( &ps->msg, &msg, sizeof(msg) );
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
case SBM_SETSCROLLINFO:
|
||||
minsize = sizeof(SCROLLINFO);
|
||||
break;
|
||||
case SBM_GETSCROLLINFO:
|
||||
if (!get_buffer_space( buffer, sizeof(SCROLLINFO ))) return FALSE;
|
||||
break;
|
||||
case SBM_GETSCROLLBARINFO:
|
||||
if (!get_buffer_space( buffer, sizeof(SCROLLBARINFO ))) return FALSE;
|
||||
break;
|
||||
case EM_GETSEL:
|
||||
case SBM_GETRANGE:
|
||||
case CB_GETEDITSEL:
|
||||
if (*wparam || *lparam)
|
||||
{
|
||||
if (!get_buffer_space( buffer, 2*sizeof(DWORD) )) return FALSE;
|
||||
if (*wparam) *wparam = (WPARAM)*buffer;
|
||||
if (*lparam) *lparam = (LPARAM)((DWORD *)*buffer + 1);
|
||||
}
|
||||
return TRUE;
|
||||
case EM_GETRECT:
|
||||
case LB_GETITEMRECT:
|
||||
case CB_GETDROPPEDCONTROLRECT:
|
||||
if (!get_buffer_space( buffer, sizeof(RECT) )) return FALSE;
|
||||
break;
|
||||
case EM_SETRECT:
|
||||
case EM_SETRECTNP:
|
||||
minsize = sizeof(RECT);
|
||||
break;
|
||||
case EM_GETLINE:
|
||||
{
|
||||
WORD len;
|
||||
if (size < sizeof(WORD)) return FALSE;
|
||||
len = *(WORD *)*buffer;
|
||||
if (!get_buffer_space( buffer, (len + 1) * sizeof(WCHAR) )) return FALSE;
|
||||
*lparam = (LPARAM)*buffer + sizeof(WORD); /* don't erase WORD at start of buffer */
|
||||
return TRUE;
|
||||
}
|
||||
case EM_SETTABSTOPS:
|
||||
case LB_SETTABSTOPS:
|
||||
if (!*wparam) return TRUE;
|
||||
minsize = *wparam * sizeof(UINT);
|
||||
break;
|
||||
case CB_ADDSTRING:
|
||||
case CB_INSERTSTRING:
|
||||
case CB_FINDSTRING:
|
||||
case CB_FINDSTRINGEXACT:
|
||||
case CB_SELECTSTRING:
|
||||
case LB_ADDSTRING:
|
||||
case LB_INSERTSTRING:
|
||||
case LB_FINDSTRING:
|
||||
case LB_FINDSTRINGEXACT:
|
||||
case LB_SELECTSTRING:
|
||||
if (!*buffer) return TRUE;
|
||||
if (!check_string( *buffer, size )) return FALSE;
|
||||
break;
|
||||
case CB_GETLBTEXT:
|
||||
{
|
||||
size = sizeof(ULONG_PTR);
|
||||
if (combobox_has_strings( hwnd ))
|
||||
size = (SendMessageW( hwnd, CB_GETLBTEXTLEN, *wparam, 0 ) + 1) * sizeof(WCHAR);
|
||||
if (!get_buffer_space( buffer, size )) return FALSE;
|
||||
break;
|
||||
}
|
||||
case LB_GETTEXT:
|
||||
{
|
||||
size = sizeof(ULONG_PTR);
|
||||
if (listbox_has_strings( hwnd ))
|
||||
size = (SendMessageW( hwnd, LB_GETTEXTLEN, *wparam, 0 ) + 1) * sizeof(WCHAR);
|
||||
if (!get_buffer_space( buffer, size )) return FALSE;
|
||||
break;
|
||||
}
|
||||
case LB_GETSELITEMS:
|
||||
if (!get_buffer_space( buffer, *wparam * sizeof(UINT) )) return FALSE;
|
||||
break;
|
||||
case WM_NEXTMENU:
|
||||
{
|
||||
MDINEXTMENU mnm;
|
||||
if (size < sizeof(ps->mnm)) return FALSE;
|
||||
mnm.hmenuIn = wine_server_ptr_handle( ps->mnm.hmenuIn );
|
||||
mnm.hmenuNext = wine_server_ptr_handle( ps->mnm.hmenuNext );
|
||||
mnm.hwndNext = wine_server_ptr_handle( ps->mnm.hwndNext );
|
||||
memcpy( &ps->mnm, &mnm, sizeof(mnm) );
|
||||
break;
|
||||
}
|
||||
case WM_SIZING:
|
||||
case WM_MOVING:
|
||||
minsize = sizeof(RECT);
|
||||
if (!get_buffer_space( buffer, sizeof(RECT) )) return FALSE;
|
||||
break;
|
||||
case WM_MDICREATE:
|
||||
{
|
||||
MDICREATESTRUCTW mcs;
|
||||
WCHAR *str = (WCHAR *)(&ps->mcs + 1);
|
||||
if (size < sizeof(ps->mcs)) return FALSE;
|
||||
size -= sizeof(ps->mcs);
|
||||
|
||||
mcs.szClass = unpack_ptr( ps->mcs.szClass );
|
||||
mcs.szTitle = unpack_ptr( ps->mcs.szTitle );
|
||||
mcs.hOwner = unpack_ptr( ps->mcs.hOwner );
|
||||
mcs.x = ps->mcs.x;
|
||||
mcs.y = ps->mcs.y;
|
||||
mcs.cx = ps->mcs.cx;
|
||||
mcs.cy = ps->mcs.cy;
|
||||
mcs.style = ps->mcs.style;
|
||||
mcs.lParam = (LPARAM)unpack_ptr( ps->mcs.lParam );
|
||||
if (ps->mcs.szClass >> 16)
|
||||
{
|
||||
if (!check_string( str, size )) return FALSE;
|
||||
mcs.szClass = str;
|
||||
size -= (lstrlenW(str) + 1) * sizeof(WCHAR);
|
||||
str += lstrlenW(str) + 1;
|
||||
}
|
||||
if (ps->mcs.szTitle >> 16)
|
||||
{
|
||||
if (!check_string( str, size )) return FALSE;
|
||||
mcs.szTitle = str;
|
||||
}
|
||||
memcpy( &ps->mcs, &mcs, sizeof(mcs) );
|
||||
break;
|
||||
}
|
||||
case WM_MDIGETACTIVE:
|
||||
if (!*lparam) return TRUE;
|
||||
if (!get_buffer_space( buffer, sizeof(BOOL) )) return FALSE;
|
||||
break;
|
||||
case WM_DEVICECHANGE:
|
||||
if (!(*wparam & 0x8000)) return TRUE;
|
||||
minsize = sizeof(DEV_BROADCAST_HDR);
|
||||
break;
|
||||
case WM_WINE_KEYBOARD_LL_HOOK:
|
||||
case WM_WINE_MOUSE_LL_HOOK:
|
||||
{
|
||||
|
@ -1291,48 +953,8 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa
|
|||
memcpy( &ps->hook, &h_extra, sizeof(h_extra) );
|
||||
break;
|
||||
}
|
||||
case WM_NCPAINT:
|
||||
if (*wparam <= 1) return TRUE;
|
||||
FIXME( "WM_NCPAINT hdc unpacking not supported\n" );
|
||||
return FALSE;
|
||||
case WM_PAINT:
|
||||
if (!*wparam) return TRUE;
|
||||
/* fall through */
|
||||
|
||||
/* these contain an HFONT */
|
||||
case WM_SETFONT:
|
||||
case WM_GETFONT:
|
||||
/* these contain an HDC */
|
||||
case WM_ERASEBKGND:
|
||||
case WM_ICONERASEBKGND:
|
||||
case WM_CTLCOLORMSGBOX:
|
||||
case WM_CTLCOLOREDIT:
|
||||
case WM_CTLCOLORLISTBOX:
|
||||
case WM_CTLCOLORBTN:
|
||||
case WM_CTLCOLORDLG:
|
||||
case WM_CTLCOLORSCROLLBAR:
|
||||
case WM_CTLCOLORSTATIC:
|
||||
case WM_PRINT:
|
||||
case WM_PRINTCLIENT:
|
||||
/* these contain an HGLOBAL */
|
||||
case WM_PAINTCLIPBOARD:
|
||||
case WM_SIZECLIPBOARD:
|
||||
/* these contain HICON */
|
||||
case WM_GETICON:
|
||||
case WM_SETICON:
|
||||
case WM_QUERYDRAGICON:
|
||||
case WM_QUERYPARKICON:
|
||||
/* these contain pointers */
|
||||
case WM_DROPOBJECT:
|
||||
case WM_QUERYDROPOBJECT:
|
||||
case WM_DRAGLOOP:
|
||||
case WM_DRAGSELECT:
|
||||
case WM_DRAGMOVE:
|
||||
FIXME( "msg %x (%s) not supported yet\n", message, SPY_GetMsgName(message, hwnd) );
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
return TRUE; /* message doesn't need any unpacking */
|
||||
return TRUE; /* message doesn't need any unpacking */
|
||||
}
|
||||
|
||||
/* default exit for most messages: check minsize and store buffer in lparam */
|
||||
|
@ -2043,10 +1665,11 @@ static BOOL init_window_call_params( struct win_proc_params *params, HWND hwnd,
|
|||
* Call a window procedure and the corresponding hooks.
|
||||
*/
|
||||
static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
|
||||
BOOL unicode, BOOL same_thread, enum wm_char_mapping mapping )
|
||||
BOOL unicode, BOOL same_thread, enum wm_char_mapping mapping,
|
||||
BOOL needs_unpack, void *buffer, size_t size )
|
||||
{
|
||||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
struct win_proc_params params;
|
||||
struct win_proc_params p, *params = &p;
|
||||
LRESULT result = 0;
|
||||
CWPSTRUCT cwp;
|
||||
CWPRETSTRUCT cwpret;
|
||||
|
@ -2054,15 +1677,23 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
|
|||
if (msg & 0x80000000)
|
||||
return handle_internal_message( hwnd, msg, wparam, lparam );
|
||||
|
||||
if (!needs_unpack) size = 0;
|
||||
if (!WIN_IsCurrentThread( hwnd )) return 0;
|
||||
if (!init_window_call_params( ¶ms, hwnd, msg, wparam, lparam, &result, !unicode, mapping ))
|
||||
if (size && !(params = HeapAlloc( GetProcessHeap(), 0, sizeof(*params) + size ))) return 0;
|
||||
if (!init_window_call_params( params, hwnd, msg, wparam, lparam, &result, !unicode, mapping ))
|
||||
{
|
||||
if (params != &p) HeapFree( GetProcessHeap(), 0, params );
|
||||
return 0;
|
||||
}
|
||||
|
||||
params->needs_unpack = needs_unpack;
|
||||
if (size) memcpy( params + 1, buffer, size );
|
||||
|
||||
/* first the WH_CALLWNDPROC hook */
|
||||
cwp.lParam = lparam;
|
||||
cwp.wParam = wparam;
|
||||
cwp.message = msg;
|
||||
cwp.hwnd = params.hwnd;
|
||||
cwp.hwnd = params->hwnd;
|
||||
HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, same_thread, (LPARAM)&cwp, unicode );
|
||||
|
||||
if (thread_info->recursion_count <= MAX_WINPROC_RECURSION)
|
||||
|
@ -2070,17 +1701,19 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
|
|||
thread_info->recursion_count++;
|
||||
|
||||
/* now call the window procedure */
|
||||
User32CallWindowProc( ¶ms, sizeof(params) );
|
||||
User32CallWindowProc( params, sizeof(*params) + size );
|
||||
|
||||
thread_info->recursion_count--;
|
||||
}
|
||||
|
||||
if (params != &p) HeapFree( GetProcessHeap(), 0, params );
|
||||
|
||||
/* and finally the WH_CALLWNDPROCRET hook */
|
||||
cwpret.lResult = result;
|
||||
cwpret.lParam = lparam;
|
||||
cwpret.wParam = wparam;
|
||||
cwpret.message = msg;
|
||||
cwpret.hwnd = params.hwnd;
|
||||
cwpret.hwnd = params->hwnd;
|
||||
HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, same_thread, (LPARAM)&cwpret, unicode );
|
||||
return result;
|
||||
}
|
||||
|
@ -2521,6 +2154,7 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags,
|
|||
NTSTATUS res;
|
||||
size_t size = 0;
|
||||
const message_data_t *msg_data = buffer;
|
||||
BOOL needs_unpack = FALSE;
|
||||
|
||||
thread_info->msg_source = prev_source;
|
||||
|
||||
|
@ -2586,6 +2220,7 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags,
|
|||
if (!unpack_message( info.msg.hwnd, info.msg.message, &info.msg.wParam,
|
||||
&info.msg.lParam, &buffer, size ))
|
||||
continue;
|
||||
needs_unpack = TRUE;
|
||||
break;
|
||||
case MSG_CALLBACK:
|
||||
info.flags = ISMEX_CALLBACK;
|
||||
|
@ -2662,6 +2297,7 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags,
|
|||
reply_message( &info, 0, &info.msg );
|
||||
continue;
|
||||
}
|
||||
needs_unpack = TRUE;
|
||||
break;
|
||||
case MSG_HARDWARE:
|
||||
if (size >= sizeof(msg_data->hardware))
|
||||
|
@ -2724,7 +2360,7 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags,
|
|||
thread_info->msg_source = msg_source_unavailable;
|
||||
result = call_window_proc( info.msg.hwnd, info.msg.message, info.msg.wParam,
|
||||
info.msg.lParam, (info.type != MSG_ASCII), FALSE,
|
||||
WMCHAR_MAP_RECVMESSAGE );
|
||||
WMCHAR_MAP_RECVMESSAGE, needs_unpack, buffer, size );
|
||||
if (thread_info->receive_info == &info )
|
||||
NtUserCallTwoParam( result, (UINT_PTR)&info.msg, NtUserReplyMessage );
|
||||
|
||||
|
@ -3038,7 +2674,7 @@ static BOOL send_message( struct send_message_info *info, DWORD_PTR *res_ptr, BO
|
|||
if (info->dest_tid == GetCurrentThreadId())
|
||||
{
|
||||
result = call_window_proc( info->hwnd, info->msg, info->wparam, info->lparam,
|
||||
unicode, TRUE, info->wm_char );
|
||||
unicode, TRUE, info->wm_char, FALSE, NULL, 0 );
|
||||
if (info->type == MSG_CALLBACK)
|
||||
call_sendmsg_callback( info->callback, info->hwnd, info->msg, info->data, result );
|
||||
ret = TRUE;
|
||||
|
|
|
@ -29,15 +29,32 @@
|
|||
#include "wingdi.h"
|
||||
#include "controls.h"
|
||||
#include "win.h"
|
||||
#include "dbt.h"
|
||||
#include "user_private.h"
|
||||
#include "wine/asm.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DECLARE_DEBUG_CHANNEL(msg);
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msg);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||
|
||||
#define WINPROC_PROC16 ((void *)1) /* placeholder for 16-bit window procs */
|
||||
|
||||
union packed_structs
|
||||
{
|
||||
struct packed_CREATESTRUCTW cs;
|
||||
struct packed_DRAWITEMSTRUCT dis;
|
||||
struct packed_MEASUREITEMSTRUCT mis;
|
||||
struct packed_DELETEITEMSTRUCT dls;
|
||||
struct packed_COMPAREITEMSTRUCT cis;
|
||||
struct packed_WINDOWPOS wp;
|
||||
struct packed_COPYDATASTRUCT cds;
|
||||
struct packed_HELPINFO hi;
|
||||
struct packed_NCCALCSIZE_PARAMS ncp;
|
||||
struct packed_MSG msg;
|
||||
struct packed_MDINEXTMENU mnm;
|
||||
struct packed_MDICREATESTRUCTW mcs;
|
||||
};
|
||||
|
||||
static inline void *get_buffer( void *static_buffer, size_t size, size_t need )
|
||||
{
|
||||
if (size >= need) return static_buffer;
|
||||
|
@ -788,9 +805,474 @@ static void dispatch_win_proc_params( struct win_proc_params *params )
|
|||
SetThreadDpiAwarenessContext( context );
|
||||
}
|
||||
|
||||
/* make sure that there is space for 'size' bytes in buffer, growing it if needed */
|
||||
static inline void *get_buffer_space( void **buffer, size_t size, size_t prev_size )
|
||||
{
|
||||
if (prev_size > size && !(*buffer = HeapAlloc( GetProcessHeap(), 0, size ))) return NULL;
|
||||
return *buffer;
|
||||
}
|
||||
|
||||
/* check whether a combobox expects strings or ids in CB_ADDSTRING/CB_INSERTSTRING */
|
||||
static inline BOOL combobox_has_strings( HWND hwnd )
|
||||
{
|
||||
DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
|
||||
return (!(style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) || (style & CBS_HASSTRINGS));
|
||||
}
|
||||
|
||||
/* check whether a listbox expects strings or ids in LB_ADDSTRING/LB_INSERTSTRING */
|
||||
static inline BOOL listbox_has_strings( HWND hwnd )
|
||||
{
|
||||
DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
|
||||
return (!(style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) || (style & LBS_HASSTRINGS));
|
||||
}
|
||||
|
||||
/* unpack a potentially 64-bit pointer, returning 0 when truncated */
|
||||
static inline void *unpack_ptr( ULONGLONG ptr64 )
|
||||
{
|
||||
if ((ULONG_PTR)ptr64 != ptr64) return 0;
|
||||
return (void *)(ULONG_PTR)ptr64;
|
||||
}
|
||||
|
||||
/* convert a server handle to a generic handle */
|
||||
static inline HANDLE unpack_handle( UINT handle )
|
||||
{
|
||||
return (HANDLE)(INT_PTR)(int)handle;
|
||||
}
|
||||
|
||||
/* make sure that the buffer contains a valid null-terminated Unicode string */
|
||||
static inline BOOL check_string( LPCWSTR str, size_t size )
|
||||
{
|
||||
for (size /= sizeof(WCHAR); size; size--, str++)
|
||||
if (!*str) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* unpack_message
|
||||
*
|
||||
* Unpack a message received from another process.
|
||||
*/
|
||||
static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam,
|
||||
void **buffer, size_t size )
|
||||
{
|
||||
size_t minsize = 0, prev_size = size;
|
||||
union packed_structs *ps = *buffer;
|
||||
|
||||
switch(message)
|
||||
{
|
||||
case WM_NCCREATE:
|
||||
case WM_CREATE:
|
||||
{
|
||||
CREATESTRUCTW cs;
|
||||
WCHAR *str = (WCHAR *)(&ps->cs + 1);
|
||||
if (size < sizeof(ps->cs)) return FALSE;
|
||||
size -= sizeof(ps->cs);
|
||||
cs.lpCreateParams = unpack_ptr( ps->cs.lpCreateParams );
|
||||
cs.hInstance = unpack_ptr( ps->cs.hInstance );
|
||||
cs.hMenu = unpack_handle( ps->cs.hMenu );
|
||||
cs.hwndParent = unpack_handle( ps->cs.hwndParent );
|
||||
cs.cy = ps->cs.cy;
|
||||
cs.cx = ps->cs.cx;
|
||||
cs.y = ps->cs.y;
|
||||
cs.x = ps->cs.x;
|
||||
cs.style = ps->cs.style;
|
||||
cs.dwExStyle = ps->cs.dwExStyle;
|
||||
cs.lpszName = unpack_ptr( ps->cs.lpszName );
|
||||
cs.lpszClass = unpack_ptr( ps->cs.lpszClass );
|
||||
if (ps->cs.lpszName >> 16)
|
||||
{
|
||||
if (!check_string( str, size )) return FALSE;
|
||||
cs.lpszName = str;
|
||||
size -= (lstrlenW(str) + 1) * sizeof(WCHAR);
|
||||
str += lstrlenW(str) + 1;
|
||||
}
|
||||
if (ps->cs.lpszClass >> 16)
|
||||
{
|
||||
if (!check_string( str, size )) return FALSE;
|
||||
cs.lpszClass = str;
|
||||
}
|
||||
memcpy( &ps->cs, &cs, sizeof(cs) );
|
||||
break;
|
||||
}
|
||||
case WM_GETTEXT:
|
||||
case WM_ASKCBFORMATNAME:
|
||||
if (!get_buffer_space( buffer, (*wparam * sizeof(WCHAR)), size )) return FALSE;
|
||||
break;
|
||||
case WM_WININICHANGE:
|
||||
if (!*lparam) return TRUE;
|
||||
/* fall through */
|
||||
case WM_SETTEXT:
|
||||
case WM_DEVMODECHANGE:
|
||||
case CB_DIR:
|
||||
case LB_DIR:
|
||||
case LB_ADDFILE:
|
||||
case EM_REPLACESEL:
|
||||
if (!check_string( *buffer, size )) return FALSE;
|
||||
break;
|
||||
case WM_GETMINMAXINFO:
|
||||
minsize = sizeof(MINMAXINFO);
|
||||
break;
|
||||
case WM_DRAWITEM:
|
||||
{
|
||||
DRAWITEMSTRUCT dis;
|
||||
if (size < sizeof(ps->dis)) return FALSE;
|
||||
dis.CtlType = ps->dis.CtlType;
|
||||
dis.CtlID = ps->dis.CtlID;
|
||||
dis.itemID = ps->dis.itemID;
|
||||
dis.itemAction = ps->dis.itemAction;
|
||||
dis.itemState = ps->dis.itemState;
|
||||
dis.hwndItem = unpack_handle( ps->dis.hwndItem );
|
||||
dis.hDC = unpack_handle( ps->dis.hDC );
|
||||
dis.rcItem = ps->dis.rcItem;
|
||||
dis.itemData = (ULONG_PTR)unpack_ptr( ps->dis.itemData );
|
||||
memcpy( &ps->dis, &dis, sizeof(dis) );
|
||||
break;
|
||||
}
|
||||
case WM_MEASUREITEM:
|
||||
{
|
||||
MEASUREITEMSTRUCT mis;
|
||||
if (size < sizeof(ps->mis)) return FALSE;
|
||||
mis.CtlType = ps->mis.CtlType;
|
||||
mis.CtlID = ps->mis.CtlID;
|
||||
mis.itemID = ps->mis.itemID;
|
||||
mis.itemWidth = ps->mis.itemWidth;
|
||||
mis.itemHeight = ps->mis.itemHeight;
|
||||
mis.itemData = (ULONG_PTR)unpack_ptr( ps->mis.itemData );
|
||||
memcpy( &ps->mis, &mis, sizeof(mis) );
|
||||
break;
|
||||
}
|
||||
case WM_DELETEITEM:
|
||||
{
|
||||
DELETEITEMSTRUCT dls;
|
||||
if (size < sizeof(ps->dls)) return FALSE;
|
||||
dls.CtlType = ps->dls.CtlType;
|
||||
dls.CtlID = ps->dls.CtlID;
|
||||
dls.itemID = ps->dls.itemID;
|
||||
dls.hwndItem = unpack_handle( ps->dls.hwndItem );
|
||||
dls.itemData = (ULONG_PTR)unpack_ptr( ps->dls.itemData );
|
||||
memcpy( &ps->dls, &dls, sizeof(dls) );
|
||||
break;
|
||||
}
|
||||
case WM_COMPAREITEM:
|
||||
{
|
||||
COMPAREITEMSTRUCT cis;
|
||||
if (size < sizeof(ps->cis)) return FALSE;
|
||||
cis.CtlType = ps->cis.CtlType;
|
||||
cis.CtlID = ps->cis.CtlID;
|
||||
cis.hwndItem = unpack_handle( ps->cis.hwndItem );
|
||||
cis.itemID1 = ps->cis.itemID1;
|
||||
cis.itemData1 = (ULONG_PTR)unpack_ptr( ps->cis.itemData1 );
|
||||
cis.itemID2 = ps->cis.itemID2;
|
||||
cis.itemData2 = (ULONG_PTR)unpack_ptr( ps->cis.itemData2 );
|
||||
cis.dwLocaleId = ps->cis.dwLocaleId;
|
||||
memcpy( &ps->cis, &cis, sizeof(cis) );
|
||||
break;
|
||||
}
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
{
|
||||
WINDOWPOS wp;
|
||||
if (size < sizeof(ps->wp)) return FALSE;
|
||||
wp.hwnd = unpack_handle( ps->wp.hwnd );
|
||||
wp.hwndInsertAfter = unpack_handle( ps->wp.hwndInsertAfter );
|
||||
wp.x = ps->wp.x;
|
||||
wp.y = ps->wp.y;
|
||||
wp.cx = ps->wp.cx;
|
||||
wp.cy = ps->wp.cy;
|
||||
wp.flags = ps->wp.flags;
|
||||
memcpy( &ps->wp, &wp, sizeof(wp) );
|
||||
break;
|
||||
}
|
||||
case WM_COPYDATA:
|
||||
{
|
||||
COPYDATASTRUCT cds;
|
||||
if (size < sizeof(ps->cds)) return FALSE;
|
||||
cds.dwData = (ULONG_PTR)unpack_ptr( ps->cds.dwData );
|
||||
if (ps->cds.lpData)
|
||||
{
|
||||
cds.cbData = ps->cds.cbData;
|
||||
cds.lpData = &ps->cds + 1;
|
||||
minsize = sizeof(ps->cds) + cds.cbData;
|
||||
}
|
||||
else
|
||||
{
|
||||
cds.cbData = 0;
|
||||
cds.lpData = 0;
|
||||
}
|
||||
memcpy( &ps->cds, &cds, sizeof(cds) );
|
||||
break;
|
||||
}
|
||||
case WM_NOTIFY:
|
||||
/* WM_NOTIFY cannot be sent across processes (MSDN) */
|
||||
return FALSE;
|
||||
case WM_HELP:
|
||||
{
|
||||
HELPINFO hi;
|
||||
if (size < sizeof(ps->hi)) return FALSE;
|
||||
hi.cbSize = sizeof(hi);
|
||||
hi.iContextType = ps->hi.iContextType;
|
||||
hi.iCtrlId = ps->hi.iCtrlId;
|
||||
hi.hItemHandle = unpack_handle( ps->hi.hItemHandle );
|
||||
hi.dwContextId = (ULONG_PTR)unpack_ptr( ps->hi.dwContextId );
|
||||
hi.MousePos = ps->hi.MousePos;
|
||||
memcpy( &ps->hi, &hi, sizeof(hi) );
|
||||
break;
|
||||
}
|
||||
case WM_STYLECHANGING:
|
||||
case WM_STYLECHANGED:
|
||||
minsize = sizeof(STYLESTRUCT);
|
||||
break;
|
||||
case WM_NCCALCSIZE:
|
||||
if (!*wparam) minsize = sizeof(RECT);
|
||||
else
|
||||
{
|
||||
NCCALCSIZE_PARAMS ncp;
|
||||
WINDOWPOS wp;
|
||||
if (size < sizeof(ps->ncp)) return FALSE;
|
||||
ncp.rgrc[0] = ps->ncp.rgrc[0];
|
||||
ncp.rgrc[1] = ps->ncp.rgrc[1];
|
||||
ncp.rgrc[2] = ps->ncp.rgrc[2];
|
||||
wp.hwnd = unpack_handle( ps->ncp.hwnd );
|
||||
wp.hwndInsertAfter = unpack_handle( ps->ncp.hwndInsertAfter );
|
||||
wp.x = ps->ncp.x;
|
||||
wp.y = ps->ncp.y;
|
||||
wp.cx = ps->ncp.cx;
|
||||
wp.cy = ps->ncp.cy;
|
||||
wp.flags = ps->ncp.flags;
|
||||
ncp.lppos = (WINDOWPOS *)((NCCALCSIZE_PARAMS *)&ps->ncp + 1);
|
||||
memcpy( &ps->ncp, &ncp, sizeof(ncp) );
|
||||
*ncp.lppos = wp;
|
||||
}
|
||||
break;
|
||||
case WM_GETDLGCODE:
|
||||
if (*lparam)
|
||||
{
|
||||
MSG msg;
|
||||
if (size < sizeof(ps->msg)) return FALSE;
|
||||
msg.hwnd = unpack_handle( ps->msg.hwnd );
|
||||
msg.message = ps->msg.message;
|
||||
msg.wParam = (ULONG_PTR)unpack_ptr( ps->msg.wParam );
|
||||
msg.lParam = (ULONG_PTR)unpack_ptr( ps->msg.lParam );
|
||||
msg.time = ps->msg.time;
|
||||
msg.pt = ps->msg.pt;
|
||||
memcpy( &ps->msg, &msg, sizeof(msg) );
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
case SBM_SETSCROLLINFO:
|
||||
minsize = sizeof(SCROLLINFO);
|
||||
break;
|
||||
case SBM_GETSCROLLINFO:
|
||||
if (!get_buffer_space( buffer, sizeof(SCROLLINFO), size )) return FALSE;
|
||||
break;
|
||||
case SBM_GETSCROLLBARINFO:
|
||||
if (!get_buffer_space( buffer, sizeof(SCROLLBARINFO), size )) return FALSE;
|
||||
break;
|
||||
case EM_GETSEL:
|
||||
case SBM_GETRANGE:
|
||||
case CB_GETEDITSEL:
|
||||
if (*wparam || *lparam)
|
||||
{
|
||||
if (!get_buffer_space( buffer, 2*sizeof(DWORD), size )) return FALSE;
|
||||
if (*wparam) *wparam = (WPARAM)*buffer;
|
||||
if (*lparam) *lparam = (LPARAM)((DWORD *)*buffer + 1);
|
||||
}
|
||||
return TRUE;
|
||||
case EM_GETRECT:
|
||||
case LB_GETITEMRECT:
|
||||
case CB_GETDROPPEDCONTROLRECT:
|
||||
if (!get_buffer_space( buffer, sizeof(RECT), size )) return FALSE;
|
||||
break;
|
||||
case EM_SETRECT:
|
||||
case EM_SETRECTNP:
|
||||
minsize = sizeof(RECT);
|
||||
break;
|
||||
case EM_GETLINE:
|
||||
{
|
||||
WORD len;
|
||||
if (size < sizeof(WORD)) return FALSE;
|
||||
len = *(WORD *)*buffer;
|
||||
if (!get_buffer_space( buffer, (len + 1) * sizeof(WCHAR), size )) return FALSE;
|
||||
*lparam = (LPARAM)*buffer + sizeof(WORD); /* don't erase WORD at start of buffer */
|
||||
return TRUE;
|
||||
}
|
||||
case EM_SETTABSTOPS:
|
||||
case LB_SETTABSTOPS:
|
||||
if (!*wparam) return TRUE;
|
||||
minsize = *wparam * sizeof(UINT);
|
||||
break;
|
||||
case CB_ADDSTRING:
|
||||
case CB_INSERTSTRING:
|
||||
case CB_FINDSTRING:
|
||||
case CB_FINDSTRINGEXACT:
|
||||
case CB_SELECTSTRING:
|
||||
case LB_ADDSTRING:
|
||||
case LB_INSERTSTRING:
|
||||
case LB_FINDSTRING:
|
||||
case LB_FINDSTRINGEXACT:
|
||||
case LB_SELECTSTRING:
|
||||
if (!*buffer) return TRUE;
|
||||
if (!check_string( *buffer, size )) return FALSE;
|
||||
break;
|
||||
case CB_GETLBTEXT:
|
||||
{
|
||||
size = sizeof(ULONG_PTR);
|
||||
if (combobox_has_strings( hwnd ))
|
||||
size = (SendMessageW( hwnd, CB_GETLBTEXTLEN, *wparam, 0 ) + 1) * sizeof(WCHAR);
|
||||
if (!get_buffer_space( buffer, size, prev_size )) return FALSE;
|
||||
break;
|
||||
}
|
||||
case LB_GETTEXT:
|
||||
{
|
||||
size = sizeof(ULONG_PTR);
|
||||
if (listbox_has_strings( hwnd ))
|
||||
size = (SendMessageW( hwnd, LB_GETTEXTLEN, *wparam, 0 ) + 1) * sizeof(WCHAR);
|
||||
if (!get_buffer_space( buffer, size, prev_size )) return FALSE;
|
||||
break;
|
||||
}
|
||||
case LB_GETSELITEMS:
|
||||
if (!get_buffer_space( buffer, *wparam * sizeof(UINT), size )) return FALSE;
|
||||
break;
|
||||
case WM_NEXTMENU:
|
||||
{
|
||||
MDINEXTMENU mnm;
|
||||
if (size < sizeof(ps->mnm)) return FALSE;
|
||||
mnm.hmenuIn = unpack_handle( ps->mnm.hmenuIn );
|
||||
mnm.hmenuNext = unpack_handle( ps->mnm.hmenuNext );
|
||||
mnm.hwndNext = unpack_handle( ps->mnm.hwndNext );
|
||||
memcpy( &ps->mnm, &mnm, sizeof(mnm) );
|
||||
break;
|
||||
}
|
||||
case WM_SIZING:
|
||||
case WM_MOVING:
|
||||
minsize = sizeof(RECT);
|
||||
if (!get_buffer_space( buffer, sizeof(RECT), size )) return FALSE;
|
||||
break;
|
||||
case WM_MDICREATE:
|
||||
{
|
||||
MDICREATESTRUCTW mcs;
|
||||
WCHAR *str = (WCHAR *)(&ps->mcs + 1);
|
||||
if (size < sizeof(ps->mcs)) return FALSE;
|
||||
size -= sizeof(ps->mcs);
|
||||
|
||||
mcs.szClass = unpack_ptr( ps->mcs.szClass );
|
||||
mcs.szTitle = unpack_ptr( ps->mcs.szTitle );
|
||||
mcs.hOwner = unpack_ptr( ps->mcs.hOwner );
|
||||
mcs.x = ps->mcs.x;
|
||||
mcs.y = ps->mcs.y;
|
||||
mcs.cx = ps->mcs.cx;
|
||||
mcs.cy = ps->mcs.cy;
|
||||
mcs.style = ps->mcs.style;
|
||||
mcs.lParam = (LPARAM)unpack_ptr( ps->mcs.lParam );
|
||||
if (ps->mcs.szClass >> 16)
|
||||
{
|
||||
if (!check_string( str, size )) return FALSE;
|
||||
mcs.szClass = str;
|
||||
size -= (lstrlenW(str) + 1) * sizeof(WCHAR);
|
||||
str += lstrlenW(str) + 1;
|
||||
}
|
||||
if (ps->mcs.szTitle >> 16)
|
||||
{
|
||||
if (!check_string( str, size )) return FALSE;
|
||||
mcs.szTitle = str;
|
||||
}
|
||||
memcpy( &ps->mcs, &mcs, sizeof(mcs) );
|
||||
break;
|
||||
}
|
||||
case WM_MDIGETACTIVE:
|
||||
if (!*lparam) return TRUE;
|
||||
if (!get_buffer_space( buffer, sizeof(BOOL), size )) return FALSE;
|
||||
break;
|
||||
case WM_DEVICECHANGE:
|
||||
if (!(*wparam & 0x8000)) return TRUE;
|
||||
minsize = sizeof(DEV_BROADCAST_HDR);
|
||||
break;
|
||||
case WM_NCPAINT:
|
||||
if (*wparam <= 1) return TRUE;
|
||||
FIXME( "WM_NCPAINT hdc unpacking not supported\n" );
|
||||
return FALSE;
|
||||
case WM_PAINT:
|
||||
if (!*wparam) return TRUE;
|
||||
/* fall through */
|
||||
|
||||
/* these contain an HFONT */
|
||||
case WM_SETFONT:
|
||||
case WM_GETFONT:
|
||||
/* these contain an HDC */
|
||||
case WM_ERASEBKGND:
|
||||
case WM_ICONERASEBKGND:
|
||||
case WM_CTLCOLORMSGBOX:
|
||||
case WM_CTLCOLOREDIT:
|
||||
case WM_CTLCOLORLISTBOX:
|
||||
case WM_CTLCOLORBTN:
|
||||
case WM_CTLCOLORDLG:
|
||||
case WM_CTLCOLORSCROLLBAR:
|
||||
case WM_CTLCOLORSTATIC:
|
||||
case WM_PRINT:
|
||||
case WM_PRINTCLIENT:
|
||||
/* these contain an HGLOBAL */
|
||||
case WM_PAINTCLIPBOARD:
|
||||
case WM_SIZECLIPBOARD:
|
||||
/* these contain HICON */
|
||||
case WM_GETICON:
|
||||
case WM_SETICON:
|
||||
case WM_QUERYDRAGICON:
|
||||
case WM_QUERYPARKICON:
|
||||
/* these contain pointers */
|
||||
case WM_DROPOBJECT:
|
||||
case WM_QUERYDROPOBJECT:
|
||||
case WM_DRAGLOOP:
|
||||
case WM_DRAGSELECT:
|
||||
case WM_DRAGMOVE:
|
||||
FIXME( "msg %x (%s) not supported yet\n", message, SPY_GetMsgName(message, hwnd) );
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
return TRUE; /* message doesn't need any unpacking */
|
||||
}
|
||||
|
||||
/* default exit for most messages: check minsize and store buffer in lparam */
|
||||
if (size < minsize) return FALSE;
|
||||
*lparam = (LPARAM)*buffer;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size )
|
||||
{
|
||||
dispatch_win_proc_params( params );
|
||||
|
||||
if (params->needs_unpack)
|
||||
{
|
||||
char stack_buffer[128];
|
||||
void *buffer;
|
||||
LRESULT result;
|
||||
MSG msg;
|
||||
|
||||
if (size > sizeof(*params))
|
||||
{
|
||||
size -= sizeof(*params);
|
||||
buffer = params + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = sizeof(stack_buffer);
|
||||
buffer = stack_buffer;
|
||||
}
|
||||
if (!unpack_message( params->hwnd, params->msg, ¶ms->wparam,
|
||||
¶ms->lparam, &buffer, size ))
|
||||
return 0;
|
||||
params->result = &result;
|
||||
|
||||
msg.hwnd = params->hwnd;
|
||||
msg.message = params->msg;
|
||||
msg.wParam = params->wparam;
|
||||
msg.lParam = params->lparam;
|
||||
dispatch_win_proc_params( params );
|
||||
|
||||
NtUserCallTwoParam( result, (UINT_PTR)&msg, NtUserReplyMessage );
|
||||
if (buffer != stack_buffer && buffer != params + 1)
|
||||
HeapFree( GetProcessHeap(), 0, buffer );
|
||||
}
|
||||
else dispatch_win_proc_params( params );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ static BOOL init_win_proc_params( struct win_proc_params *params, HWND hwnd, UIN
|
|||
params->lparam = lparam;
|
||||
params->ansi = params->ansi_dst = ansi;
|
||||
params->is_dialog = FALSE;
|
||||
params->needs_unpack = FALSE;
|
||||
params->mapping = WMCHAR_MAP_CALLWINDOWPROC;
|
||||
params->dpi_awareness = get_window_dpi_awareness_context( params->hwnd );
|
||||
get_winproc_params( params );
|
||||
|
@ -129,6 +130,7 @@ static BOOL init_window_call_params( struct win_proc_params *params, HWND hwnd,
|
|||
params->lparam = lParam;
|
||||
params->result = result;
|
||||
params->ansi = ansi;
|
||||
params->needs_unpack = FALSE;
|
||||
params->mapping = mapping;
|
||||
params->dpi_awareness = get_window_dpi_awareness_context( params->hwnd );
|
||||
return TRUE;
|
||||
|
|
|
@ -89,6 +89,7 @@ struct win_proc_params
|
|||
BOOL ansi;
|
||||
BOOL ansi_dst;
|
||||
BOOL is_dialog;
|
||||
BOOL needs_unpack;
|
||||
enum wm_char_mapping mapping;
|
||||
DPI_AWARENESS_CONTEXT dpi_awareness;
|
||||
WNDPROC procA;
|
||||
|
|
Loading…
Reference in New Issue