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>
This commit is contained in:
parent
a656ca5e32
commit
d896c2201f
|
@ -91,6 +91,7 @@ struct disk_device
|
||||||
char *unix_device; /* unix device path */
|
char *unix_device; /* unix device path */
|
||||||
char *unix_mount; /* unix mount point path */
|
char *unix_mount; /* unix mount point path */
|
||||||
char *serial; /* disk serial number */
|
char *serial; /* disk serial number */
|
||||||
|
struct volume *volume; /* associated volume */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct volume
|
struct volume
|
||||||
|
@ -746,7 +747,7 @@ static DWORD VOLUME_GetAudioCDSerial( const CDROM_TOC *toc )
|
||||||
|
|
||||||
|
|
||||||
/* create the disk device for a given volume */
|
/* 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',
|
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};
|
'\\','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_device = NULL;
|
||||||
device->unix_mount = NULL;
|
device->unix_mount = NULL;
|
||||||
device->symlink.Buffer = NULL;
|
device->symlink.Buffer = NULL;
|
||||||
|
device->volume = volume;
|
||||||
|
|
||||||
if (link_format)
|
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) )))
|
if (!(volume = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*volume) )))
|
||||||
return STATUS_NO_MEMORY;
|
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 );
|
if (udi) set_volume_udi( volume, udi );
|
||||||
list_add_tail( &volumes_list, &volume->entry );
|
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 (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)
|
if (volume->mount)
|
||||||
{
|
{
|
||||||
delete_mount_point( volume->mount );
|
delete_mount_point( volume->mount );
|
||||||
|
@ -1826,6 +1828,118 @@ static NTSTATUS query_property( struct disk_device *device, IRP *irp )
|
||||||
return status;
|
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 */
|
/* handler for ioctls on the harddisk device */
|
||||||
static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
|
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;
|
harddisk_driver = driver;
|
||||||
driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = harddisk_ioctl;
|
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 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();
|
create_drive_devices();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue