From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/user32/tests/msg.c | 146 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 7 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index baad938b6c7..33962efc790 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -2329,7 +2329,7 @@ static const struct message WmTrackPopupMenuAbort[] = { { 0 } };
-static BOOL after_end_dialog, test_def_id, paint_loop_done; +static BOOL after_end_dialog, test_def_id, paint_loop_done, wm_copydata_done; static int sequence_cnt, sequence_size; static struct recvd_message* sequence; static int log_all_parent_messages; @@ -11244,6 +11244,51 @@ static LRESULT WINAPI HotkeyMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam return ret; }
+static LRESULT WINAPI WmCopyDataProcA(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) +{ + switch (msg) + { + case WM_COPYDATA: + { + static const DWORD expected_data_sizes[3] = {0, 64, 64 * 1024 * 1024}; + static ULONG_PTR expected_dwdata = 0; + COPYDATASTRUCT *cds = (COPYDATASTRUCT *)lp; + unsigned char *ptr; + unsigned int i; + BOOL matched; + + if (cds->dwData > 2) + return FALSE; + + ok(!wm_copydata_done, "Got unexpected wm_copydata_done.\n"); + ok(wp == (WPARAM)GetDesktopWindow(), "Got unexpected wp.\n"); + ok(cds->dwData == expected_dwdata, "Got unexpected dwData %Id.\n", cds->dwData); + expected_dwdata++; + ok(cds->cbData == expected_data_sizes[cds->dwData], "Got unexpected cbData %#lx.\n", cds->cbData); + + if (cds->dwData) + ok(!!cds->lpData, "Got unexpected lpData %p.\n", cds->lpData); + else + ok(!cds->lpData, "Got unexpected lpData %p.\n", cds->lpData); + + matched = TRUE; + for (i = 0, ptr = cds->lpData; i < cds->cbData; i++, ptr++) + { + if (*ptr != i % 0xff) + { + matched = FALSE; + break; + } + } + ok(matched, "Got unexpected content.\n"); + if (cds->dwData == 2) + wm_copydata_done = TRUE; + return TRUE; + } + } + return DefWindowProcA(hwnd,msg,wp,lp); +} + static void register_classes(void) { WNDCLASSA cls; @@ -11289,6 +11334,10 @@ static void register_classes(void) cls.lpszClassName = "PaintLoopWindowClass"; register_class(&cls);
+ cls.lpfnWndProc = WmCopyDataProcA; + cls.lpszClassName = "WmCopyDataWindowClass"; + register_class(&cls); + cls.style = CS_NOCLOSE; cls.lpszClassName = "NoCloseWindowClass"; register_class(&cls); @@ -18729,7 +18778,7 @@ static void test_WaitForInputIdle( char *argv0 ) { ResetEvent( start_event ); ResetEvent( end_event ); - sprintf( path, "%s msg %u", argv0, i ); + sprintf( path, "%s msg do_wait_idle_child %u", argv0, i ); ret = CreateProcessA( NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &pi ); ok( ret, "CreateProcess '%s' failed err %lu.\n", path, GetLastError() ); if (ret) @@ -20721,6 +20770,83 @@ static void test_hook_cleanup(void) DestroyWindow( d.hwnd ); }
+static void test_WM_COPYDATA_child(void) +{ + HWND hwnd; + MSG msg; + + wm_copydata_done = FALSE; + hwnd = CreateWindowA("WmCopyDataWindowClass", "WmCopyDataWindow", + WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 100, 100, 0, 0, 0, NULL); + ok(!!hwnd, "CreateWindowA failed, error %lu\n", GetLastError()); + while (!wm_copydata_done) + { + if (PeekMessageA(&msg, 0, 0, 0, 1)) + { + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + } + DestroyWindow(hwnd); +} + +static void test_WM_COPYDATA(char **argv) +{ + static const int LARGE_DATA_SIZE = 64 * 1024 * 1024; + unsigned char *ptr, *buffer; + unsigned int timeout = 0, i; + PROCESS_INFORMATION pi; + char cmdline[MAX_PATH]; + STARTUPINFOA si = {0}; + COPYDATASTRUCT cds; + HWND hwnd = NULL; + BOOL ret; + + sprintf(cmdline, "%s %s test_WM_COPYDATA_child", argv[0], argv[1]); + ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ok(ret, "CreateProcessA failed, error %lu\n", GetLastError()); + + do + { + hwnd = FindWindowA("WmCopyDataWindowClass", "WmCopyDataWindow"); + Sleep(100); + timeout += 100; + } while (!hwnd && timeout < 1000); + ok(!!hwnd, "Failed to find test window.\n"); + + buffer = malloc(LARGE_DATA_SIZE); + ok(!!buffer, "Failed to allocate memory.\n"); + for (i = 0, ptr = buffer; i < LARGE_DATA_SIZE; i++, ptr++) + *ptr = i % 0xff; + + /* Test a WM_COPYDATA message with no data */ + cds.dwData = 0; + cds.cbData = 0; + cds.lpData = NULL; + ret = SendMessageA(hwnd, WM_COPYDATA, (WPARAM)GetDesktopWindow(), (LPARAM)&cds); + ok(ret, "WM_COPYDATA failed.\n"); + + /* Test a WM_COPYDATA message with a small amount of data */ + cds.dwData = 1; + cds.cbData = 64; + cds.lpData = buffer; + ret = SendMessageA(hwnd, WM_COPYDATA, (WPARAM)GetDesktopWindow(), (LPARAM)&cds); + ok(ret, "WM_COPYDATA failed.\n"); + + /* Test a WM_COPYDATA message with a large amount of data */ + cds.dwData = 2; + cds.cbData = LARGE_DATA_SIZE; + cds.lpData = buffer; + ret = SendMessageA(hwnd, WM_COPYDATA, (WPARAM)GetDesktopWindow(), (LPARAM)&cds); + ok(ret, "WM_COPYDATA failed.\n"); + + free(buffer); + ret = WaitForSingleObject(pi.hProcess, 1000); + ok(!ret, "WaitForSingleObject failed, error %ld.\n", GetLastError()); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); +} + START_TEST(msg) { char **test_argv; @@ -20728,12 +20854,19 @@ START_TEST(msg) BOOL (WINAPI *pIsWinEventHookInstalled)(DWORD)= 0;/*GetProcAddress(user32, "IsWinEventHookInstalled");*/ int argc;
- argc = winetest_get_mainargs( &test_argv ); - if (argc >= 3) + register_classes(); + + argc = winetest_get_mainargs(&test_argv); + if (argc == 3 && !strcmp(test_argv[2], "test_WM_COPYDATA_child")) + { + test_WM_COPYDATA_child(); + return; + } + else if (argc >= 4 && !strcmp(test_argv[2], "do_wait_idle_child")) { unsigned int arg; /* Child process. */ - sscanf (test_argv[2], "%d", (unsigned int *) &arg); + sscanf (test_argv[3], "%d", (unsigned int *) &arg); do_wait_idle_child( arg ); return; } @@ -20742,8 +20875,6 @@ START_TEST(msg) init_procs(); ImmDisableIME(0);
- register_classes(); - if (pSetWinEventHook) { hEvent_hook = pSetWinEventHook(EVENT_MIN, EVENT_MAX, @@ -20849,6 +20980,7 @@ START_TEST(msg) * which rely on active/foreground windows being correct. */ test_SetForegroundWindow(); + test_WM_COPYDATA(test_argv);
UnhookWindowsHookEx(hCBT_hook); if (pUnhookWinEvent && hEvent_hook)