From 32962bc31c3265a52a10f63e5198edce36653490 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 12 May 2005 04:17:43 +0000 Subject: [PATCH] cleanup NtDeviceIoControlFile a bit...remove some redundant stuff svn path=/trunk/; revision=15235 --- reactos/ntoskrnl/io/device.c | 201 ++++++++++++++++++----------------- 1 file changed, 105 insertions(+), 96 deletions(-) diff --git a/reactos/ntoskrnl/io/device.c b/reactos/ntoskrnl/io/device.c index cb4cd2ea5f0..ba46c6dc3a3 100644 --- a/reactos/ntoskrnl/io/device.c +++ b/reactos/ntoskrnl/io/device.c @@ -1104,114 +1104,123 @@ IoValidateDeviceIoControlAccess(IN PIRP Irp, /* * @implemented */ -NTSTATUS STDCALL -NtDeviceIoControlFile (IN HANDLE DeviceHandle, - IN HANDLE Event OPTIONAL, - IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, - IN PVOID UserApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG IoControlCode, - IN PVOID InputBuffer, - IN ULONG InputBufferLength OPTIONAL, - OUT PVOID OutputBuffer, - IN ULONG OutputBufferLength OPTIONAL) +NTSTATUS +STDCALL +NtDeviceIoControlFile(IN HANDLE DeviceHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, + IN PVOID UserApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG IoControlCode, + IN PVOID InputBuffer, + IN ULONG InputBufferLength OPTIONAL, + OUT PVOID OutputBuffer, + IN ULONG OutputBufferLength OPTIONAL) { - NTSTATUS Status; - PFILE_OBJECT FileObject; - PDEVICE_OBJECT DeviceObject; - PIRP Irp; - PIO_STACK_LOCATION StackPtr; - PKEVENT EventObject; - KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + PFILE_OBJECT FileObject; + PDEVICE_OBJECT DeviceObject; + PIRP Irp; + PIO_STACK_LOCATION StackPtr; + PKEVENT EventObject = NULL; + BOOLEAN LocalEvent; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); - DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x " - "UserApcContext %x IoStatusBlock %x IoControlCode %x " - "InputBuffer %x InputBufferLength %x OutputBuffer %x " - "OutputBufferLength %x)\n", - DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock, - IoControlCode,InputBuffer,InputBufferLength,OutputBuffer, - OutputBufferLength); + DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x " + "UserApcContext %x IoStatusBlock %x IoControlCode %x " + "InputBuffer %x InputBufferLength %x OutputBuffer %x " + "OutputBufferLength %x)\n", + DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock, + IoControlCode,InputBuffer,InputBufferLength,OutputBuffer, + OutputBufferLength); - if (IoStatusBlock == NULL) - return STATUS_ACCESS_VIOLATION; + if (IoStatusBlock == NULL) return STATUS_ACCESS_VIOLATION; - PreviousMode = ExGetPreviousMode(); + /* Check granted access against the access rights from IoContolCode */ + Status = ObReferenceObjectByHandle(DeviceHandle, + (IoControlCode >> 14) & 0x3, + IoFileObjectType, + PreviousMode, + (PVOID *) &FileObject, + NULL); + if (!NT_SUCCESS(Status)) return Status; - /* Check granted access against the access rights from IoContolCode */ - Status = ObReferenceObjectByHandle (DeviceHandle, - (IoControlCode >> 14) & 0x3, - IoFileObjectType, - PreviousMode, - (PVOID *) &FileObject, - NULL); - if (!NT_SUCCESS(Status)) + /* Check for an event */ + if (Event) { - return Status; + /* Reference it */ + Status = ObReferenceObjectByHandle(Event, + EVENT_MODIFY_STATE, + ExEventObjectType, + PreviousMode, + (PVOID*)&EventObject, + NULL); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject (FileObject); + return Status; + } + + /* Clear it */ + KeClearEvent(EventObject); } - if (Event != NULL) + /* Check if this is a direct open or not */ + if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN) { - Status = ObReferenceObjectByHandle (Event, - SYNCHRONIZE, - ExEventObjectType, - PreviousMode, - (PVOID*)&EventObject, - NULL); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject (FileObject); - return Status; - } - } - else - { - EventObject = &FileObject->Event; - KeResetEvent (EventObject); - } - - DeviceObject = FileObject->DeviceObject; - - Irp = IoBuildDeviceIoControlRequest (IoControlCode, - DeviceObject, - InputBuffer, - InputBufferLength, - OutputBuffer, - OutputBufferLength, - FALSE, - EventObject, - IoStatusBlock); - - /* Trigger FileObject/Event dereferencing */ - Irp->Tail.Overlay.OriginalFileObject = FileObject; - - Irp->RequestorMode = PreviousMode; - Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine; - Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext; - - StackPtr = IoGetNextIrpStackLocation(Irp); - StackPtr->FileObject = FileObject; - StackPtr->DeviceObject = DeviceObject; - StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength; - StackPtr->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength; - - Status = IoCallDriver(DeviceObject,Irp); - if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO)) + DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject); + } + else { - Status = KeWaitForSingleObject (EventObject, - Executive, - PreviousMode, - FileObject->Flags & FO_ALERTABLE_IO, - NULL); - if (Status != STATUS_WAIT_0) - { - /* Wait failed. */ - return Status; - } - - Status = IoStatusBlock->Status; + DeviceObject = IoGetRelatedDeviceObject(FileObject); } - return Status; + /* Check if we should use Sync IO or not */ + if (FileObject->Flags & FO_SYNCHRONOUS_IO) + { + /* Use File Object event */ + KeClearEvent(&FileObject->Event); + } + else + { + /* Use local event */ + LocalEvent = TRUE; + } + + /* Build the IRP */ + Irp = IoBuildDeviceIoControlRequest(IoControlCode, + DeviceObject, + InputBuffer, + InputBufferLength, + OutputBuffer, + OutputBufferLength, + FALSE, + EventObject, + IoStatusBlock); + + /* Set some extra settings */ + Irp->Tail.Overlay.OriginalFileObject = FileObject; + Irp->RequestorMode = PreviousMode; + StackPtr = IoGetNextIrpStackLocation(Irp); + StackPtr->FileObject = FileObject; + + /* Call the Driver */ + Status = IoCallDriver(DeviceObject, Irp); + if (Status == STATUS_PENDING) + { + if (!LocalEvent) + { + KeWaitForSingleObject(&FileObject->Event, + Executive, + PreviousMode, + FileObject->Flags & FO_ALERTABLE_IO, + NULL); + Status = FileObject->FinalStatus; + } + } + + /* Return the Status */ + return Status; } /* EOF */