ReactOS 0.4.16-dev-329-g9223134
timer.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for timer.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI ExTimerRundown (VOID)
 
VOID NTAPI ExpDeleteTimer (IN PVOID ObjectBody)
 
 _Function_class_ (KDEFERRED_ROUTINE)
 
VOID NTAPI ExpTimerApcKernelRoutine (IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArguemnt2)
 
BOOLEAN NTAPI ExpInitializeTimerImplementation (VOID)
 
NTSTATUS NTAPI NtCancelTimer (IN HANDLE TimerHandle, OUT PBOOLEAN CurrentState OPTIONAL)
 
NTSTATUS NTAPI NtCreateTimer (OUT PHANDLE TimerHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN TIMER_TYPE TimerType)
 
NTSTATUS NTAPI NtOpenTimer (OUT PHANDLE TimerHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
 
NTSTATUS NTAPI NtQueryTimer (IN HANDLE TimerHandle, IN TIMER_INFORMATION_CLASS TimerInformationClass, OUT PVOID TimerInformation, IN ULONG TimerInformationLength, OUT PULONG ReturnLength OPTIONAL)
 
NTSTATUS NTAPI NtSetTimer (IN HANDLE TimerHandle, IN PLARGE_INTEGER DueTime, IN PTIMER_APC_ROUTINE TimerApcRoutine OPTIONAL, IN PVOID TimerContext OPTIONAL, IN BOOLEAN WakeTimer, IN LONG Period OPTIONAL, OUT PBOOLEAN PreviousState OPTIONAL)
 

Variables

POBJECT_TYPE ExTimerType = NULL
 
KSPIN_LOCK ExpWakeListLock
 
LIST_ENTRY ExpWakeList
 
static GENERIC_MAPPING ExpTimerMapping
 
static const INFORMATION_CLASS_INFO ExTimerInfoClass []
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file timer.c.

Function Documentation

◆ _Function_class_()

_Function_class_ ( KDEFERRED_ROUTINE  )

Definition at line 136 of file timer.c.

143{
145 BOOLEAN Inserted = FALSE;
146
147 /* Reference the timer */
148 if (!ObReferenceObjectSafe(Timer)) return;
149
150 /* Lock the Timer */
152
153 /* Check if the timer is associated */
154 if (Timer->ApcAssociated)
155 {
156 /* Queue the APC */
157 Inserted = KeInsertQueueApc(&Timer->TimerApc,
161 }
162
163 /* Release the Timer */
165
166 /* Dereference it if we couldn't queue the APC */
167 if (!Inserted) ObDereferenceObject(Timer);
168}
unsigned char BOOLEAN
#define FALSE
Definition: types.h:117
BOOLEAN NTAPI KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost)
Definition: apc.c:735
BOOLEAN FASTCALL ObReferenceObjectSafe(IN PVOID Object)
Definition: obref.c:22
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
Definition: ex.h:108
#define IO_NO_INCREMENT
Definition: iotypes.h:598
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:687
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689
#define ObDereferenceObject
Definition: obfuncs.h:203

◆ ExpDeleteTimer()

VOID NTAPI ExpDeleteTimer ( IN PVOID  ObjectBody)

Definition at line 108 of file timer.c.

109{
111 PETIMER Timer = ObjectBody;
112
113 /* Check if it has a Wait List */
114 if (Timer->WakeTimerListEntry.Flink)
115 {
116 /* Lock the Wake List */
118
119 /* Check again, since it might've changed before we locked */
120 if (Timer->WakeTimerListEntry.Flink)
121 {
122 /* Remove it from the Wait List */
123 RemoveEntryList(&Timer->WakeTimerListEntry);
124 Timer->WakeTimerListEntry.Flink = NULL;
125 }
126
127 /* Release the Wake List */
129 }
130
131 /* Tell the Kernel to cancel the Timer and flush all queued DPCs */
132 KeCancelTimer(&Timer->KeTimer);
133 KeFlushQueuedDpcs();
134}
#define NULL
Definition: types.h:112
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
KSPIN_LOCK ExpWakeListLock
Definition: timer.c:20
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by ExpInitializeTimerImplementation().

◆ ExpInitializeTimerImplementation()

BOOLEAN NTAPI ExpInitializeTimerImplementation ( VOID  )

Definition at line 223 of file timer.c.

224{
225 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
228
229 /* Create the Timer Object Type */
230 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
231 RtlInitUnicodeString(&Name, L"Timer");
232 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
233 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
234 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(ETIMER);
235 ObjectTypeInitializer.GenericMapping = ExpTimerMapping;
236 ObjectTypeInitializer.PoolType = NonPagedPool;
237 ObjectTypeInitializer.ValidAccessMask = TIMER_ALL_ACCESS;
238 ObjectTypeInitializer.DeleteProcedure = ExpDeleteTimer;
239 Status = ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExTimerType);
240 if (!NT_SUCCESS(Status)) return FALSE;
241
242 /* Initialize the Wait List and Lock */
245 return TRUE;
246}
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
struct _ETIMER ETIMER
Status
Definition: gdiplustypes.h:25
#define OBJ_OPENLINK
Definition: winternl.h:230
#define TIMER_ALL_ACCESS
Definition: extypes.h:116
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
POBJECT_TYPE ExTimerType
Definition: timer.c:18
VOID NTAPI ExpDeleteTimer(IN PVOID ObjectBody)
Definition: timer.c:108
static GENERIC_MAPPING ExpTimerMapping
Definition: timer.c:24
LIST_ENTRY ExpWakeList
Definition: timer.c:21
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:365
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by ExpInitSystemPhase1().

