mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 16:51:39 +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 */
|
/* Cancel the timer and remove its DPC and APC */
|
||||||
KeCancelTimer(&Timer->KeTimer);
|
KeCancelTimer(&Timer->KeTimer);
|
||||||
KeRemoveQueueDpc(&Timer->TimerDpc);
|
KeRemoveQueueDpc(&Timer->TimerDpc);
|
||||||
if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo = 2;
|
if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo++;
|
||||||
|
|
||||||
/* Add another dereference to do */
|
/* Add another dereference to do */
|
||||||
DerefsToDo++;
|
DerefsToDo++;
|
||||||
|
@ -101,7 +101,6 @@ ExTimerRundown(VOID)
|
||||||
|
|
||||||
/* Release lock and return */
|
/* Release lock and return */
|
||||||
KeReleaseSpinLock(&Thread->ActiveTimerListLock, OldIrql);
|
KeReleaseSpinLock(&Thread->ActiveTimerListLock, OldIrql);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -200,7 +199,7 @@ ExpTimerApcKernelRoutine(IN PKAPC Apc,
|
||||||
|
|
||||||
/* Disable it */
|
/* Disable it */
|
||||||
Timer->ApcAssociated = FALSE;
|
Timer->ApcAssociated = FALSE;
|
||||||
DerefsToDo = 2;
|
DerefsToDo++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -306,7 +305,7 @@ NtCancelTimer(IN HANDLE TimerHandle,
|
||||||
/* Cancel the Timer */
|
/* Cancel the Timer */
|
||||||
KeCancelTimer(&Timer->KeTimer);
|
KeCancelTimer(&Timer->KeTimer);
|
||||||
KeRemoveQueueDpc(&Timer->TimerDpc);
|
KeRemoveQueueDpc(&Timer->TimerDpc);
|
||||||
if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo = 2;
|
if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo++;
|
||||||
DerefsToDo++;
|
DerefsToDo++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -351,7 +350,7 @@ NtCancelTimer(IN HANDLE TimerHandle,
|
||||||
}
|
}
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
{
|
{
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
}
|
}
|
||||||
|
@ -374,6 +373,14 @@ NtCreateTimer(OUT PHANDLE TimerHandle,
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Check for correct timer type */
|
||||||
|
if ((TimerType != NotificationTimer) &&
|
||||||
|
(TimerType != SynchronizationTimer))
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
|
return STATUS_INVALID_PARAMETER_4;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check Parameter Validity */
|
/* Check Parameter Validity */
|
||||||
if (PreviousMode != KernelMode)
|
if (PreviousMode != KernelMode)
|
||||||
{
|
{
|
||||||
|
@ -389,12 +396,6 @@ NtCreateTimer(OUT PHANDLE TimerHandle,
|
||||||
if(!NT_SUCCESS(Status)) return Status;
|
if(!NT_SUCCESS(Status)) return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for correct timer type */
|
|
||||||
if ((TimerType != NotificationTimer) && (TimerType != SynchronizationTimer))
|
|
||||||
{
|
|
||||||
return STATUS_INVALID_PARAMETER_4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the Object */
|
/* Create the Object */
|
||||||
Status = ObCreateObject(PreviousMode,
|
Status = ObCreateObject(PreviousMode,
|
||||||
ExTimerType,
|
ExTimerType,
|
||||||
|
@ -427,16 +428,20 @@ NtCreateTimer(OUT PHANDLE TimerHandle,
|
||||||
NULL,
|
NULL,
|
||||||
&hTimer);
|
&hTimer);
|
||||||
|
|
||||||
/* Make sure it's safe to write to the handle */
|
/* Check for success */
|
||||||
_SEH_TRY
|
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 */
|
/* Return to Caller */
|
||||||
|
@ -486,7 +491,7 @@ NtOpenTimer(OUT PHANDLE TimerHandle,
|
||||||
}
|
}
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
{
|
{
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
}
|
}
|
||||||
|
@ -578,13 +583,16 @@ NtSetTimer(IN HANDLE TimerHandle,
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Check for a valid Period */
|
||||||
|
if (Period < 0) return STATUS_INVALID_PARAMETER_6;
|
||||||
|
|
||||||
/* Check Parameter Validity */
|
/* Check Parameter Validity */
|
||||||
if (PreviousMode != KernelMode)
|
if (PreviousMode != KernelMode)
|
||||||
{
|
{
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
TimerDueTime = ProbeForReadLargeInteger(DueTime);
|
TimerDueTime = ProbeForReadLargeInteger(DueTime);
|
||||||
if(PreviousState) ProbeForWriteBoolean(PreviousState);
|
if (PreviousState) ProbeForWriteBoolean(PreviousState);
|
||||||
}
|
}
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
{
|
{
|
||||||
|
@ -594,9 +602,6 @@ NtSetTimer(IN HANDLE TimerHandle,
|
||||||
if(!NT_SUCCESS(Status)) return Status;
|
if(!NT_SUCCESS(Status)) return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for a valid Period */
|
|
||||||
if (Period < 0) return STATUS_INVALID_PARAMETER_6;
|
|
||||||
|
|
||||||
/* Get the Timer Object */
|
/* Get the Timer Object */
|
||||||
Status = ObReferenceObjectByHandle(TimerHandle,
|
Status = ObReferenceObjectByHandle(TimerHandle,
|
||||||
TIMER_MODIFY_STATE,
|
TIMER_MODIFY_STATE,
|
||||||
|
@ -640,7 +645,7 @@ NtSetTimer(IN HANDLE TimerHandle,
|
||||||
/* Cancel the Timer */
|
/* Cancel the Timer */
|
||||||
KeCancelTimer(&Timer->KeTimer);
|
KeCancelTimer(&Timer->KeTimer);
|
||||||
KeRemoveQueueDpc(&Timer->TimerDpc);
|
KeRemoveQueueDpc(&Timer->TimerDpc);
|
||||||
if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo = 2;
|
if (KeRemoveQueueApc(&Timer->TimerApc)) DerefsToDo++;
|
||||||
DerefsToDo++;
|
DerefsToDo++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -653,6 +658,7 @@ NtSetTimer(IN HANDLE TimerHandle,
|
||||||
State = KeReadStateTimer(&Timer->KeTimer);
|
State = KeReadStateTimer(&Timer->KeTimer);
|
||||||
|
|
||||||
/* Handle Wake Timers */
|
/* Handle Wake Timers */
|
||||||
|
Timer->WakeTimer = WakeTimer;
|
||||||
KeAcquireSpinLockAtDpcLevel(&ExpWakeListLock);
|
KeAcquireSpinLockAtDpcLevel(&ExpWakeListLock);
|
||||||
if ((WakeTimer) && !(Timer->WakeTimerListEntry.Flink))
|
if ((WakeTimer) && !(Timer->WakeTimerListEntry.Flink))
|
||||||
{
|
{
|
||||||
|
@ -713,7 +719,6 @@ NtSetTimer(IN HANDLE TimerHandle,
|
||||||
}
|
}
|
||||||
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
{
|
{
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue