[PARTMGR] Implement IOCTL_VOLUME_QUERY_VOLUME_NUMBER and IOCTL_VOLUME_IS_PARTITION (#6911)

- Implement IOCTL_VOLUME_QUERY_VOLUME_NUMBER:
  See usage example in:
  7241cebfa2/mayfield/branches/spr/src/umapps/ndassvc/service/drivematch.cpp (L627)

- Stubplement IOCTL_VOLUME_IS_PARTITION:
  The only type of volume we support right now is disk partition
  so we just return success. A more robust algorithm would be
  to check whether the volume has only one single extent, that
  covers the whole partition on which it lies upon. If this is
  not the case, return STATUS_UNSUCCESSFUL instead.
This commit is contained in:
Hermès Bélusca-Maïto 2024-05-19 20:28:15 +02:00
parent 0b366ea122
commit 0a8b421d53
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
2 changed files with 40 additions and 4 deletions

View file

@ -7,7 +7,7 @@
#include "partmgr.h" #include "partmgr.h"
static const WCHAR PartitionSymLinkFormat[] = L"\\Device\\Harddisk%u\\Partition%u"; static const WCHAR PartitionSymLinkFormat[] = L"\\Device\\Harddisk%lu\\Partition%lu";
CODE_SEG("PAGE") CODE_SEG("PAGE")
@ -25,10 +25,12 @@ PartitionCreateDevice(
WCHAR nameBuf[64]; WCHAR nameBuf[64];
UNICODE_STRING deviceName; UNICODE_STRING deviceName;
UINT32 volumeNum;
// create the device object // create the device object
swprintf(nameBuf, L"\\Device\\HarddiskVolume%u", HarddiskVolumeNextId++); volumeNum = HarddiskVolumeNextId++;
swprintf(nameBuf, L"\\Device\\HarddiskVolume%lu", volumeNum);
RtlCreateUnicodeString(&deviceName, nameBuf); RtlCreateUnicodeString(&deviceName, nameBuf);
PDEVICE_OBJECT partitionDevice; PDEVICE_OBJECT partitionDevice;
@ -74,6 +76,7 @@ PartitionCreateDevice(
partExt->PartitionLength = PartitionEntry->PartitionLength.QuadPart; partExt->PartitionLength = PartitionEntry->PartitionLength.QuadPart;
partExt->OnDiskNumber = PartitionEntry->PartitionNumber; // the "physical" partition number partExt->OnDiskNumber = PartitionEntry->PartitionNumber; // the "physical" partition number
partExt->DetectedNumber = PdoNumber; // counts only partitions with PDO created partExt->DetectedNumber = PdoNumber; // counts only partitions with PDO created
partExt->VolumeNumber = volumeNum;
partExt->DeviceObject = partitionDevice; partExt->DeviceObject = partitionDevice;
partExt->LowerDevice = FDObject; partExt->LowerDevice = FDObject;
@ -99,7 +102,7 @@ PartitionHandleStartDevice(
UNICODE_STRING partitionSymlink, interfaceName; UNICODE_STRING partitionSymlink, interfaceName;
PFDO_EXTENSION fdoExtension = PartExt->LowerDevice->DeviceExtension; PFDO_EXTENSION fdoExtension = PartExt->LowerDevice->DeviceExtension;
// \\Device\\Harddisk%u\\Partition%u // \\Device\\Harddisk%lu\\Partition%lu
swprintf(nameBuf, PartitionSymLinkFormat, swprintf(nameBuf, PartitionSymLinkFormat,
fdoExtension->DiskData.DeviceNumber, PartExt->DetectedNumber); fdoExtension->DiskData.DeviceNumber, PartExt->DetectedNumber);
@ -662,7 +665,7 @@ PartitionHandleDeviceControl(
{ {
return ForwardIrpAndForget(DeviceObject, Irp); return ForwardIrpAndForget(DeviceObject, Irp);
} }
// volume stuff (most of that should be in volmgr.sys one it is implemented) // volume stuff (most of that should be in volmgr.sys once it is implemented)
case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS: case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS:
{ {
PVOLUME_DISK_EXTENTS volExts = Irp->AssociatedIrp.SystemBuffer; PVOLUME_DISK_EXTENTS volExts = Irp->AssociatedIrp.SystemBuffer;
@ -694,6 +697,38 @@ PartitionHandleDeviceControl(
Irp->IoStatus.Information = sizeof(*volExts); Irp->IoStatus.Information = sizeof(*volExts);
break; break;
} }
case IOCTL_VOLUME_QUERY_VOLUME_NUMBER:
{
PVOLUME_NUMBER volNum = Irp->AssociatedIrp.SystemBuffer;
if (!VerifyIrpOutBufferSize(Irp, sizeof(*volNum)))
{
status = STATUS_BUFFER_TOO_SMALL;
break;
}
PartMgrAcquireLayoutLock(fdoExtension);
volNum->VolumeNumber = partExt->VolumeNumber;
RtlCopyMemory(volNum->VolumeManagerName,
L"VOLMGR ", // Must be 8 space-padded characters
sizeof(volNum->VolumeManagerName));
PartMgrReleaseLayoutLock(fdoExtension);
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(*volNum);
break;
}
case IOCTL_VOLUME_IS_PARTITION:
{
// The only type of volume we support right now is disk partition
// so we just return success. A more robust algorithm would be
// to check whether the volume has only one single extent, that
// covers the whole partition on which it lies upon. If this is
// not the case, return STATUS_UNSUCCESSFUL instead.
status = STATUS_SUCCESS;
break;
}
case IOCTL_VOLUME_ONLINE: case IOCTL_VOLUME_ONLINE:
{ {
status = STATUS_SUCCESS; status = STATUS_SUCCESS;

View file

@ -73,6 +73,7 @@ typedef struct _PARTITION_EXTENSION
UINT64 PartitionLength; UINT64 PartitionLength;
SINGLE_LIST_ENTRY ListEntry; SINGLE_LIST_ENTRY ListEntry;
UINT32 VolumeNumber; // Volume number in the "\Device\HarddiskVolumeN" device name
UINT32 DetectedNumber; UINT32 DetectedNumber;
UINT32 OnDiskNumber; // partition number for issuing Io requests to the kernel UINT32 OnDiskNumber; // partition number for issuing Io requests to the kernel
BOOLEAN IsEnumerated; // reported via IRP_MN_QUERY_DEVICE_RELATIONS BOOLEAN IsEnumerated; // reported via IRP_MN_QUERY_DEVICE_RELATIONS