◆ ExpTimerApcKernelRoutine()

VOID NTAPI ExpTimerApcKernelRoutine ( IN PKAPC  Apc,
IN OUT PKNORMAL_ROUTINE NormalRoutine,
IN OUT PVOID NormalContext,
IN OUT PVOID SystemArgument1,
IN OUT PVOID SystemArguemnt2 
)

Definition at line 172 of file timer.c.

177{
180 ULONG DerefsToDo = 1;
182
183 /* We need to find out which Timer we are */
184 Timer = CONTAINING_RECORD(Apc, ETIMER, TimerApc);
185
186 /* Lock the Timer */
188
189 /* Lock the Thread's Active Timer List*/
191
192 /* Make sure that the Timer is valid, and that it belongs to this thread */
193 if ((Timer->ApcAssociated) && (&Thread->Tcb == Timer->TimerApc.Thread))
194 {
195 /* Check if it's not periodic */
196 if (!Timer->Period)
197 {
198 /* Remove it from the Active Timers List */
199 RemoveEntryList(&Timer->ActiveTimerListEntry);
200
201 /* Disable it */
202 Timer->ApcAssociated = FALSE;
203 DerefsToDo++;
204 }
205 }
206 else
207 {
208 /* Clear the normal routine */
209 *NormalRoutine = NULL;
210 }
211
212 /* Release locks */
215
216 /* Dereference as needed */
217 ObDereferenceObjectEx(Timer, DerefsToDo);
218}
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
LONG FASTCALL ObDereferenceObjectEx(IN PVOID Object, IN LONG Count)
Definition: obref.c:88
KTHREAD Tcb
Definition: pstypes.h:1104
KSPIN_LOCK ActiveTimerListLock
Definition: pstypes.h:1127
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59

Referenced by NtSetTimer().

◆ ExTimerRundown()

VOID NTAPI ExTimerRundown ( VOID  )

Definition at line 43 of file timer.c.

44{
47 PLIST_ENTRY CurrentEntry;
49 ULONG DerefsToDo;
50
51 /* Lock the Thread's Active Timer List and loop it */
53 CurrentEntry = Thread->ActiveTimerListHead.Flink;
54 while (CurrentEntry != &Thread->ActiveTimerListHead)
55 {
56 /* Get the timer */
57 Timer = CONTAINING_RECORD(CurrentEntry, ETIMER, ActiveTimerListEntry);
58
59 /* Reference it */
61 DerefsToDo = 1;
62
63 /* Unlock the list */
65
66 /* Lock the Timer */
68
69 /* Lock the list again */
71
72 /* Make sure that the timer is valid */
73 if ((Timer->ApcAssociated) && (&Thread->Tcb == Timer->TimerApc.Thread))
74 {
75 /* Remove it from the list */
76 RemoveEntryList(&Timer->ActiveTimerListEntry);
77 Timer->ApcAssociated = FALSE;
78
79 /* Cancel the timer and remove its DPC and APC */
80 KeCancelTimer(&Timer->KeTimer);
81 KeRemoveQueueDpc(&Timer->TimerDpc);
82 if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo++;
83
84 /* Add another dereference to do */
85 DerefsToDo++;
86 }
87
88 /* Unlock the list */
90
91 /* Unlock the Timer */
93
94 /* Dereference it */
95 ObDereferenceObjectEx(Timer, DerefsToDo);
96
97 /* Loop again */
99 CurrentEntry = Thread->ActiveTimerListHead.Flink;
100 }
101
102 /* Release lock and return */
104}
BOOLEAN NTAPI KeRemoveQueueDpc(IN PKDPC Dpc)
Definition: dpc.c:878
BOOLEAN NTAPI KeRemoveQueueApc(PKAPC Apc)
LIST_ENTRY ActiveTimerListHead
Definition: pstypes.h:1128
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by PspExitThread().

