* FILE: subsystems/win32/win32k/ntuser/timer.c
* PROGRAMER: Gunnar
* Thomas Weidenmueller (w3seek@users.sourceforge.net)
+ * Michael Martin (michael.martin@reactos.org)
* REVISION HISTORY: 10/04/2003 Implemented System Timers
*
*/
static FAST_MUTEX Mutex;
static RTL_BITMAP WindowLessTimersBitMap;
static PVOID WindowLessTimersBitMapBuffer;
-static ULONG HintIndex = 0;
+static ULONG HintIndex = 1;
ERESOURCE TimerLock;
RemoveEntryList(&pTmr->ptmrList);
if ((pTmr->pWnd == NULL) && (!(pTmr->flags & TMRF_SYSTEM)))
{
- DPRINT("Clearing Bit %d)\n", pTmr->nID);
+ UINT_PTR IDEvent;
+
+ IDEvent = NUM_WINDOW_LESS_TIMERS - pTmr->nID;
IntLockWindowlessTimerBitmap();
- RtlClearBit(&WindowLessTimersBitMap, pTmr->nID);
+ RtlClearBit(&WindowLessTimersBitMap, IDEvent);
IntUnlockWindowlessTimerBitmap();
}
UserDereferenceObject(pTmr);
Ret = UserDeleteObject( UserHMGetHandle(pTmr), otTimer);
}
- if (!Ret) DPRINT1("Warning unable to delete timer\n");
+ if (!Ret) DPRINT1("Warning: Unable to delete timer\n");
return Ret;
}
PTIMER
FASTCALL
-FindTimer(PWINDOW_OBJECT Window,
+FindTimer(PWND Window,
UINT_PTR nID,
- UINT flags,
- BOOL Distroy)
+ UINT flags)
{
PLIST_ENTRY pLE;
PTIMER pTmr = FirstpTmr, RetTmr = NULL;
pTmr->pWnd == Window &&
(pTmr->flags & (TMRF_SYSTEM|TMRF_RIT)) == (flags & (TMRF_SYSTEM|TMRF_RIT)))
{
- if (Distroy)
- {
- RemoveTimer(pTmr);
- }
RetTmr = pTmr;
break;
}
break;
pLE = pTmr->ptmrList.Flink;
- pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
+ pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
} while (pTmr != FirstpTmr);
TimerLeave();
BOOL
FASTCALL
ValidateTimerCallback(PTHREADINFO pti,
- PWINDOW_OBJECT Window,
- WPARAM wParam,
LPARAM lParam)
{
PLIST_ENTRY pLE;
+ BOOL Ret = FALSE;
PTIMER pTmr = FirstpTmr;
if (!pTmr) return FALSE;
do
{
if ( (lParam == (LPARAM)pTmr->pfn) &&
- (pTmr->flags & (TMRF_SYSTEM|TMRF_RIT)) &&
+ !(pTmr->flags & (TMRF_SYSTEM|TMRF_RIT)) &&
(pTmr->pti->ppi == pti->ppi) )
+ {
+ Ret = TRUE;
break;
-
+ }
pLE = pTmr->ptmrList.Flink;
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
} while (pTmr != FirstpTmr);
TimerLeave();
- if (!pTmr) return FALSE;
-
- return TRUE;
+ return Ret;
}
UINT_PTR FASTCALL
-IntSetTimer( PWINDOW_OBJECT Window,
+IntSetTimer( PWND Window,
UINT_PTR IDEvent,
UINT Elapse,
TIMERPROC TimerFunc,
INT Type)
{
PTIMER pTmr;
- UINT Ret= IDEvent;
+ UINT Ret = IDEvent;
LARGE_INTEGER DueTime;
- DueTime.QuadPart = (LONGLONG)(-10000000);
+ DueTime.QuadPart = (LONGLONG)(-5000000);
#if 0
/* Windows NT/2k/XP behaviour */
Elapse = 10;
}
+ /* Passing an IDEvent of 0 and the SetTimer returns 1.
+ It will create the timer with an ID of 0 */
if ((Window) && (IDEvent == 0))
- IDEvent = 1;
+ Ret = 1;
- pTmr = FindTimer(Window, IDEvent, Type, FALSE);
+ pTmr = FindTimer(Window, IDEvent, Type);
if ((!pTmr) && (Window == NULL) && (!(Type & TMRF_SYSTEM)))
{
IntUnlockWindowlessTimerBitmap();
DPRINT1("Unable to find a free window-less timer id\n");
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ ASSERT(FALSE);
return 0;
}
+ IDEvent = NUM_WINDOW_LESS_TIMERS - IDEvent;
Ret = IDEvent;
- //HintIndex = IDEvent + 1;
+
IntUnlockWindowlessTimerBitmap();
}
if (!pTmr) return 0;
if (Window && (Type & TMRF_TIFROMWND))
- pTmr->pti = Window->pti->pEThread->Tcb.Win32Thread;
+ pTmr->pti = Window->head.pti->pEThread->Tcb.Win32Thread;
else
{
if (Type & TMRF_RIT)
pTmr->cmsRate = Elapse;
pTmr->pfn = TimerFunc;
pTmr->nID = IDEvent;
- pTmr->flags = Type|TMRF_INIT; // Set timer to Init mode.
+ pTmr->flags = Type|TMRF_INIT;
}
else
{
UINT_PTR
FASTCALL
-SystemTimerSet( PWINDOW_OBJECT Window,
+SystemTimerSet( PWND Window,
UINT_PTR nIDEvent,
UINT uElapse,
TIMERPROC lpTimerFunc)
{
- if (Window && Window->pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
+ if (Window && Window->head.pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
{
SetLastWin32Error(ERROR_ACCESS_DENIED);
+ DPRINT("SysemTimerSet: Access Denied!\n");
return 0;
}
return IntSetTimer( Window, nIDEvent, uElapse, lpTimerFunc, TMRF_SYSTEM);
BOOL
FASTCALL
-PostTimerMessages(PWINDOW_OBJECT Window)
+PostTimerMessages(PWND Window)
{
PLIST_ENTRY pLE;
PUSER_MESSAGE_QUEUE ThreadQueue;
{
if ( (pTmr->flags & TMRF_READY) &&
(pTmr->pti == pti) &&
- ((pTmr->pWnd == Window) || (Window == NULL) ) )
+ ((pTmr->pWnd == Window) || (Window == NULL)) )
{
- Msg.hwnd = (pTmr->pWnd) ? pTmr->pWnd->hSelf : 0;
+ Msg.hwnd = (pTmr->pWnd) ? pTmr->pWnd->head.h : 0;
Msg.message = (pTmr->flags & TMRF_SYSTEM) ? WM_SYSTIMER : WM_TIMER;
Msg.wParam = (WPARAM) pTmr->nID;
Msg.lParam = (LPARAM) pTmr->pfn;
pTmr->flags &= ~TMRF_READY;
ThreadQueue->WakeMask = ~QS_TIMER;
Hit = TRUE;
+ break;
}
pLE = pTmr->ptmrList.Flink;
KeQueryTickCount(&TickCount);
Time = MsqCalculateMessageTime(&TickCount);
- DueTime.QuadPart = (LONGLONG)(-1000000);
+ DueTime.QuadPart = (LONGLONG)(-500000);
do
{
DPRINT("TimerCount = %d\n", TimerCount);
}
-//
-//
-// Old Timer Queueing
-//
-//
-UINT_PTR FASTCALL
-InternalSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL SystemTimer)
-{
- PWINDOW_OBJECT Window;
- UINT_PTR Ret = 0;
- PTHREADINFO pti;
- PUSER_MESSAGE_QUEUE MessageQueue;
-
- DPRINT("IntSetTimer wnd %x id %p elapse %u timerproc %p systemtimer %s\n",
- Wnd, IDEvent, Elapse, TimerFunc, SystemTimer ? "TRUE" : "FALSE");
-
- if ((Wnd == NULL) && ! SystemTimer)
- {
- DPRINT("Window-less timer\n");
- /* find a free, window-less timer id */
- IntLockWindowlessTimerBitmap();
- IDEvent = RtlFindClearBitsAndSet(&WindowLessTimersBitMap, 1, HintIndex);
-
- if (IDEvent == (UINT_PTR) -1)
- {
- IntUnlockWindowlessTimerBitmap();
- DPRINT1("Unable to find a free window-less timer id\n");
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return 0;
- }
-
- HintIndex = ++IDEvent;
- IntUnlockWindowlessTimerBitmap();
- Ret = IDEvent;
- pti = PsGetCurrentThreadWin32Thread();
- MessageQueue = pti->MessageQueue;
- }
- else
- {
- if (!(Window = UserGetWindowObject(Wnd)))
- {
- DPRINT1("Invalid window handle\n");
- return 0;
- }
-
- if (Window->pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
- {
- DPRINT1("Trying to set timer for window in another process (shatter attack?)\n");
- SetLastWin32Error(ERROR_ACCESS_DENIED);
- return 0;
- }
-
- Ret = IDEvent;
- MessageQueue = Window->pti->MessageQueue;
- }
-
-#if 0
-
- /* Windows NT/2k/XP behaviour */
- if (Elapse > 0x7fffffff)
- {
- DPRINT("Adjusting uElapse\n");
- Elapse = 1;
- }
-
-#else
-
- /* Windows XP SP2 and Windows Server 2003 behaviour */
- if (Elapse > 0x7fffffff)
- {
- DPRINT("Adjusting uElapse\n");
- Elapse = 0x7fffffff;
- }
-
-#endif
-
- /* Windows 2k/XP and Windows Server 2003 SP1 behaviour */
- if (Elapse < 10)
- {
- DPRINT("Adjusting uElapse\n");
- Elapse = 10;
- }
-
- if (! MsqSetTimer(MessageQueue, Wnd,
- IDEvent, Elapse, TimerFunc,
- SystemTimer ? WM_SYSTIMER : WM_TIMER))
- {
- DPRINT1("Failed to set timer in message queue\n");
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return 0;
- }
-
-if (Ret == 0) ASSERT(FALSE);
- return Ret;
-}
-
BOOL FASTCALL
-DestroyTimersForWindow(PTHREADINFO pti, PWINDOW_OBJECT Window)
+DestroyTimersForWindow(PTHREADINFO pti, PWND Window)
{
PLIST_ENTRY pLE;
PTIMER pTmr = FirstpTmr;
}
BOOL FASTCALL
-IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer)
+IntKillTimer(PWND Window, UINT_PTR IDEvent, BOOL SystemTimer)
{
PTIMER pTmr = NULL;
DPRINT("IntKillTimer Window %x id %p systemtimer %s\n",
Window, IDEvent, SystemTimer ? "TRUE" : "FALSE");
- if ((Window) && (IDEvent == 0))
- IDEvent = 1;
-
- pTmr = FindTimer(Window, IDEvent, SystemTimer ? TMRF_SYSTEM : 0, TRUE);
- return pTmr ? TRUE : FALSE;
-}
-
-//
-//
-// Old Kill Timer
-//
-//
-BOOL FASTCALL
-InternalKillTimer(HWND Wnd, UINT_PTR IDEvent, BOOL SystemTimer)
-{
- PTHREADINFO pti;
- PWINDOW_OBJECT Window = NULL;
-
- DPRINT("IntKillTimer wnd %x id %p systemtimer %s\n",
- Wnd, IDEvent, SystemTimer ? "TRUE" : "FALSE");
+ pTmr = FindTimer(Window, IDEvent, SystemTimer ? TMRF_SYSTEM : 0);
- pti = PsGetCurrentThreadWin32Thread();
- if (Wnd)
+ if (pTmr)
{
- Window = UserGetWindowObject(Wnd);
-
- if (! MsqKillTimer(pti->MessageQueue, Wnd,
- IDEvent, SystemTimer ? WM_SYSTIMER : WM_TIMER))
- {
- // Give it another chance to find the timer.
- if (Window && !( MsqKillTimer(Window->pti->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;
- }
- }
+ TimerEnterExclusive();
+ RemoveTimer(pTmr);
+ TimerLeave();
}
- /* window-less timer? */
- if ((Wnd == NULL) && ! SystemTimer)
- {
- if (! MsqKillTimer(pti->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();
-
- ASSERT(RtlAreBitsSet(&WindowLessTimersBitMap, IDEvent - 1, 1));
- RtlClearBits(&WindowLessTimersBitMap, IDEvent - 1, 1);
-
- HintIndex = IDEvent - 1;
-
- IntUnlockWindowlessTimerBitmap();
- }
-
- return TRUE;
+ return pTmr ? TRUE : FALSE;
}
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitTimerImpl(VOID)
{
ULONG BitmapBytes;
ExInitializeFastMutex(&Mutex);
BitmapBytes = ROUND_UP(NUM_WINDOW_LESS_TIMERS, sizeof(ULONG) * 8) / 8;
- WindowLessTimersBitMapBuffer = ExAllocatePoolWithTag(PagedPool, BitmapBytes, TAG_TIMERBMP);
+ WindowLessTimersBitMapBuffer = ExAllocatePoolWithTag(NonPagedPool, BitmapBytes, TAG_TIMERBMP);
if (WindowLessTimersBitMapBuffer == NULL)
{
return STATUS_UNSUCCESSFUL;
WindowLessTimersBitMapBuffer,
BitmapBytes * 8);
- /* yes we need this, since ExAllocatePool isn't supposed to zero out allocated memory */
+ /* yes we need this, since ExAllocatePoolWithTag isn't supposed to zero out allocated memory */
RtlClearAllBits(&WindowLessTimersBitMap);
return STATUS_SUCCESS;
TIMERPROC lpTimerFunc
)
{
- PWINDOW_OBJECT Window;
+ PWND Window;
DECLARE_RETURN(UINT_PTR);
DPRINT("Enter NtUserSetTimer\n");
UINT_PTR uIDEvent
)
{
- PWINDOW_OBJECT Window;
+ PWND Window;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserKillTimer\n");
DPRINT("Enter NtUserSetSystemTimer\n");
- // This is wrong, lpTimerFunc is NULL!
- RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, TMRF_SYSTEM));
+ RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, NULL, TMRF_SYSTEM));
CLEANUP:
DPRINT("Leave NtUserSetSystemTimer, ret=%i\n", _ret_);