}
+VOID STDCALL
+NtpDeleteTimer(PVOID ObjectBody)
+{
+ KIRQL OldIrql;
+ PNTTIMER Timer = ObjectBody;
+
+ DPRINT("NtpDeleteTimer()\n");
+
+ OldIrql = KeRaiseIrqlToDpcLevel();
+
+ KeCancelTimer(&Timer->Timer);
+ KeRemoveQueueDpc(&Timer->Dpc);
+ KeRemoveQueueApc(&Timer->Apc);
+ Timer->Running = FALSE;
+
+ KeLowerIrql(OldIrql);
+}
+
+
VOID
NtpTimerDpcRoutine(PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument2)
{
PNTTIMER Timer;
-
+
DPRINT("NtpTimerDpcRoutine()\n");
-
+
Timer = (PNTTIMER)DeferredContext;
-
+
if ( Timer->Running )
{
KeInsertQueueApc(&Timer->Apc,
VOID NtInitializeTimerImplementation(VOID)
{
ExTimerType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-
+
RtlCreateUnicodeString(&ExTimerType->TypeName, L"Timer");
-
+
ExTimerType->Tag = TAG('T', 'I', 'M', 'T');
ExTimerType->MaxObjects = ULONG_MAX;
ExTimerType->MaxHandles = ULONG_MAX;
ExTimerType->Dump = NULL;
ExTimerType->Open = NULL;
ExTimerType->Close = NULL;
- ExTimerType->Delete = NULL;
+ ExTimerType->Delete = NtpDeleteTimer;
ExTimerType->Parse = NULL;
ExTimerType->Security = NULL;
ExTimerType->QueryName = NULL;
NULL);
if (!NT_SUCCESS(Status))
return Status;
-
+
OldIrql = KeRaiseIrqlToDpcLevel();
-
+
State = KeCancelTimer(&Timer->Timer);
KeRemoveQueueDpc(&Timer->Dpc);
KeRemoveQueueApc(&Timer->Apc);
Timer->Running = FALSE;
-
+
KeLowerIrql(OldIrql);
ObDereferenceObject(Timer);
-
+
if (CurrentState != NULL)
{
*CurrentState = State;
}
-
+
return STATUS_SUCCESS;
}
{
PNTTIMER Timer;
NTSTATUS Status;
-
+
DPRINT("NtCreateTimer()\n");
Status = ObCreateObject(TimerHandle,
DesiredAccess,
(PVOID*)&Timer);
if (!NT_SUCCESS(Status))
return Status;
-
+
KeInitializeTimerEx(&Timer->Timer,
TimerType);
-
+
KeInitializeDpc (&Timer->Dpc,
(PKDEFERRED_ROUTINE)NtpTimerDpcRoutine,
(PVOID)Timer);
-
+
Timer->Running = FALSE;
-
+
ObDereferenceObject(Timer);
-
+
return(STATUS_SUCCESS);
}
IN POBJECT_ATTRIBUTES ObjectAttributes)
{
NTSTATUS Status;
-
+
Status = ObOpenObjectByName(ObjectAttributes,
ExTimerType,
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
- return(Status);
+ return(Status);
}
if (TimerInformationClass != TimerBasicInformation)
ObDereferenceObject(Timer);
return(STATUS_INFO_LENGTH_MISMATCH);
}
-
+
memcpy(&TimerInformation.TimeRemaining, &Timer->Timer.DueTime,
sizeof(LARGE_INTEGER));
TimerInformation.SignalState = Timer->Timer.Header.SignalState;
ResultLength = sizeof(TIMER_BASIC_INFORMATION);
-
+
Status = MmCopyToCaller(UnsafeTimerInformation, &TimerInformation,
sizeof(TIMER_BASIC_INFORMATION));
if (!NT_SUCCESS(Status))
ObDereferenceObject(Timer);
return(Status);
}
-
+
if (UnsafeResultLength != NULL)
{
Status = MmCopyToCaller(UnsafeResultLength, &ResultLength,