◆ NtCancelTimer()

NTSTATUS NTAPI NtCancelTimer ( IN HANDLE  TimerHandle,
OUT PBOOLEAN CurrentState  OPTIONAL 
)

Definition at line 252 of file timer.c.

254{
259 PETHREAD TimerThread;
260 ULONG DerefsToDo = 1;
262 PAGED_CODE();
263
264 /* Check if we need to probe */
266 {
268 {
269 /* Make sure the pointer is valid */
271 }
273 {
274 /* Return the exception code */
276 }
277 _SEH2_END;
278 }
279
280 /* Get the Timer Object */
281 Status = ObReferenceObjectByHandle(TimerHandle,
285 (PVOID*)&Timer,
286 NULL);
287 if (NT_SUCCESS(Status))
288 {
289 /* Lock the Timer */
291
292 /* Check if it's enabled */
293 if (Timer->ApcAssociated)
294 {
295 /* Get the Thread. */
296 TimerThread = CONTAINING_RECORD(Timer->TimerApc.Thread,
297 ETHREAD,
298 Tcb);
299
300 /* Lock its active list */
302
303 /* Remove it */
304 RemoveEntryList(&Timer->ActiveTimerListEntry);
305 Timer->ApcAssociated = FALSE;
306
307 /* Unlock the list */
309
310 /* Cancel the Timer */
311 KeCancelTimer(&Timer->KeTimer);
312 KeRemoveQueueDpc(&Timer->TimerDpc);
313 if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo++;
314 DerefsToDo++;
315 }
316 else
317 {
318 /* If timer was disabled, we still need to cancel it */
319 KeCancelTimer(&Timer->KeTimer);
320 }
321
322 /* Handle a Wake Timer */
323 if (Timer->WakeTimerListEntry.Flink)
324 {
325 /* Lock the Wake List */
327
328 /* Check again, since it might've changed before we locked */
329 if (Timer->WakeTimerListEntry.Flink)
330 {
331 /* Remove it from the Wait List */
332 RemoveEntryList(&Timer->WakeTimerListEntry);
333 Timer->WakeTimerListEntry.Flink = NULL;
334 }
335
336 /* Release the Wake List */
338 }
339
340 /* Unlock the Timer */
342
343 /* Read the old State */
344 State = KeReadStateTimer(&Timer->KeTimer);
345
346 /* Dereference the Object */
347 ObDereferenceObjectEx(Timer, DerefsToDo);
348
349 /* Check if caller wants the state */
350 if (CurrentState)
351 {
353 {
354 /* Return the Timer State */
356 }
358 {
359 /* Do nothing */
360 (void)0;
361 }
362 _SEH2_END;
363 }
364 }
365
366 /* Return to Caller */
367 return Status;
368}
#define PAGED_CODE()
#define ExGetPreviousMode
Definition: ex.h:140
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define KernelMode
Definition: asm.h:34
#define TIMER_MODIFY_STATE
Definition: extypes.h:115
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define ProbeForWriteBoolean(Ptr)
Definition: probe.h:31
BOOLEAN NTAPI KeReadStateTimer(IN PKTIMER Timer)
Definition: timerobj.c:269
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
_Out_opt_ PBOOLEAN CurrentState
Definition: zwfuncs.h:393

Referenced by CancelWaitableTimer().

◆ NtCreateTimer()

NTSTATUS NTAPI NtCreateTimer ( OUT PHANDLE  TimerHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN TIMER_TYPE  TimerType 
)

Definition at line 372 of file timer.c.

