- 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:
Alex Ionescu 2006-06-30 18:14:54 +00:00
parent b42accc93a
commit d1ebf29520
3 changed files with 210 additions and 293 deletions

View file

@ -1,8 +1,8 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/io/event.c
* PURPOSE: I/O Wrappers for the Executive Event Functions
* FILE: ntoskrnl/io/iocomp.c
* PURPOSE: I/O Wrappers (called Completion Ports) for Kernel Queues
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Thomas Weidenmueller (w3seek@reactos.org)
*/

View file

@ -1,11 +1,10 @@
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/io/symlink.c
* PURPOSE: Implements symbolic links
*
* PROGRAMMERS: David Welch (welch@mcmail.com)
* PURPOSE: I/O Wrappers for Symbolic Links
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
*/
/* INCLUDES *****************************************************************/
@ -14,170 +13,106 @@
#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS ****************************************************************/
/**********************************************************************
* NAME EXPORTED
* IoCreateSymbolicLink
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*
/*
* @implemented
*/
NTSTATUS STDCALL
IoCreateSymbolicLink(PUNICODE_STRING SymbolicLinkName,
PUNICODE_STRING DeviceName)
NTSTATUS
NTAPI
IoCreateSymbolicLink(IN PUNICODE_STRING SymbolicLinkName,
IN PUNICODE_STRING DeviceName)
{
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE Handle;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE Handle;
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",
SymbolicLinkName,
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);
/* Return status */
return Status;
}
/**********************************************************************
* NAME EXPORTED
* IoCreateUnprotectedSymbolicLink
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*
/*
* @implemented
*/
NTSTATUS STDCALL
IoCreateUnprotectedSymbolicLink(PUNICODE_STRING SymbolicLinkName,
PUNICODE_STRING DeviceName)
NTSTATUS
NTAPI
IoCreateUnprotectedSymbolicLink(IN PUNICODE_STRING SymbolicLinkName,
IN PUNICODE_STRING DeviceName)
{
SECURITY_DESCRIPTOR SecurityDescriptor;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE Handle;
NTSTATUS Status;
SECURITY_DESCRIPTOR SecurityDescriptor;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE Handle;
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",
SymbolicLinkName,
DeviceName);
/* Set the DACL */
Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
TRUE,
NULL,
TRUE);
if (!NT_SUCCESS(Status)) return Status;
Status = RtlCreateSecurityDescriptor(&SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlCreateSecurityDescriptor() failed (Status %lx)\n", Status);
return(Status);
}
/* Initialize the object attributes and create the link */
InitializeObjectAttributes(&ObjectAttributes,
SymbolicLinkName,
OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
NULL,
&SecurityDescriptor);
Status = ZwCreateSymbolicLinkObject(&Handle,
SYMBOLIC_LINK_ALL_ACCESS,
&ObjectAttributes,
DeviceName);
if (NT_SUCCESS(Status)) ZwClose(Handle);
Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
TRUE,
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);
/* Return status */
return Status;
}
/**********************************************************************
* NAME EXPORTED
* IoDeleteSymbolicLink
*
* DESCRIPTION
*
* ARGUMENTS
*
* RETURN VALUE
*
* REVISIONS
*
/*
* @implemented
*/
NTSTATUS STDCALL
IoDeleteSymbolicLink(PUNICODE_STRING SymbolicLinkName)
NTSTATUS
NTAPI
IoDeleteSymbolicLink(IN PUNICODE_STRING SymbolicLinkName)
{
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE Handle;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE Handle;
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",
SymbolicLinkName->Buffer);
/* Make the link temporary and close its handle */
Status = ZwMakeTemporaryObject(Handle);
if (NT_SUCCESS(Status)) ZwClose(Handle);
InitializeObjectAttributes(&ObjectAttributes,
SymbolicLinkName,
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);
/* Return status */
return Status;
}
/* EOF */

View file

