https://git.reactos.org/?p=reactos.git;a=commitdiff;h=28ba29e4576541efa6ba9…
commit 28ba29e4576541efa6ba9bd07fc4e0381b719bbe
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Fri Mar 29 21:42:42 2019 +0100
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Fri Mar 29 21:42:42 2019 +0100
[NTOSKRNL] Implement support for FileFsDriverPathInformation in
NtQueryVolumeInformationFile
---
ntoskrnl/io/iomgr/iofunc.c | 131 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 131 insertions(+)
diff --git a/ntoskrnl/io/iomgr/iofunc.c b/ntoskrnl/io/iomgr/iofunc.c
index e6ecefc7ff..5831b55896 100644
--- a/ntoskrnl/io/iomgr/iofunc.c
+++ b/ntoskrnl/io/iomgr/iofunc.c
@@ -1052,6 +1052,88 @@ IopGetMountFlag(IN PDEVICE_OBJECT DeviceObject)
return Mounted;
}
+static
+BOOLEAN
+IopVerifyDriverObjectOnStack(IN PDEVICE_OBJECT DeviceObject,
+ IN PDRIVER_OBJECT DriverObject)
+{
+ PDEVICE_OBJECT StackDO;
+
+ /* Browse our whole device stack, trying to find the appropriate driver */
+ StackDO = IopGetDeviceAttachmentBase(DeviceObject);
+ while (StackDO != NULL)
+ {
+ /* We've found the driver, return success */
+ if (StackDO->DriverObject == DriverObject)
+ {
+ return TRUE;
+ }
+
+ /* Move to the next */
+ StackDO = StackDO->AttachedDevice;
+ }
+
+ /* We only reach there if driver was not found */
+ return FALSE;
+}
+
+static
+NTSTATUS
+IopGetDriverPathInformation(IN PFILE_OBJECT FileObject,
+ IN PFILE_FS_DRIVER_PATH_INFORMATION DriverPathInfo,
+ IN ULONG Length)
+{
+ KIRQL OldIrql;
+ NTSTATUS Status;
+ UNICODE_STRING DriverName;
+ PDRIVER_OBJECT DriverObject;
+
+ /* Make sure the structure is consistent (ie, driver name fits into the buffer) */
+ if (Length - FIELD_OFFSET(FILE_FS_DRIVER_PATH_INFORMATION, DriverName) <
DriverPathInfo->DriverNameLength)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Setup the whole driver name */
+ DriverName.Length = DriverPathInfo->DriverNameLength;
+ DriverName.MaximumLength = DriverPathInfo->DriverNameLength;
+ DriverName.Buffer = &DriverPathInfo->DriverName[0];
+
+ /* Ask Ob for such driver */
+ Status = ObReferenceObjectByName(&DriverName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ 0,
+ IoDriverObjectType,
+ KernelMode,
+ NULL,
+ (PVOID*)&DriverObject);
+ /* No such driver, bail out */
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Lock the devices database, we'll browse it */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueueIoDatabaseLock);
+ /* If we have a VPB, browse the stack from the volume */
+ if (FileObject->Vpb != NULL && FileObject->Vpb->DeviceObject !=
NULL)
+ {
+ DriverPathInfo->DriverInPath =
IopVerifyDriverObjectOnStack(FileObject->Vpb->DeviceObject, DriverObject);
+ }
+ /* Otherwise, do it from the normal device */
+ else
+ {
+ DriverPathInfo->DriverInPath =
IopVerifyDriverObjectOnStack(FileObject->DeviceObject, DriverObject);
+ }
+ KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, OldIrql);
+
+ /* No longer needed */
+ ObDereferenceObject(DriverObject);
+
+ return STATUS_SUCCESS;
+}
+
/* PUBLIC FUNCTIONS **********************************************************/
/*
@@ -4136,6 +4218,55 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
return STATUS_SUCCESS;
}
+ /* This is to be handled by the kernel, not by FSD */
+ else if (FsInformationClass == FileFsDriverPathInformation)
+ {
+ PFILE_FS_DRIVER_PATH_INFORMATION DriverPathInfo;
+
+ _SEH2_TRY
+ {
+ /* Allocate our local structure */
+ DriverPathInfo = ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_IO);
+
+ /* And copy back caller data */
+ RtlCopyMemory(DriverPathInfo, FsInformation, Length);
+
+ /* Is the driver in the IO path? */
+ Status = IopGetDriverPathInformation(FileObject, DriverPathInfo, Length);
+ /* We failed, don't continue execution */
+ if (!NT_SUCCESS(Status))
+ {
+ RtlRaiseStatus(Status);
+ }
+
+ /* We succeed, copy back info */
+ ((PFILE_FS_DRIVER_PATH_INFORMATION)FsInformation)->DriverInPath =
DriverPathInfo->DriverInPath;
+
+ /* We're done */
+ IoStatusBlock->Information = sizeof(FILE_FS_DRIVER_PATH_INFORMATION);
+ IoStatusBlock->Status = STATUS_SUCCESS;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ /* Don't leak */
+ if (DriverPathInfo != NULL)
+ {
+ ExFreePoolWithTag(DriverPathInfo, TAG_IO);
+ }
+
+ /*
+ * We didn't have an exception, but we didn't issue an IRP
+ * to complete either, so avoid duplicating code and
+ * call appropriate helper
+ */
+ IopCleanupAfterException(FileObject, NULL, NULL, Event);
+
+ return Status;
+ }
/* Get the device object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);