376{
378 HANDLE hTimer;
381 PAGED_CODE();
382
383 /* Check for correct timer type */
384 if ((TimerType != NotificationTimer) &&
386 {
387 /* Fail */
389 }
390
391 /* Check if we need to probe */
393 {
395 {
396 /* Make sure the pointer is valid */
397 ProbeForWriteHandle(TimerHandle);
398 }
400 {
401 /* Return the exception code */
403 }
404 _SEH2_END;
405 }
406
407 /* Create the Object */
412 NULL,
413 sizeof(ETIMER),
414 0,
415 0,
416 (PVOID*)&Timer);
417 if (NT_SUCCESS(Status))
418 {
419 /* Initialize the DPC */
420 KeInitializeDpc(&Timer->TimerDpc, ExpTimerDpcRoutine, Timer);
421
422 /* Initialize the Kernel Timer */
424
425 /* Initialize the timer fields */
427 Timer->ApcAssociated = FALSE;
428 Timer->WakeTimer = FALSE;
429 Timer->WakeTimerListEntry.Flink = NULL;
430
431 /* Insert the Timer */
433 NULL,
435 0,
436 NULL,
437 &hTimer);
438
439 /* Check for success */
440 if (NT_SUCCESS(Status))
441 {
442 /* Enter SEH */
444 {
445 /* Return the Timer Handle */
446 *TimerHandle = hTimer;
447 }
449 {
450 /* Do nothing */
451 (void)0;
452 }
453 _SEH2_END;
454 }
455 }
456
457 /* Return to Caller */
458 return Status;
459}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
@ SynchronizationTimer
@ NotificationTimer
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:478
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
VOID NTAPI KeInitializeTimerEx(OUT PKTIMER Timer, IN TIMER_TYPE Type)
Definition: timerobj.c:244
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ TIMER_TYPE TimerType
Definition: zwfuncs.h:403

◆ NtOpenTimer()

NTSTATUS NTAPI NtOpenTimer ( OUT PHANDLE  TimerHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes 
)

Definition at line 463 of file timer.c.

466{
467 HANDLE hTimer;
470 PAGED_CODE();
471
472 /* Check Parameter Validity */
474 {
476 {
477 /* Make sure the pointer is valid */
478 ProbeForWriteHandle(TimerHandle);
479 }
481 {
482 /* Return the exception code */
484 }
485 _SEH2_END;
486 }
487
488 /* Open the Timer */
492 NULL,
494 NULL,
495 &hTimer);
496 if (NT_SUCCESS(Status))
497 {
498 /* Enter SEH */
500 {
501 /* Return the Timer Handle */
502 *TimerHandle = hTimer;
503 }
505 {
506 /* Do nothing */
507 (void)0;
508 }
509 _SEH2_END;
510 }
511
512 /* Return to Caller */
513 return Status;
514}
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2532

Referenced by NtOpenObject().

◆ NtQueryTimer()

NTSTATUS NTAPI NtQueryTimer ( IN HANDLE  TimerHandle,
IN TIMER_INFORMATION_CLASS  TimerInformationClass,
OUT PVOID  TimerInformation,
IN ULONG  TimerInformationLength,
OUT PULONG ReturnLength  OPTIONAL 
)

Definition at line 518 of file timer.c.

