Share NtDevice/FsIoControlFile, fixes NtFsControlFile to have same functionality as NtDev... Modified: trunk/reactos/ntoskrnl/io/file.c _____
Modified: trunk/reactos/ntoskrnl/io/file.c --- trunk/reactos/ntoskrnl/io/file.c 2005-05-17 19:00:12 UTC (rev 15381) +++ trunk/reactos/ntoskrnl/io/file.c 2005-05-17 19:04:57 UTC (rev 15382) @@ -513,6 +513,130 @@
IoFreeIrp(Irp); }
+NTSTATUS +STDCALL +IopDeviceFsIoControl(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, + BOOLEAN IsDevIoCtl) +{ + NTSTATUS Status = STATUS_SUCCESS; + PFILE_OBJECT FileObject; + PDEVICE_OBJECT DeviceObject; + PIRP Irp; + PIO_STACK_LOCATION StackPtr; + PKEVENT EventObject = NULL; + BOOLEAN LocalEvent = FALSE; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + + DPRINT("IopDeviceFsIoControl(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; + + /* 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 for an event */ + if (Event) + { + /* 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); + } + + /* Check if this is a direct open or not */ + if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN) + { + DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject); + } + else + { + DeviceObject = IoGetRelatedDeviceObject(FileObject); + } + + /* 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; + Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine; + Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext; + StackPtr = IoGetNextIrpStackLocation(Irp); + StackPtr->FileObject = FileObject; + StackPtr->MajorFunction = IsDevIoCtl ? + IRP_MJ_DEVICE_CONTROL : IRP_MJ_FILE_SYSTEM_CONTROL; + + /* 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; +} + /* FUNCTIONS *****************************************************************/
/* @@ -1511,6 +1635,65 @@ return(STATUS_NOT_IMPLEMENTED); }
+/* + * @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) +{ + /* Call the Generic Function */ + return IopDeviceFsIoControl(DeviceHandle, + Event, + UserApcRoutine, + UserApcContext, + IoStatusBlock, + IoControlCode, + InputBuffer, + InputBufferLength, + OutputBuffer, + OutputBufferLength, + TRUE); +} + +/* + * @implemented + */ +NTSTATUS +STDCALL +NtFsControlFile(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) +{ + return IopDeviceFsIoControl(DeviceHandle, + Event, + UserApcRoutine, + UserApcContext, + IoStatusBlock, + IoControlCode, + InputBuffer, + InputBufferLength, + OutputBuffer, + OutputBufferLength, + FALSE); +} + NTSTATUS STDCALL NtFlushWriteBuffer(VOID)