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