diff --git a/debian/changelog b/debian/changelog index dc3d8239..64d63319 100644 --- a/debian/changelog +++ b/debian/changelog @@ -20,6 +20,7 @@ wine-compholio (1.7.31) UNRELEASED; urgency=low * Added patch to implement emulation of SIDT instruction when using Exagear. * Added patch to return more context attributes in schan_InitializeSecurityContextW. * Added patch to avoid crashing when broken app tries to release surface although refcount is zero. + * Added patch to avoid sending window messages in FindWindowExW. * Removed patch for iphlpapi stub functions (accepted upstream). * Removed patches for FindFirstFileExW (accepted upstream). * Removed patches for TLB dependencies lookup in resources (accepted upstream). diff --git a/patches/Makefile b/patches/Makefile index 15ecccec..06d003f3 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -97,6 +97,7 @@ PATCHLIST := \ shlwapi-PathIsDirectoryEmptyW.ok \ shlwapi-UrlCombine.ok \ user32-Dialog_Paint_Event.ok \ + user32-FindWindowEx.ok \ user32-GetSystemMetrics.ok \ user32-GetTipText.ok \ user32-WndProc.ok \ @@ -1665,6 +1666,23 @@ user32-Dialog_Paint_Event.ok: echo '+ { "user32-Dialog_Paint_Event", "Sebastian Lackner", "Call UpdateWindow during DIALOG_CreateIndirect." },'; \ ) > user32-Dialog_Paint_Event.ok +# Patchset user32-FindWindowEx +# | +# | Included patches: +# | * Avoid sending window messages in FindWindowExW. [by Sebastian Lackner] +# | +# | Modified files: +# | * dlls/user32/tests/win.c, dlls/user32/win.c +# | +.INTERMEDIATE: user32-FindWindowEx.ok +user32-FindWindowEx.ok: + $(call APPLY_FILE,user32-FindWindowEx/0001-user32-tests-Add-tests-to-demonstrate-FindWindow-doe.patch) + $(call APPLY_FILE,user32-FindWindowEx/0002-user32-tests-Add-tests-for-Set-Get-WindowTextA-with-.patch) + $(call APPLY_FILE,user32-FindWindowEx/0003-user32-Avoid-sending-window-messages-in-FindWindowEx.patch) + @( \ + echo '+ { "user32-FindWindowEx", "Sebastian Lackner", "Avoid sending window messages in FindWindowExW." },'; \ + ) > user32-FindWindowEx.ok + # Patchset user32-GetSystemMetrics # | # | Included patches: diff --git a/patches/user32-FindWindowEx/0001-user32-tests-Add-tests-to-demonstrate-FindWindow-doe.patch b/patches/user32-FindWindowEx/0001-user32-tests-Add-tests-to-demonstrate-FindWindow-doe.patch new file mode 100644 index 00000000..594a49e4 --- /dev/null +++ b/patches/user32-FindWindowEx/0001-user32-tests-Add-tests-to-demonstrate-FindWindow-doe.patch @@ -0,0 +1,89 @@ +From 21d6dc1c9941332c1336346d6e48f5d8daf40321 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Wed, 12 Nov 2014 04:05:49 +0100 +Subject: user32/tests: Add tests to demonstrate FindWindow doesn't send + WM_GETTEXT messages. + +--- + dlls/user32/tests/win.c | 31 +++++++++++++++++++++++++------ + 1 file changed, 25 insertions(+), 6 deletions(-) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index cfc2a02..9b805af 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -63,6 +63,7 @@ static DWORD (WINAPI *pGetLayout)(HDC hdc); + static BOOL (WINAPI *pMirrorRgn)(HWND hwnd, HRGN hrgn); + + static BOOL test_lbuttondown_flag; ++static DWORD num_gettext_msgs; + static HWND hwndMessage; + static HWND hwndMain, hwndMain2; + static HHOOK hhook; +@@ -794,6 +795,9 @@ static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPAR + flush_events( FALSE ); + } + break; ++ case WM_GETTEXT: ++ num_gettext_msgs++; ++ break; + } + + return DefWindowProcA(hwnd, msg, wparam, lparam); +@@ -6931,32 +6935,47 @@ todo_wine + static void test_FindWindowEx(void) + { + HWND hwnd, found; +- CHAR title[1]; + + hwnd = CreateWindowExA( 0, "MainWindowClass", "caption", WS_POPUP, 0,0,0,0, 0, 0, 0, NULL ); + ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() ); + +- title[0] = 0; +- +- found = FindWindowExA( 0, 0, "MainWindowClass", title ); ++ num_gettext_msgs = 0; ++ found = FindWindowExA( 0, 0, "MainWindowClass", "" ); + ok( found == NULL, "expected a NULL hwnd\n" ); ++ todo_wine ++ ok( num_gettext_msgs == 0, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); ++ ++ num_gettext_msgs = 0; + found = FindWindowExA( 0, 0, "MainWindowClass", NULL ); + ok( found == hwnd, "found is %p, expected a valid hwnd\n", found ); ++ ok( num_gettext_msgs == 0, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); ++ ++ num_gettext_msgs = 0; ++ found = FindWindowExA( 0, 0, "MainWindowClass", "caption" ); ++ ok( found == hwnd, "found is %p, expected a valid hwnd\n", found ); ++ todo_wine ++ ok( num_gettext_msgs == 0, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); + + DestroyWindow( hwnd ); + + hwnd = CreateWindowExA( 0, "MainWindowClass", NULL, WS_POPUP, 0,0,0,0, 0, 0, 0, NULL ); + ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() ); + +- found = FindWindowExA( 0, 0, "MainWindowClass", title ); ++ num_gettext_msgs = 0; ++ found = FindWindowExA( 0, 0, "MainWindowClass", "" ); + ok( found == hwnd, "found is %p, expected a valid hwnd\n", found ); ++ todo_wine ++ ok( num_gettext_msgs == 0, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); ++ ++ num_gettext_msgs = 0; + found = FindWindowExA( 0, 0, "MainWindowClass", NULL ); + ok( found == hwnd, "found is %p, expected a valid hwnd\n", found ); ++ ok( num_gettext_msgs == 0, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); + + DestroyWindow( hwnd ); + + /* test behaviour with a window title that is an empty character */ +- found = FindWindowExA( 0, 0, "Shell_TrayWnd", title ); ++ found = FindWindowExA( 0, 0, "Shell_TrayWnd", "" ); + ok( found != NULL, "found is NULL, expected a valid hwnd\n" ); + found = FindWindowExA( 0, 0, "Shell_TrayWnd", NULL ); + ok( found != NULL, "found is NULL, expected a valid hwnd\n" ); +-- +2.1.3 + diff --git a/patches/user32-FindWindowEx/0002-user32-tests-Add-tests-for-Set-Get-WindowTextA-with-.patch b/patches/user32-FindWindowEx/0002-user32-tests-Add-tests-for-Set-Get-WindowTextA-with-.patch new file mode 100644 index 00000000..5fe9c441 --- /dev/null +++ b/patches/user32-FindWindowEx/0002-user32-tests-Add-tests-for-Set-Get-WindowTextA-with-.patch @@ -0,0 +1,196 @@ +From 24c8699299d49aaa034e9e423eefce1f982e2d5b Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Wed, 12 Nov 2014 07:34:11 +0100 +Subject: user32/tests: Add tests for [Set|Get]WindowTextA with multiple + threads. + +--- + dlls/user32/tests/win.c | 134 ++++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 123 insertions(+), 11 deletions(-) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index 9b805af..c1a6130 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -64,6 +64,7 @@ static BOOL (WINAPI *pMirrorRgn)(HWND hwnd, HRGN hrgn); + + static BOOL test_lbuttondown_flag; + static DWORD num_gettext_msgs; ++static DWORD num_settext_msgs; + static HWND hwndMessage; + static HWND hwndMain, hwndMain2; + static HHOOK hhook; +@@ -798,6 +799,9 @@ static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPAR + case WM_GETTEXT: + num_gettext_msgs++; + break; ++ case WM_SETTEXT: ++ num_settext_msgs++; ++ break; + } + + return DefWindowProcA(hwnd, msg, wparam, lparam); +@@ -5689,23 +5693,131 @@ static void test_ShowWindow(void) + ok(!IsWindow(hwnd), "window should not exist\n"); + } + ++static DWORD CALLBACK gettext_msg_thread( LPVOID arg ) ++{ ++ HWND hwnd = arg; ++ char buf[32]; ++ LRESULT r; ++ ++ /* test GetWindowTextA */ ++ num_gettext_msgs = 0; ++ memset( buf, 0, sizeof(buf) ); ++ r = GetWindowTextA( hwnd, buf, sizeof(buf) ); ++ ok( r != 0, "expected a nonempty window text\n" ); ++ ok( !strcmp(buf, "caption"), "got wrong window text '%s'\n", buf ); ++ ok( num_gettext_msgs == 1, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); ++ ++ return 0; ++} ++ ++static DWORD CALLBACK settext_msg_thread( LPVOID arg ) ++{ ++ HWND hwnd = arg; ++ BOOL ret; ++ ++ /* test SetWindowTextA */ ++ num_settext_msgs = 0; ++ ret = SetWindowTextA( hwnd, "new_caption" ); ++ ok( ret != 0, "SetWindowTextA failed\n" ); ++ ok( num_settext_msgs == 1, "got %d WM_SETTEXT messages\n", num_settext_msgs ); ++ ++ return 0; ++} ++ + static void test_gettext(void) + { +- WNDCLASSA cls; +- LPCSTR clsname = "gettexttest"; ++ DWORD tid, num_msgs; ++ HANDLE thread; ++ char buf[32]; + HWND hwnd; + LRESULT r; ++ BOOL ret; ++ MSG msg; + +- memset( &cls, 0, sizeof cls ); +- cls.lpfnWndProc = DefWindowProcA; +- cls.lpszClassName = clsname; +- cls.hInstance = GetModuleHandleA(NULL); ++ hwnd = CreateWindowExA( 0, "MainWindowClass", "caption", WS_POPUP, 0, 0, 0, 0, 0, 0, 0, NULL ); ++ ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() ); ++ ++ /* test GetWindowTextA */ ++ num_gettext_msgs = 0; ++ memset( buf, 0, sizeof(buf) ); ++ r = GetWindowTextA( hwnd, buf, sizeof(buf) ); ++ ok( r != 0, "expected a nonempty window text\n" ); ++ ok( !strcmp(buf, "caption"), "got wrong window text '%s'\n", buf ); ++ ok( num_gettext_msgs == 1, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); + +- if (!RegisterClassA( &cls )) return; ++ /* test WM_GETTEXT */ ++ num_gettext_msgs = 0; ++ memset( buf, 0, sizeof(buf) ); ++ r = SendMessageA( hwnd, WM_GETTEXT, sizeof(buf), (LONG_PTR)buf ); ++ ok( r != 0, "expected a nonempty window text\n" ); ++ ok( !strcmp(buf, "caption"), "got wrong window text '%s'\n", buf ); ++ ok( num_gettext_msgs == 1, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); ++ ++ /* test SetWindowTextA */ ++ num_settext_msgs = 0; ++ ret = SetWindowTextA( hwnd, "new_caption" ); ++ ok( ret != 0, "SetWindowTextA failed\n" ); ++ ok( num_settext_msgs == 1, "got %d WM_SETTEXT messages\n", num_settext_msgs ); + +- hwnd = CreateWindowA( clsname, "test text", WS_OVERLAPPED, 0, 0, 10, 10, 0, NULL, NULL, NULL); +- ok( hwnd != NULL, "window was null\n"); ++ num_gettext_msgs = 0; ++ memset( buf, 0, sizeof(buf) ); ++ r = GetWindowTextA( hwnd, buf, sizeof(buf) ); ++ ok( r != 0, "expected a nonempty window text\n" ); ++ ok( !strcmp(buf, "new_caption"), "got wrong window text '%s'\n", buf ); ++ ok( num_gettext_msgs == 1, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); ++ ++ /* test WM_SETTEXT */ ++ num_settext_msgs = 0; ++ r = SendMessageA( hwnd, WM_SETTEXT, 0, (ULONG_PTR)"caption" ); ++ ok( r != 0, "WM_SETTEXT failed\n" ); ++ ok( num_settext_msgs == 1, "got %d WM_SETTEXT messages\n", num_settext_msgs ); + ++ num_gettext_msgs = 0; ++ memset( buf, 0, sizeof(buf) ); ++ r = GetWindowTextA( hwnd, buf, sizeof(buf) ); ++ ok( r != 0, "expected a nonempty window text\n" ); ++ ok( !strcmp(buf, "caption"), "got wrong window text '%s'\n", buf ); ++ ok( num_gettext_msgs == 1, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); ++ ++ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE )) ++ DispatchMessageA( &msg ); ++ ++ /* test interthread GetWindowTextA */ ++ num_msgs = 0; ++ thread = CreateThread( NULL, 0, gettext_msg_thread, hwnd, 0, &tid ); ++ ok(thread != NULL, "CreateThread failed, error %d\n", GetLastError()); ++ while (MsgWaitForMultipleObjects( 1, &thread, FALSE, INFINITE, QS_SENDMESSAGE ) != WAIT_OBJECT_0) ++ { ++ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE )) ++ DispatchMessageA( &msg ); ++ num_msgs++; ++ } ++ CloseHandle( thread ); ++ ok( num_msgs == 1, "got %d wakeups from MsgWaitForMultipleObjects\n", num_msgs ); ++ ++ /* test interthread SetWindowText */ ++ num_msgs = 0; ++ thread = CreateThread( NULL, 0, settext_msg_thread, hwnd, 0, &tid ); ++ ok(thread != NULL, "CreateThread failed, error %d\n", GetLastError()); ++ while (MsgWaitForMultipleObjects( 1, &thread, FALSE, INFINITE, QS_SENDMESSAGE ) != WAIT_OBJECT_0) ++ { ++ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE )) ++ DispatchMessageA( &msg ); ++ num_msgs++; ++ } ++ CloseHandle( thread ); ++ ok( num_msgs == 1, "got %d wakeups from MsgWaitForMultipleObjects\n", num_msgs ); ++ ++ num_gettext_msgs = 0; ++ memset( buf, 0, sizeof(buf) ); ++ r = GetWindowTextA( hwnd, buf, sizeof(buf) ); ++ ok( r != 0, "expected a nonempty window text\n" ); ++ ok( !strcmp(buf, "new_caption"), "got wrong window text '%s'\n", buf ); ++ ok( num_gettext_msgs == 1, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); ++ ++ /* seems to crash on every Windows version? */ ++ if (0) ++ { + r = SendMessageA( hwnd, WM_GETTEXT, 0x10, 0x1000); + ok( r == 0, "settext should return zero\n"); + +@@ -5717,9 +5829,9 @@ static void test_gettext(void) + + r = SendMessageA( hwnd, WM_GETTEXT, 0x1000, 0xff000000); + ok( r == 0, "settext should return zero (%ld)\n", r); ++ } + + DestroyWindow(hwnd); +- UnregisterClassA( clsname, NULL ); + } + + +@@ -7987,7 +8099,7 @@ START_TEST(win) + test_csparentdc(); + test_SetWindowLong(); + test_ShowWindow(); +- if (0) test_gettext(); /* crashes on NT4 */ ++ test_gettext(); + test_GetUpdateRect(); + test_Expose(); + test_layered_window(); +-- +2.1.3 + diff --git a/patches/user32-FindWindowEx/0003-user32-Avoid-sending-window-messages-in-FindWindowEx.patch b/patches/user32-FindWindowEx/0003-user32-Avoid-sending-window-messages-in-FindWindowEx.patch new file mode 100644 index 00000000..fb39919a --- /dev/null +++ b/patches/user32-FindWindowEx/0003-user32-Avoid-sending-window-messages-in-FindWindowEx.patch @@ -0,0 +1,54 @@ +From 5848b744b5510da0101458f91b4a5ec1593dfadb Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Wed, 12 Nov 2014 07:43:13 +0100 +Subject: user32: Avoid sending window messages in FindWindowExW. + +--- + dlls/user32/tests/win.c | 3 --- + dlls/user32/win.c | 2 +- + 2 files changed, 1 insertion(+), 4 deletions(-) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index c1a6130..d7ba329 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -7054,7 +7054,6 @@ static void test_FindWindowEx(void) + num_gettext_msgs = 0; + found = FindWindowExA( 0, 0, "MainWindowClass", "" ); + ok( found == NULL, "expected a NULL hwnd\n" ); +- todo_wine + ok( num_gettext_msgs == 0, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); + + num_gettext_msgs = 0; +@@ -7065,7 +7064,6 @@ static void test_FindWindowEx(void) + num_gettext_msgs = 0; + found = FindWindowExA( 0, 0, "MainWindowClass", "caption" ); + ok( found == hwnd, "found is %p, expected a valid hwnd\n", found ); +- todo_wine + ok( num_gettext_msgs == 0, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); + + DestroyWindow( hwnd ); +@@ -7076,7 +7074,6 @@ static void test_FindWindowEx(void) + num_gettext_msgs = 0; + found = FindWindowExA( 0, 0, "MainWindowClass", "" ); + ok( found == hwnd, "found is %p, expected a valid hwnd\n", found ); +- todo_wine + ok( num_gettext_msgs == 0, "got %d WM_GETTEXT messages\n", num_gettext_msgs ); + + num_gettext_msgs = 0; +diff --git a/dlls/user32/win.c b/dlls/user32/win.c +index 73cad0c..0516193 100644 +--- a/dlls/user32/win.c ++++ b/dlls/user32/win.c +@@ -1941,7 +1941,7 @@ HWND WINAPI FindWindowExW( HWND parent, HWND child, LPCWSTR className, LPCWSTR t + { + while (list[i]) + { +- if (GetWindowTextW( list[i], buffer, len + 1 )) ++ if (InternalGetWindowText( list[i], buffer, len + 1 )) + { + if (!strcmpiW( buffer, title )) break; + } +-- +2.1.3 + diff --git a/patches/user32-FindWindowEx/definition b/patches/user32-FindWindowEx/definition new file mode 100644 index 00000000..5533cef1 --- /dev/null +++ b/patches/user32-FindWindowEx/definition @@ -0,0 +1,3 @@ +Author: Sebastian Lackner +Subject: Avoid sending window messages in FindWindowExW. +Revision: 1