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