https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dac991c056c718fdd1572582af5755803ab5359a

commit dac991c056c718fdd1572582af5755803ab5359a
Author:     Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org>
AuthorDate: Fri Dec 27 17:48:04 2024 +0100
Commit:     Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org>
CommitDate: Mon Jan 6 21:26:43 2025 +0100

    [PARTMGR] Implement support for IOCTL_STORAGE_GET_DEVICE_NUMBER (#7591)
    
    CORE-13525
    
    Now, sending the IOCTL_STORAGE_GET_DEVICE_NUMBER to a disk partition
    correctly returns a non-zero STORAGE_DEVICE_NUMBER::PartitionNumber
    value. This is used by the BTRFS filesystem driver and other modules.
    
    When the STORAGE_DEVICE_NUMBER DeviceType member equals FILE_DEVICE_DISK,
    the DeviceNumber and PartitionNumber correspond respectively to the
    X and Y values in the \Device\Harddisk<X>\Partition<Y> device name.
    
    References:
    
https://learn.microsoft.com/en-us/windows/win32/api/winioctl/ni-winioctl-ioctl_storage_get_device_number
    
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddstor/ni-ntddstor-ioctl_storage_get_device_number
    
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddstor/ns-ntddstor-_storage_device_number
---
 drivers/storage/partmgr/partition.c | 40 ++++++++++++++++++++++++++++++++++---
 drivers/storage/partmgr/partmgr.c   | 12 ++++++++++-
 2 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/drivers/storage/partmgr/partition.c 
b/drivers/storage/partmgr/partition.c
index e8a38e728ca..3551898389f 100644
--- a/drivers/storage/partmgr/partition.c
+++ b/drivers/storage/partmgr/partition.c
@@ -27,17 +27,26 @@ PartitionCreateDevice(
     UNICODE_STRING deviceName;
     UINT32 volumeNum;
 
-    // Create the partition/volume device object
-
     volumeNum = HarddiskVolumeNextId++;
     swprintf(nameBuf, L"\\Device\\HarddiskVolume%lu", volumeNum);
     RtlCreateUnicodeString(&deviceName, nameBuf);
 
+    /*
+     * Create the partition/volume device object.
+     *
+     * Due to the fact we are also a (basic) volume manager, this device is
+     * ALSO a volume device. Because of this, we need to assign it a device
+     * name, and a specific device type for IoCreateDevice() to create a VPB
+     * for this device, so that a filesystem can be mounted on it.
+     * Once we get a separate volume manager, this partition DO can become
+     * anonymous, have a different device type, and without any associated VPB.
+     * (The attached volume, on the contrary, would require a VPB.)
+     */
     PDEVICE_OBJECT partitionDevice;
     NTSTATUS status = IoCreateDevice(FDObject->DriverObject,
                                      sizeof(PARTITION_EXTENSION),
                                      &deviceName,
-                                     FILE_DEVICE_DISK,
+                                     FILE_DEVICE_DISK, // 
FILE_DEVICE_MASS_STORAGE,
                                      FILE_DEVICE_SECURE_OPEN,
                                      FALSE,
                                      &partitionDevice);
@@ -55,6 +64,10 @@ PartitionCreateDevice(
     partExt->DeviceObject = partitionDevice;
     partExt->LowerDevice = FDObject;
 
+    // NOTE: See comment above.
+    // PFDO_EXTENSION fdoExtension = FDObject->DeviceExtension;
+    // partitionDevice->DeviceType = 
/*fdoExtension->LowerDevice*/FDObject->DeviceType;
+
     partitionDevice->StackSize = FDObject->StackSize;
     partitionDevice->Flags |= DO_DIRECT_IO;
 
@@ -767,6 +780,27 @@ PartitionHandleDeviceControl(
             status = STATUS_SUCCESS;
             break;
         }
+        case IOCTL_STORAGE_GET_DEVICE_NUMBER:
+        {
+            PSTORAGE_DEVICE_NUMBER deviceNumber = 
Irp->AssociatedIrp.SystemBuffer;
+            if (!VerifyIrpOutBufferSize(Irp, sizeof(*deviceNumber)))
+            {
+                status = STATUS_BUFFER_TOO_SMALL;
+                break;
+            }
+
+            PartMgrAcquireLayoutLock(fdoExtension);
+
+            deviceNumber->DeviceType = partExt->DeviceObject->DeviceType;
+            deviceNumber->DeviceNumber = fdoExtension->DiskData.DeviceNumber;
+            deviceNumber->PartitionNumber = partExt->DetectedNumber;
+
+            PartMgrReleaseLayoutLock(fdoExtension);
+
+            status = STATUS_SUCCESS;
+            Irp->IoStatus.Information = sizeof(*deviceNumber);
+            break;
+        }
         case IOCTL_STORAGE_MEDIA_REMOVAL:
         {
             return ForwardIrpAndForget(DeviceObject, Irp);
diff --git a/drivers/storage/partmgr/partmgr.c 
b/drivers/storage/partmgr/partmgr.c
index b1c37b5d964..5b79d823898 100644
--- a/drivers/storage/partmgr/partmgr.c
+++ b/drivers/storage/partmgr/partmgr.c
@@ -1182,10 +1182,17 @@ PartMgrAddDevice(
 
     PAGED_CODE();
 
+    /*
+     * Create the disk FDO. Use FILE_DEVICE_MASS_STORAGE type (or any other
+     * one that is NOT FILE_DEVICE_[DISK|VIRTUAL_DISK|CD_ROM|TAPE]), so that
+     * IoCreateDevice() doesn't automatically create a VPB for this device,
+     * even if we will later want this device to inherit the type of the
+     * underlying PDO which can have any of the types mentioned above.
+     */
     NTSTATUS status = IoCreateDevice(DriverObject,
                                      sizeof(FDO_EXTENSION),
                                      NULL,
-                                     FILE_DEVICE_BUS_EXTENDER,
+                                     FILE_DEVICE_MASS_STORAGE,
                                      FILE_AUTOGENERATED_DEVICE_NAME | 
FILE_DEVICE_SECURE_OPEN,
                                      FALSE,
                                      &deviceObject);
@@ -1210,6 +1217,9 @@ PartMgrAddDevice(
     deviceExtension->PhysicalDiskDO = PhysicalDeviceObject;
     KeInitializeEvent(&deviceExtension->SyncEvent, SynchronizationEvent, TRUE);
 
+    // Update now the device type with the actual underlying device type
+    deviceObject->DeviceType = deviceExtension->LowerDevice->DeviceType;
+
     deviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
 
     // The device is initialized

Reply via email to