Module: wine Branch: master Commit: 69834a3095985f0fdc882ca36f38061347642f4a URL: https://gitlab.winehq.org/wine/wine/-/commit/69834a3095985f0fdc882ca36f38061...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Jul 18 12:24:04 2023 +0200
win32u: Use user message packing for WM_COPYDATA.
---
dlls/user32/winproc.c | 26 ++++++-------------- dlls/win32u/message.c | 33 ++++++++++++++++++++++++++ dlls/win32u/tests/win32u.c | 59 +++++++++++++++++++++++++++++++++++++++++++--- dlls/wow64win/user.c | 14 +++++++++++ 4 files changed, 110 insertions(+), 22 deletions(-)
diff --git a/dlls/user32/winproc.c b/dlls/user32/winproc.c index fb41d444a45..1363aad3340 100644 --- a/dlls/user32/winproc.c +++ b/dlls/user32/winproc.c @@ -831,6 +831,12 @@ BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, ncp->lppos = (WINDOWPOS *)((NCCALCSIZE_PARAMS *)ncp + 1); } break; + case WM_COPYDATA: + { + COPYDATASTRUCT *cds = *buffer; + if (cds->lpData) cds->lpData = cds + 1; + break; + } case WM_GETTEXT: case WM_ASKCBFORMATNAME: case WM_WININICHANGE: @@ -848,25 +854,6 @@ BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, case WM_WINDOWPOSCHANGING: case WM_WINDOWPOSCHANGED: 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; @@ -1126,6 +1113,7 @@ BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size ) case WM_COMPAREITEM: case WM_WINDOWPOSCHANGING: case WM_WINDOWPOSCHANGED: + case WM_COPYDATA: { LRESULT *result_ptr = (LRESULT *)buffer - 1; *result_ptr = result; diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 641fa905af3..5cadaa9e75b 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -504,6 +504,25 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa memcpy( *buffer, &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_WINE_SETWINDOWPOS: { WINDOWPOS wp; @@ -1307,6 +1326,12 @@ size_t user_message_size( UINT message, WPARAM wparam, LPARAM lparam, BOOL other case WM_WINDOWPOSCHANGED: size = sizeof(WINDOWPOS); break; + case WM_COPYDATA: + { + const COPYDATASTRUCT *cds = lparam_ptr; + size = sizeof(*cds) + cds->cbData; + break; + } }
return size; @@ -1358,6 +1383,14 @@ void pack_user_message( void *buffer, size_t size, UINT message, case WM_ASKCBFORMATNAME: if (wparam) memset( buffer, 0, char_size( ansi )); return; + case WM_COPYDATA: + { + const COPYDATASTRUCT *cds = lparam_ptr; + if (cds->lpData && cds->cbData) + memcpy( (char *)buffer + sizeof(*cds), cds->lpData, cds->cbData ); + size = sizeof(*cds); + break; + } }
if (size) memcpy( buffer, lparam_ptr, size ); diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index aaa27361206..501938cd039 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -1386,9 +1386,31 @@ static void check_params( const struct lparam_hook_test *test, UINT message, ok ((LPARAM)&message < lparam && lparam < (LPARAM)NtCurrentTeb()->Tib.StackBase, "lparam is not on the stack\n");
- if (test->check_size) { - const void *expected = is_ret && test->change_lparam ? test->change_lparam : test->lparam; - ok( !memcmp( (const void *)lparam, expected, test->check_size ), "unexpected lparam content\n"); + switch (test->message) + { + case WM_COPYDATA: + { + const COPYDATASTRUCT *cds = (const COPYDATASTRUCT *)lparam; + const COPYDATASTRUCT *cds_in = (const COPYDATASTRUCT *)lparam_buffer; + ok( cds->dwData == cds_in->dwData, "cds->dwData != cds_in->dwData\n"); + ok( cds->cbData == cds_in->cbData, "cds->dwData != cds_in->dwData\n"); + if (cds_in->lpData) + { + ok( cds->lpData != cds_in->lpData, "cds->lpData == cds_in->lpData\n" ); + if (cds->cbData) + ok( !memcmp( cds->lpData, cds_in->lpData, cds->cbData ), "unexpected pvData %s\n", + wine_dbgstr_an( cds->lpData, cds->cbData )); + } + else + ok( !cds->lpData, "cds->lpData = %p\n", cds->lpData ); + } + break; + + default: + if (test->check_size) { + const void *expected = is_ret && test->change_lparam ? test->change_lparam : test->lparam; + ok( !memcmp( (const void *)lparam, expected, test->check_size ), "unexpected lparam content\n" ); + } } }
@@ -1628,6 +1650,12 @@ static void test_wndproc_hook(void) static const COMPAREITEMSTRUCT cis_in = { .itemID1 = 1 }; static const WINDOWPOS winpos_in = { .x = 1, .cy = 2 }; static const WINDOWPOS winpos_out = { .x = 10, .cy = 22 }; + static const COPYDATASTRUCT cds_in = { .dwData = 1 }; + static WORD data_word = 3; + static const COPYDATASTRUCT cds2_in = { .cbData = 2, .lpData = &data_word }; + static const COPYDATASTRUCT cds3_in = { .dwData = 2, .lpData = (void *)0xdeadbeef }; + static const COPYDATASTRUCT cds4_in = { .cbData = 2 }; + static const COPYDATASTRUCT cds5_in = { .lpData = (void *)0xdeadbeef };
static const struct lparam_hook_test lparam_hook_tests[] = { @@ -1742,6 +1770,31 @@ static void test_wndproc_hook(void) .lparam_size = sizeof(WINDOWPOS), .lparam = &winpos_in, .poison_lparam = TRUE, .check_size = sizeof(WINDOWPOS), }, + { + "WM_COPYDATA", WM_COPYDATA, .wparam = 0xdeadbeef, + .lparam_size = sizeof(cds_in), .lparam = &cds_in, .poison_lparam = TRUE, + .check_size = sizeof(cds_in), + }, + { + "WM_COPYDATA-2", WM_COPYDATA, .wparam = 0xdeadbeef, + .lparam_size = sizeof(cds2_in), .lparam = &cds2_in, .poison_lparam = TRUE, + .check_size = sizeof(cds2_in), + }, + { + "WM_COPYDATA-3", WM_COPYDATA, .wparam = 0xdeadbeef, + .lparam_size = sizeof(cds3_in), .lparam = &cds3_in, .poison_lparam = TRUE, + .check_size = sizeof(cds3_in), + }, + { + "WM_COPYDATA-4", WM_COPYDATA, .wparam = 0xdeadbeef, + .lparam_size = sizeof(cds4_in), .lparam = &cds4_in, .poison_lparam = TRUE, + .check_size = sizeof(cds4_in), + }, + { + "WM_COPYDATA-5", WM_COPYDATA, .wparam = 0xdeadbeef, + .lparam_size = sizeof(cds5_in), .lparam = &cds5_in, .poison_lparam = TRUE, + .check_size = sizeof(cds5_in), + }, /* messages that don't change lparam */ { "WM_USER", WM_USER }, { "WM_NOTIFY", WM_NOTIFY }, diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index b2a7a3887cc..429854f1950 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -720,6 +720,20 @@ static size_t packed_message_64to32( UINT message, WPARAM wparam, case WM_WINDOWPOSCHANGED: winpos_64to32( params64, params32 ); return sizeof(WINDOWPOS32); + + case WM_COPYDATA: + { + COPYDATASTRUCT32 cds32; + const COPYDATASTRUCT *cds64 = params64; + + cds32.dwData = cds64->dwData; + cds32.cbData = cds64->cbData; + cds32.lpData = PtrToUlong( cds64->lpData ); + memcpy( params32, &cds32, sizeof(cds32) ); + size -= sizeof(cds32); + if (size) memmove( (char *)params32 + sizeof(cds32), cds64 + 1, size ); + return sizeof(cds32) + size; + } }
memmove( params32, params64, size );