Based on a patch by Paul Gofman.
v2 - Changed title - Removed CoCreateInstance calls.
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/user32/tests/Makefile.in | 2 +- dlls/user32/tests/win.c | 156 ++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in index dd101d69f3c..73f692b9d4b 100644 --- a/dlls/user32/tests/Makefile.in +++ b/dlls/user32/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = user32.dll -IMPORTS = user32 gdi32 advapi32 hid +IMPORTS = user32 gdi32 advapi32 hid ole32 imm32
C_SRCS = \ broadcast.c \ diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 47864340e39..08f413c88e6 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -31,6 +31,8 @@ #include "wingdi.h" #include "winuser.h" #include "winreg.h" +#include "objbase.h" +#include "imm.h"
#include "wine/test.h"
@@ -11894,6 +11896,158 @@ static void test_cancel_mode(void) DestroyWindow(hwnd2); }
+static LRESULT CALLBACK TestWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return DefWindowProcA(hwnd, uMsg, wParam, lParam); +} + +static DWORD WINAPI window_create_noime_thread(LPVOID data) +{ + APTTYPEQUALIFIER apttypequal; + APTTYPE apttype; + HWND hwnd; + HRESULT hr; + + /* Show that Disabling IME stops the implicit MTA creation. */ + ImmDisableIME(GetCurrentThreadId()); + + hwnd = CreateWindowExA(0, "Test class", "Test window", WS_VISIBLE, 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + DestroyWindow(hwnd); + + return 0; +} + +static DWORD WINAPI window_create_setwindowpos_thread(LPVOID data) +{ + APTTYPEQUALIFIER apttypequal; + APTTYPE apttype; + HWND hwnd; + HRESULT hr; + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + hwnd = CreateWindowExA(0, "Test class", "Test window", WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU | WS_MINIMIZEBOX, 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + /* Showing the window actually causes the implicit MTA */ + SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); + + hr = CoGetApartmentType(&apttype, &apttypequal); + todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + todo_wine ok(apttype == APTTYPE_MAINSTA && apttypequal == APTTYPEQUALIFIER_NONE, "Unexpected %u/%u\n", apttype, apttypequal); + + hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(apttype == APTTYPE_MTA && apttypequal == APTTYPEQUALIFIER_NONE, "Unexpected %u/%u\n", apttype, apttypequal); + CoUninitialize(); + + DestroyWindow(hwnd); + + return 0; +} + +static DWORD WINAPI window_create_show_window_thread(LPVOID data) +{ + APTTYPEQUALIFIER apttypequal; + APTTYPE apttype; + HWND hwnd; + HRESULT hr; + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + hwnd = CreateWindowExA(0, "Test class", "Test window", WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU | WS_MINIMIZEBOX, 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + /* Showing the window actually causes the implicit MTA */ + ShowWindow(hwnd, SW_SHOW); + + hr = CoGetApartmentType(&apttype, &apttypequal); + todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + todo_wine ok(apttype == APTTYPE_MAINSTA && apttypequal == APTTYPEQUALIFIER_NONE, "Unexpected %u/%u\n", apttype, apttypequal); + + DestroyWindow(hwnd); + + return 0; +} + +static DWORD WINAPI window_create_visible_thread(LPVOID data) +{ + APTTYPEQUALIFIER apttypequal; + APTTYPE apttype; + HWND hwnd; + HRESULT hr; + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + hwnd = CreateWindowExA(0, "Test class", "Test window", WS_VISIBLE, 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); + + hr = CoGetApartmentType(&apttype, &apttypequal); + todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + todo_wine ok(apttype == APTTYPE_MAINSTA && apttypequal == APTTYPEQUALIFIER_NONE, "Unexpected %u/%u\n", apttype, apttypequal); + + DestroyWindow(hwnd); + + return 0; +} + +static void test_implicit_mta(void) +{ + APTTYPEQUALIFIER apttypequal; + APTTYPE apttype; + WNDCLASSA clsA; + HRESULT hr; + HANDLE thread; + + clsA.style = 0; + clsA.lpfnWndProc = TestWindowProc; + clsA.cbClsExtra = 0; + clsA.cbWndExtra = 0; + clsA.hInstance = GetModuleHandleA(NULL); + clsA.hIcon = 0; + clsA.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW); + clsA.hbrBackground = GetStockObject(WHITE_BRUSH); + clsA.lpszMenuName = NULL; + clsA.lpszClassName = "Test class"; + + RegisterClassA(&clsA); + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + thread = CreateThread(NULL, 0, window_create_noime_thread, NULL, 0, NULL); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); + + thread = CreateThread(NULL, 0, window_create_setwindowpos_thread, NULL, 0, NULL); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); + + thread = CreateThread(NULL, 0, window_create_show_window_thread, NULL, 0, NULL); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); + + thread = CreateThread(NULL, 0, window_create_visible_thread, NULL, 0, NULL); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); +} + START_TEST(win) { char **argv; @@ -11941,6 +12095,8 @@ START_TEST(win) return; }
+ test_implicit_mta(); + if (!RegisterWindowClasses()) assert(0);
hwndMain = CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window",
Hi,
While running your changed tests, 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=84195
Your paranoid android.
=== w2008s64 (32 bit report) ===
user32: win: Timeout
=== wvistau64 (64 bit report) ===
user32: win: Timeout
=== w2008s64 (64 bit report) ===
user32: win: Timeout
=== w10pro64_he (64 bit report) ===
user32: win.c:2271: Test failed: expected !100 win.c:2271: Test failed: expected !100
On 1/19/21 4:34 AM, Alistair Leslie-Hughes wrote:
Based on a patch by Paul Gofman.
v2 - Changed title
- Removed CoCreateInstance calls.
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com
dlls/user32/tests/Makefile.in | 2 +- dlls/user32/tests/win.c | 156 ++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 1 deletion(-)
I'm not really sure this subject is an improvement.
For whatever it's worth, I recall that Nikolay wrote a patch for this bug two years ago:
https://www.winehq.org/pipermail/wine-devel/2019-January/138404.html
diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in index dd101d69f3c..73f692b9d4b 100644 --- a/dlls/user32/tests/Makefile.in +++ b/dlls/user32/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = user32.dll -IMPORTS = user32 gdi32 advapi32 hid +IMPORTS = user32 gdi32 advapi32 hid ole32 imm32
C_SRCS = \ broadcast.c \ diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 47864340e39..08f413c88e6 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -31,6 +31,8 @@ #include "wingdi.h" #include "winuser.h" #include "winreg.h" +#include "objbase.h" +#include "imm.h"
#include "wine/test.h"
@@ -11894,6 +11896,158 @@ static void test_cancel_mode(void) DestroyWindow(hwnd2); }
+static LRESULT CALLBACK TestWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{
- return DefWindowProcA(hwnd, uMsg, wParam, lParam);
+}
+static DWORD WINAPI window_create_noime_thread(LPVOID data) +{
- APTTYPEQUALIFIER apttypequal;
- APTTYPE apttype;
- HWND hwnd;
- HRESULT hr;
- /* Show that Disabling IME stops the implicit MTA creation. */
- ImmDisableIME(GetCurrentThreadId());
- hwnd = CreateWindowExA(0, "Test class", "Test window", WS_VISIBLE, 0, 0, 100, 100,
GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
- hr = CoGetApartmentType(&apttype, &apttypequal);
- ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
- DestroyWindow(hwnd);
- return 0;
+}
+static DWORD WINAPI window_create_setwindowpos_thread(LPVOID data) +{
- APTTYPEQUALIFIER apttypequal;
- APTTYPE apttype;
- HWND hwnd;
- HRESULT hr;
- hr = CoGetApartmentType(&apttype, &apttypequal);
- ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
- hwnd = CreateWindowExA(0, "Test class", "Test window", WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU | WS_MINIMIZEBOX, 0, 0, 100, 100,
GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
- hr = CoGetApartmentType(&apttype, &apttypequal);
- ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
- /* Showing the window actually causes the implicit MTA */
- SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
- hr = CoGetApartmentType(&apttype, &apttypequal);
- todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- todo_wine ok(apttype == APTTYPE_MAINSTA && apttypequal == APTTYPEQUALIFIER_NONE, "Unexpected %u/%u\n", apttype, apttypequal);
- hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- hr = CoGetApartmentType(&apttype, &apttypequal);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- ok(apttype == APTTYPE_MTA && apttypequal == APTTYPEQUALIFIER_NONE, "Unexpected %u/%u\n", apttype, apttypequal);
- CoUninitialize();
- DestroyWindow(hwnd);
- return 0;
+}
+static DWORD WINAPI window_create_show_window_thread(LPVOID data) +{
- APTTYPEQUALIFIER apttypequal;
- APTTYPE apttype;
- HWND hwnd;
- HRESULT hr;
- hr = CoGetApartmentType(&apttype, &apttypequal);
- ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
- hwnd = CreateWindowExA(0, "Test class", "Test window", WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU | WS_MINIMIZEBOX, 0, 0, 100, 100,
GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
- hr = CoGetApartmentType(&apttype, &apttypequal);
- ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
- /* Showing the window actually causes the implicit MTA */
- ShowWindow(hwnd, SW_SHOW);
- hr = CoGetApartmentType(&apttype, &apttypequal);
- todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- todo_wine ok(apttype == APTTYPE_MAINSTA && apttypequal == APTTYPEQUALIFIER_NONE, "Unexpected %u/%u\n", apttype, apttypequal);
- DestroyWindow(hwnd);
- return 0;
+}
+static DWORD WINAPI window_create_visible_thread(LPVOID data) +{
- APTTYPEQUALIFIER apttypequal;
- APTTYPE apttype;
- HWND hwnd;
- HRESULT hr;
- hr = CoGetApartmentType(&apttype, &apttypequal);
- ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
- hwnd = CreateWindowExA(0, "Test class", "Test window", WS_VISIBLE, 0, 0, 100, 100,
GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
- hr = CoGetApartmentType(&apttype, &apttypequal);
- todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- todo_wine ok(apttype == APTTYPE_MAINSTA && apttypequal == APTTYPEQUALIFIER_NONE, "Unexpected %u/%u\n", apttype, apttypequal);
- DestroyWindow(hwnd);
- return 0;
+}
+static void test_implicit_mta(void) +{
- APTTYPEQUALIFIER apttypequal;
- APTTYPE apttype;
- WNDCLASSA clsA;
- HRESULT hr;
- HANDLE thread;
- clsA.style = 0;
- clsA.lpfnWndProc = TestWindowProc;
- clsA.cbClsExtra = 0;
- clsA.cbWndExtra = 0;
- clsA.hInstance = GetModuleHandleA(NULL);
- clsA.hIcon = 0;
- clsA.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
- clsA.hbrBackground = GetStockObject(WHITE_BRUSH);
- clsA.lpszMenuName = NULL;
- clsA.lpszClassName = "Test class";
- RegisterClassA(&clsA);
- hr = CoGetApartmentType(&apttype, &apttypequal);
- ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr);
- thread = CreateThread(NULL, 0, window_create_noime_thread, NULL, 0, NULL);
- WaitForSingleObject(thread, INFINITE);
- CloseHandle(thread);
- thread = CreateThread(NULL, 0, window_create_setwindowpos_thread, NULL, 0, NULL);
- WaitForSingleObject(thread, INFINITE);
- CloseHandle(thread);
- thread = CreateThread(NULL, 0, window_create_show_window_thread, NULL, 0, NULL);
- WaitForSingleObject(thread, INFINITE);
- CloseHandle(thread);
- thread = CreateThread(NULL, 0, window_create_visible_thread, NULL, 0, NULL);
- WaitForSingleObject(thread, INFINITE);
- CloseHandle(thread);
+}
START_TEST(win) { char **argv; @@ -11941,6 +12095,8 @@ START_TEST(win) return; }
test_implicit_mta();
if (!RegisterWindowClasses()) assert(0);
hwndMain = CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window",
On 20/1/21 5:09 am, Zebediah Figura (she/her) wrote:
On 1/19/21 4:34 AM, Alistair Leslie-Hughes wrote:
Based on a patch by Paul Gofman.
v2 - Changed title - Removed CoCreateInstance calls.
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com
dlls/user32/tests/Makefile.in | 2 +- dlls/user32/tests/win.c | 156 ++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 1 deletion(-)
I'm not really sure this subject is an improvement.
For whatever it's worth, I recall that Nikolay wrote a patch for this bug two years ago:
https://www.winehq.org/pipermail/wine-devel/2019-January/138404.html
Yes, I'm aware of this patch.
If Nikolay wants to rebase/resend his patch, I would be fine with that too.
Alistair.
On 1/19/21 1:34 PM, Alistair Leslie-Hughes wrote:
Based on a patch by Paul Gofman.
v2 - Changed title
- Removed CoCreateInstance calls.
The title wasn't the only place.
I think tests should use child processes to be more reliable, especially when disabling IME.