[PATCH 2/4] mountmgr: Add support for IRP_MJ_QUERY_VOLUME_INFORMATION.

Zebediah Figura z.figura12 at gmail.com
Wed Jul 15 21:11:34 CDT 2020


On 7/15/20 8:58 PM, Erich E. Hoover wrote:
> On Wed, Jul 15, 2020 at 9:35 AM Zebediah Figura <z.figura12 at gmail.com> wrote:
>> . ..
>> 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.
>> ...
> 
> Thanks Zeb!  At least the way we're currently doing things, it looks
> to me like that would be problematic.  Right now we create a
> disk_device for every volume (this is fine), but that we can also
> change the device type of a volume at any time (this looks
> problematic).  That's not unsolvable though, I can see a couple
> choices:

Right, I guess my point is that we probably shouldn't be treating disks
and volumes as interchangeable. If someone were to map a Unix path, I
think that should be a "volume" regardless of whether it's removable or
not, and that any "volume" should have an implicit "drive" attached, but
not the reverse. At least, that's my understanding of how it works on
Windows, but of course I could be wrong about that.

> 1) if we call set_volume_info with (type != disk_device->type) then we
> could store the volume info, delete the device (and volume), and then
> recreate it again
> 2) we could add an optional volume entry to disk_device on creation,
> making the reverse lookup simple (even if the device type changes)
> 
> I've attached an example of the second option, since that seems
> simpler, and would appreciate your thoughts.

I would agree that for now this seems like a reasonable solution. We
should fix drives and volumes, but that's somewhat orthogonal to this
patch series...

> 
> Best,
> Erich
> 
> 
>> 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/9d33dcf9/attachment.sig>


More information about the wine-devel mailing list