[PATCH 2/5] user32/tests: Add tests for UOI_TIMERPROC_EXCEPTION_SUPPRESSION.

Jinoh Kang jinoh.kang.kr at gmail.com
Mon Apr 18 05:48:59 CDT 2022


Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
 dlls/user32/tests/msg.c | 130 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 130 insertions(+)

diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index a2adf56565d..a2264361c24 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
 
@@ -10648,8 +10650,17 @@ static void CALLBACK callback_count(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWOR
 }
 
 static DWORD exception;
+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++;
     RaiseException(exception, 0, 0, NULL);
 }
@@ -10813,10 +10824,116 @@ static void test_timers_no_wnd(void)
     while (i > 0) KillTimer(NULL, ids[--i]);
 }
 
+static LONG WINAPI timer_exception_filter(EXCEPTION_POINTERS *eptr)
+{
+    if (eptr->ExceptionRecord->ExceptionCode == exception &&
+        eptr->ExceptionRecord->ExceptionFlags == 0 &&
+        eptr->ExceptionRecord->NumberParameters == 0)
+    {
+        exception = 0;
+        return EXCEPTION_CONTINUE_EXECUTION;
+    }
+
+    return EXCEPTION_CONTINUE_SEARCH;
+}
+
+#if defined(USE_COMPILER_EXCEPTIONS) || defined(__i386__)
+static 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;
+}
+
+extern void dispatch_message_handle_exception(const MSG *msg);
+#if defined(__x86_64__)
+__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__)
+__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__)
+__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\n");
+    count++;
+    exception = 0;
+}
+#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);
@@ -10831,6 +10948,19 @@ static void test_timers_exception(DWORD code)
     DispatchMessageA(&msg);
     ok(count == 1, "did not get one count as expected (%i).\n", count);
 
+    value = FALSE;
+    tproc_exc_suppress = &value;
+    count = 0;
+    dispatch_message_handle_exception(&msg);
+    ok(count == 1, "expected count to be 1, got %d\n", count);
+    todo_wine
+    ok(exception == 0, "exception from timer procedure shall be propagated\n");
+
+    value = TRUE;
+    ret = SetUserObjectInformationW(GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, &value, sizeof(value));
+    todo_wine
+    ok(ret, "SetUserObjectInformation error %lu\n", GetLastError());
+
     KillTimer(NULL, id);
 }
 
-- 
2.34.1




More information about the wine-devel mailing list