523{
527 PTIMER_BASIC_INFORMATION BasicInfo = TimerInformation;
528 PAGED_CODE();
529
530 /* Check Validity */
531 Status = DefaultQueryInfoBufferCheck(TimerInformationClass,
533 sizeof(ExTimerInfoClass) /
534 sizeof(ExTimerInfoClass[0]),
536 TimerInformation,
537 TimerInformationLength,
539 NULL,
541 if (!NT_SUCCESS(Status)) return Status;
542
543 /* Get the Timer Object */
544 Status = ObReferenceObjectByHandle(TimerHandle,
548 (PVOID*)&Timer,
549 NULL);
550 if (NT_SUCCESS(Status))
551 {
552 /* Return the Basic Information */
554 {
555 /* Return the remaining time, corrected */
556 BasicInfo->TimeRemaining.QuadPart = Timer->
557 KeTimer.DueTime.QuadPart -
559
560 /* Return the current state */
561 BasicInfo->SignalState = KeReadStateTimer(&Timer->KeTimer);
562
563 /* Return the buffer length if requested */
565 }
567 {
568 /* Get the exception code */
570 }
571 _SEH2_END;
572
573 /* Dereference Object */
575 }
576
577 /* Return Status */
578 return Status;
579}
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
#define ICIF_PROBE_READ_WRITE
Definition: icif.h:24
struct _TIMER_BASIC_INFORMATION TIMER_BASIC_INFORMATION
#define TIMER_QUERY_STATE
Definition: extypes.h:114
static const INFORMATION_CLASS_INFO ExTimerInfoClass[]
Definition: timer.c:33
static __inline NTSTATUS DefaultQueryInfoBufferCheck(_In_ ULONG Class, _In_ const INFORMATION_CLASS_INFO *ClassList, _In_ ULONG ClassListEntries, _In_ ULONG Flags, _In_opt_ PVOID Buffer, _In_ ULONG BufferLength, _In_opt_ PULONG ReturnLength, _In_opt_ PULONG_PTR ReturnLengthPtr, _In_ KPROCESSOR_MODE PreviousMode)
Probe helper that validates the provided parameters whenever a NtQuery*** system call is invoked from...
Definition: probe.h:219
#define KeQueryInterruptTime()
Definition: ke.h:37
LARGE_INTEGER TimeRemaining
Definition: extypes.h:713
LONGLONG QuadPart
Definition: typedefs.h:114

◆ NtSetTimer()

NTSTATUS NTAPI NtSetTimer ( IN HANDLE  TimerHandle,
IN PLARGE_INTEGER  DueTime,
IN PTIMER_APC_ROUTINE TimerApcRoutine  OPTIONAL,
IN PVOID TimerContext  OPTIONAL,
IN BOOLEAN  WakeTimer,
IN LONG Period  OPTIONAL,
OUT PBOOLEAN PreviousState  OPTIONAL 
)

Definition at line 583 of file timer.c.

590{
596 LARGE_INTEGER TimerDueTime;
597 PETHREAD TimerThread;
598 ULONG DerefsToDo = 1;
600 PAGED_CODE();
601
602 /* Check for a valid Period */
603 if (Period < 0) return STATUS_INVALID_PARAMETER_6;
604
605 /* Check if we need to probe */
607 {
609 {
610 /* Probe and capture the due time */
611 TimerDueTime = ProbeForReadLargeInteger(DueTime);
612
613 /* Probe the state pointer if one was passed */
615 }
617 {
618 /* Return the exception code */
620 }
621 _SEH2_END;
622 }
623 else
624 {
625 /* Capture the time directly */
626 TimerDueTime = *DueTime;
627 }
628
629 /* Get the Timer Object */
630 Status = ObReferenceObjectByHandle(TimerHandle,
634 (PVOID*)&Timer,
635 NULL);
636
637 /*
638 * Tell the user we don't support Wake Timers...
639 * when we have the ability to use/detect the Power Management
640 * functionality required to support them, make this check dependent
641 * on the actual PM capabilities
642 */
643 if (NT_SUCCESS(Status) && WakeTimer)
644 {
646 }
647
648 /* Check status */
649 if (NT_SUCCESS(Status))
650 {
651 /* Lock the Timer */
653
654 /* Cancel Running Timer */
655 if (Timer->ApcAssociated)
656 {
657 /* Get the Thread. */
658 TimerThread = CONTAINING_RECORD(Timer->TimerApc.Thread,
659 ETHREAD,
660 Tcb);
661
662 /* Lock its active list */
664
665 /* Remove it */
666 RemoveEntryList(&Timer->ActiveTimerListEntry);
667 Timer->ApcAssociated = FALSE;
668
669 /* Unlock the list */
671
672 /* Cancel the Timer */
673 KeCancelTimer(&Timer->KeTimer);
674 KeRemoveQueueDpc(&Timer->TimerDpc);
675 if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo++;
676 DerefsToDo++;
677 }
678 else
679 {
680 /* If timer was disabled, we still need to cancel it */
681 KeCancelTimer(&Timer->KeTimer);
682 }
683
684 /* Read the State */
685 State = KeReadStateTimer(&Timer->KeTimer);
686
687 /* Handle Wake Timers */
688 Timer->WakeTimer = WakeTimer;
690 if ((WakeTimer) && !(Timer->WakeTimerListEntry.Flink))
691 {
692 /* Insert it into the list */
693 InsertTailList(&ExpWakeList, &Timer->WakeTimerListEntry);
694 }
695 else if (!(WakeTimer) && (Timer->WakeTimerListEntry.Flink))
696 {
697 /* Remove it from the list */
698 RemoveEntryList(&Timer->WakeTimerListEntry);
699 Timer->WakeTimerListEntry.Flink = NULL;
700 }
702
703 /* Set up the APC Routine if specified */
704 Timer->Period = Period;
705 if (TimerApcRoutine)
706 {
707 /* Initialize the APC */
708 KeInitializeApc(&Timer->TimerApc,
709 &Thread->Tcb,
716
717 /* Lock the Thread's Active List and Insert */
720 &Timer->ActiveTimerListEntry);
721 Timer->ApcAssociated = TRUE;
723
724 /* One less dereference to do */
725 DerefsToDo--;
726 }
727
728 /* Enable and Set the Timer */
729 KeSetTimerEx(&Timer->KeTimer,
730 TimerDueTime,
731 Period,
732 TimerApcRoutine ? &Timer->TimerDpc : NULL);
733
734 /* Unlock the Timer */
736
737 /* Dereference if it was previously enabled */
738 if (DerefsToDo) ObDereferenceObjectEx(Timer, DerefsToDo);
739
740 /* Check if we need to return the State */
741 if (PreviousState)
742 {
743 /* Enter SEH */
745 {
746 /* Return the Timer State */
748 }
750 {
751 /* Do nothing */
752 (void)0;
753 }
754 _SEH2_END;
755 }
756 }
757
758 /* Return to Caller */
759 return Status;
760}
#define InsertTailList(ListHead, Entry)
VOID(NTAPI * PKRUNDOWN_ROUTINE)(IN struct _KAPC *Apc)
Definition: ketypes.h:750
@ CurrentApcEnvironment
Definition: ketypes.h:769
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:744
VOID NTAPI ExpTimerApcKernelRoutine(IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArguemnt2)
Definition: timer.c:172
VOID NTAPI KeInitializeApc(IN PKAPC Apc, IN PKTHREAD Thread, IN KAPC_ENVIRONMENT TargetEnvironment, IN PKKERNEL_ROUTINE KernelRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, IN PKNORMAL_ROUTINE NormalRoutine, IN KPROCESSOR_MODE Mode, IN PVOID Context)
Definition: apc.c:651
#define STATUS_INVALID_PARAMETER_6
Definition: ntstatus.h:480
#define STATUS_TIMER_RESUME_IGNORED
Definition: ntstatus.h:151
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOLEAN NTAPI KeSetTimerEx(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:294
_In_ WDF_POWER_DEVICE_STATE PreviousState
Definition: wdfdevice.h:829
_In_ WDFTIMER _In_ LONGLONG DueTime
Definition: wdftimer.h:190
_In_ LARGE_INTEGER _In_ ULONG Period
Definition: kefuncs.h:1313
_In_ PLARGE_INTEGER _In_opt_ PTIMER_APC_ROUTINE _In_opt_ PVOID TimerContext
Definition: zwfuncs.h:430
_In_ PLARGE_INTEGER _In_opt_ PTIMER_APC_ROUTINE TimerApcRoutine
Definition: zwfuncs.h:429

Referenced by SetWaitableTimer().

Variable Documentation

◆ ExpTimerMapping

GENERIC_MAPPING ExpTimerMapping
static
Initial value:
=
{
}
#define SYNCHRONIZE
Definition: nt_native.h:61
#define STANDARD_RIGHTS_READ
Definition: nt_native.h:65
#define STANDARD_RIGHTS_WRITE
Definition: nt_native.h:66
#define STANDARD_RIGHTS_EXECUTE
Definition: nt_native.h:67

Definition at line 24 of file timer.c.

Referenced by ExpInitializeTimerImplementation().

◆ ExpWakeList

LIST_ENTRY ExpWakeList

Definition at line 21 of file timer.c.

Referenced by ExpInitializeTimerImplementation(), and NtSetTimer().

◆ ExpWakeListLock

KSPIN_LOCK ExpWakeListLock

◆ ExTimerInfoClass

const INFORMATION_CLASS_INFO ExTimerInfoClass[]
static
Initial value:
=
{
}
#define ICIF_QUERY
Definition: icif.h:18
#define IQS_SAME(Type, Alignment, Flags)
Definition: icif.h:37

Definition at line 33 of file timer.c.

Referenced by NtQueryTimer().

◆ ExTimerType