mirror of
https://github.com/reactos/reactos.git
synced 2025-07-30 21:42:46 +00:00
- Fix reference count bugs in executive timer implementation.
- Don't modify status when failing due to an access fault (NT doesn't!). - Do parameter checks before bothering with expensive SEHing. svn path=/trunk/; revision=25608
This commit is contained in:
parent
36433ba5ec
commit
2ef08cc69b
1 changed files with 31 additions and 26 deletions
|
@ -79,7 +79,7 @@ ExTimerRundown(VOID)
|
|||
/* Cancel the timer and remove its DPC and APC */
|
||||
KeCancelTimer(&Timer->KeTimer);
|
||||
KeRemoveQueueDpc(&Timer->TimerDpc);
|
||||
if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo = 2;
|
||||
if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo++;
|
||||
|
||||
/* Add another dereference to do */
|
||||
DerefsToDo++;
|
||||
|
@ -101,7 +101,6 @@ ExTimerRundown(VOID)
|
|||
|
||||
/* Release lock and return */
|
||||
KeReleaseSpinLock(&Thread->ActiveTimerListLock, OldIrql);
|
||||
return;
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -200,7 +199,7 @@ ExpTimerApcKernelRoutine(IN PKAPC Apc,
|
|||
|
||||
/* Disable it */
|
||||
Timer->ApcAssociated = FALSE;
|
||||
DerefsToDo = 2;
|
||||
DerefsToDo++;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -306,7 +305,7 @@ NtCancelTimer(IN HANDLE TimerHandle,
|
|||
/* Cancel the Timer */
|
||||
KeCancelTimer(&Timer->KeTimer);
|
||||
KeRemoveQueueDpc(&Timer->TimerDpc);
|
||||
if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo = 2;
|
||||
if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo++;
|
||||
DerefsToDo++;
|
||||
}
|
||||
else
|
||||
|
@ -351,7 +350,7 @@ NtCancelTimer(IN HANDLE TimerHandle,
|
|||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
|
@ -374,6 +373,14 @@ NtCreateTimer(OUT PHANDLE TimerHandle,
|
|||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Check for correct timer type */
|
||||
if ((TimerType != NotificationTimer) &&
|
||||
(TimerType != SynchronizationTimer))
|
||||
{
|
||||
/* Fail */
|
||||
return STATUS_INVALID_PARAMETER_4;
|
||||
}
|
||||
|
||||
/* Check Parameter Validity */
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
|
@ -389,12 +396,6 @@ NtCreateTimer(OUT PHANDLE TimerHandle,
|
|||
if(!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
|
||||
/* Check for correct timer type */
|
||||
if ((TimerType != NotificationTimer) && (TimerType != SynchronizationTimer))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER_4;
|
||||
}
|
||||
|
||||
/* Create the Object */
|
||||
Status = ObCreateObject(PreviousMode,
|
||||
ExTimerType,
|
||||
|
@ -427,16 +428,20 @@ NtCreateTimer(OUT PHANDLE TimerHandle,
|
|||
NULL,
|
||||
&hTimer);
|
||||
|
||||
/* Make sure it's safe to write to the handle */
|
||||
_SEH_TRY
|
||||
/* Check for success */
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
*TimerHandle = hTimer;
|
||||
/* Make sure it's safe to write to the handle */
|
||||
_SEH_TRY
|
||||
{
|
||||
*TimerHandle = hTimer;
|
||||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
|
||||
/* Return to Caller */
|
||||
|
@ -486,7 +491,7 @@ NtOpenTimer(OUT PHANDLE TimerHandle,
|
|||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
|
@ -578,13 +583,16 @@ NtSetTimer(IN HANDLE TimerHandle,
|
|||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Check for a valid Period */
|
||||
if (Period < 0) return STATUS_INVALID_PARAMETER_6;
|
||||
|
||||
/* Check Parameter Validity */
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
TimerDueTime = ProbeForReadLargeInteger(DueTime);
|
||||
if(PreviousState) ProbeForWriteBoolean(PreviousState);
|
||||
if (PreviousState) ProbeForWriteBoolean(PreviousState);
|
||||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
|
@ -594,9 +602,6 @@ NtSetTimer(IN HANDLE TimerHandle,
|
|||
if(!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
|
||||
/* Check for a valid Period */
|
||||
if (Period < 0) return STATUS_INVALID_PARAMETER_6;
|
||||
|
||||
/* Get the Timer Object */
|
||||
Status = ObReferenceObjectByHandle(TimerHandle,
|
||||
TIMER_MODIFY_STATE,
|
||||
|
@ -640,7 +645,7 @@ NtSetTimer(IN HANDLE TimerHandle,
|
|||
/* Cancel the Timer */
|
||||
KeCancelTimer(&Timer->KeTimer);
|
||||
KeRemoveQueueDpc(&Timer->TimerDpc);
|
||||
if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo = 2;
|
||||
if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo++;
|
||||
DerefsToDo++;
|
||||
}
|
||||
else
|
||||
|
@ -653,6 +658,7 @@ NtSetTimer(IN HANDLE TimerHandle,
|
|||
State = KeReadStateTimer(&Timer->KeTimer);
|
||||
|
||||
/* Handle Wake Timers */
|
||||
Timer->WakeTimer = WakeTimer;
|
||||
KeAcquireSpinLockAtDpcLevel(&ExpWakeListLock);
|
||||
if ((WakeTimer) && !(Timer->WakeTimerListEntry.Flink))
|
||||
{
|
||||
|
@ -713,7 +719,6 @@ NtSetTimer(IN HANDLE TimerHandle,
|
|||
}
|
||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue