USER32: allow threads to set timers on other threads windows

Mike McCormack mike at codeweavers.com
Sat Nov 13 03:58:02 CST 2004


ChangeLog:
* allow threads to set timers on other threads windows
-------------- next part --------------
Index: windows/timer.c
===================================================================
RCS file: /home/wine/wine/windows/timer.c,v
retrieving revision 1.44
diff -u -r1.44 timer.c
--- windows/timer.c	26 Nov 2003 22:29:30 -0000	1.44
+++ windows/timer.c	13 Nov 2004 09:42:06 -0000
@@ -130,12 +130,7 @@
     int i;
     TIMER * pTimer;
     WNDPROC winproc = 0;
-
-    if (hwnd && !(hwnd = WIN_IsCurrentThread( hwnd )))
-    {
-        SetLastError( ERROR_INVALID_WINDOW_HANDLE );
-        return 0;
-    }
+    DWORD tid, pid;
 
     if (!timeout)
       {       /* timeout==0 is a legal argument  UB 990821*/
@@ -145,6 +140,27 @@
 
     EnterCriticalSection( &csTimer );
 
+    /* get the id of the thread and process we're about to add the timer to */
+    if (hwnd)
+    {
+        tid = GetWindowThreadProcessId( hwnd, &pid );
+        if (!tid)
+        {
+            LeaveCriticalSection( &csTimer );
+            return FALSE;
+        }
+
+        /* don't allow setting timers on other process windows */
+        if (pid != GetCurrentProcessId())
+        {
+            ERR("trying to set a timer on process %ld\n", pid);
+            LeaveCriticalSection( &csTimer );
+            return FALSE;
+        }
+    }
+    else
+        tid = GetCurrentThreadId();
+
       /* Check if there's already a timer with the same hwnd and id */
 
     for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
@@ -188,7 +204,7 @@
       /* Add the timer */
 
     pTimer->hwnd    = hwnd;
-    pTimer->thread  = GetCurrentThreadId();
+    pTimer->thread  = tid;
     pTimer->msg     = sys ? WM_SYSTIMER : WM_TIMER;
     pTimer->id      = id;
     pTimer->timeout = timeout;
Index: server/queue.c
===================================================================
RCS file: /home/wine/wine/server/queue.c,v
retrieving revision 1.45
diff -u -r1.45 queue.c
--- server/queue.c	27 Oct 2004 21:55:00 -0000	1.45
+++ server/queue.c	13 Nov 2004 09:42:07 -0000
@@ -1569,15 +1569,28 @@
 DECL_HANDLER(set_win_timer)
 {
     struct timer *timer;
-    struct msg_queue *queue = get_current_queue();
-    user_handle_t win = get_user_full_handle( req->win );
+    struct msg_queue *queue = NULL;
+    user_handle_t win = 0;
+    struct thread *thread = NULL;
 
-    if (!queue) return;
+    if (req->win)
+    {
+        win = get_user_full_handle( req->win );
+        if (win && (thread = get_window_thread( win )))
+        {
+            queue = thread->queue;
+            release_object( thread );
+        }
+    }
+    else
+        queue = get_current_queue();
 
     /* remove it if it existed already */
     if (win) kill_timer( queue, win, req->msg, req->id );
 
-    if ((timer = set_timer( queue, req->rate )))
+    if (!queue)
+        set_error( STATUS_INVALID_PARAMETER );
+    else if ((timer = set_timer( queue, req->rate )))
     {
         timer->win    = win;
         timer->msg    = req->msg;
@@ -1589,7 +1602,21 @@
 /* kill a window timer */
 DECL_HANDLER(kill_win_timer)
 {
-    struct msg_queue *queue = current->queue;
+    struct msg_queue *queue = NULL;
+    user_handle_t win = 0;
+    struct thread *thread = NULL;
+
+    if (req->win)
+    {
+        win = get_user_full_handle( req->win );
+        if (win && (thread = get_window_thread( win )))
+        {
+            queue = thread->queue;
+            release_object( thread );
+        }
+    }
+    else
+        queue = current->queue;
 
     if (!queue || !kill_timer( queue, get_user_full_handle(req->win), req->msg, req->id ))
         set_error( STATUS_INVALID_PARAMETER );


More information about the wine-patches mailing list