From: Paul Gofman pgofman@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 );
From: Paul Gofman pgofman@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 );
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@4' /usr/bin/i686-w64-mingw32-ld: tmp67b219fb/win32u-00000000.spec.o:fake:(.edata+0x1164): undefined reference to `NtUserGetThreadState@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.