https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f315111bb583b1911d1d9…
commit f315111bb583b1911d1d9069c964ca5d4735ac18
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Thu Jan 9 19:34:56 2025 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Jan 21 19:16:02 2025 +0100
[NTOS:IO] Improve some comments in IoVolumeDeviceToDosName()
Addendum to commit 5afb7ab003.
---
ntoskrnl/io/iomgr/volume.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/ntoskrnl/io/iomgr/volume.c b/ntoskrnl/io/iomgr/volume.c
index 3f614e27c98..5d5614b4454 100644
--- a/ntoskrnl/io/iomgr/volume.c
+++ b/ntoskrnl/io/iomgr/volume.c
@@ -1328,7 +1328,7 @@ IoVolumeDeviceToDosName(
return Status;
}
- /* Now, query the MountMgr for the DOS path */
+ /* Retrieve the MountMgr controlling device */
RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME);
Status = IoGetDeviceObjectPointer(&MountMgrDevice, FILE_READ_ATTRIBUTES,
&FileObject, &DeviceObject);
@@ -1337,6 +1337,7 @@ IoVolumeDeviceToDosName(
return Status;
}
+ /* Now, query the MountMgr for the DOS path */
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH,
DeviceObject,
@@ -1362,7 +1363,7 @@ IoVolumeDeviceToDosName(
goto Quit;
}
- /* Compute the needed size to store the DOS name.
+ /* Compute the needed size to store the DOS path.
* Even if MOUNTMGR_VOLUME_PATHS allows bigger name lengths
* than MAXUSHORT, we can't use them, because we have to return
* this in an UNICODE_STRING that stores length in a USHORT. */
@@ -1373,8 +1374,8 @@ IoVolumeDeviceToDosName(
goto Quit;
}
- /* Reallocate the memory, even in case of success, because
- * that's the buffer that will be returned to the caller */
+ /* Allocate the buffer, even in case of success,
+ * because it is returned to the caller */
VolumePathPtr = ExAllocatePoolWithTag(PagedPool, Length, TAG_DEV2DOS);
if (!VolumePathPtr)
{
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8bb7cd286bc106dd67a86…
commit 8bb7cd286bc106dd67a869e045d589960873bd1b
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Jan 19 23:00:04 2025 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Jan 21 19:16:01 2025 +0100
[MOUNTMGR] Fix three more bugs in MountMgrQueryDosVolumePath() (#6990)
- When trying to find a device, don't fail with STATUS_NOT_FOUND if no
associated symbolic links are present. Instead, that test was wrong,
and should go out of the search loop to do the drive-letter processing.
Addendum to commit f9f5a78715.
- In addition, when using the associated-device method, fix the list
used to retrieve the corresponding device.
- In the TryWithVolumeName: block, reset DeviceString to NULL after
freeing, so that we can correctly fail with STATUS_NOT_FOUND if no
suitable device was found, before initializing the output data.
---
drivers/storage/mountmgr/device.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/storage/mountmgr/device.c b/drivers/storage/mountmgr/device.c
index fdf6af9435b..22710b7b4d7 100644
--- a/drivers/storage/mountmgr/device.c
+++ b/drivers/storage/mountmgr/device.c
@@ -887,20 +887,16 @@ MountMgrQueryDosVolumePath(IN PDEVICE_EXTENSION DeviceExtension,
}
}
- /* We didn't find, break */
- if (SymlinksEntry == &(DeviceInformation->SymbolicLinksListHead))
- {
- return STATUS_NOT_FOUND;
- }
+ /* If we've found a device via drive letter, do default processing */
+ if (SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead))
+ break;
- /* It doesn't have associated device, go to fallback method */
+ /* If it doesn't have an associated device, go to fallback method */
if (IsListEmpty(&DeviceInformation->AssociatedDevicesHead))
- {
goto TryWithVolumeName;
- }
/* Create a string with the information about the device */
- AssociatedDevice = CONTAINING_RECORD(&(DeviceInformation->SymbolicLinksListHead), ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
+ AssociatedDevice = CONTAINING_RECORD(&(DeviceInformation->AssociatedDevicesHead), ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
OldLength = DeviceLength;
OldBuffer = DeviceString;
DeviceLength += AssociatedDevice->String.Length;
@@ -967,6 +963,7 @@ TryWithVolumeName:
if (DeviceString)
{
FreePool(DeviceString);
+ DeviceString = NULL;
DeviceLength = 0;
}
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=be97a36f25c3fec7ad8ca…
commit be97a36f25c3fec7ad8ca6c43aeadfe12d9eab34
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Jan 19 22:23:56 2025 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Jan 21 19:15:59 2025 +0100
[MOUNTMGR] Simplify MountMgrQueryDosVolumePath() code (#6990)
- Use a variable of correct type instead of casting every time.
- Remove one level of indentation by returning early.
---
drivers/storage/mountmgr/device.c | 66 ++++++++++++++++++++-------------------
1 file changed, 34 insertions(+), 32 deletions(-)
diff --git a/drivers/storage/mountmgr/device.c b/drivers/storage/mountmgr/device.c
index ca8ed5c1395..62d28cf7192 100644
--- a/drivers/storage/mountmgr/device.c
+++ b/drivers/storage/mountmgr/device.c
@@ -819,6 +819,7 @@ MountMgrQueryDosVolumePath(IN PDEVICE_EXTENSION DeviceExtension,
PLIST_ENTRY SymlinksEntry;
UNICODE_STRING SymbolicName;
PMOUNTMGR_TARGET_NAME Target;
+ PMOUNTMGR_VOLUME_PATHS Output;
PWSTR DeviceString, OldBuffer;
USHORT DeviceLength, OldLength;
PDEVICE_INFORMATION DeviceInformation;
@@ -992,46 +993,47 @@ TryWithVolumeName:
}
RtlCopyMemory(DeviceString, SymlinkInformation->Name.Buffer, DeviceLength);
- /* Ensure we are in the right namespace; [1] can be ? */
+ /* Ensure we are in the Win32 namespace; [1] can be '?' */
DeviceString[1] = L'\\';
}
}
- /* If we found something */
- if (DeviceString)
- {
- /* At least, we will return our length */
- ((PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer)->MultiSzLength = DeviceLength;
- /* MOUNTMGR_VOLUME_PATHS is a string + a ULONG */
- Irp->IoStatus.Information = DeviceLength + sizeof(ULONG);
+ /* If we didn't find something, fail */
+ if (!DeviceString)
+ return STATUS_NOT_FOUND;
- /* If we have enough room for copying the string */
- if (sizeof(ULONG) + DeviceLength <= Stack->Parameters.DeviceIoControl.OutputBufferLength)
- {
- /* Copy it */
- if (DeviceLength)
- {
- RtlCopyMemory(((PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer)->MultiSz, DeviceString, DeviceLength);
- }
+ /* Get the output buffer */
+ Output = (PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer;
- /* And double zero at its end - this is needed in case of multiple paths which are separated by a single 0 */
- FreePool(DeviceString);
- ((PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer)->MultiSz[DeviceLength / sizeof(WCHAR)] = 0;
- ((PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer)->MultiSz[DeviceLength / sizeof(WCHAR) + 1] = 0;
+ /* At least, we will return our length */
+ Output->MultiSzLength = DeviceLength;
+ /* MOUNTMGR_VOLUME_PATHS is a string + a ULONG */
+ Irp->IoStatus.Information = DeviceLength + sizeof(ULONG);
- return STATUS_SUCCESS;
- }
- else
+ /* If we have enough room for copying the string */
+ if (sizeof(ULONG) + DeviceLength <= Stack->Parameters.DeviceIoControl.OutputBufferLength)
+ {
+ /* Copy it */
+ if (DeviceLength)
{
- /* Just return appropriate size and leave */
- FreePool(DeviceString);
- Irp->IoStatus.Information = sizeof(ULONG);
- return STATUS_BUFFER_OVERFLOW;
+ RtlCopyMemory(Output->MultiSz, DeviceString, DeviceLength);
}
- }
- /* Fail */
- return STATUS_NOT_FOUND;
+ /* And double-NUL at its end - this is needed in case of
+ * multiple paths which are separated by a single NUL */
+ FreePool(DeviceString);
+ Output->MultiSz[DeviceLength / sizeof(WCHAR)] = UNICODE_NULL;
+ Output->MultiSz[DeviceLength / sizeof(WCHAR) + 1] = UNICODE_NULL;
+
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ /* Just return the size needed and leave */
+ FreePool(DeviceString);
+ Irp->IoStatus.Information = sizeof(ULONG);
+ return STATUS_BUFFER_OVERFLOW;
+ }
}
/*
@@ -1557,7 +1559,7 @@ MountMgrQueryDosVolumePaths(IN PDEVICE_EXTENSION DeviceExtension,
MountMgrNotifyNameChange(DeviceExtension, &SymbolicName, FALSE);
}
- /* Get output buffer */
+ /* Get the output buffer */
Output = (PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer;
/* Set required size */
@@ -1566,7 +1568,7 @@ MountMgrQueryDosVolumePaths(IN PDEVICE_EXTENSION DeviceExtension,
/* Compute total length */
OutputLength = Output->MultiSzLength + sizeof(ULONG);
- /* If it cannot fit, just return need size and quit */
+ /* If it cannot fit, just return the size needed and leave */
if (OutputLength > Stack->Parameters.DeviceIoControl.OutputBufferLength)
{
Irp->IoStatus.Information = sizeof(ULONG);
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bae799382aa84dc54d01d…
commit bae799382aa84dc54d01ddbc7259609194f922b5
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sat Jan 11 22:31:47 2025 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Jan 21 19:15:58 2025 +0100
[KMTESTS] Improve IoVolumeDeviceToDosName() tests (#6990)
- Limit the HarddiskVolume loop to 32 trials (instead of an unknown
number of them). Ideally the list of volumes has to be queried from
the volume manager, instead of hardcoding them (TODO).
- Verify that the buffer returned by IoVolumeDeviceToDosName() is
indeed a unicode multi-string (ends with two NULs), and, in the
case it specifies a volume GUID, that it's a valid one.
---
modules/rostests/kmtests/ntos_io/IoVolume.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/modules/rostests/kmtests/ntos_io/IoVolume.c b/modules/rostests/kmtests/ntos_io/IoVolume.c
index 51d5eccfb3f..a0824e5ef82 100644
--- a/modules/rostests/kmtests/ntos_io/IoVolume.c
+++ b/modules/rostests/kmtests/ntos_io/IoVolume.c
@@ -6,7 +6,7 @@
*/
#include <kmt_test.h>
-
+#include <mountmgr.h>
static
void
@@ -24,17 +24,16 @@ TestIoVolumeDeviceToDosName(void)
RtlInitEmptyUnicodeString(&VolumeDeviceName,
VolumeDeviceNameBuffer,
sizeof(VolumeDeviceNameBuffer));
- VolumeNumber = 0;
- while (1)
+ // TODO: Query the partition/volume manager for the list of volumes.
+ for (VolumeNumber = 0; VolumeNumber < 32; ++VolumeNumber)
{
- VolumeNumber++;
Status = RtlStringCbPrintfW(VolumeDeviceName.Buffer,
VolumeDeviceName.MaximumLength,
L"\\Device\\HarddiskVolume%lu",
VolumeNumber);
if (!NT_SUCCESS(Status))
{
- trace("RtlStringCbPrintfW(0x%lx) failed with %lx\n",
+ trace("RtlStringCbPrintfW(%lu) failed with 0x%lx\n",
VolumeNumber, Status);
break;
}
@@ -46,7 +45,7 @@ TestIoVolumeDeviceToDosName(void)
&DeviceObject);
if (!NT_SUCCESS(Status))
{
- trace("IoGetDeviceObjectPointer(%wZ) failed with %lx\n",
+ trace("IoGetDeviceObjectPointer(%wZ) failed with 0x%lx\n",
&VolumeDeviceName, Status);
continue;
}
@@ -56,6 +55,22 @@ TestIoVolumeDeviceToDosName(void)
if (!skip(NT_SUCCESS(Status), "No DOS name\n"))
{
trace("DOS name for %wZ is %wZ\n", &VolumeDeviceName, &DosName);
+
+ /* The DosName should contain one NUL-terminated string (always there?),
+ * plus one final NUL-terminator */
+ ok(DosName.MaximumLength == DosName.Length + sizeof(UNICODE_NULL),
+ "Unexpected DOS name maximum length %hu, expected %hu\n",
+ DosName.MaximumLength, DosName.Length + sizeof(UNICODE_NULL));
+ ok(DosName.Length >= sizeof(UNICODE_NULL),
+ "DOS name too short (length: %lu)\n",
+ DosName.Length / sizeof(WCHAR));
+ ok(DosName.Buffer[DosName.Length / sizeof(WCHAR)] == UNICODE_NULL,
+ "Missing NUL-terminator (1)\n");
+ ok(DosName.Buffer[DosName.MaximumLength / sizeof(WCHAR) - 1] == UNICODE_NULL,
+ "Missing NUL-terminator (2)\n");
+
+ /* The DOS name is either a drive letter, or a
+ * volume GUID name (if the volume is not mounted) */
if (DosName.Length == 2 * sizeof(WCHAR))
{
ok(DosName.Buffer[0] >= L'A' &&
@@ -67,6 +82,8 @@ TestIoVolumeDeviceToDosName(void)
{
ok(RtlPrefixUnicodeString(&DosVolumePrefix, &DosName, FALSE),
"Unexpected volume path: %wZ\n", &DosName);
+ ok(MOUNTMGR_IS_DOS_VOLUME_NAME(&DosName),
+ "Invalid DOS volume path returned: %wZ\n", &DosName);
}
RtlFreeUnicodeString(&DosName);
}