[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