user32: Add exception handling for timer callbacks.
This commit is contained in:
parent
9196e2ed21
commit
f20f411925
|
@ -43,6 +43,7 @@
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
#include "controls.h"
|
#include "controls.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
#include "wine/exception.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msg);
|
WINE_DEFAULT_DEBUG_CHANNEL(msg);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||||
|
@ -3065,8 +3066,20 @@ LRESULT WINAPI DispatchMessageA( const MSG* msg )
|
||||||
/* Process timer messages */
|
/* Process timer messages */
|
||||||
if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
|
if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
|
||||||
{
|
{
|
||||||
if (msg->lParam) return CallWindowProcA( (WNDPROC)msg->lParam, msg->hwnd,
|
if (msg->lParam)
|
||||||
msg->message, msg->wParam, GetTickCount() );
|
{
|
||||||
|
__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;
|
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
|
* If the lpMsg parameter points to a WM_TIMER message and the
|
||||||
* parameter of the WM_TIMER message is not NULL, the lParam parameter
|
* parameter of the WM_TIMER message is not NULL, the lParam parameter
|
||||||
* points to the function that is called instead of the window
|
* 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.
|
* The message must be valid.
|
||||||
*
|
*
|
||||||
|
@ -3123,8 +3137,20 @@ LRESULT WINAPI DispatchMessageW( const MSG* msg )
|
||||||
/* Process timer messages */
|
/* Process timer messages */
|
||||||
if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
|
if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
|
||||||
{
|
{
|
||||||
if (msg->lParam) return CallWindowProcW( (WNDPROC)msg->lParam, msg->hwnd,
|
if (msg->lParam)
|
||||||
msg->message, msg->wParam, GetTickCount() );
|
{
|
||||||
|
__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;
|
if (!msg->hwnd) return 0;
|
||||||
|
|
||||||
|
|
|
@ -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
|
#define TIMER_ID 0x19
|
||||||
|
|
||||||
static DWORD WINAPI timer_thread_proc(LPVOID x)
|
static DWORD WINAPI timer_thread_proc(LPVOID x)
|
||||||
|
@ -7834,6 +7840,7 @@ static void test_timers(void)
|
||||||
{
|
{
|
||||||
struct timer_info info;
|
struct timer_info info;
|
||||||
DWORD id;
|
DWORD id;
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
info.hWnd = CreateWindow ("TestWindowClass", NULL,
|
info.hWnd = CreateWindow ("TestWindowClass", NULL,
|
||||||
WS_OVERLAPPEDWINDOW ,
|
WS_OVERLAPPEDWINDOW ,
|
||||||
|
@ -7855,6 +7862,12 @@ static void test_timers(void)
|
||||||
|
|
||||||
ok( KillTimer(info.hWnd, TIMER_ID), "KillTimer failed\n");
|
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");
|
ok(DestroyWindow(info.hWnd), "failed to destroy window\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue