On 7/15/20 8:58 PM, Erich E. Hoover wrote:
On Wed, Jul 15, 2020 at 9:35 AM Zebediah Figura z.figura12@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.
- 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