Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
v2: added some tests for GetWindowWord(), moved filtering.
dlls/user32/tests/win.c | 230 ++++++++++++++++++++++++++++++++++++++++ dlls/user32/win.c | 31 +++++- 2 files changed, 258 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 3444abaf96..d9a8e85d7b 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -6330,6 +6330,233 @@ static int check_error(DWORD actual, DWORD expected) return (!sets_last_error && (actual == 0xdeadbeef)) || (actual == expected); }
+static void test_set_window_long_size(void) +{ +#ifdef _WIN64 + WNDPROC wnd_proc, wnd_proc_2; + LONG_PTR retval; + HWND hwnd; + LONG ret; + + /* It's not allowed to set or get 64-bit pointer values using 32-bit functions. */ + hwnd = CreateWindowExA(0, "MainWindowClass", "Child window", WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CHILD | + WS_MAXIMIZEBOX | WS_VISIBLE, 100, 100, 200, 200, hwndMain, 0, GetModuleHandleA(NULL), NULL); + ok(hwnd != NULL, "Failed to create test window.\n"); + + /* GWLP_WNDPROC */ + SetLastError(0xdeadbeef); + wnd_proc = (WNDPROC)(LONG_PTR)GetWindowLongA(hwnd, GWLP_WNDPROC); +todo_wine + ok(!wnd_proc && GetLastError() == ERROR_INVALID_INDEX, "Unexpected window proc.\n"); + + wnd_proc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC); + ok(!!wnd_proc, "Unexpected window proc.\n"); + + SetLastError(0xdeadbeef); + wnd_proc_2 = (WNDPROC)(LONG_PTR)SetWindowLongA(hwnd, GWLP_WNDPROC, 0xdeadbeef); + ok(!wnd_proc_2 && GetLastError() == ERROR_INVALID_INDEX, "Unexpected window proc.\n"); + + wnd_proc_2 = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC); + ok(wnd_proc_2 == wnd_proc, "Unexpected window proc.\n"); + + SetLastError(0xdeadbeef); + ret = GetWindowWord(hwnd, GWLP_WNDPROC); + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected return value.\n"); + + /* GWLP_USERDATA */ + SetWindowLongPtrA(hwnd, GWLP_USERDATA, ((LONG_PTR)1 << 32) | 123); + ret = GetWindowLongA(hwnd, GWLP_USERDATA); + ok(ret == 123, "Unexpected user data %#x.\n", ret); + retval = GetWindowLongPtrA(hwnd, GWLP_USERDATA); + ok(retval > 123, "Unexpected user data.\n"); + ret = GetWindowWord(hwnd, GWLP_USERDATA); +todo_wine + ok(ret == 123, "Unexpected user data %#x.\n", ret); + ret = SetWindowWord(hwnd, GWLP_USERDATA, 124); +todo_wine + ok(ret == 123, "Unexpected user data %#x.\n", ret); + ret = GetWindowLongA(hwnd, GWLP_USERDATA); +todo_wine + ok(ret == 124, "Unexpected user data %#x.\n", ret); + retval = GetWindowLongPtrA(hwnd, GWLP_USERDATA); +todo_wine + ok(retval == 124, "Unexpected user data.\n"); + + SetWindowLongA(hwnd, GWLP_USERDATA, (1 << 16) | 123); + ret = GetWindowLongA(hwnd, GWLP_USERDATA); + ok(ret == ((1 << 16) | 123), "Unexpected user data %#x.\n", ret); + ret = GetWindowWord(hwnd, GWLP_USERDATA); +todo_wine + ok(ret == 123, "Unexpected user data %#x.\n", ret); + + ret = SetWindowWord(hwnd, GWLP_USERDATA, 124); +todo_wine + ok(ret == 123, "Unexpected user data %#x.\n", ret); + ret = GetWindowLongA(hwnd, GWLP_USERDATA); +todo_wine + ok(ret == ((1 << 16) | 124), "Unexpected user data %#x.\n", ret); + ret = GetWindowWord(hwnd, GWLP_USERDATA); +todo_wine + ok(ret == 124, "Unexpected user data %#x.\n", ret); + + /* GWLP_ID */ + ret = SetWindowLongA(hwnd, GWLP_ID, 1); + ok(!ret, "Unexpected id %#x.\n", ret); + + ret = GetWindowLongA(hwnd, GWLP_ID); + ok(ret == 1, "Unexpected id %#x.\n", ret); + + ret = GetWindowLongW(hwnd, GWLP_ID); + ok(ret == 1, "Unexpected id %#x.\n", ret); + + SetWindowLongPtrA(hwnd, GWLP_ID, ((LONG_PTR)1 << 32) | 123); + ret = GetWindowLongA(hwnd, GWLP_ID); + ok(ret == 123, "Unexpected id %#x.\n", ret); + ret = GetWindowLongW(hwnd, GWLP_ID); + ok(ret == 123, "Unexpected id %#x.\n", ret); + retval = GetWindowLongPtrA(hwnd, GWLP_ID); + ok(retval > 123, "Unexpected id.\n"); + SetLastError(0xdeadbeef); + ret = GetWindowWord(hwnd, GWLP_ID); +todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected id %#x.\n", ret); + + /* GWLP_HINSTANCE */ + retval = GetWindowLongPtrA(hwnd, GWLP_HINSTANCE); + ok(retval == (LONG_PTR)GetModuleHandleA(NULL), "Unexpected instance %#lx.\n", retval); + + SetLastError(0xdeadbeef); + ret = GetWindowLongA(hwnd, GWLP_HINSTANCE); +todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected instance %#x.\n", ret); + + SetLastError(0xdeadbeef); + ret = GetWindowLongW(hwnd, GWLP_HINSTANCE); +todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected instance %#x.\n", ret); + + SetLastError(0xdeadbeef); + ret = GetWindowWord(hwnd, GWLP_HINSTANCE); +todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected instance %#x.\n", ret); + + SetLastError(0xdeadbeef); + ret = SetWindowLongA(hwnd, GWLP_HINSTANCE, 1); + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected instance %#x.\n", ret); + + SetLastError(0xdeadbeef); + ret = SetWindowLongW(hwnd, GWLP_HINSTANCE, 1); + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected instance %#x.\n", ret); + + /* GWLP_HWNDPARENT */ + SetLastError(0xdeadbeef); + ret = GetWindowLongA(hwnd, GWLP_HWNDPARENT); +todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected parent window %#x.\n", ret); + + SetLastError(0xdeadbeef); + ret = SetWindowLongA(hwnd, GWLP_HWNDPARENT, 0); + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected parent window %#x.\n", ret); + + SetLastError(0xdeadbeef); + ret = SetWindowLongW(hwnd, GWLP_HWNDPARENT, 0); + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected parent window %#x.\n", ret); + + SetLastError(0xdeadbeef); + ret = GetWindowWord(hwnd, GWLP_HWNDPARENT); +todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected parent window %#x.\n", ret); + + DestroyWindow(hwnd); +#endif +} + +static void test_set_window_word_size(void) +{ + WNDPROC wnd_proc, wnd_proc_2; + LONG_PTR retval; + HWND hwnd; + LONG ret; + + /* It's not allowed to set or get 64-bit pointer values using 32-bit functions. */ + hwnd = CreateWindowExA(0, "MainWindowClass", "Child window", WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CHILD | + WS_MAXIMIZEBOX | WS_VISIBLE, 100, 100, 200, 200, hwndMain, 0, GetModuleHandleA(NULL), NULL); + ok(hwnd != NULL, "Failed to create test window.\n"); + + /* GWLP_WNDPROC */ + wnd_proc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC); + ok(!!wnd_proc, "Unexpected window proc.\n"); + + SetLastError(0xdeadbeef); + ret = GetWindowWord(hwnd, GWLP_WNDPROC); + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected window proc.\n"); + + SetLastError(0xdeadbeef); + ret = SetWindowWord(hwnd, GWLP_WNDPROC, 0xbeef); + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected window proc.\n"); + + wnd_proc_2 = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC); + ok(wnd_proc_2 == wnd_proc, "Unexpected window proc.\n"); + + /* GWLP_USERDATA */ + ret = SetWindowLongA(hwnd, GWLP_USERDATA, (1 << 16) | 123); + ok(!ret, "Unexpected user data %#x.\n", ret); + ret = GetWindowLongA(hwnd, GWLP_USERDATA); + ok(ret > 123, "Unexpected user data %#x.\n", ret); + ret = GetWindowWord(hwnd, GWLP_USERDATA); +todo_wine + ok(ret == 123, "Unexpected user data %#x.\n", ret); + ret = SetWindowWord(hwnd, GWLP_USERDATA, 124); +todo_wine + ok(ret == 123, "Unexpected user data %#x.\n", ret); + ret = GetWindowWord(hwnd, GWLP_USERDATA); +todo_wine + ok(ret == 124, "Unexpected user data %#x.\n", ret); + ret = GetWindowLongA(hwnd, GWLP_USERDATA); +todo_wine + ok(ret == ((1 << 16) | 124), "Unexpected user data %#x.\n", ret); + + /* GWLP_ID */ + ret = SetWindowLongA(hwnd, GWLP_ID, 1); + ok(!ret, "Unexpected id %#x.\n", ret); + ret = GetWindowLongA(hwnd, GWLP_ID); + ok(ret == 1, "Unexpected id %#x.\n", ret); + + SetLastError(0xdeadbeef); + ret = GetWindowWord(hwnd, GWLP_ID); +todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected id %#x.\n", ret); + SetLastError(0xdeadbeef); + ret = SetWindowWord(hwnd, GWLP_ID, 2); +todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected id %#x.\n", ret); + + /* GWLP_HINSTANCE */ + retval = GetWindowLongPtrA(hwnd, GWLP_HINSTANCE); + ok(retval == (LONG_PTR)GetModuleHandleA(NULL), "Unexpected instance %#lx.\n", retval); + + SetLastError(0xdeadbeef); + ret = GetWindowWord(hwnd, GWLP_HINSTANCE); +todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected instance %#x.\n", ret); + + SetLastError(0xdeadbeef); + ret = SetWindowWord(hwnd, GWLP_HINSTANCE, 0xdead); +todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected instance %#x.\n", ret); + + /* GWLP_HWNDPARENT */ + retval = GetWindowLongPtrA(hwnd, GWLP_HWNDPARENT); + ok(!!retval, "Unexpected parent window %#x.\n", ret); + + SetLastError(0xdeadbeef); + ret = GetWindowWord(hwnd, GWLP_HWNDPARENT); +todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected parent window %#x.\n", ret); + + DestroyWindow(hwnd); +} + static void test_SetWindowLong(void) { LONG_PTR retval; @@ -6371,6 +6598,9 @@ static void test_SetWindowLong(void) /* set it back to ANSI */ SetWindowLongPtrA(hwndMain, GWLP_WNDPROC, 0); } + + test_set_window_long_size(); + test_set_window_word_size(); }
static LRESULT WINAPI check_style_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 24b2a2ffd5..f5ac867d2b 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -2734,7 +2734,19 @@ WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval ) */ LONG WINAPI DECLSPEC_HOTPATCH SetWindowLongA( HWND hwnd, INT offset, LONG newval ) { - return WIN_SetWindowLong( hwnd, offset, sizeof(LONG), newval, FALSE ); + switch (offset) + { +#ifdef _WIN64 + case GWLP_WNDPROC: + case GWLP_HINSTANCE: + case GWLP_HWNDPARENT: + WARN( "Invalid offset %d\n", offset ); + SetLastError( ERROR_INVALID_INDEX ); + return 0; +#endif + default: + return WIN_SetWindowLong( hwnd, offset, sizeof(LONG), newval, FALSE ); + } }
@@ -2808,8 +2820,21 @@ LONG WINAPI DECLSPEC_HOTPATCH SetWindowLongW( HWND hwnd, /* [in] window to alter */ INT offset, /* [in] offset, in bytes, of location to alter */ LONG newval /* [in] new value of location */ -) { - return WIN_SetWindowLong( hwnd, offset, sizeof(LONG), newval, TRUE ); +) +{ + switch (offset) + { +#ifdef _WIN64 + case GWLP_WNDPROC: + case GWLP_HINSTANCE: + case GWLP_HWNDPARENT: + WARN("Invalid offset %d\n", offset ); + SetLastError( ERROR_INVALID_INDEX ); + return 0; +#endif + default: + return WIN_SetWindowLong( hwnd, offset, sizeof(LONG), newval, TRUE ); + } }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/user32/tests/win.c | 4 ---- dlls/user32/win.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index d9a8e85d7b..639eef4c42 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -6346,7 +6346,6 @@ static void test_set_window_long_size(void) /* GWLP_WNDPROC */ SetLastError(0xdeadbeef); wnd_proc = (WNDPROC)(LONG_PTR)GetWindowLongA(hwnd, GWLP_WNDPROC); -todo_wine ok(!wnd_proc && GetLastError() == ERROR_INVALID_INDEX, "Unexpected window proc.\n");
wnd_proc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC); @@ -6427,12 +6426,10 @@ todo_wine
SetLastError(0xdeadbeef); ret = GetWindowLongA(hwnd, GWLP_HINSTANCE); -todo_wine ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected instance %#x.\n", ret);
SetLastError(0xdeadbeef); ret = GetWindowLongW(hwnd, GWLP_HINSTANCE); -todo_wine ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected instance %#x.\n", ret);
SetLastError(0xdeadbeef); @@ -6451,7 +6448,6 @@ todo_wine /* GWLP_HWNDPARENT */ SetLastError(0xdeadbeef); ret = GetWindowLongA(hwnd, GWLP_HWNDPARENT); -todo_wine ok(!ret && GetLastError() == ERROR_INVALID_INDEX, "Unexpected parent window %#x.\n", ret);
SetLastError(0xdeadbeef); diff --git a/dlls/user32/win.c b/dlls/user32/win.c index f5ac867d2b..0bb9fd9cba 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -2690,7 +2690,19 @@ WORD WINAPI GetWindowWord( HWND hwnd, INT offset ) */ LONG WINAPI GetWindowLongA( HWND hwnd, INT offset ) { - return WIN_GetWindowLong( hwnd, offset, sizeof(LONG), FALSE ); + switch (offset) + { +#ifdef _WIN64 + case GWLP_WNDPROC: + case GWLP_HINSTANCE: + case GWLP_HWNDPARENT: + WARN( "Invalid offset %d\n", offset ); + SetLastError( ERROR_INVALID_INDEX ); + return 0; +#endif + default: + return WIN_GetWindowLong( hwnd, offset, sizeof(LONG), FALSE ); + } }
@@ -2699,7 +2711,19 @@ LONG WINAPI GetWindowLongA( HWND hwnd, INT offset ) */ LONG WINAPI GetWindowLongW( HWND hwnd, INT offset ) { - return WIN_GetWindowLong( hwnd, offset, sizeof(LONG), TRUE ); + switch (offset) + { +#ifdef _WIN64 + case GWLP_WNDPROC: + case GWLP_HINSTANCE: + case GWLP_HWNDPARENT: + WARN( "Invalid offset %d\n", offset ); + SetLastError( ERROR_INVALID_INDEX ); + return 0; +#endif + default: + return WIN_GetWindowLong( hwnd, offset, sizeof(LONG), TRUE ); + } }
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=48457
Your paranoid android.
=== debian9 (64 bit WoW report) ===
user32: clipboard.c:1630: Test failed: gle 5 clipboard.c:1632: Test failed: expected moveable mem (nil) clipboard.c:1637: Test failed: expected moveable mem (nil) clipboard.c:1642: Test failed: expected moveable mem (nil) clipboard.c:1648: Test failed: expected moveable mem (nil) clipboard.c:1654: Test failed: expected bitmap (nil) clipboard.c:1655: Test failed: different bitmap (nil) / 0x5e003f clipboard.c:1658: Test failed: expected bitmap (nil) clipboard.c:1659: Test failed: different bitmap (nil) / 0xb0045 clipboard.c:1662: Test failed: expected palette (nil) clipboard.c:1663: Test failed: different palette (nil) / 0xc0041 clipboard.c:1666: Test failed: expected fixed mem (nil) clipboard.c:1668: Test failed: expected fixed mem (nil) clipboard.c:1670: Test failed: gle 1418