[ros-diffs] [pschweitzer] 55354: [NTOSKRNL] Implement IoVolumeDeviceToDosName(), taking advantage of newcomer in the branch, MountMgr :-). This implementation will in fact don't work as MountMgr doesn't implem...

pschweitzer at svn.reactos.org pschweitzer at svn.reactos.org
Tue Jan 31 18:18:46 UTC 2012


Author: pschweitzer
Date: Tue Jan 31 18:18:46 2012
New Revision: 55354

URL: http://svn.reactos.org/svn/reactos?rev=55354&view=rev
Log:
[NTOSKRNL]
Implement IoVolumeDeviceToDosName(), taking advantage of newcomer in the branch, MountMgr :-).
This implementation will in fact don't work as MountMgr doesn't implement that part... But the day it's ready, this function will be!

Modified:
    branches/usb-bringup-trunk/ntoskrnl/include/ntoskrnl.h
    branches/usb-bringup-trunk/ntoskrnl/io/iomgr/volume.c

Modified: branches/usb-bringup-trunk/ntoskrnl/include/ntoskrnl.h
URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/ntoskrnl/include/ntoskrnl.h?rev=55354&r1=55353&r2=55354&view=diff
==============================================================================
--- branches/usb-bringup-trunk/ntoskrnl/include/ntoskrnl.h [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/ntoskrnl/include/ntoskrnl.h [iso-8859-1] Tue Jan 31 18:18:46 2012
@@ -31,6 +31,7 @@
 #include <ntifs.h>
 #include <wdmguid.h>
 #include <arc/arc.h>
+#include <mountmgr.h>
 #undef NTHALAPI
 #define NTHALAPI __declspec(dllimport)
 #include <ndk/asm.h>

Modified: branches/usb-bringup-trunk/ntoskrnl/io/iomgr/volume.c
URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/ntoskrnl/io/iomgr/volume.c?rev=55354&r1=55353&r2=55354&view=diff
==============================================================================
--- branches/usb-bringup-trunk/ntoskrnl/io/iomgr/volume.c [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/ntoskrnl/io/iomgr/volume.c [iso-8859-1] Tue Jan 31 18:18:46 2012
@@ -1269,15 +1269,165 @@
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 NTAPI
 IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject,
                         OUT PUNICODE_STRING DosName)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PIRP Irp;
+    ULONG Length;
+    KEVENT Event;
+    NTSTATUS Status;
+    PFILE_OBJECT FileObject;
+    PDEVICE_OBJECT DeviceObject;
+    IO_STATUS_BLOCK IoStatusBlock;
+    UNICODE_STRING MountMgrDevice;
+    MOUNTMGR_VOLUME_PATHS VolumePath;
+    PMOUNTMGR_VOLUME_PATHS VolumePathPtr;
+    /*
+     * This variable with be required to query device name.
+     * It's based on MOUNTDEV_NAME (mountmgr.h).
+     * Doing it that way will prevent dyn memory allocation.
+     * Device name won't be longer.
+     */
+    struct
+    {
+        USHORT NameLength;
+        WCHAR DeviceName[256];
+    } DeviceName;
+
+    PAGED_CODE();
+
+    /* First step, getting device name */
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
+                                        VolumeDeviceObject, NULL, 0,
+                                        &DeviceName, sizeof(DeviceName),
+                                        FALSE, &Event, &IoStatusBlock);
+    if (!Irp)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    Status = IoCallDriver(VolumeDeviceObject, Irp);
+    if (Status == STATUS_PENDING)
+    {
+        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+        Status = IoStatusBlock.Status;
+    }
+
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* Now that we have the device name, we can query the MountMgr
+     * So, get its device object first.
+     */
+    RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME);
+    Status = IoGetDeviceObjectPointer(&MountMgrDevice, FILE_READ_ATTRIBUTES,
+                                      &FileObject, &DeviceObject);
+    if (!NT_SUCCESS(Status))
+    {
+        return Status;
+    }
+
+    /* Then, use the proper IOCTL to query the DOS name */
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH,
+                                        DeviceObject, &DeviceName, sizeof(DeviceName),
+                                        &VolumePath, sizeof(VolumePath),
+                                        FALSE, &Event, &IoStatusBlock);
+    if (!Irp)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto DereferenceFO;
+    }
+
+    Status = IoCallDriver(VolumeDeviceObject, Irp);
+    if (Status == STATUS_PENDING)
+    {
+        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+        Status = IoStatusBlock.Status;
+    }
+
+    /* Only tolerated failure here is buffer too small, which is
+     * expected.
+     */
+    if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
+    {
+        goto DereferenceFO;
+    }
+
+    /* Compute needed size to store DOS name.
+     * 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 on USHORT.
+     */ 
+    Length = VolumePath.MultiSzLength + sizeof(VolumePath);
+    if (Length > MAXUSHORT)
+    {
+        Status = STATUS_INVALID_BUFFER_SIZE;
+        goto DereferenceFO;
+    }
+
+    /* Reallocate memory, even in case of success, because
+     * that's the buffer that will be returned to caller
+     */
+    VolumePathPtr = ExAllocatePoolWithTag(PagedPool, Length, 'D2d ');
+    if (!VolumePathPtr)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto DereferenceFO;
+    }
+
+    /* Requery DOS path with proper size */
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH,
+                                        DeviceObject, &DeviceName, sizeof(DeviceName),
+                                        VolumePathPtr, Length,
+                                        FALSE, &Event, &IoStatusBlock);
+    if (!Irp)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto ReleaseMemory;
+    }
+
+    Status = IoCallDriver(VolumeDeviceObject, Irp);
+    if (Status == STATUS_PENDING)
+    {
+        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+        Status = IoStatusBlock.Status;
+    }
+
+    if (!NT_SUCCESS(Status))
+    {
+        goto ReleaseMemory;
+    }
+
+    /* Set output string */
+    DosName->Length = VolumePathPtr->MultiSzLength;
+    DosName->MaximumLength = VolumePathPtr->MultiSzLength + sizeof(UNICODE_NULL);
+    /* Our MOUNTMGR_VOLUME_PATHS will be used as output buffer */
+    DosName->Buffer = (PWSTR)VolumePathPtr;
+    /* Move name at the begin, RtlMoveMemory is OK with overlapping */
+    RtlMoveMemory(DosName->Buffer, VolumePathPtr->MultiSz, VolumePathPtr->MultiSzLength);
+    DosName->Buffer[DosName->Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+    /* DON'T release buffer, just dereference FO, and return success */
+    Status = STATUS_SUCCESS;
+    goto DereferenceFO;
+
+ReleaseMemory:
+    ExFreePoolWithTag(VolumePathPtr, 'D2d ');
+
+DereferenceFO:
+    ObDereferenceObject(FileObject);
+
+    return Status;
 }
 
 /* EOF */




More information about the Ros-diffs mailing list