@ -1,12 +1,9 @@
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/timer.c
* PURPOSE: IO timers
*
* PROGRAMMERS: David Welch (welch@mcmail.com)
* Alex Ionescu (alex@relsoft.net)
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/io/iocomp.c
* PURPOSE: I/O Wrappers for Executive Timers
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES *****************************************************************/
@ -28,196 +25,181 @@ KTIMER IopTimer;
/* Keep count of how many timers we have */
ULONG IopTimerCount = 0;
/* FUNCTIONS *****************************************************************/
/* PRIVATE FUNCTIONS *********************************************************/
static VOID STDCALL
VOID
NTAPI
IopTimerDispatch(IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2)
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2)
{
KIRQL OldIrql;
PLIST_ENTRY TimerEntry;
PIO_TIMER Timer;
ULONG i;
KIRQL OldIrql;
PLIST_ENTRY TimerEntry;
PIO_TIMER Timer;
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 */
if (IopTimerCount) {
/* Call the Timer Routine of each enabled Timer */
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 */
KeAcquireSpinLock(&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);
}
/* Unlock the Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
}
}
VOID
STDCALL
IopRemoveTimerFromTimerList(
IN PIO_TIMER Timer
)
NTAPI
IopRemoveTimerFromTimerList(IN PIO_TIMER Timer)
{
KIRQL OldIrql;
KIRQL OldIrql;
/* Lock Timers */
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
/* Lock Timers */
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
/* Remove Timer from the List and Drop the Timer Count if Enabled */
RemoveEntryList(&Timer->IoTimerList);
if (Timer->TimerEnabled) IopTimerCount--;
/* Remove Timer from the List and Drop the Timer Count if Enabled */
RemoveEntryList(&Timer->IoTimerList);
if (Timer->TimerEnabled) IopTimerCount--;
/* Unlock the Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
/* Unlock the Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
}
VOID
FASTCALL
IopInitTimerImplementation(VOID)
/* FUNCTION: Initializes the IO Timer Object Implementation
* RETURNS: NOTHING
*/
{
LARGE_INTEGER ExpireTime;
LARGE_INTEGER ExpireTime;
/* Initialize Timer List Lock */
KeInitializeSpinLock(&IopTimerLock);
/* Initialize Timer List Lock */
KeInitializeSpinLock(&IopTimerLock);
/* Initialize Timer List */
InitializeListHead(&IopTimerQueueHead);
/* Initialize Timer List */
InitializeListHead(&IopTimerQueueHead);
/* Initialize the DPC/Timer which will call the other Timer Routines */
ExpireTime.QuadPart = -10000000;
KeInitializeDpc(&IopTimerDpc, IopTimerDispatch, NULL);
KeInitializeTimerEx(&IopTimer, SynchronizationTimer);
KeSetTimerEx(&IopTimer, ExpireTime, 1000, &IopTimerDpc);
/* Initialize the DPC/Timer which will call the other Timer Routines */
ExpireTime.QuadPart = -10000000;
KeInitializeDpc(&IopTimerDpc, IopTimerDispatch, NULL);
KeInitializeTimerEx(&IopTimer, SynchronizationTimer);
KeSetTimerEx(&IopTimer, ExpireTime, 1000, &IopTimerDpc);
}
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
NTSTATUS
STDCALL
IoInitializeTimer(PDEVICE_OBJECT DeviceObject,
PIO_TIMER_ROUTINE TimerRoutine,
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
*/
NTAPI
IoInitializeTimer(IN PDEVICE_OBJECT DeviceObject,
IN PIO_TIMER_ROUTINE TimerRoutine,
IN PVOID Context)
{
DPRINT("IoInitializeTimer() called for Device Object: 0x%p with Routine: 0x%p \n", DeviceObject, TimerRoutine);
PIO_TIMER IoTimer = DeviceObject->Timer;
PAGED_CODE();
/* Allocate Timer */
if (!DeviceObject->Timer) {
DeviceObject->Timer = ExAllocatePoolWithTag(NonPagedPool,
sizeof(IO_TIMER),
TAG_IO_TIMER);
if (!DeviceObject->Timer) return STATUS_INSUFFICIENT_RESOURCES;
/* Check if we don't have a timer yet */
if (!IoTimer)
{
/* Allocate Timer */
IoTimer = ExAllocatePoolWithTag(NonPagedPool,
sizeof(IO_TIMER),
TAG_IO_TIMER);
if (!IoTimer) return STATUS_INSUFFICIENT_RESOURCES;
/* Set up the Timer Structure */
DeviceObject->Timer->Type = IO_TYPE_TIMER;
DeviceObject->Timer->DeviceObject = DeviceObject;
}
/* Set up the Timer Structure */
RtlZeroMemory(IoTimer, sizeof(IO_TIMER));
IoTimer->Type = IO_TYPE_TIMER;
IoTimer->DeviceObject = DeviceObject;
DeviceObject->Timer = IoTimer;
}
DeviceObject->Timer->TimerRoutine = TimerRoutine;
DeviceObject->Timer->Context = Context;
DeviceObject->Timer->TimerEnabled = FALSE;
/* Setup the timer routine and context */
IoTimer->TimerRoutine = TimerRoutine;
IoTimer->Context = Context;
/* Add it to the Timer List */
ExInterlockedInsertTailList(&IopTimerQueueHead,
&DeviceObject->Timer->IoTimerList,
&IopTimerLock);
/* Add it to the Timer List */
ExInterlockedInsertTailList(&IopTimerQueueHead,
&IoTimer->IoTimerList,
&IopTimerLock);
/* Return Success */
DPRINT("IoInitializeTimer() Completed\n");
return(STATUS_SUCCESS);
/* Return Success */
return STATUS_SUCCESS;
}
/*
* @implemented
*/
VOID
STDCALL
IoStartTimer(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
*/
NTAPI
IoStartTimer(IN PDEVICE_OBJECT DeviceObject)
{
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 */
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
/* Check if the timer isn't already enabled */
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*/
if (!DeviceObject->Timer->TimerEnabled) {
DeviceObject->Timer->TimerEnabled = TRUE;
IopTimerCount++;
}
/* Unlock Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
DPRINT("IoStartTimer Completed for Device Object: 0x%p New Count: %x \n", DeviceObject, IopTimerCount);
/* Unlock Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
}
}
/*
* @implemented
*/
VOID
STDCALL
NTAPI
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 */
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
/* Check if the timer is enabled */
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*/
if (DeviceObject->Timer->TimerEnabled) {
DeviceObject->Timer->TimerEnabled = FALSE;
IopTimerCount--;
}
/* Unlock Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
DPRINT("IoStopTimer Completed for Device Object: 0x%p New Count: %x \n", DeviceObject, IopTimerCount);
/* Unlock Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
}
/* EOF */