Pretty much the same as https://gitlab.winehq.org/wine/wine/-/merge_requests/1843, but on win32u side, to figure and validate the syscall entry signatures.
-- v3: win32u/tests: Test NtUserGetPointerInfoList syscall signature. win32u/tests: Test NtUserIsMouseInPointerEnabled syscall. win32u/tests: Test NtUserEnableMouseInPointer syscall. win32u: Stub NtUserGetPointerInfoList syscall. win32u: Stub NtUserIsMouseInPointerEnabled syscall. win32u: Move NtUserEnableMouseInPointer from user32. include: Declare some NtUser pointer related syscalls.
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53847 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51537 --- include/ntuser.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/include/ntuser.h b/include/ntuser.h index 7bbe7037f20..3b821f0c9fe 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -701,6 +701,7 @@ BOOL WINAPI NtUserDrawIconEx( HDC hdc, INT x0, INT y0, HICON icon, INT width, DWORD WINAPI NtUserDrawMenuBarTemp( HWND hwnd, HDC hdc, RECT *rect, HMENU handle, HFONT font ); BOOL WINAPI NtUserEmptyClipboard(void); BOOL WINAPI NtUserEnableMenuItem( HMENU handle, UINT id, UINT flags ); +BOOL WINAPI NtUserEnableMouseInPointer( BOOL ); BOOL WINAPI NtUserEnableScrollBar( HWND hwnd, UINT bar, UINT flags ); BOOL WINAPI NtUserEndDeferWindowPosEx( HDWP hdwp, BOOL async ); BOOL WINAPI NtUserEndMenu(void); @@ -760,6 +761,8 @@ int WINAPI NtUserGetMouseMovePointsEx( UINT size, MOUSEMOVEPOINT *ptin, MOUS BOOL WINAPI NtUserGetObjectInformation( HANDLE handle, INT index, void *info, DWORD len, DWORD *needed ); HWND WINAPI NtUserGetOpenClipboardWindow(void); +BOOL WINAPI NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, UINT_PTR, UINT_PTR, SIZE_T size, + UINT32 *entry_count, UINT32 *pointer_count, void *pointer_info ); INT WINAPI NtUserGetPriorityClipboardFormat( UINT *list, INT count ); HWINSTA WINAPI NtUserGetProcessWindowStation(void); HANDLE WINAPI NtUserGetProp( HWND hwnd, const WCHAR *str ); @@ -789,6 +792,7 @@ NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const struct user_client_procs HICON WINAPI NtUserInternalGetWindowIcon( HWND hwnd, UINT type ); INT WINAPI NtUserInternalGetWindowText( HWND hwnd, WCHAR *text, INT count ); BOOL WINAPI NtUserIsClipboardFormatAvailable( UINT format ); +BOOL WINAPI NtUserIsMouseInPointerEnabled(void); BOOL WINAPI NtUserInvalidateRect( HWND hwnd, const RECT *rect, BOOL erase ); BOOL WINAPI NtUserInvalidateRgn( HWND hwnd, HRGN hrgn, BOOL erase ); BOOL WINAPI NtUserKillTimer( HWND hwnd, UINT_PTR id );
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53847 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51537 --- dlls/user32/input.c | 11 ----------- dlls/user32/user32.spec | 2 +- dlls/win32u/input.c | 12 ++++++++++++ dlls/win32u/syscall.c | 1 + dlls/win32u/win32u.spec | 2 +- 5 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c index c5387cf9212..3b0a13842c8 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -495,17 +495,6 @@ BOOL WINAPI UnloadKeyboardLayout( HKL layout ) }
-/*********************************************************************** - * EnableMouseInPointer (USER32.@) - */ -BOOL WINAPI EnableMouseInPointer(BOOL enable) -{ - FIXME("(%#x) stub\n", enable); - - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - static DWORD CALLBACK devnotify_window_callback(HANDLE handle, DWORD flags, DEV_BROADCAST_HDR *header) { SendMessageTimeoutW(handle, WM_DEVICECHANGE, flags, (LPARAM)header, SMTO_ABORTIFHUNG, 2000, NULL); diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index 1628c7ca74a..f0e32c633d8 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -205,7 +205,7 @@ @ stdcall EditWndProc(long long long long) EditWndProcA @ stdcall EmptyClipboard() NtUserEmptyClipboard @ stdcall EnableMenuItem(long long long) NtUserEnableMenuItem -@ stdcall EnableMouseInPointer(long) +@ stdcall EnableMouseInPointer(long) NtUserEnableMouseInPointer @ stdcall EnableNonClientDpiScaling(long) @ stdcall -import EnableScrollBar(long long long) NtUserEnableScrollBar @ stdcall EnableWindow(long long) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index fd16d03f733..b6ccc70faf1 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2153,6 +2153,18 @@ void toggle_caret( HWND hwnd ) if (ret && !hidden) display_caret( hwnd, &r ); }
+ +/********************************************************************** + * NtUserEnableMouseInPointer (win32u.@) + */ +BOOL WINAPI NtUserEnableMouseInPointer( BOOL enable ) +{ + FIXME( "enable %u stub!\n", enable ); + RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); + return FALSE; +} + + HWND get_shell_window(void) { HWND hwnd = 0; diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index 32812a3d881..a0fba9f8045 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -145,6 +145,7 @@ static void * const syscalls[] = NtUserDrawIconEx, NtUserEmptyClipboard, NtUserEnableMenuItem, + NtUserEnableMouseInPointer, NtUserEnableScrollBar, NtUserEndDeferWindowPosEx, NtUserEndMenu, diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index c3ed3c0559a..6f3b2c31577 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -861,7 +861,7 @@ @ stub NtUserEnableChildWindowDpiMessage @ stub NtUserEnableIAMAccess @ stdcall -syscall NtUserEnableMenuItem(long long long) -@ stub NtUserEnableMouseInPointer +@ stdcall -syscall NtUserEnableMouseInPointer(long) @ stub NtUserEnableMouseInPointerForWindow @ stub NtUserEnableMouseInputForCursorSuppression @ stub NtUserEnableNonClientDpiScaling
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53847 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51537 --- dlls/user32/tests/input.c | 10 ++++------ dlls/user32/user32.spec | 1 + dlls/win32u/input.c | 10 ++++++++++ dlls/win32u/syscall.c | 1 + dlls/win32u/win32u.spec | 2 +- 5 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 95abdbb601b..f8b40099091 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -4844,17 +4844,15 @@ static void test_EnableMouseInPointer_process( const char *arg ) ok( !ret, "EnableMouseInPointer succeeded\n" ); todo_wine ok( GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError() ); - if (!pIsMouseInPointerEnabled) ret = !enable; - else ret = pIsMouseInPointerEnabled(); - todo_wine_if(!pIsMouseInPointerEnabled) + ret = pIsMouseInPointerEnabled(); + todo_wine_if(enable) ok( ret == enable, "IsMouseInPointerEnabled returned %u, error %lu\n", ret, GetLastError() );
ret = pEnableMouseInPointer( enable ); todo_wine ok( ret, "EnableMouseInPointer failed, error %lu\n", GetLastError() ); - if (!pIsMouseInPointerEnabled) ret = !enable; - else ret = pIsMouseInPointerEnabled(); - todo_wine_if(!pIsMouseInPointerEnabled) + ret = pIsMouseInPointerEnabled(); + todo_wine_if(enable) ok( ret == enable, "IsMouseInPointerEnabled returned %u, error %lu\n", ret, GetLastError() );
test_GetPointerInfo( enable ); diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index f0e32c633d8..38462607ccd 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -475,6 +475,7 @@ # @ stub IsHungThread @ stdcall IsIconic(long) @ stdcall IsMenu(long) +@ stdcall IsMouseInPointerEnabled() NtUserIsMouseInPointerEnabled @ stdcall IsProcessDPIAware() @ stdcall IsRectEmpty(ptr) # @ stub IsServerSideWindow diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index b6ccc70faf1..e8530812b3d 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2164,6 +2164,16 @@ BOOL WINAPI NtUserEnableMouseInPointer( BOOL enable ) return FALSE; }
+/********************************************************************** + * NtUserIsMouseInPointerEnabled (win32u.@) + */ +BOOL WINAPI NtUserIsMouseInPointerEnabled(void) +{ + FIXME( "stub!\n" ); + RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); + return FALSE; +} +
HWND get_shell_window(void) { diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index a0fba9f8045..3e3c5aba58c 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -222,6 +222,7 @@ static void * const syscalls[] = NtUserInvalidateRect, NtUserInvalidateRgn, NtUserIsClipboardFormatAvailable, + NtUserIsMouseInPointerEnabled, NtUserKillTimer, NtUserLockWindowUpdate, NtUserLogicalToPerMonitorDPIPhysicalPoint, diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 6f3b2c31577..0c4d4a3971d 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1051,7 +1051,7 @@ @ stdcall -syscall NtUserInvalidateRgn(long long long) @ stub NtUserIsChildWindowDpiMessageEnabled @ stdcall -syscall NtUserIsClipboardFormatAvailable(long) -@ stub NtUserIsMouseInPointerEnabled +@ stdcall -syscall NtUserIsMouseInPointerEnabled() @ stub NtUserIsMouseInputEnabled @ stub NtUserIsNonClientDpiScalingEnabled @ stub NtUserIsResizeLayoutSynchronizationEnabled
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53847 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51537 --- dlls/win32u/input.c | 11 +++++++++++ dlls/win32u/syscall.c | 1 + dlls/win32u/win32u.spec | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index e8530812b3d..0fcb1e7c9b3 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2174,6 +2174,17 @@ BOOL WINAPI NtUserIsMouseInPointerEnabled(void) return FALSE; }
+/********************************************************************** + * NtUserGetPointerInfoList (win32u.@) + */ +BOOL WINAPI NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, UINT_PTR unk0, UINT_PTR unk1, SIZE_T size, + UINT32 *entry_count, UINT32 *pointer_count, void *pointer_info ) +{ + FIXME( "id %#x, type %#x, unk0 %#zx, unk1 %#zx, size %#zx, entry_count %p, pointer_count %p, pointer_info %p stub!\n", + id, (int)type, unk0, unk1, (size_t)size, entry_count, pointer_count, pointer_info ); + RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); + return FALSE; +}
HWND get_shell_window(void) { diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index 3e3c5aba58c..9020aa01126 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -193,6 +193,7 @@ static void * const syscalls[] = NtUserGetMouseMovePointsEx, NtUserGetObjectInformation, NtUserGetOpenClipboardWindow, + NtUserGetPointerInfoList, NtUserGetPriorityClipboardFormat, NtUserGetProcessDpiAwarenessContext, NtUserGetProcessWindowStation, diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 0c4d4a3971d..6e1a0a51175 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -971,7 +971,7 @@ @ stub NtUserGetPointerDeviceRects @ stub NtUserGetPointerDevices @ stub NtUserGetPointerFrameTimes -@ stub NtUserGetPointerInfoList +@ stdcall -syscall NtUserGetPointerInfoList(long long long long long ptr ptr ptr) @ stub NtUserGetPointerInputTransform @ stub NtUserGetPointerProprietaryId @ stub NtUserGetPointerType
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53847 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51537 --- dlls/win32u/tests/win32u.c | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+)
diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 87419f6fadb..8eb98034798 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "ntuser.h"
+static BOOL (WINAPI *pNtUserEnableMouseInPointer)( BOOL );
static void test_NtUserEnumDisplayDevices(void) { @@ -822,6 +823,46 @@ static void test_inter_process_child( HWND hwnd ) PostMessageA( hwnd, WM_USER, 0, 0 ); }
+static void test_NtUserEnableMouseInPointer_process( const char *arg ) +{ + HANDLE win32u = GetModuleHandleW( L"win32u" ); + DWORD enable = strtoul( arg, 0, 10 ); + BOOL ret; + + pNtUserEnableMouseInPointer = (void *)GetProcAddress( win32u, "NtUserEnableMouseInPointer" ); + + ret = pNtUserEnableMouseInPointer( enable ); + todo_wine + ok( ret, "NtUserEnableMouseInPointer failed, error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + ret = pNtUserEnableMouseInPointer( !enable ); + ok( !ret, "NtUserEnableMouseInPointer succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError() ); + + ret = pNtUserEnableMouseInPointer( enable ); + todo_wine + ok( ret, "NtUserEnableMouseInPointer failed, error %lu\n", GetLastError() ); +} + +static void test_NtUserEnableMouseInPointer( char **argv, BOOL enable ) +{ + STARTUPINFOA startup = {.cb = sizeof(STARTUPINFOA)}; + PROCESS_INFORMATION info = {0}; + char cmdline[MAX_PATH * 2]; + BOOL ret; + + sprintf( cmdline, "%s %s NtUserEnableMouseInPointer %u", argv[0], argv[1], enable ); + ret = CreateProcessA( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info ); + ok( ret, "CreateProcessA failed, error %lu\n", GetLastError() ); + if (!ret) return; + + wait_child_process( info.hProcess ); + CloseHandle( info.hThread ); + CloseHandle( info.hProcess ); +} + START_TEST(win32u) { char **argv; @@ -837,6 +878,14 @@ START_TEST(win32u) return; }
+ if (argc > 3 && !strcmp( argv[2], "NtUserEnableMouseInPointer" )) + { + winetest_push_context( "enable %s", argv[3] ); + test_NtUserEnableMouseInPointer_process( argv[3] ); + winetest_pop_context(); + return; + } + test_NtUserEnumDisplayDevices(); test_window_props(); test_class(); @@ -851,4 +900,7 @@ START_TEST(win32u)
test_NtUserCloseWindowStation(); test_NtUserDisplayConfigGetDeviceInfo(); + + test_NtUserEnableMouseInPointer( argv, FALSE ); + test_NtUserEnableMouseInPointer( argv, TRUE ); }
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53847 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51537 --- dlls/win32u/tests/win32u.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 8eb98034798..c9d7159b368 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "ntuser.h"
+static BOOL (WINAPI *pNtUserIsMouseInPointerEnabled)(void); static BOOL (WINAPI *pNtUserEnableMouseInPointer)( BOOL );
static void test_NtUserEnumDisplayDevices(void) @@ -830,20 +831,33 @@ static void test_NtUserEnableMouseInPointer_process( const char *arg ) BOOL ret;
pNtUserEnableMouseInPointer = (void *)GetProcAddress( win32u, "NtUserEnableMouseInPointer" ); + pNtUserIsMouseInPointerEnabled = (void *)GetProcAddress( win32u, "NtUserIsMouseInPointerEnabled" ); + + ret = pNtUserIsMouseInPointerEnabled(); + ok( !ret, "NtUserIsMouseInPointerEnabled returned %u, error %lu\n", ret, GetLastError() );
ret = pNtUserEnableMouseInPointer( enable ); todo_wine ok( ret, "NtUserEnableMouseInPointer failed, error %lu\n", GetLastError() ); + ret = pNtUserIsMouseInPointerEnabled(); + todo_wine_if(enable) + ok( ret == enable, "NtUserIsMouseInPointerEnabled returned %u, error %lu\n", ret, GetLastError() );
SetLastError( 0xdeadbeef ); ret = pNtUserEnableMouseInPointer( !enable ); ok( !ret, "NtUserEnableMouseInPointer succeeded\n" ); todo_wine ok( GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError() ); + ret = pNtUserIsMouseInPointerEnabled(); + todo_wine_if(enable) + ok( ret == enable, "NtUserIsMouseInPointerEnabled returned %u, error %lu\n", ret, GetLastError() );
ret = pNtUserEnableMouseInPointer( enable ); todo_wine ok( ret, "NtUserEnableMouseInPointer failed, error %lu\n", GetLastError() ); + ret = pNtUserIsMouseInPointerEnabled(); + todo_wine_if(enable) + ok( ret == enable, "NtUserIsMouseInPointerEnabled returned %u, error %lu\n", ret, GetLastError() ); }
static void test_NtUserEnableMouseInPointer( char **argv, BOOL enable )
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53847 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51537 --- dlls/win32u/tests/win32u.c | 260 +++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+)
diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index c9d7159b368..6fb6fa63c00 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -24,9 +24,33 @@ #include "winbase.h" #include "ntuser.h"
+static BOOL (WINAPI *pNtUserGetPointerInfoList)( UINT32, POINTER_INPUT_TYPE, UINT_PTR, UINT_PTR, SIZE_T, UINT32 *, UINT32 *, void * ); static BOOL (WINAPI *pNtUserIsMouseInPointerEnabled)(void); static BOOL (WINAPI *pNtUserEnableMouseInPointer)( BOOL );
+#define check_member_( file, line, val, exp, fmt, member ) \ + ok_(file, line)( (val).member == (exp).member, "got " #member " " fmt "\n", (val).member ) +#define check_member( val, exp, fmt, member ) \ + check_member_( __FILE__, __LINE__, val, exp, fmt, member ) + +static void flush_events(void) +{ + int min_timeout = 100, diff = 200; + DWORD time = GetTickCount() + diff; + MSG msg; + + while (diff > 0) + { + if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break; + while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) + { + TranslateMessage( &msg ); + DispatchMessageA( &msg ); + } + diff = time - GetTickCount(); + } +} + static void test_NtUserEnumDisplayDevices(void) { NTSTATUS ret; @@ -824,6 +848,239 @@ static void test_inter_process_child( HWND hwnd ) PostMessageA( hwnd, WM_USER, 0, 0 ); }
+static DWORD CALLBACK test_NtUserGetPointerInfoList_thread( void *arg ) +{ + POINTER_INFO pointer_info[4] = {0}; + UINT32 entry_count, pointer_count; + HWND hwnd; + BOOL ret; + + hwnd = CreateWindowW( L"test", L"test name", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 100, 100, 200, 200, 0, 0, NULL, 0 ); + flush_events(); + + memset( &pointer_info, 0xcd, sizeof(pointer_info) ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO), &entry_count, &pointer_count, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + ok( pointer_count == 2, "got pointer_count %u\n", pointer_count ); + ok( entry_count == 2, "got entry_count %u\n", entry_count ); + + DestroyWindow( hwnd ); + + return 0; +} + +#define check_pointer_info( a, b ) check_pointer_info_( __LINE__, a, b ) +static void check_pointer_info_( int line, const POINTER_INFO *actual, const POINTER_INFO *expected ) +{ + check_member( *actual, *expected, "%#lx", pointerType ); + check_member( *actual, *expected, "%#x", pointerId ); + check_member( *actual, *expected, "%#x", frameId ); + check_member( *actual, *expected, "%#x", pointerFlags ); + check_member( *actual, *expected, "%p", sourceDevice ); + check_member( *actual, *expected, "%p", hwndTarget ); + check_member( *actual, *expected, "%+ld", ptPixelLocation.x ); + check_member( *actual, *expected, "%+ld", ptPixelLocation.y ); + check_member( *actual, *expected, "%+ld", ptHimetricLocation.x ); + check_member( *actual, *expected, "%+ld", ptHimetricLocation.y ); + check_member( *actual, *expected, "%+ld", ptPixelLocationRaw.x ); + check_member( *actual, *expected, "%+ld", ptPixelLocationRaw.y ); + check_member( *actual, *expected, "%+ld", ptHimetricLocationRaw.x ); + check_member( *actual, *expected, "%+ld", ptHimetricLocationRaw.y ); + check_member( *actual, *expected, "%lu", dwTime ); + check_member( *actual, *expected, "%u", historyCount ); + check_member( *actual, *expected, "%#x", InputData ); + check_member( *actual, *expected, "%#lx", dwKeyStates ); + check_member( *actual, *expected, "%I64u", PerformanceCount ); + check_member( *actual, *expected, "%#x", ButtonChangeType ); +} + +static void test_NtUserGetPointerInfoList( BOOL mouse_in_pointer_enabled ) +{ + void *invalid_ptr = (void *)0xdeadbeef; + POINTER_TOUCH_INFO touch_info[4] = {0}; + POINTER_PEN_INFO pen_info[4] = {0}; + POINTER_INFO pointer_info[4] = {0}; + UINT32 entry_count, pointer_count; + WNDCLASSW cls = + { + .lpfnWndProc = DefWindowProcW, + .hInstance = GetModuleHandleW( NULL ), + .hbrBackground = GetStockObject( WHITE_BRUSH ), + .lpszClassName = L"test", + }; + HANDLE thread; + SIZE_T size; + ATOM class; + DWORD res; + HWND hwnd; + BOOL ret; + + if (!pNtUserGetPointerInfoList) + { + win_skip( "NtUserGetPointerInfoList not found, skipping tests\n" ); + return; + } + + class = RegisterClassW( &cls ); + ok( class, "RegisterClassW failed: %lu\n", GetLastError() ); + + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO), invalid_ptr, &pointer_count, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_NOACCESS, "got error %lu\n", GetLastError() ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO), &entry_count, invalid_ptr, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_NOACCESS, "got error %lu\n", GetLastError() ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO), &entry_count, &pointer_count, invalid_ptr ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_NOACCESS || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* w10 32bit */, "got error %lu\n", GetLastError() ); + + memset( pointer_info, 0xcd, sizeof(pointer_info) ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO), &entry_count, &pointer_count, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + ok( pointer_count == 2, "got pointer_count %u\n", pointer_count ); + ok( entry_count == 2, "got entry_count %u\n", entry_count ); + + SetCursorPos( 500, 500 ); /* avoid generating mouse message on window creation */ + + hwnd = CreateWindowW( L"test", L"test name", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 100, 100, 200, 200, 0, 0, NULL, 0 ); + flush_events(); + + memset( pointer_info, 0xcd, sizeof(pointer_info) ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO), &entry_count, &pointer_count, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + todo_wine + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + ok( pointer_count == 2, "got pointer_count %u\n", pointer_count ); + ok( entry_count == 2, "got entry_count %u\n", entry_count ); + + SetCursorPos( 200, 200 ); + flush_events(); + mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 ); + flush_events(); + mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 ); + flush_events(); + mouse_event( MOUSEEVENTF_MOVE, 10, 10, 0, 0 ); + flush_events(); + + memset( pointer_info, 0xcd, sizeof(pointer_info) ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO), &entry_count, &pointer_count, pointer_info ); + todo_wine_if(mouse_in_pointer_enabled) + ok( ret == mouse_in_pointer_enabled, "NtUserGetPointerInfoList failed, error %lu\n", GetLastError() ); + if (!ret) + { + todo_wine + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + goto done; + } + + ok( pointer_count == 1, "got pointer_count %u\n", pointer_count ); + ok( entry_count == 1, "got entry_count %u\n", entry_count ); + ok( pointer_info[0].pointerType == PT_MOUSE, "got pointerType %lu\n", pointer_info[0].pointerType ); + ok( pointer_info[0].pointerId == 1, "got pointerId %u\n", pointer_info[0].pointerId ); + ok( !!pointer_info[0].frameId, "got frameId %u\n", pointer_info[0].frameId ); + ok( pointer_info[0].pointerFlags == (0x20000 | POINTER_MESSAGE_FLAG_INRANGE | POINTER_MESSAGE_FLAG_PRIMARY), + "got pointerFlags %#x\n", pointer_info[0].pointerFlags ); + ok( pointer_info[0].sourceDevice == INVALID_HANDLE_VALUE || broken(!!pointer_info[0].sourceDevice) /* w1064v1809 32bit */, + "got sourceDevice %p\n", pointer_info[0].sourceDevice ); + ok( pointer_info[0].hwndTarget == hwnd, "got hwndTarget %p\n", pointer_info[0].hwndTarget ); + ok( !!pointer_info[0].ptPixelLocation.x, "got ptPixelLocation %s\n", wine_dbgstr_point( &pointer_info[0].ptPixelLocation ) ); + ok( !!pointer_info[0].ptPixelLocation.y, "got ptPixelLocation %s\n", wine_dbgstr_point( &pointer_info[0].ptPixelLocation ) ); + ok( !!pointer_info[0].ptHimetricLocation.x, "got ptHimetricLocation %s\n", wine_dbgstr_point( &pointer_info[0].ptHimetricLocation ) ); + ok( !!pointer_info[0].ptHimetricLocation.y, "got ptHimetricLocation %s\n", wine_dbgstr_point( &pointer_info[0].ptHimetricLocation ) ); + ok( !!pointer_info[0].ptPixelLocationRaw.x, "got ptPixelLocationRaw %s\n", wine_dbgstr_point( &pointer_info[0].ptPixelLocationRaw ) ); + ok( !!pointer_info[0].ptPixelLocationRaw.y, "got ptPixelLocationRaw %s\n", wine_dbgstr_point( &pointer_info[0].ptPixelLocationRaw ) ); + ok( !!pointer_info[0].ptHimetricLocationRaw.x, "got ptHimetricLocationRaw %s\n", wine_dbgstr_point( &pointer_info[0].ptHimetricLocationRaw ) ); + ok( !!pointer_info[0].ptHimetricLocationRaw.y, "got ptHimetricLocationRaw %s\n", wine_dbgstr_point( &pointer_info[0].ptHimetricLocationRaw ) ); + ok( !!pointer_info[0].dwTime, "got dwTime %lu\n", pointer_info[0].dwTime ); + ok( pointer_info[0].historyCount == 1, "got historyCount %u\n", pointer_info[0].historyCount ); + ok( pointer_info[0].InputData == 0, "got InputData %u\n", pointer_info[0].InputData ); + ok( pointer_info[0].dwKeyStates == 0, "got dwKeyStates %lu\n", pointer_info[0].dwKeyStates ); + ok( !!pointer_info[0].PerformanceCount, "got PerformanceCount %I64u\n", pointer_info[0].PerformanceCount ); + ok( pointer_info[0].ButtonChangeType == 0, "got ButtonChangeType %u\n", pointer_info[0].ButtonChangeType ); + + thread = CreateThread( NULL, 0, test_NtUserGetPointerInfoList_thread, NULL, 0, NULL ); + res = WaitForSingleObject( thread, 5000 ); + ok( !res, "WaitForSingleObject returned %#lx, error %lu\n", res, GetLastError() ); + + memset( pen_info, 0xa5, sizeof(pen_info) ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_PEN, 0, 0, sizeof(POINTER_PEN_INFO), &entry_count, &pointer_count, pen_info ); + ok( ret, "NtUserGetPointerInfoList failed, error %lu\n", GetLastError() ); + ok( pointer_count == 1, "got pointer_count %u\n", pointer_count ); + ok( entry_count == 1, "got entry_count %u\n", entry_count ); + check_pointer_info( &pen_info[0].pointerInfo, &pointer_info[0] ); + memset( touch_info, 0xa5, sizeof(touch_info) ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_TOUCH, 0, 0, sizeof(POINTER_TOUCH_INFO), &entry_count, &pointer_count, touch_info ); + ok( ret, "NtUserGetPointerInfoList failed, error %lu\n", GetLastError() ); + ok( pointer_count == 1, "got pointer_count %u\n", pointer_count ); + ok( entry_count == 1, "got entry_count %u\n", entry_count ); + check_pointer_info( &touch_info[0].pointerInfo, &pointer_info[0] ); + + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO) - 1, &entry_count, &pointer_count, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_PEN, 0, 0, sizeof(POINTER_PEN_INFO) - 1, &entry_count, &pointer_count, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_TOUCH, 0, 0, sizeof(POINTER_TOUCH_INFO) - 1, &entry_count, &pointer_count, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_TOUCHPAD, 0, 0, sizeof(POINTER_TOUCH_INFO) - 1, &entry_count, &pointer_count, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_POINTER, 0, 0, sizeof(POINTER_INFO) + 1, &entry_count, &pointer_count, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_PEN, 0, 0, sizeof(POINTER_PEN_INFO) + 1, &entry_count, &pointer_count, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_TOUCH, 0, 0, sizeof(POINTER_TOUCH_INFO) + 1, &entry_count, &pointer_count, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_TOUCHPAD, 0, 0, sizeof(POINTER_TOUCH_INFO) + 1, &entry_count, &pointer_count, pointer_info ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + + for (size = 0; size < 0xfff; ++size) + { + char buffer[0x1000]; + entry_count = pointer_count = 2; + ret = pNtUserGetPointerInfoList( 1, PT_MOUSE, 0, 0, size, &entry_count, &pointer_count, buffer ); + ok( !ret, "NtUserGetPointerInfoList succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() ); + } + +done: + DestroyWindow( hwnd ); + + ret = UnregisterClassW( L"test", GetModuleHandleW(NULL) ); + ok( ret, "UnregisterClassW failed: %lu\n", GetLastError() ); +} + static void test_NtUserEnableMouseInPointer_process( const char *arg ) { HANDLE win32u = GetModuleHandleW( L"win32u" ); @@ -832,6 +1089,7 @@ static void test_NtUserEnableMouseInPointer_process( const char *arg )
pNtUserEnableMouseInPointer = (void *)GetProcAddress( win32u, "NtUserEnableMouseInPointer" ); pNtUserIsMouseInPointerEnabled = (void *)GetProcAddress( win32u, "NtUserIsMouseInPointerEnabled" ); + pNtUserGetPointerInfoList = (void *)GetProcAddress( win32u, "NtUserGetPointerInfoList" );
ret = pNtUserIsMouseInPointerEnabled(); ok( !ret, "NtUserIsMouseInPointerEnabled returned %u, error %lu\n", ret, GetLastError() ); @@ -858,6 +1116,8 @@ static void test_NtUserEnableMouseInPointer_process( const char *arg ) ret = pNtUserIsMouseInPointerEnabled(); todo_wine_if(enable) ok( ret == enable, "NtUserIsMouseInPointerEnabled returned %u, error %lu\n", ret, GetLastError() ); + + test_NtUserGetPointerInfoList( enable ); }
static void test_NtUserEnableMouseInPointer( char **argv, BOOL enable )
These need entries in wow64win, at least in the syscall list if not properly implementing the thunks.