Index: subsystems/win32/win32k/ntuser/message.c =================================================================== --- subsystems/win32/win32k/ntuser/message.c (revision 47195) +++ subsystems/win32/win32k/ntuser/message.c (working copy) @@ -880,22 +880,13 @@ goto MsgExit; } - if (ThreadQueue->WakeMask & QS_TIMER) - if (PostTimerMessages(Window)) // If there are timers ready, - goto CheckMessages; // go back and process them. + /* Check for completed Timers */ + Present = GetTimerMessages(pti,Window, &Msg->Msg, RemoveMessages); - // LOL! Polling Timer Queue? How much time is spent doing this? - /* Check for WM_(SYS)TIMER messages */ - Present = MsqGetTimerMessage( ThreadQueue, - Window, - MsgFilterMin, - MsgFilterMax, - &Msg->Msg, - RemoveMessages); if (Present) { Msg->FreeLParam = FALSE; - goto MessageFound; + goto MsgExit; } if(Present) Index: subsystems/win32/win32k/ntuser/caret.c =================================================================== --- subsystems/win32/win32k/ntuser/caret.c (revision 47195) +++ subsystems/win32/win32k/ntuser/caret.c (working copy) @@ -189,7 +189,7 @@ ThreadQueue->CaretInfo->Pos.x = X; ThreadQueue->CaretInfo->Pos.y = Y; co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0); - IntSetTimer(ThreadQueue->CaretInfo->hWnd, IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TRUE); + IntSetTimer(UserGetWindowObject(ThreadQueue->CaretInfo->hWnd), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TMRF_SYSTEM); } return TRUE; } @@ -302,7 +302,7 @@ { co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0); } - IntSetTimer(ThreadQueue->CaretInfo->hWnd, IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TRUE); + IntSetTimer(UserGetWindowObject(ThreadQueue->CaretInfo->hWnd), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TMRF_SYSTEM); } return TRUE; Index: subsystems/win32/win32k/ntuser/timer.c =================================================================== --- subsystems/win32/win32k/ntuser/timer.c (revision 47195) +++ subsystems/win32/win32k/ntuser/timer.c (working copy) @@ -57,7 +57,7 @@ { Ret = UserCreateObject(gHandleTable, NULL, &Handle, otTimer, sizeof(TIMER)); if (Ret) InsertTailList(&FirstpTmr->ptmrList, &Ret->ptmrList); - } + } return Ret; } @@ -68,8 +68,11 @@ { if (pTmr) { + pTmr->flags |= TMRF_DELETEPENDING; +/* RemoveEntryList(&pTmr->ptmrList); UserDeleteObject( UserHMGetHandle(pTmr), otTimer); +*/ return TRUE; } return FALSE; @@ -83,7 +86,7 @@ BOOL Distroy) { PLIST_ENTRY pLE; - PTIMER pTmr = FirstpTmr; + PTIMER pTmr = FirstpTmr, RetTmr = NULL; KeEnterCriticalRegion(); do { @@ -98,6 +101,7 @@ RemoveTimer(pTmr); pTmr = (PTIMER)1; // We are here to remove the timer. } + RetTmr = pTmr; break; } @@ -106,7 +110,7 @@ } while (pTmr != FirstpTmr); KeLeaveCriticalRegion(); - return pTmr; + return RetTmr; } PTIMER @@ -164,7 +168,7 @@ // Rename it to IntSetTimer after move. UINT_PTR FASTCALL -InternalSetTimer( PWINDOW_OBJECT Window, +IntSetTimer( PWINDOW_OBJECT Window, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, @@ -215,15 +219,15 @@ pTmr->pWnd = Window; pTmr->cmsCountdown = Elapse; pTmr->cmsRate = Elapse; - pTmr->flags = Type|TMRF_INIT; // Set timer to Init mode. pTmr->pfn = TimerFunc; pTmr->nID = IDEvent; - - InsertTailList(&FirstpTmr->ptmrList, &pTmr->ptmrList); + pTmr->flags = Type|TMRF_INIT; // Set timer to Init mode. } + // Start the timer thread! - KeSetTimer(MasterTimer, DueTime, NULL); + if (pTmr == FirstpTmr) + KeSetTimer(MasterTimer, DueTime, NULL); if (!pTmr->nID) return 1; return pTmr->nID; @@ -248,7 +252,7 @@ { // Need to start gdi syncro timers then start timer with Hang App proc // that calles Idle process so the screen savers will know to run...... - InternalSetTimer(NULL, 0, 1000, SystemTimerProc, TMRF_RIT); + IntSetTimer(NULL, 0, 1000, SystemTimerProc, TMRF_RIT); } UINT_PTR @@ -263,11 +267,57 @@ SetLastWin32Error(ERROR_ACCESS_DENIED); return 0; } - return InternalSetTimer( Window, nIDEvent, uElapse, lpTimerFunc, TMRF_SYSTEM); + return IntSetTimer( Window, nIDEvent, uElapse, lpTimerFunc, TMRF_SYSTEM); } BOOL FASTCALL +GetTimerMessages(PTHREADINFO ThreadContext, PWINDOW_OBJECT Window, MSG *Msg, BOOL RemoveMessages) +{ + PLIST_ENTRY pLE; + BOOL Hit = FALSE; + PTIMER pTmr = FirstpTmr; + LARGE_INTEGER LargeTickCount; + + if (!pTmr) return FALSE; + + KeEnterCriticalRegion(); + + do + { + if ((pTmr->flags & TMRF_READY) && + (pTmr->pti == ThreadContext) && + (!(pTmr->flags & TMRF_RIT))) + { + ASSERT((ULONG_PTR)Window != 1); + + Msg->hwnd = pTmr->pWnd ? pTmr->pWnd->hSelf : 0; + Msg->message = (pTmr->flags & TMRF_SYSTEM) ? WM_SYSTIMER : WM_TIMER; + Msg->wParam = (WPARAM) pTmr->nID; + Msg->lParam = (LPARAM) pTmr->pfn; + KeQueryTickCount(&LargeTickCount); + Msg->time = MsqCalculateMessageTime(&LargeTickCount); + Msg->pt = gpsi->ptCursor; + + if (RemoveMessages) + pTmr->flags &= ~TMRF_READY; + //ThreadQueue->WakeMask = ~QS_TIMER; + Hit = TRUE; + break; + } + + pLE = pTmr->ptmrList.Flink; + pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); + } while (pTmr != FirstpTmr); + + KeLeaveCriticalRegion(); + + return Hit; + +} + +BOOL +FASTCALL PostTimerMessages(PWINDOW_OBJECT Window) { PLIST_ENTRY pLE; @@ -288,19 +338,22 @@ ThreadQueue = pti->MessageQueue; KeEnterCriticalRegion(); + do { if ( (pTmr->flags & TMRF_READY) && (pTmr->pti == pti) && (pTmr->pWnd == Window)) { + ASSERT((ULONG_PTR)Window != 1); + Msg.hwnd = Window->hSelf; Msg.message = (pTmr->flags & TMRF_SYSTEM) ? WM_SYSTIMER : WM_TIMER; Msg.wParam = (WPARAM) pTmr->nID; Msg.lParam = (LPARAM) pTmr->pfn; + MsqPostMessage(ThreadQueue, &Msg, FALSE, QS_POSTMESSAGE); - pTmr->flags &= ~TMRF_READY; ThreadQueue->WakeMask = ~QS_TIMER; Hit = TRUE; @@ -309,6 +362,7 @@ pLE = pTmr->ptmrList.Flink; pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList); } while (pTmr != FirstpTmr); + KeLeaveCriticalRegion(); return Hit; @@ -330,7 +384,7 @@ KeQueryTickCount(&TickCount); Time = MsqCalculateMessageTime(&TickCount); - DueTime.QuadPart = (LONGLONG)(-10000000); + DueTime.QuadPart = (LONGLONG)(-1000000); do { @@ -341,7 +395,7 @@ continue; } - if (pTmr->flags & TMRF_INIT) + if (pTmr->flags & TMRF_INIT) pTmr->flags &= ~TMRF_INIT; // Skip this run. else { @@ -359,15 +413,22 @@ } else { - pTmr->flags |= TMRF_READY; // Set timer ready to be ran. // Set thread message queue for this timer. if (pTmr->pti->MessageQueue) { // Wakeup thread - pTmr->pti->MessageQueue->WakeMask |= QS_TIMER; - KeSetEvent(pTmr->pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); + //pTmr->pti->MessageQueue->WakeMask |= QS_TIMER; + if (pTmr->pti->MessageQueue->WakeMask & QS_TIMER) + KeSetEvent(pTmr->pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); } + pTmr->flags |= TMRF_READY; // Set timer ready to be ran. } } + else if (pTmr->flags & TMRF_DELETEPENDING) + { + RemoveEntryList(&pTmr->ptmrList); + UserDeleteObject( UserHMGetHandle(pTmr), otTimer); + } + pTmr->cmsCountdown = pTmr->cmsRate; } else @@ -391,7 +452,7 @@ // // UINT_PTR FASTCALL -IntSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL SystemTimer) +InternalSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL SystemTimer) { PWINDOW_OBJECT Window; UINT_PTR Ret = 0; @@ -401,6 +462,10 @@ DPRINT("IntSetTimer wnd %x id %p elapse %u timerproc %p systemtimer %s\n", Wnd, IDEvent, Elapse, TimerFunc, SystemTimer ? "TRUE" : "FALSE"); + Window = UserGetWindowObject(Wnd); + return InternalSetTimer(Window,IDEvent, Elapse, TimerFunc, SystemTimer ? TMRF_SYSTEM : 0); + + if ((Wnd == NULL) && ! SystemTimer) { DPRINT("Window-less timer\n"); @@ -483,8 +548,26 @@ BOOL FASTCALL -IntKillTimer(HWND Wnd, UINT_PTR IDEvent, BOOL SystemTimer) +IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer) { + PTIMER pTmr = NULL; + DPRINT("IntKillTimer Window %x id %p systemtimer %s\n", + Window, IDEvent, SystemTimer ? "TRUE" : "FALSE"); +//return FALSE; + 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; @@ -574,7 +657,7 @@ DPRINT("Enter NtUserSetTimer\n"); UserEnterExclusive(); - RETURN(IntSetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc, FALSE)); + RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, 0)); CLEANUP: DPRINT("Leave NtUserSetTimer, ret=%i\n", _ret_); @@ -591,13 +674,16 @@ UINT_PTR uIDEvent ) { + PWINDOW_OBJECT Window; DECLARE_RETURN(BOOL); DPRINT("Enter NtUserKillTimer\n"); UserEnterExclusive(); - RETURN(IntKillTimer(hWnd, uIDEvent, FALSE)); + Window = UserGetWindowObject(hWnd); + RETURN(IntKillTimer(Window, uIDEvent, FALSE)); + CLEANUP: DPRINT("Leave NtUserKillTimer, ret=%i\n", _ret_); UserLeave(); @@ -620,7 +706,7 @@ UserEnterExclusive(); // This is wrong, lpTimerFunc is NULL! - RETURN(IntSetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc, TRUE)); + RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, TMRF_SYSTEM)); CLEANUP: DPRINT("Leave NtUserSetSystemTimer, ret=%i\n", _ret_); Index: subsystems/win32/win32k/include/timer.h =================================================================== --- subsystems/win32/win32k/include/timer.h (revision 47195) +++ subsystems/win32/win32k/include/timer.h (working copy) @@ -23,12 +23,14 @@ #define TMRF_ONESHOT 0x0010 #define TMRF_WAITING 0x0020 #define TMRF_TIFROMWND 0x0040 +#define TMRF_DELETEPENDING 0x0080 extern PKTIMER MasterTimer; 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); +BOOL FASTCALL IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer); +UINT_PTR FASTCALL IntSetTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, INT Type); +BOOL FASTCALL GetTimerMessages(PTHREADINFO ThreadContext, PWINDOW_OBJECT Window, MSG *Msg, BOOL RemoveMessages); PTIMER FASTCALL FindSystemTimer(PMSG); BOOL FASTCALL ValidateTimerCallback(PTHREADINFO,PWINDOW_OBJECT,WPARAM,LPARAM); VOID CALLBACK SystemTimerProc(HWND,UINT,UINT_PTR,DWORD);