mountmgr: Return the disk serial from IOCTL_STORAGE_QUERY_PROPERTY(StorageDeviceProperty).
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
51c9db55e6
commit
4ed26b63ca
|
@ -317,7 +317,7 @@ static void udisks_new_device( const char *udi )
|
||||||
if (device)
|
if (device)
|
||||||
{
|
{
|
||||||
if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr, NULL );
|
if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr, NULL );
|
||||||
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
|
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
p_dbus_message_unref( reply );
|
p_dbus_message_unref( reply );
|
||||||
|
@ -385,7 +385,7 @@ static const char *udisks2_string_from_array( DBusMessageIter *iter )
|
||||||
|
|
||||||
/* find the drive entry in the dictionary and get its parameters */
|
/* find the drive entry in the dictionary and get its parameters */
|
||||||
static void udisks2_get_drive_info( const char *drive_name, DBusMessageIter *dict,
|
static void udisks2_get_drive_info( const char *drive_name, DBusMessageIter *dict,
|
||||||
enum device_type *drive_type, int *removable )
|
enum device_type *drive_type, int *removable, const char **serial )
|
||||||
{
|
{
|
||||||
DBusMessageIter iter, drive, variant;
|
DBusMessageIter iter, drive, variant;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -403,6 +403,8 @@ static void udisks2_get_drive_info( const char *drive_name, DBusMessageIter *dic
|
||||||
p_dbus_message_iter_get_basic( &variant, removable );
|
p_dbus_message_iter_get_basic( &variant, removable );
|
||||||
else if (!strcmp( name, "MediaCompatibility" ))
|
else if (!strcmp( name, "MediaCompatibility" ))
|
||||||
*drive_type = udisks_parse_media_compatibility( &variant );
|
*drive_type = udisks_parse_media_compatibility( &variant );
|
||||||
|
else if (!strcmp( name, "Id" ))
|
||||||
|
p_dbus_message_iter_get_basic( &variant, serial );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,6 +417,7 @@ static void udisks2_add_device( const char *udi, DBusMessageIter *dict, DBusMess
|
||||||
const char *mount_point = NULL;
|
const char *mount_point = NULL;
|
||||||
const char *type = NULL;
|
const char *type = NULL;
|
||||||
const char *drive = NULL;
|
const char *drive = NULL;
|
||||||
|
const char *id = NULL;
|
||||||
GUID guid, *guid_ptr = NULL;
|
GUID guid, *guid_ptr = NULL;
|
||||||
const char *iface, *name;
|
const char *iface, *name;
|
||||||
int removable = FALSE;
|
int removable = FALSE;
|
||||||
|
@ -448,7 +451,7 @@ static void udisks2_add_device( const char *udi, DBusMessageIter *dict, DBusMess
|
||||||
else if (!strcmp( name, "Drive" ))
|
else if (!strcmp( name, "Drive" ))
|
||||||
{
|
{
|
||||||
p_dbus_message_iter_get_basic( &variant, &drive );
|
p_dbus_message_iter_get_basic( &variant, &drive );
|
||||||
udisks2_get_drive_info( drive, dict, &drive_type, &removable );
|
udisks2_get_drive_info( drive, dict, &drive_type, &removable, &id );
|
||||||
}
|
}
|
||||||
else if (!strcmp( name, "IdUUID" ))
|
else if (!strcmp( name, "IdUUID" ))
|
||||||
{
|
{
|
||||||
|
@ -483,7 +486,7 @@ static void udisks2_add_device( const char *udi, DBusMessageIter *dict, DBusMess
|
||||||
if (device)
|
if (device)
|
||||||
{
|
{
|
||||||
if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr, NULL );
|
if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr, NULL );
|
||||||
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
|
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr, id );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -799,7 +802,7 @@ static void hal_new_device( LibHalContext *ctx, const char *udi )
|
||||||
/* add property watch for mount point */
|
/* add property watch for mount point */
|
||||||
p_libhal_device_add_property_watch( ctx, udi, &error );
|
p_libhal_device_add_property_watch( ctx, udi, &error );
|
||||||
}
|
}
|
||||||
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
|
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr, NULL );
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (type) p_libhal_free_string( type );
|
if (type) p_libhal_free_string( type );
|
||||||
|
|
|
@ -89,6 +89,7 @@ struct disk_device
|
||||||
STORAGE_DEVICE_NUMBER devnum; /* device number info */
|
STORAGE_DEVICE_NUMBER devnum; /* device number info */
|
||||||
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 */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct volume
|
struct volume
|
||||||
|
@ -873,6 +874,7 @@ static void delete_disk_device( struct disk_device *device )
|
||||||
}
|
}
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, device->unix_device );
|
RtlFreeHeap( GetProcessHeap(), 0, device->unix_device );
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, device->unix_mount );
|
RtlFreeHeap( GetProcessHeap(), 0, device->unix_mount );
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, device->serial );
|
||||||
RtlFreeUnicodeString( &device->name );
|
RtlFreeUnicodeString( &device->name );
|
||||||
IoDeleteDevice( device->dev_obj );
|
IoDeleteDevice( device->dev_obj );
|
||||||
}
|
}
|
||||||
|
@ -1078,9 +1080,40 @@ static BOOL get_volume_device_info( struct volume *volume )
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set disk serial for dos devices that reside on a given Unix device */
|
||||||
|
static void set_dos_devices_disk_serial( struct disk_device *device )
|
||||||
|
{
|
||||||
|
struct dos_drive *drive;
|
||||||
|
struct stat dev_st, drive_st;
|
||||||
|
char *path, *p;
|
||||||
|
|
||||||
|
if (!device->serial || !device->unix_mount || stat( device->unix_mount, &dev_st ) == -1) return;
|
||||||
|
|
||||||
|
if (!(path = get_dosdevices_path( &p ))) return;
|
||||||
|
p[2] = 0;
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry )
|
||||||
|
{
|
||||||
|
/* drives mapped to Unix devices already have serial set, if available */
|
||||||
|
if (drive->volume->device->unix_device) continue;
|
||||||
|
|
||||||
|
p[0] = 'a' + drive->drive;
|
||||||
|
|
||||||
|
/* copy serial if drive resides on this Unix device */
|
||||||
|
if (stat( path, &drive_st ) != -1 && drive_st.st_rdev == dev_st.st_rdev)
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, drive->volume->device->serial );
|
||||||
|
drive->volume->device->serial = strdupA( device->serial );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree( GetProcessHeap(), 0, path );
|
||||||
|
}
|
||||||
|
|
||||||
/* change the information for an existing volume */
|
/* change the information for an existing volume */
|
||||||
static NTSTATUS set_volume_info( struct volume *volume, struct dos_drive *drive, const char *device,
|
static NTSTATUS set_volume_info( struct volume *volume, struct dos_drive *drive, const char *device,
|
||||||
const char *mount_point, enum device_type type, const GUID *guid )
|
const char *mount_point, enum device_type type, const GUID *guid,
|
||||||
|
const char *disk_serial )
|
||||||
{
|
{
|
||||||
void *id = NULL;
|
void *id = NULL;
|
||||||
unsigned int id_len = 0;
|
unsigned int id_len = 0;
|
||||||
|
@ -1107,9 +1140,12 @@ static NTSTATUS set_volume_info( struct volume *volume, struct dos_drive *drive,
|
||||||
{
|
{
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, disk_device->unix_device );
|
RtlFreeHeap( GetProcessHeap(), 0, disk_device->unix_device );
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, disk_device->unix_mount );
|
RtlFreeHeap( GetProcessHeap(), 0, disk_device->unix_mount );
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, disk_device->serial );
|
||||||
}
|
}
|
||||||
disk_device->unix_device = strdupA( device );
|
disk_device->unix_device = strdupA( device );
|
||||||
disk_device->unix_mount = strdupA( mount_point );
|
disk_device->unix_mount = strdupA( mount_point );
|
||||||
|
disk_device->serial = strdupA( disk_serial );
|
||||||
|
set_dos_devices_disk_serial( disk_device );
|
||||||
|
|
||||||
if (!get_volume_device_info( volume ))
|
if (!get_volume_device_info( volume ))
|
||||||
{
|
{
|
||||||
|
@ -1306,7 +1342,7 @@ static void create_drive_devices(void)
|
||||||
{
|
{
|
||||||
/* don't reset uuid if we used an existing volume */
|
/* don't reset uuid if we used an existing volume */
|
||||||
const GUID *guid = volume ? NULL : get_default_uuid(i);
|
const GUID *guid = volume ? NULL : get_default_uuid(i);
|
||||||
set_volume_info( drive->volume, drive, device, link, drive_type, guid );
|
set_volume_info( drive->volume, drive, device, link, drive_type, guid, NULL );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1459,7 +1495,7 @@ void set_scsi_device_name( SCSI_ADDRESS *scsi_addr, const UNICODE_STRING *dev )
|
||||||
|
|
||||||
/* create a new disk volume */
|
/* create a new disk volume */
|
||||||
NTSTATUS add_volume( const char *udi, const char *device, const char *mount_point,
|
NTSTATUS add_volume( const char *udi, const char *device, const char *mount_point,
|
||||||
enum device_type type, const GUID *guid )
|
enum device_type type, const GUID *guid, const char *disk_serial )
|
||||||
{
|
{
|
||||||
struct volume *volume;
|
struct volume *volume;
|
||||||
NTSTATUS status = STATUS_SUCCESS;
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
@ -1480,13 +1516,13 @@ NTSTATUS add_volume( const char *udi, const char *device, const char *mount_poin
|
||||||
else status = create_volume( udi, type, &volume );
|
else status = create_volume( udi, type, &volume );
|
||||||
|
|
||||||
found:
|
found:
|
||||||
if (!status) status = set_volume_info( volume, NULL, device, mount_point, type, guid );
|
if (!status) status = set_volume_info( volume, NULL, device, mount_point, type, guid, disk_serial );
|
||||||
if (volume) release_volume( volume );
|
if (volume) release_volume( volume );
|
||||||
LeaveCriticalSection( &device_section );
|
LeaveCriticalSection( &device_section );
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a new disk volume */
|
/* remove a disk volume */
|
||||||
NTSTATUS remove_volume( const char *udi )
|
NTSTATUS remove_volume( const char *udi )
|
||||||
{
|
{
|
||||||
NTSTATUS status = STATUS_NO_SUCH_DEVICE;
|
NTSTATUS status = STATUS_NO_SUCH_DEVICE;
|
||||||
|
@ -1560,7 +1596,7 @@ found:
|
||||||
p[0] = 'a' + drive->drive;
|
p[0] = 'a' + drive->drive;
|
||||||
p[2] = 0;
|
p[2] = 0;
|
||||||
update_symlink( path, mount_point, volume->device->unix_mount );
|
update_symlink( path, mount_point, volume->device->unix_mount );
|
||||||
set_volume_info( volume, drive, device, mount_point, type, guid );
|
set_volume_info( volume, drive, device, mount_point, type, guid, NULL );
|
||||||
|
|
||||||
TRACE( "added device %c: udi %s for %s on %s type %u\n",
|
TRACE( "added device %c: udi %s for %s on %s type %u\n",
|
||||||
'a' + drive->drive, wine_dbgstr_a(udi), wine_dbgstr_a(device),
|
'a' + drive->drive, wine_dbgstr_a(udi), wine_dbgstr_a(device),
|
||||||
|
@ -1713,7 +1749,7 @@ NTSTATUS query_unix_device( ULONGLONG unix_dev, enum device_type *type,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void query_property(IRP *irp)
|
static void query_property( struct disk_device *device, IRP *irp )
|
||||||
{
|
{
|
||||||
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
|
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
|
||||||
STORAGE_PROPERTY_QUERY *query = irp->AssociatedIrp.SystemBuffer;
|
STORAGE_PROPERTY_QUERY *query = irp->AssociatedIrp.SystemBuffer;
|
||||||
|
@ -1737,6 +1773,9 @@ static void query_property(IRP *irp)
|
||||||
case StorageDeviceProperty:
|
case StorageDeviceProperty:
|
||||||
{
|
{
|
||||||
STORAGE_DEVICE_DESCRIPTOR *descriptor;
|
STORAGE_DEVICE_DESCRIPTOR *descriptor;
|
||||||
|
DWORD len = sizeof(*descriptor);
|
||||||
|
|
||||||
|
if (device->serial) len += strlen( device->serial ) + 1;
|
||||||
|
|
||||||
if (!irp->UserBuffer
|
if (!irp->UserBuffer
|
||||||
|| irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DESCRIPTOR_HEADER))
|
|| irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DESCRIPTOR_HEADER))
|
||||||
|
@ -1745,7 +1784,7 @@ static void query_property(IRP *irp)
|
||||||
{
|
{
|
||||||
descriptor = irp->UserBuffer;
|
descriptor = irp->UserBuffer;
|
||||||
descriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
descriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
||||||
descriptor->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
descriptor->Size = len;
|
||||||
irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
|
irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
|
||||||
irp->IoStatus.u.Status = STATUS_SUCCESS;
|
irp->IoStatus.u.Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1756,7 +1795,7 @@ static void query_property(IRP *irp)
|
||||||
memset( irp->UserBuffer, 0, irpsp->Parameters.DeviceIoControl.OutputBufferLength );
|
memset( irp->UserBuffer, 0, irpsp->Parameters.DeviceIoControl.OutputBufferLength );
|
||||||
descriptor = irp->UserBuffer;
|
descriptor = irp->UserBuffer;
|
||||||
descriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
descriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
||||||
descriptor->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
descriptor->Size = len;
|
||||||
descriptor->DeviceType = FILE_DEVICE_DISK;
|
descriptor->DeviceType = FILE_DEVICE_DISK;
|
||||||
descriptor->DeviceTypeModifier = 0;
|
descriptor->DeviceTypeModifier = 0;
|
||||||
descriptor->RemovableMedia = FALSE;
|
descriptor->RemovableMedia = FALSE;
|
||||||
|
@ -1764,11 +1803,15 @@ static void query_property(IRP *irp)
|
||||||
descriptor->VendorIdOffset = 0;
|
descriptor->VendorIdOffset = 0;
|
||||||
descriptor->ProductIdOffset = 0;
|
descriptor->ProductIdOffset = 0;
|
||||||
descriptor->ProductRevisionOffset = 0;
|
descriptor->ProductRevisionOffset = 0;
|
||||||
descriptor->SerialNumberOffset = 0;
|
|
||||||
descriptor->BusType = BusTypeScsi;
|
descriptor->BusType = BusTypeScsi;
|
||||||
descriptor->RawPropertiesLength = 0;
|
descriptor->RawPropertiesLength = 0;
|
||||||
|
if (!device->serial) descriptor->SerialNumberOffset = 0;
|
||||||
irp->IoStatus.Information = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
else
|
||||||
|
{
|
||||||
|
descriptor->SerialNumberOffset = sizeof(*descriptor);
|
||||||
|
strcpy( (char *)descriptor + descriptor->SerialNumberOffset, device->serial );
|
||||||
|
}
|
||||||
|
irp->IoStatus.Information = len;
|
||||||
irp->IoStatus.u.Status = STATUS_SUCCESS;
|
irp->IoStatus.u.Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1854,7 +1897,7 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_STORAGE_QUERY_PROPERTY:
|
case IOCTL_STORAGE_QUERY_PROPERTY:
|
||||||
query_property( irp );
|
query_property( dev, irp );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
|
|
@ -148,7 +148,7 @@ static void appeared_callback( DADiskRef disk, void *context )
|
||||||
if ((ref = CFDictionaryGetValue( dict, CFSTR("DAMediaRemovable") )) && CFBooleanGetValue( ref ))
|
if ((ref = CFDictionaryGetValue( dict, CFSTR("DAMediaRemovable") )) && CFBooleanGetValue( ref ))
|
||||||
add_dos_device( -1, device, device, mount_point, type, guid_ptr, &devname );
|
add_dos_device( -1, device, device, mount_point, type, guid_ptr, &devname );
|
||||||
else
|
else
|
||||||
if (guid_ptr) add_volume( device, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
|
if (guid_ptr) add_volume( device, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr, NULL );
|
||||||
|
|
||||||
if ((fd = open( device, O_RDONLY )) >= 0)
|
if ((fd = open( device, O_RDONLY )) >= 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,7 @@ enum device_type
|
||||||
};
|
};
|
||||||
|
|
||||||
extern NTSTATUS add_volume( const char *udi, const char *device, const char *mount_point,
|
extern NTSTATUS add_volume( const char *udi, const char *device, const char *mount_point,
|
||||||
enum device_type type, const GUID *guid ) DECLSPEC_HIDDEN;
|
enum device_type type, const GUID *guid, const char *disk_serial ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS remove_volume( const char *udi ) DECLSPEC_HIDDEN;
|
extern NTSTATUS remove_volume( const char *udi ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
|
extern NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
|
||||||
const char *mount_point, enum device_type type, const GUID *guid,
|
const char *mount_point, enum device_type type, const GUID *guid,
|
||||||
|
|
Loading…
Reference in New Issue