Peter Dons Tychsen : user32: Add exception handling for timer callbacks.

Alexandre Julliard julliard at winehq.org
Wed Sep 30 10:56:09 CDT 2009


Module: wine
Branch: master
Commit: f20f411925e789a2aecf740776f441335837ac5f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f20f411925e789a2aecf740776f441335837ac5f

Author: Peter Dons Tychsen <donpedro at tdcadsl.dk>
Date:   Wed Sep 30 01:39:25 2009 +0200

user32: Add exception handling for timer callbacks.

---

 dlls/user32/message.c   |   36 +++++++++++++++++++++++++++++++-----
 dlls/user32/tests/msg.c |   13 +++++++++++++
 2 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index 3f7a4cd..4e9a62c 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -43,6 +43,7 @@
 #include "win.h"
 #include "controls.h"
 #include "wine/debug.h"
+#include "wine/exception.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msg);
 WINE_DECLARE_DEBUG_CHANNEL(relay);
@@ -3065,8 +3066,20 @@ LRESULT WINAPI DispatchMessageA( const MSG* msg )
       /* Process timer messages */
     if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
     {
-        if (msg->lParam) return CallWindowProcA( (WNDPROC)msg->lParam, msg->hwnd,
-                                                 msg->message, msg->wParam, GetTickCount() );
+        if (msg->lParam)
+        {
+            __TRY
+            {
+                retval = CallWindowProcA( (WNDPROC)msg->lParam, msg->hwnd,
+                                          msg->message, msg->wParam, GetTickCount() );
+            }
+            __EXCEPT_PAGE_FAULT
+            {
+                retval = 0;
+            }
+            __ENDTRY
+            return retval;
+        }
     }
     if (!msg->hwnd) return 0;
 
@@ -3103,7 +3116,8 @@ LRESULT WINAPI DispatchMessageA( const MSG* msg )
  * If the lpMsg parameter points to a WM_TIMER message and the
  * parameter of the WM_TIMER message is not NULL, the lParam parameter
  * points to the function that is called instead of the window
- * procedure.
+ * procedure. The function stored in lParam (timer callback) is protected
+ * from causing page-faults.
  *
  * The message must be valid.
  *
@@ -3123,8 +3137,20 @@ LRESULT WINAPI DispatchMessageW( const MSG* msg )
       /* Process timer messages */
     if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
     {
-        if (msg->lParam) return CallWindowProcW( (WNDPROC)msg->lParam, msg->hwnd,
-                                                 msg->message, msg->wParam, GetTickCount() );
+        if (msg->lParam)
+        {
+            __TRY
+            {
+                retval = CallWindowProcW( (WNDPROC)msg->lParam, msg->hwnd,
+                                          msg->message, msg->wParam, GetTickCount() );
+            }
+            __EXCEPT_PAGE_FAULT
+            {
+                retval = 0;
+            }
+            __ENDTRY
+            return retval;
+        }
     }
     if (!msg->hwnd) return 0;
 
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 9208c9d..aeb1b62 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -7813,6 +7813,12 @@ static VOID CALLBACK tfunc(HWND hwnd, UINT uMsg, UINT_PTR id, DWORD dwTime)
 {
 }
 
+static VOID CALLBACK tfunc_crash(HWND hwnd, UINT uMsg, UINT_PTR id, DWORD dwTime)
+{
+    /* Crash on purpose */
+    *(volatile int *)0 = 2;
+}
+
 #define TIMER_ID  0x19
 
 static DWORD WINAPI timer_thread_proc(LPVOID x)
@@ -7834,6 +7840,7 @@ static void test_timers(void)
 {
     struct timer_info info;
     DWORD id;
+    MSG msg;
 
     info.hWnd = CreateWindow ("TestWindowClass", NULL,
        WS_OVERLAPPEDWINDOW ,
@@ -7855,6 +7862,12 @@ static void test_timers(void)
 
     ok( KillTimer(info.hWnd, TIMER_ID), "KillTimer failed\n");
 
+    /* Test timer callback with crash */
+    info.id = SetTimer(info.hWnd, TIMER_ID, 0, tfunc_crash);
+    ok(info.id, "SetTimer failed\n");
+    Sleep(150);
+    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+
     ok(DestroyWindow(info.hWnd), "failed to destroy window\n");
 }
 




More information about the wine-cvs mailing list