cleanup NtDeviceIoControlFile a bit...remove some redundant stuff

svn path=/trunk/; revision=15235
This commit is contained in:
Alex Ionescu 2005-05-12 04:17:43 +00:00
parent 942e1f4649
commit 32962bc31c

View file

@ -1104,114 +1104,123 @@ IoValidateDeviceIoControlAccess(IN PIRP Irp,
/* /*
* @implemented * @implemented
*/ */
NTSTATUS STDCALL NTSTATUS
NtDeviceIoControlFile (IN HANDLE DeviceHandle, STDCALL
IN HANDLE Event OPTIONAL, NtDeviceIoControlFile(IN HANDLE DeviceHandle,
IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, IN HANDLE Event OPTIONAL,
IN PVOID UserApcContext OPTIONAL, IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID UserApcContext OPTIONAL,
IN ULONG IoControlCode, OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID InputBuffer, IN ULONG IoControlCode,
IN ULONG InputBufferLength OPTIONAL, IN PVOID InputBuffer,
OUT PVOID OutputBuffer, IN ULONG InputBufferLength OPTIONAL,
IN ULONG OutputBufferLength OPTIONAL) OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength OPTIONAL)
{ {
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION StackPtr; PIO_STACK_LOCATION StackPtr;
PKEVENT EventObject; PKEVENT EventObject = NULL;
KPROCESSOR_MODE PreviousMode; BOOLEAN LocalEvent;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x " DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x "
"UserApcContext %x IoStatusBlock %x IoControlCode %x " "UserApcContext %x IoStatusBlock %x IoControlCode %x "
"InputBuffer %x InputBufferLength %x OutputBuffer %x " "InputBuffer %x InputBufferLength %x OutputBuffer %x "
"OutputBufferLength %x)\n", "OutputBufferLength %x)\n",
DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock, DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock,
IoControlCode,InputBuffer,InputBufferLength,OutputBuffer, IoControlCode,InputBuffer,InputBufferLength,OutputBuffer,
OutputBufferLength); OutputBufferLength);
if (IoStatusBlock == NULL) if (IoStatusBlock == NULL) return STATUS_ACCESS_VIOLATION;
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 */ /* Check for an event */
Status = ObReferenceObjectByHandle (DeviceHandle, if (Event)
(IoControlCode >> 14) & 0x3,
IoFileObjectType,
PreviousMode,
(PVOID *) &FileObject,
NULL);
if (!NT_SUCCESS(Status))
{ {
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, DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
SYNCHRONIZE, }
ExEventObjectType, else
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))
{ {
Status = KeWaitForSingleObject (EventObject, DeviceObject = IoGetRelatedDeviceObject(FileObject);
Executive,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
if (Status != STATUS_WAIT_0)
{
/* Wait failed. */
return Status;
}
Status = IoStatusBlock->Status;
} }
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 */ /* EOF */