Implemented KeRemoveQueueApc() (not exported).

Implemented timer object.

svn path=/trunk/; revision=1601
This commit is contained in:
Eric Kohl
2001-02-04 17:28:13 +00:00
parent 543839bcee
commit fef0ed0d35
5 changed files with 313 additions and 60 deletions
+2
View File
@@ -103,6 +103,8 @@ VOID KeContextToTrapFrame(PCONTEXT Context,
PKTRAP_FRAME TrapFrame);
VOID KeReleaseDispatcherDatabaseLockAtDpcLevel(BOOLEAN Wait);
BOOLEAN STDCALL KeRemoveQueueApc (PKAPC Apc);
/* INITIALIZATION FUNCTIONS *************************************************/
VOID KeInitExceptions(VOID);
+2
View File
@@ -1,4 +1,6 @@
VOID NtInitializeEventImplementation(VOID);
VOID NtInitializeEventPairImplementation(VOID);
VOID NtInitializeSemaphoreImplementation(VOID);
VOID NtInitializeMutantImplementation(VOID);
VOID NtInitializeTimerImplementation(VOID);
NTSTATUS NiInitPort(VOID);
+40 -1
View File
@@ -220,7 +220,7 @@ VOID STDCALL KiDeliverApc(ULONG Unknown1,
KeReleaseSpinLock(&PiApcLock, oldlvl);
}
VOID STDCALL
VOID STDCALL
KeInsertQueueApc (PKAPC Apc,
PVOID SystemArgument1,
PVOID SystemArgument2,
@@ -296,6 +296,45 @@ KeInsertQueueApc (PKAPC Apc,
KeReleaseSpinLock(&PiApcLock, oldlvl);
}
BOOLEAN STDCALL
KeRemoveQueueApc (PKAPC Apc)
/*
* FUNCTION: Removes APC object from the apc queue
* ARGUMENTS:
* Apc = APC to remove
* RETURNS: TRUE if the APC was in the queue
* FALSE otherwise
* NOTE: This function is not exported.
*/
{
KIRQL oldIrql;
PKTHREAD TargetThread;
KeAcquireSpinLockAtDpcLevel(&PiApcLock);
KeRaiseIrql(HIGH_LEVEL, &oldIrql);
if (Apc->Inserted == FALSE)
{
KeReleaseSpinLock(&PiApcLock, oldIrql);
return(FALSE);
}
TargetThread = Apc->Thread;
RemoveEntryList(&Apc->ApcListEntry);
if (Apc->ApcMode == KernelMode)
{
TargetThread->ApcState.KernelApcPending--;
}
else
{
TargetThread->ApcState.UserApcPending--;
}
Apc->Inserted = FALSE;
KeReleaseSpinLock(&PiApcLock, oldIrql);
return(TRUE);
}
VOID STDCALL
KeInitializeApc (PKAPC Apc,
PKTHREAD Thread,
+5 -1
View File
@@ -1,4 +1,5 @@
/*
/* $Id: nt.c,v 1.6 2001/02/04 17:28:13 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/nt/nt.c
@@ -22,5 +23,8 @@ VOID NtInit(VOID)
NtInitializeEventImplementation();
NtInitializeEventPairImplementation();
NtInitializeSemaphoreImplementation();
NtInitializeTimerImplementation();
NiInitPort();
}
/* EOF */
+264 -58
View File
@@ -1,4 +1,5 @@
/*
/* $Id: nttimer.c,v 1.7 2001/02/04 17:28:13 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/nt/nttimer.c
@@ -11,84 +12,289 @@
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <ntos/synch.h>
#include <internal/ob.h>
#include <internal/ke.h>
#include <limits.h>
#include <internal/debug.h>
/* TYPES ********************************************************************/
typedef struct _NTTIMER
{
KTIMER Timer;
KDPC Dpc;
KAPC Apc;
BOOLEAN Running;
} NTTIMER, *PNTTIMER;
/* GLOBALS ******************************************************************/
#if 0
POBJECT_TYPE ExTimerType = NULL;
static GENERIC_MAPPING ExpTimerMapping = {
STANDARD_RIGHTS_READ | TIMER_QUERY_STATE,
STANDARD_RIGHTS_WRITE | TIMER_MODIFY_STATE,
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
TIMER_ALL_ACCESS};
#endif
/* FUNCTIONS *****************************************************************/
NTSTATUS
STDCALL
NtCancelTimer (
IN HANDLE TimerHandle,
OUT PBOOLEAN CurrentState OPTIONAL
)
NtpCreateTimer(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
POBJECT_ATTRIBUTES ObjectAttributes)
{
DPRINT("NtpCreateTimer(ObjectBody %x, Parent %x, RemainingPath %S)\n",
ObjectBody, Parent, RemainingPath);
if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
{
return(STATUS_UNSUCCESSFUL);
}
if (Parent != NULL && RemainingPath != NULL)
{
ObAddEntryDirectory(Parent, ObjectBody, RemainingPath+1);
}
return(STATUS_SUCCESS);
}
VOID
NtpTimerDpcRoutine(PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2)
{
PNTTIMER Timer;
KIRQL OldIrql;
DPRINT("NtpTimerDpcRoutine()\n");
Timer = (PNTTIMER)DeferredContext;
OldIrql = KeRaiseIrqlToDpcLevel();
if (Timer->Running == TRUE)
{
KeInsertQueueApc(&Timer->Apc,
SystemArgument1,
SystemArgument2,
KernelMode);
}
KeLowerIrql(OldIrql);
}
VOID
NtpTimerApcKernelRoutine(PKAPC Apc,
PKNORMAL_ROUTINE* NormalRoutine,
PVOID* NormalContext,
PVOID* SystemArgument1,
PVOID* SystemArguemnt2)
{
DPRINT("NtpTimerApcKernelRoutine()\n");
}
VOID NtInitializeTimerImplementation(VOID)
{
ExTimerType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
RtlCreateUnicodeString(&ExTimerType->TypeName, L"Timer");
ExTimerType->MaxObjects = ULONG_MAX;
ExTimerType->MaxHandles = ULONG_MAX;
ExTimerType->TotalObjects = 0;
ExTimerType->TotalHandles = 0;
ExTimerType->PagedPoolCharge = 0;
ExTimerType->NonpagedPoolCharge = sizeof(NTTIMER);
ExTimerType->Mapping = &ExpTimerMapping;
ExTimerType->Dump = NULL;
ExTimerType->Open = NULL;
ExTimerType->Close = NULL;
ExTimerType->Delete = NULL;
ExTimerType->Parse = NULL;
ExTimerType->Security = NULL;
ExTimerType->QueryName = NULL;
ExTimerType->OkayToClose = NULL;
ExTimerType->Create = NtpCreateTimer;
}
NTSTATUS STDCALL
NtCancelTimer(IN HANDLE TimerHandle,
OUT PBOOLEAN CurrentState OPTIONAL)
{
PNTTIMER Timer;
NTSTATUS Status;
BOOLEAN State;
KIRQL OldIrql;
DPRINT("NtCancelTimer()\n");
Status = ObReferenceObjectByHandle(TimerHandle,
TIMER_ALL_ACCESS,
ExTimerType,
UserMode,
(PVOID*)&Timer,
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;
}
NTSTATUS STDCALL
NtCreateTimer(OUT PHANDLE TimerHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN TIMER_TYPE TimerType)
{
PNTTIMER Timer;
DPRINT("NtCreateTimer()\n");
Timer = ObCreateObject(TimerHandle,
DesiredAccess,
ObjectAttributes,
ExTimerType);
KeInitializeTimerEx(&Timer->Timer,
TimerType);
KeInitializeDpc (&Timer->Dpc,
(PKDEFERRED_ROUTINE)NtpTimerDpcRoutine,
(PVOID)Timer);
Timer->Running = FALSE;
ObDereferenceObject(Timer);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
NtOpenTimer(OUT PHANDLE TimerHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes)
{
NTSTATUS Status;
Status = ObOpenObjectByName(ObjectAttributes,
ExTimerType,
NULL,
UserMode,
DesiredAccess,
NULL,
TimerHandle);
return Status;
}
NTSTATUS STDCALL
NtQueryTimer(IN HANDLE TimerHandle,
IN CINT TimerInformationClass,
OUT PVOID TimerInformation,
IN ULONG Length,
OUT PULONG ResultLength)
{
UNIMPLEMENTED;
}
NTSTATUS
STDCALL
NtCreateTimer (
OUT PHANDLE TimerHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN TIMER_TYPE TimerType
)
NTSTATUS STDCALL
NtSetTimer(IN HANDLE TimerHandle,
IN PLARGE_INTEGER DueTime,
IN PTIMERAPCROUTINE TimerApcRoutine,
IN PVOID TimerContext,
IN BOOL WakeTimer,
IN ULONG Period OPTIONAL,
OUT PBOOLEAN PreviousState OPTIONAL)
{
UNIMPLEMENTED;
PNTTIMER Timer;
NTSTATUS Status;
BOOLEAN Result;
KIRQL OldIrql;
BOOLEAN State;
DPRINT("NtSetTimer()\n");
Status = ObReferenceObjectByHandle(TimerHandle,
TIMER_ALL_ACCESS,
ExTimerType,
KeGetPreviousMode(),
(PVOID*)&Timer,
NULL);
if (!NT_SUCCESS(Status))
return Status;
State = KeReadStateTimer(&Timer->Timer);
if (Timer->Running == TRUE)
{
/* cancel running timer */
OldIrql = KeRaiseIrqlToDpcLevel();
KeCancelTimer(&Timer->Timer);
KeRemoveQueueDpc(&Timer->Dpc);
KeRemoveQueueApc(&Timer->Apc);
Timer->Running = FALSE;
KeLowerIrql(OldIrql);
}
KeInitializeApc(&Timer->Apc,
KeGetCurrentThread(),
0,
(PKKERNEL_ROUTINE)NtpTimerApcKernelRoutine,
(PKRUNDOWN_ROUTINE)NULL,
(PKNORMAL_ROUTINE)TimerApcRoutine,
KeGetPreviousMode(),
TimerContext);
Result = KeSetTimerEx (&Timer->Timer,
*DueTime,
Period,
&Timer->Dpc);
if (Result == FALSE)
{
ObDereferenceObject(Timer);
return STATUS_UNSUCCESSFUL;
}
Timer->Running = TRUE;
ObDereferenceObject(Timer);
if (PreviousState != NULL)
{
*PreviousState = State;
}
return STATUS_SUCCESS;
}
NTSTATUS
STDCALL
NtOpenTimer (
OUT PHANDLE TimerHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
)
{
UNIMPLEMENTED;
}
NTSTATUS
STDCALL
NtQueryTimer (
IN HANDLE TimerHandle,
IN CINT TimerInformationClass,
OUT PVOID TimerInformation,
IN ULONG Length,
OUT PULONG ResultLength
)
{
UNIMPLEMENTED;
}
NTSTATUS
STDCALL
NtSetTimer (
IN HANDLE TimerHandle,
IN PLARGE_INTEGER DueTime,
IN PTIMERAPCROUTINE TimerApcRoutine,
IN PVOID TimerContext,
IN BOOL WakeTimer,
IN ULONG Period OPTIONAL,
OUT PBOOLEAN PreviousState OPTIONAL
)
{
UNIMPLEMENTED;
}
/* EOF */