[PATCH 2/4] mountmgr: Add support for IRP_MJ_QUERY_VOLUME_INFORMATION.
Zebediah Figura
z.figura12 at gmail.com
Wed Jul 15 10:35:21 CDT 2020
On 7/15/20 10:08 AM, Erich E. Hoover wrote:
> From 2dd03df6e1fc2944d7590cc400059b05a8edbaa1 Mon Sep 17 00:00:00 2001
> From: "Erich E. Hoover" <erich.e.hoover at gmail.com>
> Date: Fri, 12 Jun 2020 14:48:25 -0600
> Subject: mountmgr: Add support for IRP_MJ_QUERY_VOLUME_INFORMATION.
>
> Signed-off-by: Erich E. Hoover <erich.e.hoover at gmail.com>
> ---
> dlls/mountmgr.sys/device.c | 137 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 137 insertions(+)
>
> diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
> index f7a1f1e9b55..439dbc0c7d3 100644
> --- a/dlls/mountmgr.sys/device.c
> +++ b/dlls/mountmgr.sys/device.c
> @@ -1818,6 +1818,142 @@ static void query_property( struct disk_device *device, IRP *irp )
> }
> }
>
> +/* find a volume that matches the given mount point */
> +static struct volume *find_mount_volume( const char *mount_point, enum device_type type )
> +{
> + struct volume *volume;
> + struct disk_device *disk_device;
> +
> + LIST_FOR_EACH_ENTRY( volume, &volumes_list, struct volume, entry )
> + {
> + int match = 0;
> +
> + disk_device = volume->device;
> + if (disk_device->type != type) continue;
> + if (mount_point && disk_device->unix_mount)
> + {
> + if (strcmp( mount_point, disk_device->unix_mount )) continue;
> + match++;
> + }
> + if (!match) continue;
> + TRACE( "found matching volume %s for mount %s type %u\n",
> + debugstr_guid(&volume->guid), debugstr_a(mount_point), type );
> + return grab_volume( volume );
> + }
> + return NULL;
> +}
This seems less than ideal. I guess maybe a better thing to do is have a
union of "struct disk_device" and "struct volume" in the device extension.
We could probably do a better job of properly differentiating drives and
volumes anyway, e.g. I think we currently create a "volume" object for
all drives, and we create a "disk_device" for drives defined with
DEFINE_UNIX_DRIVE and DRIVE_REMOVABLE. It's my understanding that only
"volumes" can be mounted, even for removable drives.
> +
> +static NTSTATUS WINAPI harddisk_query_volume( DEVICE_OBJECT *device, IRP *irp )
> +{
> + IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
> + int info_class = irpsp->Parameters.QueryVolume.FsInformationClass;
> + ULONG length = irpsp->Parameters.QueryVolume.Length;
> + struct disk_device *dev = device->DeviceExtension;
> + PIO_STATUS_BLOCK io = &irp->IoStatus;
> + struct volume *volume;
> +
> + TRACE( "volume query %x length %u\n", info_class,
> + length );
> +
> + EnterCriticalSection( &device_section );
> + volume = find_mount_volume( dev->unix_mount, DEVICE_HARDDISK_VOL );
> + if (!volume)
> + {
> + io->u.Status = STATUS_BAD_DEVICE_TYPE;
> + goto done;
> + }
> +
> + switch(info_class)
> + {
> + case FileFsVolumeInformation:
> + {
> +
> + FILE_FS_VOLUME_INFORMATION *info = irp->UserBuffer;
> +
> + if (length < sizeof(FILE_FS_VOLUME_INFORMATION))
> + {
> + io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
> + break;
> + }
> +
> + info->VolumeCreationTime.QuadPart = 0; /* FIXME */
> + info->VolumeSerialNumber = volume->serial;
> + info->VolumeLabelLength = min( strlenW(volume->label) * sizeof(WCHAR),
> + length - offsetof( FILE_FS_VOLUME_INFORMATION, VolumeLabel ) );
> + info->SupportsObjects = (get_mountmgr_fs_type(volume->fs_type) == MOUNTMGR_FS_TYPE_NTFS);
> + memcpy( info->VolumeLabel, volume->label, info->VolumeLabelLength );
> +
> + io->Information = offsetof( FILE_FS_VOLUME_INFORMATION, VolumeLabel ) + info->VolumeLabelLength;
> + io->u.Status = STATUS_SUCCESS;
> + break;
> + }
> + case FileFsAttributeInformation:
> + {
> + static const WCHAR fatW[] = {'F','A','T'};
> + static const WCHAR fat32W[] = {'F','A','T','3','2'};
> + static const WCHAR ntfsW[] = {'N','T','F','S'};
> + static const WCHAR cdfsW[] = {'C','D','F','S'};
> + static const WCHAR udfW[] = {'U','D','F'};
> +
> + FILE_FS_ATTRIBUTE_INFORMATION *info = irp->UserBuffer;
> + enum mountmgr_fs_type fs_type = get_mountmgr_fs_type(volume->fs_type);
> +
> + if (length < sizeof(FILE_FS_ATTRIBUTE_INFORMATION))
> + {
> + io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
> + break;
> + }
> +
> + switch (fs_type)
> + {
> + case MOUNTMGR_FS_TYPE_ISO9660:
> + info->FileSystemAttributes = FILE_READ_ONLY_VOLUME;
> + info->MaximumComponentNameLength = 221;
> + info->FileSystemNameLength = min( sizeof(cdfsW), length - offsetof( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName ) );
> + memcpy(info->FileSystemName, cdfsW, info->FileSystemNameLength);
> + break;
> + case MOUNTMGR_FS_TYPE_UDF:
> + info->FileSystemAttributes = FILE_READ_ONLY_VOLUME | FILE_UNICODE_ON_DISK | FILE_CASE_SENSITIVE_SEARCH;
> + info->MaximumComponentNameLength = 255;
> + info->FileSystemNameLength = min( sizeof(udfW), length - offsetof( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName ) );
> + memcpy(info->FileSystemName, udfW, info->FileSystemNameLength);
> + break;
> + case MOUNTMGR_FS_TYPE_FAT:
> + info->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES; /* FIXME */
> + info->MaximumComponentNameLength = 255;
> + info->FileSystemNameLength = min( sizeof(fatW), length - offsetof( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName ) );
> + memcpy(info->FileSystemName, fatW, info->FileSystemNameLength);
> + break;
> + case MOUNTMGR_FS_TYPE_FAT32:
> + info->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES; /* FIXME */
> + info->MaximumComponentNameLength = 255;
> + info->FileSystemNameLength = min( sizeof(fat32W), length - offsetof( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName ) );
> + memcpy(info->FileSystemName, fat32W, info->FileSystemNameLength);
> + break;
> + default:
> + info->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES | FILE_PERSISTENT_ACLS;
> + info->MaximumComponentNameLength = 255;
> + info->FileSystemNameLength = min( sizeof(ntfsW), length - offsetof( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName ) );
> + memcpy(info->FileSystemName, ntfsW, info->FileSystemNameLength);
> + break;
> + }
> +
> + io->Information = offsetof( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName ) + info->FileSystemNameLength;
> + io->u.Status = STATUS_SUCCESS;
> + break;
> + }
> + default:
> + FIXME("Unsupported volume query %x\n", irpsp->Parameters.QueryVolume.FsInformationClass);
> + io->u.Status = STATUS_NOT_SUPPORTED;
> + break;
> + }
> +
> +done:
> + LeaveCriticalSection( &device_section );
> + IoCompleteRequest( irp, IO_NO_INCREMENT );
> + return STATUS_SUCCESS;
> +}
> +
> /* handler for ioctls on the harddisk device */
> static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
> {
> @@ -1915,6 +2051,7 @@ NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *pa
>
> harddisk_driver = driver;
> driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = harddisk_ioctl;
> + driver->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = harddisk_query_volume;
>
> /* create a harddisk0 device that isn't assigned to any drive */
> create_disk_device( DEVICE_HARDDISK, &device );
>
> --
> 2.17.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20200715/484177e6/attachment-0001.sig>
More information about the wine-devel
mailing list