From 762c1e58de2a4080e4be6d444bd731d503c01055 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Wed, 6 Aug 2008 02:05:17 +0000 Subject: [PATCH] Win32k Timers: - This is relative to bugs 3634 and 2393. Please leave additional information in bug report 2393. - Timer code should not be associated with message queues, since theses types of queues are subject to being destroyed. This creates a problem of loosing timers. - This is a first part of a rewrite of the timers. Moving the timers from the message queue to a linked list very similar to our DCE code. This will simplify timer handling too. svn path=/trunk/; revision=35138 --- .../subsystems/win32/win32k/include/timer.h | 12 ++++++ reactos/subsystems/win32/win32k/ntuser/hook.c | 2 +- .../subsystems/win32/win32k/ntuser/timer.c | 43 +++++++++++++++---- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/timer.h b/reactos/subsystems/win32/win32k/include/timer.h index ea99591dfa1..d44e38e1e3a 100644 --- a/reactos/subsystems/win32/win32k/include/timer.h +++ b/reactos/subsystems/win32/win32k/include/timer.h @@ -1,6 +1,18 @@ #ifndef _WIN32K_TIMER_H #define _WIN32K_TIMER_H +typedef struct _TIMER +{ + LIST_ENTRY ptmrList; + PW32THREADINFO pti; + PWINDOW_OBJECT pWnd; // hWnd + UINT_PTR nID; // Specifies a nonzero timer identifier. + INT cmsCountdown; // uElapse + INT cmsRate; // uElapse + FLONG flags; + TIMERPROC pfn; // lpTimerFunc +} TIMER, *PTIMER; + NTSTATUS FASTCALL InitTimerImpl(VOID); BOOL FASTCALL IntKillTimer(HWND Wnd, UINT_PTR IDEvent, BOOL SystemTimer); UINT_PTR FASTCALL IntSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL SystemTimer); diff --git a/reactos/subsystems/win32/win32k/ntuser/hook.c b/reactos/subsystems/win32/win32k/ntuser/hook.c index acddc1c3779..1f8846a5de0 100644 --- a/reactos/subsystems/win32/win32k/ntuser/hook.c +++ b/reactos/subsystems/win32/win32k/ntuser/hook.c @@ -1131,7 +1131,7 @@ NtUserSetWindowsHookEx( ModuleName.MaximumLength); if (! NT_SUCCESS(Status)) { - ExFreePool(Hook->ModuleName.Buffer); + ExFreePool(Hook->ModuleName.Buffer); UserDereferenceObject(Hook); IntRemoveHook(Hook, WinStaObj, FALSE); if (NULL != Thread) diff --git a/reactos/subsystems/win32/win32k/ntuser/timer.c b/reactos/subsystems/win32/win32k/ntuser/timer.c index c61cd1f7f04..9db2c4ca6a9 100644 --- a/reactos/subsystems/win32/win32k/ntuser/timer.c +++ b/reactos/subsystems/win32/win32k/ntuser/timer.c @@ -16,12 +16,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: Window timers messages - * FILE: subsys/win32k/ntuser/timer.c + * FILE: subsystems/win32/win32k/ntuser/timer.c * PROGRAMER: Gunnar * Thomas Weidenmueller (w3seek@users.sourceforge.net) * REVISION HISTORY: 10/04/2003 Implemented System Timers @@ -37,6 +36,8 @@ /* GLOBALS *******************************************************************/ +static PTIMER FirstpTmr = NULL; + /* Windows 2000 has room for 32768 window-less timers */ #define NUM_WINDOW_LESS_TIMERS 1024 @@ -148,20 +149,40 @@ IntSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL S BOOL FASTCALL IntKillTimer(HWND Wnd, UINT_PTR IDEvent, BOOL SystemTimer) { + PWINDOW_OBJECT Window = NULL; + DPRINT("IntKillTimer wnd %x id %p systemtimer %s\n", Wnd, IDEvent, SystemTimer ? "TRUE" : "FALSE"); - if (! MsqKillTimer(PsGetCurrentThreadWin32Thread()->MessageQueue, Wnd, - IDEvent, SystemTimer ? WM_SYSTIMER : WM_TIMER)) + if (Wnd) { - DPRINT1("Unable to locate timer in message queue\n"); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return FALSE; + Window = UserGetWindowObject(Wnd); + + if (! MsqKillTimer(PsGetCurrentThreadWin32Thread()->MessageQueue, Wnd, + IDEvent, SystemTimer ? WM_SYSTIMER : WM_TIMER)) + { + // Give it another chance to find the timer. + if (Window && !( MsqKillTimer(Window->MessageQueue, Wnd, + IDEvent, SystemTimer ? WM_SYSTIMER : WM_TIMER))) + { + DPRINT1("Unable to locate timer in message queue for Window.\n"); + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + } } /* window-less timer? */ if ((Wnd == NULL) && ! SystemTimer) { + if (! MsqKillTimer(PsGetCurrentThreadWin32Thread()->MessageQueue, Wnd, + IDEvent, SystemTimer ? WM_SYSTIMER : WM_TIMER)) + { + DPRINT1("Unable to locate timer in message queue for Window-less timer.\n"); + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + /* Release the id */ IntLockWindowlessTimerBitmap(); @@ -195,6 +216,12 @@ InitTimerImpl(VOID) /* yes we need this, since ExAllocatePool isn't supposed to zero out allocated memory */ RtlClearAllBits(&WindowLessTimersBitMap); + if (!FirstpTmr) + { + FirstpTmr = ExAllocatePoolWithTag(PagedPool, sizeof(TIMER), TAG_TIMERBMP); + if (FirstpTmr) InitializeListHead(&FirstpTmr->ptmrList); + } + return STATUS_SUCCESS; }