https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d605b5063fa4e659b371f…
commit d605b5063fa4e659b371fbd4a37a85953dea6039
Author: Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Fri Mar 29 09:08:36 2019 +0100
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Sat Mar 30 10:13:27 2019 +0100
[NTOS:IO] Send IRPs to the correct device in IoVolumeDeviceToDosName. CORE-15415
---
modules/rostests/kmtests/CMakeLists.txt | 1 +
modules/rostests/kmtests/kmtest_drv/testlist.c | 2 +
modules/rostests/kmtests/ntos_io/IoVolume.c | 122 +++++++++++++++++++++++++
ntoskrnl/io/iomgr/volume.c | 4 +-
4 files changed, 127 insertions(+), 2 deletions(-)
diff --git a/modules/rostests/kmtests/CMakeLists.txt
b/modules/rostests/kmtests/CMakeLists.txt
index 8d56d61b2d..c12751eaa0 100644
--- a/modules/rostests/kmtests/CMakeLists.txt
+++ b/modules/rostests/kmtests/CMakeLists.txt
@@ -67,6 +67,7 @@ list(APPEND KMTEST_DRV_SOURCE
ntos_io/IoInterrupt.c
ntos_io/IoIrp.c
ntos_io/IoMdl.c
+ ntos_io/IoVolume.c
ntos_ke/KeApc.c
ntos_ke/KeDevQueue.c
ntos_ke/KeDpc.c
diff --git a/modules/rostests/kmtests/kmtest_drv/testlist.c
b/modules/rostests/kmtests/kmtest_drv/testlist.c
index 11d63bbad2..3dc3a6d0fc 100644
--- a/modules/rostests/kmtests/kmtest_drv/testlist.c
+++ b/modules/rostests/kmtests/kmtest_drv/testlist.c
@@ -33,6 +33,7 @@ KMT_TESTFUNC Test_IoFilesystem;
KMT_TESTFUNC Test_IoInterrupt;
KMT_TESTFUNC Test_IoIrp;
KMT_TESTFUNC Test_IoMdl;
+KMT_TESTFUNC Test_IoVolume;
KMT_TESTFUNC Test_KeApc;
KMT_TESTFUNC Test_KeDeviceQueue;
KMT_TESTFUNC Test_KeDpc;
@@ -106,6 +107,7 @@ const KMT_TEST TestList[] =
{ "IoInterrupt", Test_IoInterrupt },
{ "IoIrp", Test_IoIrp },
{ "IoMdl", Test_IoMdl },
+ { "IoVolume", Test_IoVolume },
{ "KeApc", Test_KeApc },
{ "KeDeviceQueue", Test_KeDeviceQueue },
{ "KeDpc", Test_KeDpc },
diff --git a/modules/rostests/kmtests/ntos_io/IoVolume.c
b/modules/rostests/kmtests/ntos_io/IoVolume.c
new file mode 100644
index 0000000000..ad862f49aa
--- /dev/null
+++ b/modules/rostests/kmtests/ntos_io/IoVolume.c
@@ -0,0 +1,122 @@
+/*
+ * PROJECT: ReactOS kernel-mode tests
+ * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later)
+ * PURPOSE: Kernel-Mode Test Suite Volume Device test
+ * COPYRIGHT: Copyright 2019 Thomas Faber (thomas.faber(a)reactos.org)
+ */
+
+#include <kmt_test.h>
+
+static
+NTSTATUS
+GetNextVolumeDevice(
+ _Inout_ PUNICODE_STRING VolumeDeviceName,
+ _Inout_ PULONG VolumeNumber,
+ _In_ NTSTATUS PreviousStatus)
+{
+ NTSTATUS Status;
+
+#ifndef __REACTOS__
+ *VolumeNumber++;
+ Status = RtlStringCbPrintfW(VolumeDeviceName->Buffer,
+ VolumeDeviceName->MaximumLength,
+ L"\\Device\\HarddiskVolume%lu",
+ *VolumeNumber);
+#else
+ /* ROS's storage stack is old an broken, we don't have HarddiskVolumeN */
+ ULONG DiskNumber, PartitionNumber;
+ DiskNumber = *VolumeNumber >> 16;
+ PartitionNumber = *VolumeNumber & 0xffff;
+ if (!NT_SUCCESS(PreviousStatus))
+ {
+ if (PartitionNumber == 1)
+ {
+ /* Looks like this disk doesn't exist (or has no partitions),
+ * so we're done */
+ return STATUS_NO_MORE_ENTRIES;
+ }
+ DiskNumber++;
+ PartitionNumber = 0;
+ }
+ PartitionNumber++;
+ Status = RtlStringCbPrintfW(VolumeDeviceName->Buffer,
+ VolumeDeviceName->MaximumLength,
+ L"\\Device\\Harddisk%lu\\Partition%lu",
+ DiskNumber,
+ PartitionNumber);
+ *VolumeNumber = DiskNumber << 16 | PartitionNumber;
+#endif
+ return Status;
+}
+
+static
+void
+TestIoVolumeDeviceToDosName(void)
+{
+ NTSTATUS Status;
+ ULONG VolumeNumber;
+ WCHAR VolumeDeviceNameBuffer[32];
+ UNICODE_STRING VolumeDeviceName;
+ PFILE_OBJECT FileObject;
+ PDEVICE_OBJECT DeviceObject;
+ UNICODE_STRING DosName;
+ UNICODE_STRING DosVolumePrefix = RTL_CONSTANT_STRING(L"\\\\?\\Volume");
+
+ RtlInitEmptyUnicodeString(&VolumeDeviceName,
+ VolumeDeviceNameBuffer,
+ sizeof(VolumeDeviceNameBuffer));
+ VolumeNumber = 0;
+ Status = STATUS_SUCCESS;
+ while (1)
+ {
+ Status = GetNextVolumeDevice(&VolumeDeviceName,
+ &VolumeNumber,
+ Status);
+ if (!NT_SUCCESS(Status))
+ {
+ trace("GetNextVolumeDevice(0x%lx) failed with %lx\n",
+ VolumeNumber, Status);
+ break;
+ }
+
+ RtlInitUnicodeString(&VolumeDeviceName, VolumeDeviceNameBuffer);
+ Status = IoGetDeviceObjectPointer(&VolumeDeviceName,
+ READ_CONTROL,
+ &FileObject,
+ &DeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ trace("IoGetDeviceObjectPointer(%wZ) failed with %lx\n",
+ &VolumeDeviceName, Status);
+ continue;
+ }
+
+ Status = IoVolumeDeviceToDosName(DeviceObject, &DosName);
+ ok_eq_hex(Status, STATUS_SUCCESS);
+ if (!skip(NT_SUCCESS(Status), "No DOS name\n"))
+ {
+ trace("DOS name for %wZ is %wZ\n", &VolumeDeviceName,
&DosName);
+ if (DosName.Length == 2 * sizeof(WCHAR))
+ {
+ ok(DosName.Buffer[0] >= L'A' &&
+ DosName.Buffer[0] <= L'Z' &&
+ DosName.Buffer[1] == L':',
+ "Unexpected drive letter: %wZ\n", &DosName);
+ }
+ else
+ {
+ ok(RtlPrefixUnicodeString(&DosVolumePrefix, &DosName, FALSE),
+ "Unexpected volume path: %wZ\n", &DosName);
+ }
+ RtlFreeUnicodeString(&DosName);
+ }
+ ObDereferenceObject(FileObject);
+ Status = STATUS_SUCCESS;
+ }
+ ok(VolumeNumber > 1, "No volumes found\n");
+}
+
+START_TEST(IoVolume)
+{
+ TestIoVolumeDeviceToDosName();
+}
diff --git a/ntoskrnl/io/iomgr/volume.c b/ntoskrnl/io/iomgr/volume.c
index d5ab2ec17d..6c2e3191e9 100644
--- a/ntoskrnl/io/iomgr/volume.c
+++ b/ntoskrnl/io/iomgr/volume.c
@@ -1346,7 +1346,7 @@ IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject,
goto DereferenceFO;
}
- Status = IoCallDriver(VolumeDeviceObject, Irp);
+ Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
@@ -1396,7 +1396,7 @@ IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject,
goto ReleaseMemory;
}
- Status = IoCallDriver(VolumeDeviceObject, Irp);
+ Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);