mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 13:45:56 +00:00
- Rewrite Timers, nothing is using it except a bogus system timer for raw input thread is loaded and running.
svn path=/trunk/; revision=38779
This commit is contained in:
parent
a3c29b9686
commit
a0d07a719b
7 changed files with 309 additions and 13 deletions
|
@ -37,4 +37,6 @@ PKBL UserHklToKbl(HKL hKl);
|
||||||
#define ThreadHasInputAccess(W32Thread) \
|
#define ThreadHasInputAccess(W32Thread) \
|
||||||
(TRUE)
|
(TRUE)
|
||||||
|
|
||||||
|
extern PTHREADINFO ptiRawInput;
|
||||||
|
|
||||||
#endif /* _WIN32K_INPUT_H */
|
#endif /* _WIN32K_INPUT_H */
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#define TAG_CALLBACK TAG('C', 'B', 'C', 'K') /* callback memory */
|
#define TAG_CALLBACK TAG('C', 'B', 'C', 'K') /* callback memory */
|
||||||
#define TAG_WINSTA TAG('W', 'S', 'T', 'A') /* window station */
|
#define TAG_WINSTA TAG('W', 'S', 'T', 'A') /* window station */
|
||||||
#define TAG_PDCE TAG('U', 's', 'd', 'c') /* dce */
|
#define TAG_PDCE TAG('U', 's', 'd', 'c') /* dce */
|
||||||
|
#define TAG_INPUT TAG('U', 's', 's', 'y') /* Input */
|
||||||
|
|
||||||
/* gdi objects from the handle table */
|
/* gdi objects from the handle table */
|
||||||
#define TAG_DC TAG('G', 'l', 'a', '1') /* dc */
|
#define TAG_DC TAG('G', 'l', 'a', '1') /* dc */
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
typedef struct _TIMER
|
typedef struct _TIMER
|
||||||
{
|
{
|
||||||
LIST_ENTRY ptmrList;
|
LIST_ENTRY ptmrList;
|
||||||
PW32THREADINFO pti;
|
PTHREADINFO pti;
|
||||||
PWINDOW_OBJECT pWnd; // hWnd
|
PWINDOW_OBJECT pWnd; // hWnd
|
||||||
UINT_PTR nID; // Specifies a nonzero timer identifier.
|
UINT_PTR nID; // Specifies a nonzero timer identifier.
|
||||||
INT cmsCountdown; // uElapse
|
INT cmsCountdown; // uElapse
|
||||||
|
@ -22,13 +22,19 @@ typedef struct _TIMER
|
||||||
#define TMRF_INIT 0x0008
|
#define TMRF_INIT 0x0008
|
||||||
#define TMRF_ONESHOT 0x0010
|
#define TMRF_ONESHOT 0x0010
|
||||||
#define TMRF_WAITING 0x0020
|
#define TMRF_WAITING 0x0020
|
||||||
|
#define TMRF_TIFROMWND 0x0040
|
||||||
|
|
||||||
|
extern PKTIMER MasterTimer;
|
||||||
|
|
||||||
NTSTATUS FASTCALL InitTimerImpl(VOID);
|
NTSTATUS FASTCALL InitTimerImpl(VOID);
|
||||||
BOOL FASTCALL IntKillTimer(HWND Wnd, UINT_PTR IDEvent, BOOL SystemTimer);
|
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);
|
UINT_PTR FASTCALL IntSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL SystemTimer);
|
||||||
PTIMER FASTCALL FindSystemTimer(PMSG);
|
PTIMER FASTCALL FindSystemTimer(PMSG);
|
||||||
BOOL FASTCALL ValidateTimerCallback(PW32THREADINFO,PWINDOW_OBJECT,WPARAM,LPARAM);
|
BOOL FASTCALL ValidateTimerCallback(PTHREADINFO,PWINDOW_OBJECT,WPARAM,LPARAM);
|
||||||
VOID CALLBACK SystemTimerProc(HWND,UINT,UINT_PTR,DWORD);
|
VOID CALLBACK SystemTimerProc(HWND,UINT,UINT_PTR,DWORD);
|
||||||
UINT_PTR FASTCALL SetSystemTimer(HWND,UINT_PTR,UINT,TIMERPROC);
|
UINT_PTR FASTCALL SetSystemTimer(PWINDOW_OBJECT,UINT_PTR,UINT,TIMERPROC);
|
||||||
|
BOOL FASTCALL PostTimerMessages(HWND);
|
||||||
|
VOID FASTCALL ProcessTimers(VOID);
|
||||||
|
VOID FASTCALL StartTheTimers(VOID);
|
||||||
|
|
||||||
#endif /* _WIN32K_TIMER_H */
|
#endif /* _WIN32K_TIMER_H */
|
||||||
|
|
|
@ -36,9 +36,12 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
extern BYTE gQueueKeyStateTable[];
|
extern BYTE gQueueKeyStateTable[];
|
||||||
|
extern NTSTATUS Win32kInitWin32Thread(PETHREAD Thread);
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
PTHREADINFO ptiRawInput;
|
||||||
|
PKTIMER MasterTimer;
|
||||||
|
|
||||||
static HANDLE MouseDeviceHandle;
|
static HANDLE MouseDeviceHandle;
|
||||||
static HANDLE MouseThreadHandle;
|
static HANDLE MouseThreadHandle;
|
||||||
|
@ -46,6 +49,8 @@ static CLIENT_ID MouseThreadId;
|
||||||
static HANDLE KeyboardThreadHandle;
|
static HANDLE KeyboardThreadHandle;
|
||||||
static CLIENT_ID KeyboardThreadId;
|
static CLIENT_ID KeyboardThreadId;
|
||||||
static HANDLE KeyboardDeviceHandle;
|
static HANDLE KeyboardDeviceHandle;
|
||||||
|
static HANDLE RawInputThreadHandle;
|
||||||
|
static CLIENT_ID RawInputThreadId;
|
||||||
static KEVENT InputThreadsStart;
|
static KEVENT InputThreadsStart;
|
||||||
static BOOLEAN InputThreadsRunning = FALSE;
|
static BOOLEAN InputThreadsRunning = FALSE;
|
||||||
|
|
||||||
|
@ -468,7 +473,6 @@ KeyboardThreadMain(PVOID StartContext)
|
||||||
MSG msg;
|
MSG msg;
|
||||||
PUSER_MESSAGE_QUEUE FocusQueue;
|
PUSER_MESSAGE_QUEUE FocusQueue;
|
||||||
struct _ETHREAD *FocusThread;
|
struct _ETHREAD *FocusThread;
|
||||||
extern NTSTATUS Win32kInitWin32Thread(PETHREAD Thread);
|
|
||||||
|
|
||||||
PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans = NULL;
|
PKEYBOARD_INDICATOR_TRANSLATION IndicatorTrans = NULL;
|
||||||
UINT ModifierState = 0;
|
UINT ModifierState = 0;
|
||||||
|
@ -832,6 +836,79 @@ KeyboardEscape:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PVOID Objects[2];
|
||||||
|
/*
|
||||||
|
Raw Input Thread.
|
||||||
|
Since this relies on InputThreadsStart, just fake it.
|
||||||
|
*/
|
||||||
|
static VOID APIENTRY
|
||||||
|
RawInputThreadMain(PVOID StartContext)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
LARGE_INTEGER DueTime;
|
||||||
|
|
||||||
|
DueTime.QuadPart = (LONGLONG)(-10000000);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
KEVENT Event;
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &DueTime);
|
||||||
|
} while (!NT_SUCCESS(Status));
|
||||||
|
|
||||||
|
|
||||||
|
Objects[0] = &InputThreadsStart;
|
||||||
|
|
||||||
|
MasterTimer = ExAllocatePoolWithTag(NonPagedPool, sizeof(KTIMER), TAG_INPUT);
|
||||||
|
if (!MasterTimer)
|
||||||
|
{
|
||||||
|
DPRINT1("Win32K: Failed making Raw Input thread a win32 thread.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
KeInitializeTimer(MasterTimer);
|
||||||
|
Objects[1] = MasterTimer;
|
||||||
|
|
||||||
|
// This thread requires win32k!
|
||||||
|
Status = Win32kInitWin32Thread(PsGetCurrentThread());
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Win32K: Failed making Raw Input thread a win32 thread.\n");
|
||||||
|
return; //(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
ptiRawInput = PsGetCurrentThreadWin32Thread();
|
||||||
|
DPRINT1("\nRaw Input Thread 0x%x \n", ptiRawInput);
|
||||||
|
|
||||||
|
|
||||||
|
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
|
||||||
|
LOW_REALTIME_PRIORITY + 3);
|
||||||
|
|
||||||
|
UserEnterExclusive();
|
||||||
|
StartTheTimers();
|
||||||
|
UserLeave();
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATM, we just have one job to handle, merge the other two later.
|
||||||
|
//
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
DPRINT( "Raw Input Thread Waiting for start event\n" );
|
||||||
|
|
||||||
|
Status = KeWaitForMultipleObjects( 2,
|
||||||
|
Objects,
|
||||||
|
WaitAll, //WaitAny,
|
||||||
|
WrUserRequest,
|
||||||
|
KernelMode,
|
||||||
|
TRUE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
DPRINT( "Raw Input Thread Starting...\n" );
|
||||||
|
|
||||||
|
ProcessTimers();
|
||||||
|
}
|
||||||
|
DPRINT1("Raw Input Thread Exit!\n");
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
InitInputImpl(VOID)
|
InitInputImpl(VOID)
|
||||||
{
|
{
|
||||||
|
@ -845,6 +922,18 @@ InitInputImpl(VOID)
|
||||||
DPRINT1("Failed to initialize default keyboard layout!\n");
|
DPRINT1("Failed to initialize default keyboard layout!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status = PsCreateSystemThread(&RawInputThreadHandle,
|
||||||
|
THREAD_ALL_ACCESS,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&RawInputThreadId,
|
||||||
|
RawInputThreadMain,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Win32K: Failed to create raw thread.\n");
|
||||||
|
}
|
||||||
|
|
||||||
Status = PsCreateSystemThread(&KeyboardThreadHandle,
|
Status = PsCreateSystemThread(&KeyboardThreadHandle,
|
||||||
THREAD_ALL_ACCESS,
|
THREAD_ALL_ACCESS,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
|
@ -360,7 +360,7 @@ IntDispatchMessage(PMSG pMsg)
|
||||||
{
|
{
|
||||||
if (pMsg->message == WM_TIMER)
|
if (pMsg->message == WM_TIMER)
|
||||||
{
|
{
|
||||||
if (ValidateTimerCallback(GetW32ThreadInfo(),Window,pMsg->wParam,pMsg->lParam))
|
if (ValidateTimerCallback(PsGetCurrentThreadWin32Thread(),Window,pMsg->wParam,pMsg->lParam))
|
||||||
{
|
{
|
||||||
return co_IntCallWindowProc((WNDPROC)pMsg->lParam,
|
return co_IntCallWindowProc((WNDPROC)pMsg->lParam,
|
||||||
TRUE,
|
TRUE,
|
||||||
|
@ -829,6 +829,11 @@ CheckMessages:
|
||||||
goto MsgExit;
|
goto MsgExit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ThreadQueue->WakeMask & QS_TIMER)
|
||||||
|
if (PostTimerMessages(hWnd)) // If there are timers ready,
|
||||||
|
goto CheckMessages; // go back and process them.
|
||||||
|
|
||||||
|
// LOL! Polling Timer Queue? How much time is spent doing this?
|
||||||
/* Check for WM_(SYS)TIMER messages */
|
/* Check for WM_(SYS)TIMER messages */
|
||||||
Present = MsqGetTimerMessage(ThreadQueue, hWnd, MsgFilterMin, MsgFilterMax,
|
Present = MsqGetTimerMessage(ThreadQueue, hWnd, MsgFilterMin, MsgFilterMax,
|
||||||
&Msg->Msg, RemoveMessages);
|
&Msg->Msg, RemoveMessages);
|
||||||
|
|
|
@ -1117,7 +1117,7 @@ NtUserValidateTimerCallback(
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ret = ValidateTimerCallback(GetW32ThreadInfo(), Window, wParam, lParam);
|
Ret = ValidateTimerCallback(PsGetCurrentThreadWin32Thread(), Window, wParam, lParam);
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
UserLeave();
|
UserLeave();
|
||||||
|
|
|
@ -37,6 +37,9 @@
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
static PTIMER FirstpTmr = NULL;
|
static PTIMER FirstpTmr = NULL;
|
||||||
|
static LONG TimeLast = 0;
|
||||||
|
|
||||||
|
#define MAX_ELAPSE_TIME 0x7FFFFFFF
|
||||||
|
|
||||||
/* Windows 2000 has room for 32768 window-less timers */
|
/* Windows 2000 has room for 32768 window-less timers */
|
||||||
#define NUM_WINDOW_LESS_TIMERS 1024
|
#define NUM_WINDOW_LESS_TIMERS 1024
|
||||||
|
@ -54,6 +57,7 @@ static ULONG HintIndex = 0;
|
||||||
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Mutex)
|
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Mutex)
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
static
|
||||||
PTIMER
|
PTIMER
|
||||||
FASTCALL
|
FASTCALL
|
||||||
CreateTimer(VOID)
|
CreateTimer(VOID)
|
||||||
|
@ -144,7 +148,7 @@ FindSystemTimer(PMSG pMsg)
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ValidateTimerCallback(PW32THREADINFO pti,
|
ValidateTimerCallback(PTHREADINFO pti,
|
||||||
PWINDOW_OBJECT Window,
|
PWINDOW_OBJECT Window,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
|
@ -158,7 +162,7 @@ ValidateTimerCallback(PW32THREADINFO pti,
|
||||||
{
|
{
|
||||||
if ( (lParam == (LPARAM)pTmr->pfn) &&
|
if ( (lParam == (LPARAM)pTmr->pfn) &&
|
||||||
(pTmr->flags & (TMRF_SYSTEM|TMRF_RIT)) &&
|
(pTmr->flags & (TMRF_SYSTEM|TMRF_RIT)) &&
|
||||||
(pTmr->pti->pi == pti->pi) )
|
(pTmr->pti->ThreadInfo->kpi == pti->ThreadInfo->kpi) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pTmr = (PTIMER)pTmr->ptmrList.Flink;
|
pTmr = (PTIMER)pTmr->ptmrList.Flink;
|
||||||
|
@ -172,13 +176,73 @@ ValidateTimerCallback(PW32THREADINFO pti,
|
||||||
|
|
||||||
// Rename it to IntSetTimer after move.
|
// Rename it to IntSetTimer after move.
|
||||||
UINT_PTR FASTCALL
|
UINT_PTR FASTCALL
|
||||||
InternalSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL SystemTimer)
|
InternalSetTimer( PWINDOW_OBJECT Window,
|
||||||
|
UINT_PTR IDEvent,
|
||||||
|
UINT Elapse,
|
||||||
|
TIMERPROC TimerFunc,
|
||||||
|
INT Type)
|
||||||
{
|
{
|
||||||
return 0;
|
PTIMER pTmr;
|
||||||
|
LARGE_INTEGER DueTime;
|
||||||
|
DueTime.QuadPart = (LONGLONG)(-10000000);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Windows NT/2k/XP behaviour */
|
||||||
|
if (Elapse > MAX_ELAPSE_TIME)
|
||||||
|
{
|
||||||
|
DPRINT("Adjusting uElapse\n");
|
||||||
|
Elapse = 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Windows XP SP2 and Windows Server 2003 behaviour */
|
||||||
|
if (Elapse > MAX_ELAPSE_TIME)
|
||||||
|
{
|
||||||
|
DPRINT("Adjusting uElapse\n");
|
||||||
|
Elapse = MAX_ELAPSE_TIME;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Windows 2k/XP and Windows Server 2003 SP1 behaviour */
|
||||||
|
if (Elapse < 10)
|
||||||
|
{
|
||||||
|
DPRINT("Adjusting uElapse\n");
|
||||||
|
Elapse = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTmr = FindTimer(Window, IDEvent, Type, FALSE);
|
||||||
|
if (!pTmr)
|
||||||
|
{
|
||||||
|
pTmr = CreateTimer();
|
||||||
|
if (!pTmr) return 0;
|
||||||
|
|
||||||
|
if (Window && (Type & TMRF_TIFROMWND))
|
||||||
|
pTmr->pti = Window->OwnerThread->Tcb.Win32Thread;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Type & TMRF_RIT)
|
||||||
|
pTmr->pti = ptiRawInput;
|
||||||
|
else
|
||||||
|
pTmr->pti = PsGetCurrentThreadWin32Thread();
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the timer thread!
|
||||||
|
KeSetTimer(MasterTimer, DueTime, NULL);
|
||||||
|
|
||||||
|
if (!pTmr->nID) return 1;
|
||||||
|
return pTmr->nID;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Process system timers.
|
// Process win32k system timers.
|
||||||
//
|
//
|
||||||
VOID
|
VOID
|
||||||
CALLBACK
|
CALLBACK
|
||||||
|
@ -187,18 +251,147 @@ SystemTimerProc(HWND hwnd,
|
||||||
UINT_PTR idEvent,
|
UINT_PTR idEvent,
|
||||||
DWORD dwTime)
|
DWORD dwTime)
|
||||||
{
|
{
|
||||||
|
DPRINT( "Timer Running!\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
StartTheTimers(VOID)
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT_PTR
|
UINT_PTR
|
||||||
FASTCALL
|
FASTCALL
|
||||||
SetSystemTimer( HWND hWnd,
|
SetSystemTimer( PWINDOW_OBJECT Window,
|
||||||
UINT_PTR nIDEvent,
|
UINT_PTR nIDEvent,
|
||||||
UINT uElapse,
|
UINT uElapse,
|
||||||
TIMERPROC lpTimerFunc)
|
TIMERPROC lpTimerFunc)
|
||||||
{
|
{
|
||||||
return 0;
|
if (Window && Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return InternalSetTimer( Window, nIDEvent, uElapse, lpTimerFunc, TMRF_SYSTEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
FASTCALL
|
||||||
|
PostTimerMessages(HWND hWnd)
|
||||||
|
{
|
||||||
|
PUSER_MESSAGE_QUEUE ThreadQueue;
|
||||||
|
MSG Msg;
|
||||||
|
PTHREADINFO pti;
|
||||||
|
PWINDOW_OBJECT pWnd = NULL;
|
||||||
|
BOOL Hit = FALSE;
|
||||||
|
PTIMER pTmr = FirstpTmr;
|
||||||
|
|
||||||
|
if (!pTmr) return FALSE;
|
||||||
|
|
||||||
|
if (hWnd)
|
||||||
|
{
|
||||||
|
pWnd = UserGetWindowObject(hWnd);
|
||||||
|
if (!pWnd || !pWnd->Wnd) return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pti = PsGetCurrentThreadWin32Thread();
|
||||||
|
ThreadQueue = pti->MessageQueue;
|
||||||
|
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ( (pTmr->flags & TMRF_READY) &&
|
||||||
|
(pTmr->pti == pti) &&
|
||||||
|
(pTmr->pWnd == pWnd))
|
||||||
|
{
|
||||||
|
Msg.hwnd = hWnd;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTmr = (PTIMER)pTmr->ptmrList.Flink;
|
||||||
|
} while (pTmr != FirstpTmr);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
|
return Hit;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
ProcessTimers(VOID)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER TickCount, DueTime;
|
||||||
|
LONG Time;
|
||||||
|
PTIMER pTmr = FirstpTmr;
|
||||||
|
|
||||||
|
if (!pTmr) return;
|
||||||
|
|
||||||
|
UserEnterExclusive();
|
||||||
|
|
||||||
|
KeQueryTickCount(&TickCount);
|
||||||
|
Time = MsqCalculateMessageTime(&TickCount);
|
||||||
|
|
||||||
|
DueTime.QuadPart = (LONGLONG)(-10000000);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (pTmr->flags & TMRF_WAITING)
|
||||||
|
{
|
||||||
|
pTmr = (PTIMER)pTmr->ptmrList.Flink;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pTmr->flags & TMRF_INIT)
|
||||||
|
pTmr->flags &= ~TMRF_INIT; // Skip this run.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pTmr->cmsCountdown < 0)
|
||||||
|
{
|
||||||
|
if (!(pTmr->flags & TMRF_READY))
|
||||||
|
{
|
||||||
|
if (pTmr->flags & TMRF_ONESHOT)
|
||||||
|
pTmr->flags |= TMRF_WAITING;
|
||||||
|
|
||||||
|
if (pTmr->flags & TMRF_RIT)
|
||||||
|
{
|
||||||
|
// Hard coded call here, inside raw input thread.
|
||||||
|
pTmr->pfn(NULL, WM_SYSTIMER, pTmr->nID, (LPARAM)pTmr);
|
||||||
|
}
|
||||||
|
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->cmsCountdown = pTmr->cmsRate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pTmr->cmsCountdown -= Time - TimeLast;
|
||||||
|
}
|
||||||
|
pTmr = (PTIMER)pTmr->ptmrList.Flink;
|
||||||
|
} while (pTmr != FirstpTmr);
|
||||||
|
|
||||||
|
// Restart the timer thread!
|
||||||
|
KeSetTimer(MasterTimer, DueTime, NULL);
|
||||||
|
|
||||||
|
TimeLast = Time;
|
||||||
|
|
||||||
|
UserLeave();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue