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 (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 );
|
||||
|
@ -385,7 +385,7 @@ static const char *udisks2_string_from_array( DBusMessageIter *iter )
|
|||
|
||||
/* find the drive entry in the dictionary and get its parameters */
|
||||
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;
|
||||
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 );
|
||||
else if (!strcmp( name, "MediaCompatibility" ))
|
||||
*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 *type = NULL;
|
||||
const char *drive = NULL;
|
||||
const char *id = NULL;
|
||||
GUID guid, *guid_ptr = NULL;
|
||||
const char *iface, *name;
|
||||
int removable = FALSE;
|
||||
|
@ -448,7 +451,7 @@ static void udisks2_add_device( const char *udi, DBusMessageIter *dict, DBusMess
|
|||
else if (!strcmp( name, "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" ))
|
||||
{
|
||||
|
@ -483,7 +486,7 @@ static void udisks2_add_device( const char *udi, DBusMessageIter *dict, DBusMess
|
|||
if (device)
|
||||
{
|
||||
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 */
|
||||
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:
|
||||
if (type) p_libhal_free_string( type );
|
||||
|
|
|
@ -89,6 +89,7 @@ struct disk_device
|
|||
STORAGE_DEVICE_NUMBER devnum; /* device number info */
|
||||
char *unix_device; /* unix device path */
|
||||
char *unix_mount; /* unix mount point path */
|
||||
char *serial; /* disk serial number */
|
||||
};
|
||||
|
||||
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_mount );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, device->serial );
|
||||
RtlFreeUnicodeString( &device->name );
|
||||
IoDeleteDevice( device->dev_obj );
|
||||
}
|
||||
|
@ -1078,9 +1080,40 @@ static BOOL get_volume_device_info( struct volume *volume )
|
|||
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 */
|
||||
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;
|
||||
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_mount );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, disk_device->serial );
|
||||
}
|
||||
disk_device->unix_device = strdupA( device );
|
||||
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 ))
|
||||
{
|
||||
|
@ -1306,7 +1342,7 @@ static void create_drive_devices(void)
|
|||
{
|
||||
/* don't reset uuid if we used an existing volume */
|
||||
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
|
||||
{
|
||||
|
@ -1459,7 +1495,7 @@ void set_scsi_device_name( SCSI_ADDRESS *scsi_addr, const UNICODE_STRING *dev )
|
|||
|
||||
/* create a new disk volume */
|
||||
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;
|
||||
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 );
|
||||
|
||||
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 );
|
||||
LeaveCriticalSection( &device_section );
|
||||
return status;
|
||||
}
|
||||
|
||||
/* create a new disk volume */
|
||||
/* remove a disk volume */
|
||||
NTSTATUS remove_volume( const char *udi )
|
||||
{
|
||||
NTSTATUS status = STATUS_NO_SUCH_DEVICE;
|
||||
|
@ -1560,7 +1596,7 @@ found:
|
|||
p[0] = 'a' + drive->drive;
|
||||
p[2] = 0;
|
||||
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",
|
||||
'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;
|
||||
}
|
||||
|
||||
static void query_property(IRP *irp)
|
||||
static void query_property( struct disk_device *device, IRP *irp )
|
||||
{
|
||||
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
|
||||
STORAGE_PROPERTY_QUERY *query = irp->AssociatedIrp.SystemBuffer;
|
||||
|
@ -1737,6 +1773,9 @@ static void query_property(IRP *irp)
|
|||
case StorageDeviceProperty:
|
||||
{
|
||||
STORAGE_DEVICE_DESCRIPTOR *descriptor;
|
||||
DWORD len = sizeof(*descriptor);
|
||||
|
||||
if (device->serial) len += strlen( device->serial ) + 1;
|
||||
|
||||
if (!irp->UserBuffer
|
||||
|| irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DESCRIPTOR_HEADER))
|
||||
|
@ -1745,7 +1784,7 @@ static void query_property(IRP *irp)
|
|||
{
|
||||
descriptor = irp->UserBuffer;
|
||||
descriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
||||
descriptor->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
||||
descriptor->Size = len;
|
||||
irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
|
||||
irp->IoStatus.u.Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -1756,7 +1795,7 @@ static void query_property(IRP *irp)
|
|||
memset( irp->UserBuffer, 0, irpsp->Parameters.DeviceIoControl.OutputBufferLength );
|
||||
descriptor = irp->UserBuffer;
|
||||
descriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
||||
descriptor->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
||||
descriptor->Size = len;
|
||||
descriptor->DeviceType = FILE_DEVICE_DISK;
|
||||
descriptor->DeviceTypeModifier = 0;
|
||||
descriptor->RemovableMedia = FALSE;
|
||||
|
@ -1764,11 +1803,15 @@ static void query_property(IRP *irp)
|
|||
descriptor->VendorIdOffset = 0;
|
||||
descriptor->ProductIdOffset = 0;
|
||||
descriptor->ProductRevisionOffset = 0;
|
||||
descriptor->SerialNumberOffset = 0;
|
||||
descriptor->BusType = BusTypeScsi;
|
||||
descriptor->RawPropertiesLength = 0;
|
||||
|
||||
irp->IoStatus.Information = sizeof(STORAGE_DEVICE_DESCRIPTOR);
|
||||
if (!device->serial) descriptor->SerialNumberOffset = 0;
|
||||
else
|
||||
{
|
||||
descriptor->SerialNumberOffset = sizeof(*descriptor);
|
||||
strcpy( (char *)descriptor + descriptor->SerialNumberOffset, device->serial );
|
||||
}
|
||||
irp->IoStatus.Information = len;
|
||||
irp->IoStatus.u.Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1854,7 +1897,7 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
|
|||
break;
|
||||
}
|
||||
case IOCTL_STORAGE_QUERY_PROPERTY:
|
||||
query_property( irp );
|
||||
query_property( dev, irp );
|
||||
break;
|
||||
default:
|
||||
{
|
||||
|
|
|
@ -148,7 +148,7 @@ static void appeared_callback( DADiskRef disk, void *context )
|
|||
if ((ref = CFDictionaryGetValue( dict, CFSTR("DAMediaRemovable") )) && CFBooleanGetValue( ref ))
|
||||
add_dos_device( -1, device, device, mount_point, type, guid_ptr, &devname );
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -51,7 +51,7 @@ enum device_type
|
|||
};
|
||||
|
||||
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 add_dos_device( int letter, const char *udi, const char *device,
|
||||
const char *mount_point, enum device_type type, const GUID *guid,
|
||||
|
|
Loading…
Reference in New Issue