Commit e445303ab45 (user32/tests: Make a few more messages optional., 2014-03-20) modified test_unicode_wm_char so that it skips non-essential messages (e.g. WM_DWMNCRENDERINGCHANGED) from GetMessageW.
Extend this for messages from GetMessageA as well.
Also, handle the case where no messages other than WM_QUIT are received at all.
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v1 -> v2: add patch, fixes intermittent test failures on w1064
dlls/user32/tests/msg.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index a2adf56565d..918ee97bfa5 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -15182,6 +15182,16 @@ static void test_dbcs_wm_char(void) DestroyWindow(hwnd2); }
+static BOOL get_next_msg( BOOL (*WINAPI getmessage)(MSG *, HWND, UINT, UINT), + MSG *msg, HWND hwnd ) +{ + while ((*getmessage)( msg, hwnd, 0, 0 )) + { + if (!ignore_message( msg->message )) return TRUE; + } + return FALSE; +} + static void test_unicode_wm_char(void) { HWND hwnd; @@ -15212,11 +15222,7 @@ static void test_unicode_wm_char(void)
PostMessageW( hwnd, WM_CHAR, 0x3b1, 0 );
- while (GetMessageW( &msg, hwnd, 0, 0 )) - { - if (!ignore_message( msg.message )) break; - } - + ok( get_next_msg( GetMessageW, &msg, hwnd ), "expected a recongized message\n" ); ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd ); ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message ); ok( msg.wParam == 0x3b1, "bad wparam %Ix\n", msg.wParam ); @@ -15236,7 +15242,7 @@ static void test_unicode_wm_char(void) /* greek alpha -> 'a' in cp1252 */ PostMessageW( hwnd, WM_CHAR, 0x3b1, 0 );
- ok( GetMessageA( &msg, hwnd, 0, 0 ), "no message\n" ); + ok( get_next_msg( GetMessageA, &msg, hwnd ), "expected a recognized message\n" ); ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd ); ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message ); ok( msg.wParam == 0x61, "bad wparam %Ix\n", msg.wParam ); @@ -15257,7 +15263,7 @@ static void test_unicode_wm_char(void) /* greek alpha -> 0xe1 in cp1253 */ PostMessageW( hwnd, WM_CHAR, 0x3b1, 0 );
- ok( GetMessageA( &msg, hwnd, 0, 0 ), "no message\n" ); + ok( get_next_msg( GetMessageA, &msg, hwnd ), "expected a recognized message\n" ); ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd ); ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message ); ok( msg.wParam == 0xe1, "bad wparam %Ix\n", msg.wParam );
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v1 -> v2: no changes
include/winuser.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/winuser.h b/include/winuser.h index f9af7db0331..3d0451adff6 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -97,6 +97,7 @@ typedef void* HPOWERNOTIFY; #define UOI_NAME 2 #define UOI_TYPE 3 #define UOI_USER_SID 4 +#define UOI_TIMERPROC_EXCEPTION_SUPPRESSION 7
#define WSF_VISIBLE 1 #define DF_ALLOWOTHERACCOUNTHOOK 1
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v1 -> v2: - shorten line width - s/SetUserObjectInformation/SetUserObjectInformationW/ - add case for UOI config performed prior to the dispatch - mark UOI_TIMERPROC_EXCEPTION_SUPPRESSION exception handling as broken - deal with EXCEPTION_BREAKPOINT IP rewinding on x86/x64 architectures. - explicitly test for exception handling phase - skip exception tests if on non-PE build or compiler has no SEH support
dlls/user32/tests/msg.c | 189 ++++++++++++++++++++++++++++++++++++++++ include/wine/asm.h | 1 + 2 files changed, 190 insertions(+)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 918ee97bfa5..7fb8469ec2a 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -34,6 +34,8 @@ #include "commctrl.h"
#include "wine/test.h" +#include "wine/asm.h" +#include "wine/exception.h"
#define MDI_FIRST_CHILD_ID 2004
@@ -10647,11 +10649,33 @@ static void CALLBACK callback_count(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWOR count++; }
+enum timer_exception_phase { + TIMER_EXCEPTION_INITIAL, + TIMER_EXCEPTION_RAISED, + TIMER_EXCEPTION_CONTINUE, + TIMER_EXCEPTION_CONTINUE_OK, +}; + static DWORD exception; +static enum timer_exception_phase timer_exc_phase; +static BOOL *tproc_exc_suppress = NULL; static void CALLBACK callback_exception(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { + if (tproc_exc_suppress) + { + BOOL res = SetUserObjectInformationW(GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, + tproc_exc_suppress, sizeof(*tproc_exc_suppress)); + todo_wine + ok(res, "SetUserObjectInformationW error %lu\n", GetLastError()); + tproc_exc_suppress = NULL; + } + count++; + timer_exc_phase = TIMER_EXCEPTION_RAISED; RaiseException(exception, 0, 0, NULL); + ok(timer_exc_phase == TIMER_EXCEPTION_CONTINUE, + "expected phase %d, got %d\n", TIMER_EXCEPTION_CONTINUE, timer_exc_phase); + timer_exc_phase = TIMER_EXCEPTION_CONTINUE_OK; }
static DWORD WINAPI timer_thread_proc(LPVOID x) @@ -10813,10 +10837,127 @@ static void test_timers_no_wnd(void) while (i > 0) KillTimer(NULL, ids[--i]); }
+static LONG WINAPI timer_exception_filter(EXCEPTION_POINTERS *eptr) +{ + if (timer_exc_phase == TIMER_EXCEPTION_RAISED && + eptr->ExceptionRecord->ExceptionCode == exception && + eptr->ExceptionRecord->ExceptionFlags == 0 && + eptr->ExceptionRecord->NumberParameters == 0) + { + if (eptr->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) + { +#if defined(__i386__) + if ((ULONG_PTR)eptr->ExceptionRecord->ExceptionAddress == eptr->ContextRecord->Eip + 1) + eptr->ContextRecord->Eip++; /* cancel EIP rewinding */ +#elif defined(__x86_64__) + if ((ULONG_PTR)eptr->ExceptionRecord->ExceptionAddress == eptr->ContextRecord->Rip + 1) + eptr->ContextRecord->Rip++; /* cancel RIP rewinding */ +#endif + } + timer_exc_phase = TIMER_EXCEPTION_CONTINUE; + return EXCEPTION_CONTINUE_EXECUTION; + } + + return EXCEPTION_CONTINUE_SEARCH; +} + +extern void dispatch_message_handle_exception(const MSG *msg); + +#if defined(USE_COMPILER_EXCEPTIONS) || defined(__i386__) +void dispatch_message_handle_exception(const MSG *msg) +{ + __TRY + { + DispatchMessageA( msg ); + } + __EXCEPT(timer_exception_filter) + { + } + __ENDTRY +} +#else +EXCEPTION_DISPOSITION WINAPI timer_exception_handler( EXCEPTION_RECORD *rec, + void *frame, + CONTEXT *context, + DISPATCHER_CONTEXT *dispatch ) +{ + EXCEPTION_POINTERS ptrs = { rec, context }; + + if (timer_exception_filter( &ptrs ) == EXCEPTION_CONTINUE_EXECUTION) + return ExceptionContinueExecution; + + return ExceptionContinueSearch; +} +#if defined(__x86_64__) && defined(__ASM_SEH_SUPPORTED) +__ASM_GLOBAL_FUNC( dispatch_message_handle_exception, + __ASM_SEH(".seh_handler " __ASM_NAME("timer_exception_handler") ", @except\n\t") + "subq $0x28,%rsp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 0x28\n\t") + __ASM_SEH(".seh_stackalloc 0x28\n\t") + __ASM_SEH(".seh_endprologue\n\t") + "callq *__imp_DispatchMessageA(%rip)\n\t" + "nop\n\t" + "addq $0x28,%rsp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset -0x28\n\t") + "ret" ); +#elif defined(__arm__) && defined(__WINE_PE_BUILD) +__ASM_GLOBAL_FUNC( dispatch_message_handle_exception, + "1:\n\t" + "push {r4,lr}\n\t" + __ASM_CFI(".cfi_def_cfa_offset 8\n\t") + __ASM_CFI(".cfi_offset r4, -8\n\t") + __ASM_CFI(".cfi_offset lr, -4\n\t") + "ldr ip, =__imp_DispatchMessageA\n\t" + "ldr ip, [ip]\n\t" + "blx ip\n\t" + "pop {r4,pc}\n" + "2:\n\t" + ".section ".pdata", "dr"\n\t" + ".rva " __ASM_NAME("dispatch_message_handle_exception") "\n\t" + ".rva .Lunwind__dispatch_message_handle_exception\n\t" + ".section ".xdata", "dr"\n" + ".Lunwind__dispatch_message_handle_exception:\n\t" + ".long 0x10100000 + ((2b - 1b) / 2)\n\t" + ".long 0xfbfbffd4\n\t" + ".rva " __ASM_NAME("timer_exception_handler") "\n\t" + ".text" ); +#elif defined(__aarch64__) && defined(__ASM_SEH_SUPPORTED) +__ASM_GLOBAL_FUNC( dispatch_message_handle_exception, + __ASM_SEH(".seh_handler " __ASM_NAME("timer_exception_handler") ", @except\n\t") + "stp x29, x30, [sp, #-16]!\n\t" + __ASM_CFI(".cfi_def_cfa_offset 16\n\t") + __ASM_CFI(".cfi_offset x29, -16\n\t") + __ASM_CFI(".cfi_offset x30, -8\n\t") + __ASM_SEH(".seh_save_fplr_x 16\n\t") + __ASM_SEH(".seh_endprologue\n\t") + "mov x29, sp\n\t" + "adrp x8, __imp_DispatchMessageA\n\t" + "ldr x8, [x8, :lo12:__imp_DispatchMessageA]\n\t" + "blr x8\n\t" + "nop\n\t" + __ASM_SEH(".seh_startepilogue\n\t") + "ldp x29, x30, [sp], #16\n\t" + __ASM_CFI(".cfi_restore x29\n\t") + __ASM_CFI(".cfi_restore x30\n\t") + __ASM_CFI(".cfi_def_cfa sp, 0\n\t") + __ASM_SEH(".seh_save_fplr_x 16\n\t") + __ASM_SEH(".seh_endepilogue\n\t") + "ret" ); +#else +void dispatch_message_handle_exception(const MSG *msg) +{ + skip("dispatch_message_handle_exception not implemented on this build configuration\n"); + count++; + timer_exc_phase = TIMER_EXCEPTION_CONTINUE_OK; +} +#endif +#endif + static void test_timers_exception(DWORD code) { UINT_PTR id; MSG msg; + BOOL ret, value;
exception = code; id = SetTimer(NULL, 0, 1000, callback_exception); @@ -10828,8 +10969,56 @@ static void test_timers_exception(DWORD code) msg.lParam = (LPARAM)callback_exception;
count = 0; + timer_exc_phase = TIMER_EXCEPTION_INITIAL; DispatchMessageA(&msg); ok(count == 1, "did not get one count as expected (%i).\n", count); + ok(timer_exc_phase == TIMER_EXCEPTION_RAISED, + "expected phase %d, got %d\n", TIMER_EXCEPTION_RAISED, timer_exc_phase); + + value = FALSE; + ret = SetUserObjectInformationW(GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, + &value, sizeof(value)); + if (!ret && GetLastError() == ERROR_INVALID_FUNCTION) + { + win_skip("UOI_TIMERPROC_EXCEPTION_SUPPRESSION not supported on this platform\n"); + } + else + { + todo_wine + ok(ret, "SetUserObjectInformationW error %lu\n", GetLastError()); + + count = 0; + timer_exc_phase = TIMER_EXCEPTION_INITIAL; + dispatch_message_handle_exception(&msg); + ok(count == 1, "expected count to be 1, got %d\n", count); + todo_wine + ok(timer_exc_phase == TIMER_EXCEPTION_CONTINUE_OK || + broken(timer_exc_phase == TIMER_EXCEPTION_RAISED) /* < win10 1507 */, + "expected phase %d, got %d\n", TIMER_EXCEPTION_CONTINUE_OK, timer_exc_phase); + + value = TRUE; + ret = SetUserObjectInformationW(GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, + &value, sizeof(value)); + todo_wine + ok(ret, "SetUserObjectInformationW error %lu\n", GetLastError()); + + value = FALSE; + tproc_exc_suppress = &value; + count = 0; + timer_exc_phase = TIMER_EXCEPTION_INITIAL; + dispatch_message_handle_exception(&msg); + ok(count == 1, "expected count to be 1, got %d\n", count); + todo_wine + ok(timer_exc_phase == TIMER_EXCEPTION_CONTINUE_OK || + broken(timer_exc_phase == TIMER_EXCEPTION_RAISED) /* < win10 1507 */, + "expected phase %d, got %d\n", TIMER_EXCEPTION_CONTINUE_OK, timer_exc_phase); + + value = TRUE; + ret = SetUserObjectInformationW(GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, + &value, sizeof(value)); + todo_wine + ok(ret, "SetUserObjectInformationW error %lu\n", GetLastError()); + }
KillTimer(NULL, id); } diff --git a/include/wine/asm.h b/include/wine/asm.h index 0547ee94b19..9200491afd0 100644 --- a/include/wine/asm.h +++ b/include/wine/asm.h @@ -50,6 +50,7 @@ # define __ASM_SEH(str) # else # define __ASM_SEH(str) str +# define __ASM_SEH_SUPPORTED # endif #else # define __ASM_SEH(str)
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v1 -> v2: adjust for changes in previous patch
dlls/user32/message.c | 11 ++++++++++- dlls/user32/tests/msg.c | 6 ------ dlls/user32/user32.spec | 2 +- dlls/user32/user_main.c | 1 + dlls/user32/user_private.h | 1 + dlls/user32/winstation.c | 23 ++++++++++++++++++++++- 6 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 611f603fc1e..8be708a118d 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -851,6 +851,15 @@ BOOL WINAPI TranslateMessage( const MSG *msg ) }
+static LONG WINAPI timerproc_exception_filter(EXCEPTION_POINTERS *eptr) +{ + if (suppress_timerproc_exception) + return EXCEPTION_EXECUTE_HANDLER; + + return EXCEPTION_CONTINUE_SEARCH; +} + + /*********************************************************************** * DispatchMessageA (USER32.@) * @@ -870,7 +879,7 @@ LRESULT WINAPI DECLSPEC_HOTPATCH DispatchMessageA( const MSG* msg ) retval = CallWindowProcA( (WNDPROC)msg->lParam, msg->hwnd, msg->message, msg->wParam, GetTickCount() ); } - __EXCEPT_ALL + __EXCEPT(timerproc_exception_filter) { retval = 0; } diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 7fb8469ec2a..5125f8d77ac 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -10665,7 +10665,6 @@ static void CALLBACK callback_exception(HWND hwnd, UINT uMsg, UINT_PTR idEvent, { BOOL res = SetUserObjectInformationW(GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, tproc_exc_suppress, sizeof(*tproc_exc_suppress)); - todo_wine ok(res, "SetUserObjectInformationW error %lu\n", GetLastError()); tproc_exc_suppress = NULL; } @@ -10984,14 +10983,12 @@ static void test_timers_exception(DWORD code) } else { - todo_wine ok(ret, "SetUserObjectInformationW error %lu\n", GetLastError());
count = 0; timer_exc_phase = TIMER_EXCEPTION_INITIAL; dispatch_message_handle_exception(&msg); ok(count == 1, "expected count to be 1, got %d\n", count); - todo_wine ok(timer_exc_phase == TIMER_EXCEPTION_CONTINUE_OK || broken(timer_exc_phase == TIMER_EXCEPTION_RAISED) /* < win10 1507 */, "expected phase %d, got %d\n", TIMER_EXCEPTION_CONTINUE_OK, timer_exc_phase); @@ -10999,7 +10996,6 @@ static void test_timers_exception(DWORD code) value = TRUE; ret = SetUserObjectInformationW(GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, &value, sizeof(value)); - todo_wine ok(ret, "SetUserObjectInformationW error %lu\n", GetLastError());
value = FALSE; @@ -11008,7 +11004,6 @@ static void test_timers_exception(DWORD code) timer_exc_phase = TIMER_EXCEPTION_INITIAL; dispatch_message_handle_exception(&msg); ok(count == 1, "expected count to be 1, got %d\n", count); - todo_wine ok(timer_exc_phase == TIMER_EXCEPTION_CONTINUE_OK || broken(timer_exc_phase == TIMER_EXCEPTION_RAISED) /* < win10 1507 */, "expected phase %d, got %d\n", TIMER_EXCEPTION_CONTINUE_OK, timer_exc_phase); @@ -11016,7 +11011,6 @@ static void test_timers_exception(DWORD code) value = TRUE; ret = SetUserObjectInformationW(GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, &value, sizeof(value)); - todo_wine ok(ret, "SetUserObjectInformationW error %lu\n", GetLastError()); }
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index 783684e8cc7..6e288f6e315 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -714,7 +714,7 @@ @ stdcall SetThreadDpiAwarenessContext(ptr) @ stdcall SetTimer(long long long ptr) @ stdcall SetUserObjectInformationA(long long ptr long) -@ stdcall SetUserObjectInformationW(long long ptr long) NtUserSetObjectInformation +@ stdcall SetUserObjectInformationW(long long ptr long) @ stdcall SetUserObjectSecurity(long ptr ptr) @ stdcall SetWinEventHook(long long long ptr long long long) @ stdcall SetWindowCompositionAttribute(ptr ptr) diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index c477d0325d3..7e37ff36251 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -37,6 +37,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(graphics); WINE_DECLARE_DEBUG_CHANNEL(message);
HMODULE user32_module = 0; +BOOL suppress_timerproc_exception = TRUE;
static DWORD exiting_thread_id;
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 52e57a5e6f1..8970569d45c 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -66,6 +66,7 @@ static inline struct user_thread_info *get_user_thread_info(void) }
extern HMODULE user32_module DECLSPEC_HIDDEN; +extern BOOL suppress_timerproc_exception DECLSPEC_HIDDEN;
struct dce; struct tagWND; diff --git a/dlls/user32/winstation.c b/dlls/user32/winstation.c index c0c8ec7a14f..495e22727dc 100644 --- a/dlls/user32/winstation.c +++ b/dlls/user32/winstation.c @@ -389,12 +389,33 @@ BOOL WINAPI GetUserObjectInformationA( HANDLE handle, INT index, LPVOID info, DW }
+/****************************************************************************** + * SetUserObjectInformationW (USER32.@) + */ +BOOL WINAPI SetUserObjectInformationW( HANDLE handle, INT index, LPVOID info, DWORD len ) +{ + if (index == UOI_TIMERPROC_EXCEPTION_SUPPRESSION) + { + if (handle != GetCurrentProcess() || len != sizeof(BOOL)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + suppress_timerproc_exception = *(const BOOL *)info; + return TRUE; + } + + return NtUserSetObjectInformation( handle, index, info, len ); +} + + /****************************************************************************** * SetUserObjectInformationA (USER32.@) */ BOOL WINAPI SetUserObjectInformationA( HANDLE handle, INT index, LPVOID info, DWORD len ) { - return NtUserSetObjectInformation( handle, index, info, len ); + return SetUserObjectInformationW( handle, index, info, len ); }
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v1 -> v2: - remove test for invalid info index - inconsistent across Windows versions
dlls/win32u/tests/win32u.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index 401913f0aee..f3e4c876b36 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -505,6 +505,39 @@ static void test_window_text(void) DestroyWindow( hwnd ); }
+static void test_NtUserSetObjectInformation(void) +{ + SetLastError( 0xdeadbeef ); + NtUserSetObjectInformation( GetProcessWindowStation(), UOI_FLAGS, (void *)NULL, sizeof(USEROBJECTFLAGS) ); + todo_wine + ok( GetLastError() == ERROR_NOACCESS, "NtUserSetObjectInformation error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + NtUserSetObjectInformation( GetThreadDesktop(GetCurrentThreadId()), UOI_FLAGS, (void *)NULL, sizeof(USEROBJECTFLAGS) ); + todo_wine + ok( GetLastError() == ERROR_NOACCESS, "NtUserSetObjectInformation error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + NtUserSetObjectInformation( GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, (void *)TRUE, 0 ); + todo_wine + ok( GetLastError() == 0xdeadbeef, "NtUserSetObjectInformation error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + NtUserSetObjectInformation( GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, (void *)0xdeadbeef, 0xdeadbeef ); + todo_wine + ok( GetLastError() == 0xdeadbeef, "NtUserSetObjectInformation error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + NtUserSetObjectInformation( GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, (void *)-1, -1 ); + todo_wine + ok( GetLastError() == 0xdeadbeef, "NtUserSetObjectInformation error %lu\n", GetLastError() ); + + SetLastError( 0xdeadbeef ); + NtUserSetObjectInformation( NULL, UOI_TIMERPROC_EXCEPTION_SUPPRESSION, (void *)-1, -1 ); + todo_wine + ok( GetLastError() == 0xdeadbeef, "NtUserSetObjectInformation error %lu\n", GetLastError() ); +} + START_TEST(win32u) { /* native win32u.dll fails if user32 is not loaded, so make sure it's fully initialized */ @@ -519,4 +552,5 @@ START_TEST(win32u) test_window_text();
test_NtUserCloseWindowStation(); + test_NtUserSetObjectInformation(); }
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v1 -> v2: no changes
dlls/win32u/tests/win32u.c | 4 ---- dlls/win32u/winstation.c | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c index f3e4c876b36..3d5f48bf41e 100644 --- a/dlls/win32u/tests/win32u.c +++ b/dlls/win32u/tests/win32u.c @@ -519,22 +519,18 @@ static void test_NtUserSetObjectInformation(void)
SetLastError( 0xdeadbeef ); NtUserSetObjectInformation( GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, (void *)TRUE, 0 ); - todo_wine ok( GetLastError() == 0xdeadbeef, "NtUserSetObjectInformation error %lu\n", GetLastError() );
SetLastError( 0xdeadbeef ); NtUserSetObjectInformation( GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, (void *)0xdeadbeef, 0xdeadbeef ); - todo_wine ok( GetLastError() == 0xdeadbeef, "NtUserSetObjectInformation error %lu\n", GetLastError() );
SetLastError( 0xdeadbeef ); NtUserSetObjectInformation( GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, (void *)-1, -1 ); - todo_wine ok( GetLastError() == 0xdeadbeef, "NtUserSetObjectInformation error %lu\n", GetLastError() );
SetLastError( 0xdeadbeef ); NtUserSetObjectInformation( NULL, UOI_TIMERPROC_EXCEPTION_SUPPRESSION, (void *)-1, -1 ); - todo_wine ok( GetLastError() == 0xdeadbeef, "NtUserSetObjectInformation error %lu\n", GetLastError() ); }
diff --git a/dlls/win32u/winstation.c b/dlls/win32u/winstation.c index 8e47c97510e..15c77da0c31 100644 --- a/dlls/win32u/winstation.c +++ b/dlls/win32u/winstation.c @@ -372,6 +372,8 @@ BOOL WINAPI NtUserSetObjectInformation( HANDLE handle, INT index, void *info, DW BOOL ret; const USEROBJECTFLAGS *obj_flags = info;
+ if (index == UOI_TIMERPROC_EXCEPTION_SUPPRESSION) return TRUE; + if (index != UOI_FLAGS || !info || len < sizeof(*obj_flags)) { SetLastError( ERROR_INVALID_PARAMETER );
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=112963
Your paranoid android.
=== w10pro64_he (64 bit report) ===
user32: msg.c:12807: Test failed: message time not advanced: 4c6c54 4c6c54 msg.c:12808: Test failed: coords not changed: (101 101) (101 101) msg.c:12825: Test failed: message time not advanced: 4c6c54 4c6c54 msg.c:12826: Test failed: coords not changed: (101 101) (101 101)