[PATCH 0/2] MR7172: win32u: Implement a couple of syscalls.
From: Paul Gofman <pgofman(a)codeweavers.com> And use it in user32.dll. --- dlls/user32/message.c | 4 ++-- dlls/win32u/main.c | 5 +++++ dlls/win32u/message.c | 23 ++++++++++++++++++++++ dlls/win32u/tests/win32u.c | 40 ++++++++++++++++++++++++++++++++++++++ dlls/win32u/win32u.spec | 2 +- dlls/wow64win/user.c | 7 +++++++ include/ntuser.h | 5 +++++ 7 files changed, 83 insertions(+), 3 deletions(-) diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 73b41820adc..a4a1acd9e9e 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -970,7 +970,7 @@ DWORD WINAPI GetMessagePos(void) */ LONG WINAPI GetMessageTime(void) { - return NtUserGetThreadInfo()->message_time; + return NtUserGetThreadState( USER_GET_THREAD_STATE_MSGTIME ); } @@ -980,7 +980,7 @@ LONG WINAPI GetMessageTime(void) */ LPARAM WINAPI GetMessageExtraInfo(void) { - return NtUserGetThreadInfo()->message_extra; + return NtUserGetThreadState( USER_GET_THREAD_STATE_MSGEXTRAINFO ); } diff --git a/dlls/win32u/main.c b/dlls/win32u/main.c index 11628dcccca..e862e53048f 100644 --- a/dlls/win32u/main.c +++ b/dlls/win32u/main.c @@ -1694,6 +1694,11 @@ HDESK SYSCALL_API NtUserGetThreadDesktop( DWORD thread ) SYSCALL_FUNC( NtUserGetThreadDesktop ); } +ULONG_PTR SYSCALL_API NtUserGetThreadState( DWORD request ) +{ + SYSCALL_FUNC( NtUserGetThreadState ); +} + BOOL SYSCALL_API NtUserGetTitleBarInfo( HWND hwnd, TITLEBARINFO *info ) { SYSCALL_FUNC( NtUserGetTitleBarInfo ); diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 2f1e14c82c8..57b5b95ac09 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -4581,3 +4581,26 @@ BOOL WINAPI NtUserTranslateMessage( const MSG *msg, UINT flags ) } return TRUE; } + +/*********************************************************************** + * NtUserGetThreadState (win32u.@) + */ +ULONG_PTR WINAPI NtUserGetThreadState( ULONG request ) +{ + TRACE( "request %d.\n", (int)request ); + + switch(request) + { + case USER_GET_THREAD_STATE_MSGEXTRAINFO: + return NtUserGetThreadInfo()->message_extra; + + case USER_GET_THREAD_STATE_MSGTIME: + return NtUserGetThreadInfo()->message_time; + + default: + FIXME( "request %d is not supported.\n", (int)request ); + break; + } + + return 0; +} diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 8e1b56f6501..d4d27628124 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -2515,6 +2515,45 @@ static void test_NtUserSetProcessDpiAwarenessContext( ULONG context ) winetest_pop_context(); } +static LRESULT CALLBACK test_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + return DefWindowProcA( hwnd, msg, wparam, lparam ); +} + +static void test_message_info(void) +{ + DWORD_PTR ret, expected; + HWND hwnd; + WNDCLASSA cls; + MSG msg; + + memset(&cls, 0, sizeof(cls)); + cls.lpfnWndProc = test_window_proc; + cls.hInstance = GetModuleHandleA(NULL); + cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW); + cls.lpszClassName = "Test class"; + RegisterClassA( &cls ); + hwnd = CreateWindowExA( 0, "Test class", NULL, WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, NULL ); + ShowWindow( hwnd, SW_SHOW ); + while (PeekMessageA( &msg, NULL, 0, 0, PM_NOREMOVE )) + { + GetMessageA( &msg, NULL, 0, 0 ); + expected = GetMessageTime(); + ret = NtUserGetThreadState( USER_GET_THREAD_STATE_MSGTIME ); + ok( ret == expected || broken( !ret ) /* Before Win10 1709 */, "got %#Ix, expected %#Ix.\n", ret, expected ); + SetMessageExtraInfo( 0xdeadbeef ); + expected = GetMessageExtraInfo(); + ret = NtUserGetThreadState( USER_GET_THREAD_STATE_MSGEXTRAINFO ); + ok( expected == 0xdeadbeef, "got %#Ix.\n", expected ); + ok( ret == expected || broken( !ret ) /* Before Win10 1709 */, "got %#Ix, expected %#Ix.\n", ret, expected ); + TranslateMessage( &msg ); + DispatchMessageA( &msg ); + } + + DestroyWindow( hwnd ); + UnregisterClassA( "Test class", cls.hInstance ); +} + START_TEST(win32u) { char **argv; @@ -2563,6 +2602,7 @@ START_TEST(win32u) test_NtUserCloseWindowStation(); test_NtUserDisplayConfigGetDeviceInfo(); test_NtUserQueryWindow(); + test_message_info(); run_in_process( argv, "NtUserEnableMouseInPointer 0" ); run_in_process( argv, "NtUserEnableMouseInPointer 1" ); diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 08f27ad6671..899b2d815d3 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1101,7 +1101,7 @@ @ stdcall -syscall NtUserGetSystemDpiForProcess(long) @ stdcall -syscall NtUserGetSystemMenu(long long) @ stdcall -syscall NtUserGetThreadDesktop(long) -@ stub NtUserGetThreadState +@ stdcall -syscall NtUserGetThreadState(long) @ stdcall -syscall NtUserGetTitleBarInfo(long ptr) @ stub NtUserGetTopLevelWindow @ stub NtUserGetTouchInputInfo diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 28944f15d07..487c2e56072 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -3100,6 +3100,13 @@ NTSTATUS WINAPI wow64_NtUserGetThreadDesktop( UINT *args ) return HandleToUlong( NtUserGetThreadDesktop( thread )); } +NTSTATUS WINAPI wow64_NtUserGetThreadState( UINT *args ) +{ + DWORD request = get_ulong( &args ); + + return NtUserGetThreadState( request ); +} + NTSTATUS WINAPI wow64_NtUserGetTitleBarInfo( UINT *args ) { HWND hwnd = get_handle( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index 01fdd4b17e4..565a884afea 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -700,6 +700,10 @@ typedef enum _WINDOWINFOCLASS WindowDefaultInputContext, } WINDOWINFOCLASS; +/* NtUserGetThreadState requests */ +#define USER_GET_THREAD_STATE_MSGEXTRAINFO 7 +#define USER_GET_THREAD_STATE_MSGTIME 9 + W32KAPI HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags ); W32KAPI BOOL WINAPI NtUserAddClipboardFormatListener( HWND hwnd ); W32KAPI UINT WINAPI NtUserAssociateInputContext( HWND hwnd, HIMC ctx, ULONG flags ); @@ -838,6 +842,7 @@ W32KAPI BOOL WINAPI NtUserGetScrollBarInfo( HWND hwnd, LONG id, SCROLLBARINFO W32KAPI ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process ); W32KAPI HMENU WINAPI NtUserGetSystemMenu( HWND hwnd, BOOL revert ); W32KAPI HDESK WINAPI NtUserGetThreadDesktop( DWORD thread ); +W32KAPI ULONG_PTR WINAPI NtUserGetThreadState( ULONG request ); W32KAPI BOOL WINAPI NtUserGetTitleBarInfo( HWND hwnd, TITLEBARINFO *info ); W32KAPI INT WINAPI NtUserGetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ); W32KAPI BOOL WINAPI NtUserGetUpdatedClipboardFormats( UINT *formats, UINT size, UINT *out_size ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7172
From: Paul Gofman <pgofman(a)codeweavers.com> --- dlls/user32/message.c | 10 ---------- dlls/user32/user32.spec | 2 +- dlls/win32u/main.c | 5 +++++ dlls/win32u/message.c | 16 ++++++++++++++++ dlls/win32u/tests/win32u.c | 28 ++++++++++++++++++++++++++++ dlls/win32u/win32u.spec | 2 +- dlls/wow64win/user.c | 7 +++++++ include/ntuser.h | 1 + 8 files changed, 59 insertions(+), 12 deletions(-) diff --git a/dlls/user32/message.c b/dlls/user32/message.c index a4a1acd9e9e..8943f1fa09e 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -996,16 +996,6 @@ LPARAM WINAPI SetMessageExtraInfo(LPARAM lParam) } -/*********************************************************************** - * GetCurrentInputMessageSource (USER32.@) - */ -BOOL WINAPI GetCurrentInputMessageSource( INPUT_MESSAGE_SOURCE *source ) -{ - *source = NtUserGetThreadInfo()->msg_source; - return TRUE; -} - - /*********************************************************************** * MsgWaitForMultipleObjects (USER32.@) */ diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index 9d3a8f7bef8..09bf38613c4 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -537,7 +537,7 @@ @ stdcall GetClipboardSequenceNumber() NtUserGetClipboardSequenceNumber @ stdcall GetClipboardViewer() NtUserGetClipboardViewer @ stdcall GetComboBoxInfo(long ptr) -@ stdcall GetCurrentInputMessageSource(ptr) +@ stdcall GetCurrentInputMessageSource(ptr) NtUserGetCurrentInputMessageSource @ stdcall GetCursor() NtUserGetCursor @ stdcall GetCursorFrameInfo(long long long ptr ptr) @ stdcall GetCursorInfo(ptr) NtUserGetCursorInfo diff --git a/dlls/win32u/main.c b/dlls/win32u/main.c index e862e53048f..e23c1b7703a 100644 --- a/dlls/win32u/main.c +++ b/dlls/win32u/main.c @@ -1483,6 +1483,11 @@ HWND SYSCALL_API NtUserGetClipboardViewer(void) SYSCALL_FUNC( NtUserGetClipboardViewer ); } +BOOL SYSCALL_API NtUserGetCurrentInputMessageSource( INPUT_MESSAGE_SOURCE *source ) +{ + SYSCALL_FUNC( NtUserGetCurrentInputMessageSource ); +} + HCURSOR SYSCALL_API NtUserGetCursor(void) { SYSCALL_FUNC( NtUserGetCursor ); diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 57b5b95ac09..3357876e579 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -4604,3 +4604,19 @@ ULONG_PTR WINAPI NtUserGetThreadState( ULONG request ) return 0; } + +/*********************************************************************** + * NtUserGetCurrentInputMessageSource (win32u.@) + */ +BOOL WINAPI NtUserGetCurrentInputMessageSource( INPUT_MESSAGE_SOURCE *source ) +{ + TRACE( "source %p.\n", source ); + + if (!source) + { + RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); + return FALSE; + } + *source = NtUserGetThreadInfo()->msg_source; + return TRUE; +} diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index d4d27628124..7d1523197a8 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -2522,10 +2522,12 @@ static LRESULT CALLBACK test_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LP static void test_message_info(void) { + INPUT_MESSAGE_SOURCE msg_src, msg_src_expected; DWORD_PTR ret, expected; HWND hwnd; WNDCLASSA cls; MSG msg; + BOOL bret; memset(&cls, 0, sizeof(cls)); cls.lpfnWndProc = test_window_proc; @@ -2535,6 +2537,21 @@ static void test_message_info(void) RegisterClassA( &cls ); hwnd = CreateWindowExA( 0, "Test class", NULL, WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, NULL ); ShowWindow( hwnd, SW_SHOW ); + + SetLastError( 0xdeadbeef ); + bret = NtUserGetCurrentInputMessageSource( NULL ); + ok( !bret && GetLastError() == ERROR_INVALID_PARAMETER, "got bret %d, error %lu.\n", bret, GetLastError() ); + + SetLastError( 0xdeadbeef ); + memset( &msg_src, 0xcc, sizeof(msg_src_expected) ); + bret = NtUserGetCurrentInputMessageSource( &msg_src ); + ok( bret && GetLastError() == 0xdeadbeef, "got bret %d, error %lu.\n", bret, GetLastError() ); + memset( &msg_src_expected, 0xcc, sizeof(msg_src_expected) ); + bret = GetCurrentInputMessageSource( &msg_src_expected ); + ok( bret, "got error %lu.\n", GetLastError() ); + ok( msg_src.deviceType == msg_src_expected.deviceType, "got %d, expected %d.\n", msg_src.deviceType, msg_src_expected.deviceType ); + ok( msg_src.originId == msg_src_expected.originId, "got %d, expected %d.\n", msg_src.originId, msg_src_expected.originId ); + while (PeekMessageA( &msg, NULL, 0, 0, PM_NOREMOVE )) { GetMessageA( &msg, NULL, 0, 0 ); @@ -2546,6 +2563,17 @@ static void test_message_info(void) ret = NtUserGetThreadState( USER_GET_THREAD_STATE_MSGEXTRAINFO ); ok( expected == 0xdeadbeef, "got %#Ix.\n", expected ); ok( ret == expected || broken( !ret ) /* Before Win10 1709 */, "got %#Ix, expected %#Ix.\n", ret, expected ); + + SetLastError( 0xdeadbeef ); + memset( &msg_src, 0xcc, sizeof(msg_src_expected) ); + bret = NtUserGetCurrentInputMessageSource( &msg_src ); + ok( bret && GetLastError() == 0xdeadbeef, "got bret %d, error %lu.\n", bret, GetLastError() ); + memset( &msg_src_expected, 0xcc, sizeof(msg_src_expected) ); + bret = GetCurrentInputMessageSource( &msg_src_expected ); + ok( bret, "got error %lu.\n", GetLastError() ); + ok( msg_src.deviceType == msg_src_expected.deviceType, "got %d, expected %d.\n", msg_src.deviceType, msg_src_expected.deviceType ); + ok( msg_src.originId == msg_src_expected.originId, "got %d, expected %d.\n", msg_src.originId, msg_src_expected.originId ); + TranslateMessage( &msg ); DispatchMessageA( &msg ); } diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 899b2d815d3..0e71ced3819 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -997,7 +997,7 @@ @ stub NtUserGetControlBrush @ stub NtUserGetControlColor @ stub NtUserGetCurrentDpiInfoForWindow -@ stub NtUserGetCurrentInputMessageSource +@ stdcall -syscall NtUserGetCurrentInputMessageSource(ptr) @ stdcall -syscall NtUserGetCursor() @ stdcall -syscall NtUserGetCursorFrameInfo(long long ptr ptr) @ stdcall -syscall NtUserGetCursorInfo(ptr) diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 487c2e56072..79bc47de17d 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -2416,6 +2416,13 @@ NTSTATUS WINAPI wow64_NtUserGetClipboardViewer( UINT *args ) return HandleToUlong( NtUserGetClipboardViewer() ); } +NTSTATUS WINAPI wow64_NtUserGetCurrentInputMessageSource( UINT *args ) +{ + INPUT_MESSAGE_SOURCE *source = get_ptr( &args ); + + return NtUserGetCurrentInputMessageSource( source ); +} + NTSTATUS WINAPI wow64_NtUserGetCursor( UINT *args ) { return HandleToUlong( NtUserGetCursor() ); diff --git a/include/ntuser.h b/include/ntuser.h index 565a884afea..f2a8605f92e 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -795,6 +795,7 @@ W32KAPI INT WINAPI NtUserGetClipboardFormatName( UINT format, WCHAR *buffer, W32KAPI HWND WINAPI NtUserGetClipboardOwner(void); W32KAPI DWORD WINAPI NtUserGetClipboardSequenceNumber(void); W32KAPI HWND WINAPI NtUserGetClipboardViewer(void); +W32KAPI BOOL WINAPI NtUserGetCurrentInputMessageSource( INPUT_MESSAGE_SOURCE *source ); W32KAPI HCURSOR WINAPI NtUserGetCursor(void); W32KAPI HCURSOR WINAPI NtUserGetCursorFrameInfo( HCURSOR hCursor, DWORD istep, DWORD *rate_jiffies, DWORD *num_steps ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7172
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=150985 Your paranoid android. === debian11 (build log) === /usr/bin/i686-w64-mingw32-ld: tmp67b219fb/win32u-00000000.spec.o:fake:(.edata+0xfc4): undefined reference to `NtUserGetCurrentInputMessageSource(a)4' /usr/bin/i686-w64-mingw32-ld: tmp67b219fb/win32u-00000000.spec.o:fake:(.edata+0x1164): undefined reference to `NtUserGetThreadState(a)4' collect2: error: ld returned 1 exit status Task: The win32 Wine build failed === debian11b (build log) === /usr/bin/x86_64-w64-mingw32-ld: tmp67d0d51b/win32u-00000000.spec.o:fake:(.edata+0xfc0): undefined reference to `NtUserGetCurrentInputMessageSource' /usr/bin/x86_64-w64-mingw32-ld: tmp67d0d51b/win32u-00000000.spec.o:fake:(.edata+0x1160): undefined reference to `NtUserGetThreadState' collect2: error: ld returned 1 exit status Task: The wow64 Wine build failed
The Finals now depends on that. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7172#note_92549
participants (3)
-
Marvin -
Paul Gofman -
Paul Gofman (@gofman)