From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/winproc.c | 80 ++++++++------------------------------ dlls/win32u/message.c | 58 +++++++++++++++++++++++++-- dlls/win32u/tests/win32u.c | 6 +++ dlls/wow64win/user.c | 20 ++++++++++ 4 files changed, 98 insertions(+), 66 deletions(-)
diff --git a/dlls/user32/winproc.c b/dlls/user32/winproc.c index 55d0e50b0a5..217b02f70ad 100644 --- a/dlls/user32/winproc.c +++ b/dlls/user32/winproc.c @@ -28,22 +28,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msg); WINE_DECLARE_DEBUG_CHANNEL(relay);
-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; @@ -754,21 +738,6 @@ static inline void *get_buffer_space( void **buffer, size_t size, size_t prev_si return *buffer; }
-/* 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; -} - -/* 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; -} - static size_t string_size( const void *str, BOOL ansi ) { return ansi ? strlen( str ) + 1 : (wcslen( str ) + 1) * sizeof(WCHAR); @@ -783,7 +752,6 @@ BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, void **buffer, size_t size, BOOL ansi ) { size_t minsize = 0; - union packed_structs *ps = *buffer;
switch(message) { @@ -826,6 +794,22 @@ BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, *lparam = (LPARAM)ptr; return TRUE; } + case WM_MDICREATE: + { + MDICREATESTRUCTA *mcs = *buffer; + char *str = (char *)(mcs + 1); + + if (!IS_INTRESOURCE(mcs->szClass)) + { + mcs->szClass = str; + str += string_size( mcs->szClass, ansi ); + } + if (!IS_INTRESOURCE(mcs->szTitle)) + { + mcs->szTitle = str; + } + break; + } case WM_GETTEXT: case WM_ASKCBFORMATNAME: case WM_WININICHANGE: @@ -874,37 +858,6 @@ BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, case WM_SIZING: case WM_MOVING: 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( *buffer, &mcs, sizeof(mcs) ); - break; - } case WM_MDIGETACTIVE: if (!*lparam) return TRUE; if (!get_buffer_space( buffer, sizeof(BOOL), size )) return FALSE; @@ -1047,6 +1000,7 @@ BOOL WINAPI User32CallWindowProc( struct win_proc_params *params, ULONG size ) case WM_NEXTMENU: case WM_SIZING: case WM_MOVING: + case WM_MDICREATE: { LRESULT *result_ptr = (LRESULT *)buffer - 1; *result_ptr = result; diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 47f4af53fc5..6cf507f5bee 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -649,6 +649,35 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa 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) + { + mcs.szClass = str; + size -= (lstrlenW(str) + 1) * sizeof(WCHAR); + str += lstrlenW(str) + 1; + } + if (ps->mcs.szTitle >> 16) + { + mcs.szTitle = str; + } + memcpy( *buffer, &mcs, sizeof(mcs) ); + break; + } case WM_WINE_SETWINDOWPOS: { WINDOWPOS wp; @@ -1496,6 +1525,14 @@ size_t user_message_size( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, case WM_NEXTMENU: size = sizeof(MDINEXTMENU); break; + case WM_MDICREATE: + { + const MDICREATESTRUCTW *mcs = lparam_ptr; + size = sizeof(*mcs); + if (!IS_INTRESOURCE(mcs->szClass)) size += string_size( mcs->szClass, ansi ); + if (!IS_INTRESOURCE(mcs->szTitle)) size += string_size( mcs->szTitle, ansi ); + break; + } }
return size; @@ -1564,6 +1601,24 @@ void pack_user_message( void *buffer, size_t size, UINT message, case EM_GETLINE: size = sizeof(WORD); break; + case WM_MDICREATE: + { + MDICREATESTRUCTW *mcs = buffer; + char *ptr = (char *)(mcs + 1); + + memcpy( buffer, lparam_ptr, sizeof(*mcs) ); + if (!IS_INTRESOURCE(mcs->szClass)) + { + ptr += copy_string( ptr, mcs->szClass, ansi ); + mcs->szClass = inline_ptr; + } + if (!IS_INTRESOURCE(mcs->szTitle)) + { + copy_string( ptr, mcs->szTitle, ansi ); + mcs->szTitle = inline_ptr; + } + return; + } }
if (size) memcpy( buffer, lparam_ptr, size ); @@ -1700,9 +1755,6 @@ static void copy_reply( LRESULT result, HWND hwnd, UINT message, WPARAM wparam, case WM_MDIGETACTIVE: if (lparam) copy_size = sizeof(BOOL); break; - case WM_MDICREATE: - copy_size = sizeof(MDICREATESTRUCTW); - break; default: return; } diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index d31e53405a3..0acea87ac10 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -1684,6 +1684,7 @@ static void test_wndproc_hook(void) static const UINT32 items_out[2] = { 1, 2 }; static const MDINEXTMENU nm_in = { .hmenuIn = (HMENU)0xdeadbeef }; static const MDINEXTMENU nm_out = { .hmenuIn = (HMENU)1 }; + static const MDICREATESTRUCTW mcs_in = { .x = 1, .y = 2 };
static const struct lparam_hook_test lparam_hook_tests[] = { @@ -1908,6 +1909,11 @@ static void test_wndproc_hook(void) .lparam_size = sizeof(nm_in), .lparam = &nm_in, .change_lparam = &nm_out, .check_size = sizeof(nm_in) }, + { + "WM_MDICREATE", WM_MDICREATE, + .lparam_size = sizeof(mcs_in), .lparam = &mcs_in, .poison_lparam = TRUE, + .check_size = sizeof(mcs_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 684c365d0df..6e86056cdb8 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -773,6 +773,26 @@ static size_t packed_message_64to32( UINT message, WPARAM wparam, next32->hwndNext = HandleToLong( next64->hwndNext ); return sizeof(*next32); } + + case WM_MDICREATE: + { + MDICREATESTRUCT32 mcs32; + const MDICREATESTRUCTW *mcs64 = params64; + + mcs32.szClass = PtrToUlong( mcs64->szClass ); + mcs32.szTitle = PtrToUlong( mcs64->szTitle ); + mcs32.hOwner = HandleToLong( mcs64->hOwner ); + mcs32.x = mcs64->x; + mcs32.y = mcs64->y; + mcs32.cx = mcs64->cx; + mcs32.cy = mcs64->cy; + mcs32.style = mcs64->style; + mcs32.lParam = mcs64->lParam; + size -= sizeof(*mcs64); + if (size) memmove( (char *)params32 + sizeof(mcs32), mcs64 + 1, size ); + memcpy( params32, &mcs32, sizeof(mcs32) ); + return sizeof(mcs32) + size; + } }
memmove( params32, params64, size );