Module: wine Branch: master Commit: d896c2201f5c03fae738d74e6ad617aa772f86e7 URL: https://source.winehq.org/git/wine.git/?a=commit;h=d896c2201f5c03fae738d74e6...
Author: Erich E. Hoover erich.e.hoover@gmail.com Date: Fri Jun 12 14:48:25 2020 -0600
mountmgr.sys: Add support for volume information queries.
Signed-off-by: Erich E. Hoover erich.e.hoover@gmail.com Signed-off-by: Zebediah Figura z.figura12@gmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/mountmgr.sys/device.c | 123 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 119 insertions(+), 4 deletions(-)
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c index c9cee002bc0..dd2c7d70759 100644 --- a/dlls/mountmgr.sys/device.c +++ b/dlls/mountmgr.sys/device.c @@ -91,6 +91,7 @@ struct disk_device char *unix_device; /* unix device path */ char *unix_mount; /* unix mount point path */ char *serial; /* disk serial number */ + struct volume *volume; /* associated volume */ };
struct volume @@ -746,7 +747,7 @@ static DWORD VOLUME_GetAudioCDSerial( const CDROM_TOC *toc )
/* create the disk device for a given volume */ -static NTSTATUS create_disk_device( enum device_type type, struct disk_device **device_ret ) +static NTSTATUS create_disk_device( enum device_type type, struct disk_device **device_ret, struct volume *volume ) { static const WCHAR harddiskvolW[] = {'\','D','e','v','i','c','e', '\','H','a','r','d','d','i','s','k','V','o','l','u','m','e','%','u',0}; @@ -808,6 +809,7 @@ static NTSTATUS create_disk_device( enum device_type type, struct disk_device ** device->unix_device = NULL; device->unix_mount = NULL; device->symlink.Buffer = NULL; + device->volume = volume;
if (link_format) { @@ -930,7 +932,7 @@ static NTSTATUS create_volume( const char *udi, enum device_type type, struct vo if (!(volume = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*volume) ))) return STATUS_NO_MEMORY;
- if (!(status = create_disk_device( type, &volume->device ))) + if (!(status = create_disk_device( type, &volume->device, volume ))) { if (udi) set_volume_udi( volume, udi ); list_add_tail( &volumes_list, &volume->entry ); @@ -1125,7 +1127,7 @@ static NTSTATUS set_volume_info( struct volume *volume, struct dos_drive *drive,
if (type != disk_device->type) { - if ((status = create_disk_device( type, &disk_device ))) return status; + if ((status = create_disk_device( type, &disk_device, volume ))) return status; if (volume->mount) { delete_mount_point( volume->mount ); @@ -1826,6 +1828,118 @@ static NTSTATUS query_property( struct disk_device *device, IRP *irp ) return status; }
+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; + NTSTATUS status; + + TRACE( "volume query %x length %u\n", info_class, length ); + + EnterCriticalSection( &device_section ); + volume = dev->volume; + if (!volume) + { + status = STATUS_BAD_DEVICE_TYPE; + goto done; + } + + switch(info_class) + { + case FileFsVolumeInformation: + { + + FILE_FS_VOLUME_INFORMATION *info = irp->AssociatedIrp.SystemBuffer; + + if (length < sizeof(FILE_FS_VOLUME_INFORMATION)) + { + 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; + 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->AssociatedIrp.SystemBuffer; + enum mountmgr_fs_type fs_type = get_mountmgr_fs_type(volume->fs_type); + + if (length < sizeof(FILE_FS_ATTRIBUTE_INFORMATION)) + { + 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; + status = STATUS_SUCCESS; + break; + } + default: + FIXME("Unsupported volume query %x\n", irpsp->Parameters.QueryVolume.FsInformationClass); + status = STATUS_NOT_SUPPORTED; + break; + } + +done: + io->u.Status = status; + LeaveCriticalSection( &device_section ); + IoCompleteRequest( irp, IO_NO_INCREMENT ); + return status; +} + /* handler for ioctls on the harddisk device */ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp ) { @@ -1925,9 +2039,10 @@ 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 ); + create_disk_device( DEVICE_HARDDISK, &device, NULL );
create_drive_devices();