mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:42:56 +00:00
- Io*SymbolicLink should use OBJ_CASE_INSENSITIVE
- Use DELETE instead of SYMBOLIC_LINK_ALL_ACCESS when deleting. - Fix formatting in timer.c - Clear the IO_TIMER structure when creating it. svn path=/trunk/; revision=22722
This commit is contained in:
parent
b42accc93a
commit
d1ebf29520
3 changed files with 210 additions and 293 deletions
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS Kernel
|
* PROJECT: ReactOS Kernel
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* FILE: ntoskrnl/io/event.c
|
* FILE: ntoskrnl/io/iocomp.c
|
||||||
* PURPOSE: I/O Wrappers for the Executive Event Functions
|
* PURPOSE: I/O Wrappers (called Completion Ports) for Kernel Queues
|
||||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
* Thomas Weidenmueller (w3seek@reactos.org)
|
* Thomas Weidenmueller (w3seek@reactos.org)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
/* $Id$
|
/*
|
||||||
*
|
* PROJECT: ReactOS Kernel
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
|
||||||
* FILE: ntoskrnl/io/symlink.c
|
* FILE: ntoskrnl/io/symlink.c
|
||||||
* PURPOSE: Implements symbolic links
|
* PURPOSE: I/O Wrappers for Symbolic Links
|
||||||
*
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
* Eric Kohl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
@ -14,170 +13,106 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
/**********************************************************************
|
/*
|
||||||
* NAME EXPORTED
|
|
||||||
* IoCreateSymbolicLink
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
*
|
|
||||||
* ARGUMENTS
|
|
||||||
*
|
|
||||||
* RETURN VALUE
|
|
||||||
*
|
|
||||||
* REVISIONS
|
|
||||||
*
|
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS
|
||||||
IoCreateSymbolicLink(PUNICODE_STRING SymbolicLinkName,
|
NTAPI
|
||||||
PUNICODE_STRING DeviceName)
|
IoCreateSymbolicLink(IN PUNICODE_STRING SymbolicLinkName,
|
||||||
|
IN PUNICODE_STRING DeviceName)
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
/* Initialize the object attributes and create the link */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
SymbolicLinkName,
|
||||||
|
OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
SePublicDefaultSd);
|
||||||
|
Status = ZwCreateSymbolicLinkObject(&Handle,
|
||||||
|
SYMBOLIC_LINK_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
DeviceName);
|
||||||
|
if (NT_SUCCESS(Status)) ZwClose(Handle);
|
||||||
|
|
||||||
DPRINT("IoCreateSymbolicLink(SymbolicLinkName %wZ, DeviceName %wZ)\n",
|
/* Return status */
|
||||||
SymbolicLinkName,
|
return Status;
|
||||||
DeviceName);
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
SymbolicLinkName,
|
|
||||||
OBJ_PERMANENT,
|
|
||||||
NULL,
|
|
||||||
SePublicDefaultSd);
|
|
||||||
|
|
||||||
Status = ZwCreateSymbolicLinkObject(&Handle,
|
|
||||||
SYMBOLIC_LINK_ALL_ACCESS,
|
|
||||||
&ObjectAttributes,
|
|
||||||
DeviceName);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("ZwCreateSymbolicLinkObject() failed (Status %lx)\n", Status);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
ZwClose(Handle);
|
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**********************************************************************
|
|
||||||
* NAME EXPORTED
|
|
||||||
* IoCreateUnprotectedSymbolicLink
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
*
|
|
||||||
* ARGUMENTS
|
|
||||||
*
|
|
||||||
* RETURN VALUE
|
|
||||||
*
|
|
||||||
* REVISIONS
|
|
||||||
*
|
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS
|
||||||
IoCreateUnprotectedSymbolicLink(PUNICODE_STRING SymbolicLinkName,
|
NTAPI
|
||||||
PUNICODE_STRING DeviceName)
|
IoCreateUnprotectedSymbolicLink(IN PUNICODE_STRING SymbolicLinkName,
|
||||||
|
IN PUNICODE_STRING DeviceName)
|
||||||
{
|
{
|
||||||
SECURITY_DESCRIPTOR SecurityDescriptor;
|
SECURITY_DESCRIPTOR SecurityDescriptor;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
/* Create an SD */
|
||||||
|
Status = RtlCreateSecurityDescriptor(&SecurityDescriptor,
|
||||||
|
SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
DPRINT("IoCreateUnprotectedSymbolicLink(SymbolicLinkName %wZ, DeviceName %wZ)\n",
|
/* Set the DACL */
|
||||||
SymbolicLinkName,
|
Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
|
||||||
DeviceName);
|
TRUE,
|
||||||
|
NULL,
|
||||||
|
TRUE);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
Status = RtlCreateSecurityDescriptor(&SecurityDescriptor,
|
/* Initialize the object attributes and create the link */
|
||||||
SECURITY_DESCRIPTOR_REVISION);
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
if (!NT_SUCCESS(Status))
|
SymbolicLinkName,
|
||||||
{
|
OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
|
||||||
DPRINT1("RtlCreateSecurityDescriptor() failed (Status %lx)\n", Status);
|
NULL,
|
||||||
return(Status);
|
&SecurityDescriptor);
|
||||||
}
|
Status = ZwCreateSymbolicLinkObject(&Handle,
|
||||||
|
SYMBOLIC_LINK_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
DeviceName);
|
||||||
|
if (NT_SUCCESS(Status)) ZwClose(Handle);
|
||||||
|
|
||||||
Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
|
/* Return status */
|
||||||
TRUE,
|
return Status;
|
||||||
NULL,
|
|
||||||
TRUE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("RtlSetDaclSecurityDescriptor() failed (Status %lx)\n", Status);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
SymbolicLinkName,
|
|
||||||
OBJ_PERMANENT,
|
|
||||||
NULL,
|
|
||||||
&SecurityDescriptor);
|
|
||||||
|
|
||||||
Status = ZwCreateSymbolicLinkObject(&Handle,
|
|
||||||
SYMBOLIC_LINK_ALL_ACCESS,
|
|
||||||
&ObjectAttributes,
|
|
||||||
DeviceName);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("ZwCreateSymbolicLinkObject() failed (Status %lx)\n", Status);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
ZwClose(Handle);
|
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/**********************************************************************
|
|
||||||
* NAME EXPORTED
|
|
||||||
* IoDeleteSymbolicLink
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
*
|
|
||||||
* ARGUMENTS
|
|
||||||
*
|
|
||||||
* RETURN VALUE
|
|
||||||
*
|
|
||||||
* REVISIONS
|
|
||||||
*
|
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS
|
||||||
IoDeleteSymbolicLink(PUNICODE_STRING SymbolicLinkName)
|
NTAPI
|
||||||
|
IoDeleteSymbolicLink(IN PUNICODE_STRING SymbolicLinkName)
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
/* Initialize the object attributes and open the link */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
SymbolicLinkName,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = ZwOpenSymbolicLinkObject(&Handle, DELETE, &ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
DPRINT("IoDeleteSymbolicLink (SymbolicLinkName %S)\n",
|
/* Make the link temporary and close its handle */
|
||||||
SymbolicLinkName->Buffer);
|
Status = ZwMakeTemporaryObject(Handle);
|
||||||
|
if (NT_SUCCESS(Status)) ZwClose(Handle);
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
/* Return status */
|
||||||
SymbolicLinkName,
|
return Status;
|
||||||
OBJ_OPENLINK,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
Status = ZwOpenSymbolicLinkObject(&Handle,
|
|
||||||
SYMBOLIC_LINK_ALL_ACCESS,
|
|
||||||
&ObjectAttributes);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
return(Status);
|
|
||||||
|
|
||||||
Status = ZwMakeTemporaryObject(Handle);
|
|
||||||
ZwClose(Handle);
|
|
||||||
|
|
||||||
return(Status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
/* $Id$
|
/*
|
||||||
*
|
* PROJECT: ReactOS Kernel
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* FILE: ntoskrnl/io/iocomp.c
|
||||||
* FILE: ntoskrnl/io/timer.c
|
* PURPOSE: I/O Wrappers for Executive Timers
|
||||||
* PURPOSE: IO timers
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
*
|
|
||||||
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
|
||||||
* Alex Ionescu (alex@relsoft.net)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
@ -28,196 +25,181 @@ KTIMER IopTimer;
|
||||||
/* Keep count of how many timers we have */
|
/* Keep count of how many timers we have */
|
||||||
ULONG IopTimerCount = 0;
|
ULONG IopTimerCount = 0;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
static VOID STDCALL
|
VOID
|
||||||
|
NTAPI
|
||||||
IopTimerDispatch(IN PKDPC Dpc,
|
IopTimerDispatch(IN PKDPC Dpc,
|
||||||
IN PVOID DeferredContext,
|
IN PVOID DeferredContext,
|
||||||
IN PVOID SystemArgument1,
|
IN PVOID SystemArgument1,
|
||||||
IN PVOID SystemArgument2)
|
IN PVOID SystemArgument2)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PLIST_ENTRY TimerEntry;
|
PLIST_ENTRY TimerEntry;
|
||||||
PIO_TIMER Timer;
|
PIO_TIMER Timer;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
DPRINT("Dispatching IO Timers. There are: %x \n", IopTimerCount);
|
/* Check if any Timers are actualyl enabled as of now */
|
||||||
|
if (IopTimerCount)
|
||||||
|
{
|
||||||
|
/* Lock the Timers */
|
||||||
|
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
|
||||||
|
|
||||||
/* Check if any Timers are actualyl enabled as of now */
|
/* Call the Timer Routine of each enabled Timer */
|
||||||
if (IopTimerCount) {
|
for (TimerEntry = IopTimerQueueHead.Flink, i = IopTimerCount;
|
||||||
|
(TimerEntry != &IopTimerQueueHead) && i;
|
||||||
|
TimerEntry = TimerEntry->Flink)
|
||||||
|
{
|
||||||
|
/* Get the timer and check if it's enabled */
|
||||||
|
Timer = CONTAINING_RECORD(TimerEntry, IO_TIMER, IoTimerList);
|
||||||
|
if (Timer->TimerEnabled)
|
||||||
|
{
|
||||||
|
/* Call the timer routine */
|
||||||
|
Timer->TimerRoutine(Timer->DeviceObject, Timer->Context);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Lock the Timers */
|
/* Unlock the Timers */
|
||||||
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
|
KeReleaseSpinLock(&IopTimerLock, OldIrql);
|
||||||
|
}
|
||||||
/* Call the Timer Routine of each enabled Timer */
|
|
||||||
for(TimerEntry = IopTimerQueueHead.Flink, i = IopTimerCount;
|
|
||||||
(TimerEntry != &IopTimerQueueHead) && i;
|
|
||||||
TimerEntry = TimerEntry->Flink) {
|
|
||||||
|
|
||||||
Timer = CONTAINING_RECORD(TimerEntry, IO_TIMER, IoTimerList);
|
|
||||||
if (Timer->TimerEnabled) {
|
|
||||||
DPRINT("Dispatching a Timer Routine: 0x%p for Device Object: 0x%p \n",
|
|
||||||
Timer->TimerRoutine,
|
|
||||||
Timer->DeviceObject);
|
|
||||||
Timer->TimerRoutine(Timer->DeviceObject, Timer->Context);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unlock the Timers */
|
|
||||||
KeReleaseSpinLock(&IopTimerLock, OldIrql);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
IopRemoveTimerFromTimerList(
|
IopRemoveTimerFromTimerList(IN PIO_TIMER Timer)
|
||||||
IN PIO_TIMER Timer
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
|
||||||
/* Lock Timers */
|
/* Lock Timers */
|
||||||
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
|
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
|
||||||
|
|
||||||
/* Remove Timer from the List and Drop the Timer Count if Enabled */
|
/* Remove Timer from the List and Drop the Timer Count if Enabled */
|
||||||
RemoveEntryList(&Timer->IoTimerList);
|
RemoveEntryList(&Timer->IoTimerList);
|
||||||
if (Timer->TimerEnabled) IopTimerCount--;
|
if (Timer->TimerEnabled) IopTimerCount--;
|
||||||
|
|
||||||
/* Unlock the Timers */
|
/* Unlock the Timers */
|
||||||
KeReleaseSpinLock(&IopTimerLock, OldIrql);
|
KeReleaseSpinLock(&IopTimerLock, OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
IopInitTimerImplementation(VOID)
|
IopInitTimerImplementation(VOID)
|
||||||
/* FUNCTION: Initializes the IO Timer Object Implementation
|
|
||||||
* RETURNS: NOTHING
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
LARGE_INTEGER ExpireTime;
|
LARGE_INTEGER ExpireTime;
|
||||||
|
|
||||||
/* Initialize Timer List Lock */
|
/* Initialize Timer List Lock */
|
||||||
KeInitializeSpinLock(&IopTimerLock);
|
KeInitializeSpinLock(&IopTimerLock);
|
||||||
|
|
||||||
/* Initialize Timer List */
|
/* Initialize Timer List */
|
||||||
InitializeListHead(&IopTimerQueueHead);
|
InitializeListHead(&IopTimerQueueHead);
|
||||||
|
|
||||||
/* Initialize the DPC/Timer which will call the other Timer Routines */
|
/* Initialize the DPC/Timer which will call the other Timer Routines */
|
||||||
ExpireTime.QuadPart = -10000000;
|
ExpireTime.QuadPart = -10000000;
|
||||||
KeInitializeDpc(&IopTimerDpc, IopTimerDispatch, NULL);
|
KeInitializeDpc(&IopTimerDpc, IopTimerDispatch, NULL);
|
||||||
KeInitializeTimerEx(&IopTimer, SynchronizationTimer);
|
KeInitializeTimerEx(&IopTimer, SynchronizationTimer);
|
||||||
KeSetTimerEx(&IopTimer, ExpireTime, 1000, &IopTimerDpc);
|
KeSetTimerEx(&IopTimer, ExpireTime, 1000, &IopTimerDpc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
NTAPI
|
||||||
IoInitializeTimer(PDEVICE_OBJECT DeviceObject,
|
IoInitializeTimer(IN PDEVICE_OBJECT DeviceObject,
|
||||||
PIO_TIMER_ROUTINE TimerRoutine,
|
IN PIO_TIMER_ROUTINE TimerRoutine,
|
||||||
PVOID Context)
|
IN PVOID Context)
|
||||||
/*
|
|
||||||
* FUNCTION: Sets up a driver-supplied IoTimer routine associated with a given
|
|
||||||
* device object
|
|
||||||
* ARGUMENTS:
|
|
||||||
* DeviceObject = Device object whose timer is be initialized
|
|
||||||
* TimerRoutine = Driver supplied routine which will be called once per
|
|
||||||
* second if the timer is active
|
|
||||||
* Context = Driver supplied context to be passed to the TimerRoutine
|
|
||||||
* RETURNS: Status
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
DPRINT("IoInitializeTimer() called for Device Object: 0x%p with Routine: 0x%p \n", DeviceObject, TimerRoutine);
|
PIO_TIMER IoTimer = DeviceObject->Timer;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Allocate Timer */
|
/* Check if we don't have a timer yet */
|
||||||
if (!DeviceObject->Timer) {
|
if (!IoTimer)
|
||||||
DeviceObject->Timer = ExAllocatePoolWithTag(NonPagedPool,
|
{
|
||||||
sizeof(IO_TIMER),
|
/* Allocate Timer */
|
||||||
TAG_IO_TIMER);
|
IoTimer = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
if (!DeviceObject->Timer) return STATUS_INSUFFICIENT_RESOURCES;
|
sizeof(IO_TIMER),
|
||||||
|
TAG_IO_TIMER);
|
||||||
|
if (!IoTimer) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
/* Set up the Timer Structure */
|
/* Set up the Timer Structure */
|
||||||
DeviceObject->Timer->Type = IO_TYPE_TIMER;
|
RtlZeroMemory(IoTimer, sizeof(IO_TIMER));
|
||||||
DeviceObject->Timer->DeviceObject = DeviceObject;
|
IoTimer->Type = IO_TYPE_TIMER;
|
||||||
}
|
IoTimer->DeviceObject = DeviceObject;
|
||||||
|
DeviceObject->Timer = IoTimer;
|
||||||
|
}
|
||||||
|
|
||||||
DeviceObject->Timer->TimerRoutine = TimerRoutine;
|
/* Setup the timer routine and context */
|
||||||
DeviceObject->Timer->Context = Context;
|
IoTimer->TimerRoutine = TimerRoutine;
|
||||||
DeviceObject->Timer->TimerEnabled = FALSE;
|
IoTimer->Context = Context;
|
||||||
|
|
||||||
/* Add it to the Timer List */
|
/* Add it to the Timer List */
|
||||||
ExInterlockedInsertTailList(&IopTimerQueueHead,
|
ExInterlockedInsertTailList(&IopTimerQueueHead,
|
||||||
&DeviceObject->Timer->IoTimerList,
|
&IoTimer->IoTimerList,
|
||||||
&IopTimerLock);
|
&IopTimerLock);
|
||||||
|
|
||||||
/* Return Success */
|
/* Return Success */
|
||||||
DPRINT("IoInitializeTimer() Completed\n");
|
return STATUS_SUCCESS;
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
IoStartTimer(PDEVICE_OBJECT DeviceObject)
|
IoStartTimer(IN PDEVICE_OBJECT DeviceObject)
|
||||||
/*
|
|
||||||
* FUNCTION: Starts a timer so the driver-supplied IoTimer routine will be
|
|
||||||
* called once per second
|
|
||||||
* ARGUMENTS:
|
|
||||||
* DeviceObject = Device whose timer is to be started
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
PIO_TIMER IoTimer = DeviceObject->Timer;
|
||||||
|
|
||||||
DPRINT("IoStartTimer for Device Object: 0x%p\n", DeviceObject);
|
/* Make sure the device isn't unloading */
|
||||||
|
if (!(((PEXTENDED_DEVOBJ_EXTENSION)(DeviceObject->DeviceObjectExtension))->
|
||||||
|
ExtensionFlags & (DOE_UNLOAD_PENDING |
|
||||||
|
DOE_DELETE_PENDING |
|
||||||
|
DOE_REMOVE_PENDING |
|
||||||
|
DOE_REMOVE_PROCESSED)))
|
||||||
|
{
|
||||||
|
/* Lock Timers */
|
||||||
|
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
|
||||||
|
|
||||||
/* Lock Timers */
|
/* Check if the timer isn't already enabled */
|
||||||
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
|
if (!IoTimer->TimerEnabled)
|
||||||
|
{
|
||||||
|
/* Enable it and increase the timer count */
|
||||||
|
IoTimer->TimerEnabled = TRUE;
|
||||||
|
IopTimerCount++;
|
||||||
|
}
|
||||||
|
|
||||||
/* If the timer isn't already enabled, enable it and increase IO Timer Count*/
|
/* Unlock Timers */
|
||||||
if (!DeviceObject->Timer->TimerEnabled) {
|
KeReleaseSpinLock(&IopTimerLock, OldIrql);
|
||||||
DeviceObject->Timer->TimerEnabled = TRUE;
|
}
|
||||||
IopTimerCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unlock Timers */
|
|
||||||
KeReleaseSpinLock(&IopTimerLock, OldIrql);
|
|
||||||
DPRINT("IoStartTimer Completed for Device Object: 0x%p New Count: %x \n", DeviceObject, IopTimerCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
IoStopTimer(PDEVICE_OBJECT DeviceObject)
|
IoStopTimer(PDEVICE_OBJECT DeviceObject)
|
||||||
/*
|
|
||||||
* FUNCTION: Disables for a specified device object so the driver-supplied
|
|
||||||
* IoTimer is not called
|
|
||||||
* ARGUMENTS:
|
|
||||||
* DeviceObject = Device whose timer is to be stopped
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
PIO_TIMER IoTimer = DeviceObject->Timer;
|
||||||
|
|
||||||
DPRINT("IoStopTimer for Device Object: 0x%p\n", DeviceObject);
|
/* Lock Timers */
|
||||||
|
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
|
||||||
|
|
||||||
/* Lock Timers */
|
/* Check if the timer is enabled */
|
||||||
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
|
if (IoTimer->TimerEnabled)
|
||||||
|
{
|
||||||
|
/* Disable it and decrease the timer count */
|
||||||
|
IoTimer->TimerEnabled = FALSE;
|
||||||
|
IopTimerCount--;
|
||||||
|
}
|
||||||
|
|
||||||
/* If the timer is enabled, disable it and decrease IO Timer Count*/
|
/* Unlock Timers */
|
||||||
if (DeviceObject->Timer->TimerEnabled) {
|
KeReleaseSpinLock(&IopTimerLock, OldIrql);
|
||||||
DeviceObject->Timer->TimerEnabled = FALSE;
|
|
||||||
IopTimerCount--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unlock Timers */
|
|
||||||
KeReleaseSpinLock(&IopTimerLock, OldIrql);
|
|
||||||
DPRINT("IoStopTimer Completed for Device Object: 0x%p New Count: %x \n", DeviceObject, IopTimerCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue