mountmgr: Pass the SCSI device information when creating a volume.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-11-25 12:29:00 +01:00
parent 37b7259f07
commit 88cde9e717
4 changed files with 65 additions and 100 deletions

View File

@ -258,7 +258,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, NULL );
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr, NULL, NULL );
}
p_dbus_message_unref( reply );
@ -427,7 +427,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, id );
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr, id, NULL );
}
}

View File

@ -1362,35 +1362,8 @@ static void create_drive_devices(void)
RtlFreeHeap( GetProcessHeap(), 0, path );
}
/* open the "Logical Unit" key for a given SCSI address */
static HKEY get_scsi_device_lun_key( SCSI_ADDRESS *scsi_addr )
{
WCHAR dataW[50];
HKEY scsi_key, port_key, bus_key, target_key, lun_key;
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, scsi_keyW, 0, KEY_READ|KEY_WRITE, &scsi_key )) return NULL;
snprintfW( dataW, ARRAY_SIZE( dataW ), scsi_port_keyW, scsi_addr->PortNumber );
if (RegCreateKeyExW( scsi_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &port_key, NULL )) return NULL;
RegCloseKey( scsi_key );
snprintfW( dataW, ARRAY_SIZE( dataW ), scsi_bus_keyW, scsi_addr->PathId );
if (RegCreateKeyExW( port_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &bus_key, NULL )) return NULL;
RegCloseKey( port_key );
snprintfW( dataW, ARRAY_SIZE( dataW ), target_id_keyW, scsi_addr->TargetId );
if (RegCreateKeyExW( bus_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &target_key, NULL )) return NULL;
RegCloseKey( bus_key );
snprintfW( dataW, ARRAY_SIZE( dataW ), lun_keyW, scsi_addr->Lun );
if (RegCreateKeyExW( target_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &lun_key, NULL )) return NULL;
RegCloseKey( target_key );
return lun_key;
}
/* fill in the "Logical Unit" key for a given SCSI address */
void create_scsi_entry( SCSI_ADDRESS *scsi_addr, UINT init_id, const char *driver, UINT type, const char *model, const UNICODE_STRING *dev )
static void create_scsi_entry( struct volume *volume, const struct scsi_info *info )
{
static UCHAR tape_no = 0;
static const WCHAR tapeW[] = {'T','a','p','e','%','d',0};
@ -1412,34 +1385,34 @@ void create_scsi_entry( SCSI_ADDRESS *scsi_addr, UINT init_id, const char *drive
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, scsi_keyW, 0, KEY_READ|KEY_WRITE, &scsi_key )) return;
snprintfW( dataW, ARRAY_SIZE( dataW ), scsi_port_keyW, scsi_addr->PortNumber );
snprintfW( dataW, ARRAY_SIZE( dataW ), scsi_port_keyW, info->addr.PortNumber );
if (RegCreateKeyExW( scsi_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &port_key, NULL )) return;
RegCloseKey( scsi_key );
RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, driver, strlen(driver)+1);
RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, info->driver, strlen(info->driver)+1);
RegSetValueExW( port_key, driverW, 0, REG_SZ, (const BYTE *)dataW, sizeW );
value = 10;
RegSetValueExW( port_key, bus_time_scanW, 0, REG_DWORD, (const BYTE *)&value, sizeof(value));
value = 0;
snprintfW( dataW, ARRAY_SIZE( dataW ), scsi_bus_keyW, scsi_addr->PathId );
snprintfW( dataW, ARRAY_SIZE( dataW ), scsi_bus_keyW, info->addr.PathId );
if (RegCreateKeyExW( port_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &bus_key, NULL )) return;
RegCloseKey( port_key );
snprintfW( dataW, ARRAY_SIZE( dataW ), init_id_keyW, init_id );
snprintfW( dataW, ARRAY_SIZE( dataW ), init_id_keyW, info->init_id );
if (RegCreateKeyExW( bus_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &target_key, NULL )) return;
RegCloseKey( target_key );
snprintfW( dataW, ARRAY_SIZE( dataW ), target_id_keyW, scsi_addr->TargetId );
snprintfW( dataW, ARRAY_SIZE( dataW ), target_id_keyW, info->addr.TargetId );
if (RegCreateKeyExW( bus_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &target_key, NULL )) return;
RegCloseKey( bus_key );
snprintfW( dataW, ARRAY_SIZE( dataW ), lun_keyW, scsi_addr->Lun );
snprintfW( dataW, ARRAY_SIZE( dataW ), lun_keyW, info->addr.Lun );
if (RegCreateKeyExW( target_key, dataW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &lun_key, NULL )) return;
RegCloseKey( target_key );
switch (type)
switch (info->type)
{
case SCSI_DISK_PERIPHERAL: data = "DiskPeripheral"; break;
case SCSI_TAPE_PERIPHERAL: data = "TapePeripheral"; break;
@ -1466,16 +1439,17 @@ void create_scsi_entry( SCSI_ADDRESS *scsi_addr, UINT init_id, const char *drive
RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, data, strlen(data)+1);
RegSetValueExW( lun_key, typeW, 0, REG_SZ, (const BYTE *)dataW, sizeW );
RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, model, strlen(model)+1);
RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, info->model, strlen(info->model)+1);
RegSetValueExW( lun_key, identW, 0, REG_SZ, (const BYTE *)dataW, sizeW );
if (dev)
if (volume)
{
UNICODE_STRING *dev = &volume->device->name;
WCHAR *buffer = memchrW( dev->Buffer+1, '\\', dev->Length )+1;
ULONG length = dev->Length - (buffer - dev->Buffer)*sizeof(WCHAR);
RegSetValueExW( lun_key, devnameW, 0, REG_SZ, (const BYTE *)buffer, length );
}
else if (type == SCSI_TAPE_PERIPHERAL)
else if (info->type == SCSI_TAPE_PERIPHERAL)
{
snprintfW( dataW, ARRAY_SIZE( dataW ), tapeW, tape_no++ );
RegSetValueExW( lun_key, devnameW, 0, REG_SZ, (const BYTE *)dataW, strlenW( dataW ) );
@ -1484,25 +1458,10 @@ void create_scsi_entry( SCSI_ADDRESS *scsi_addr, UINT init_id, const char *drive
RegCloseKey( lun_key );
}
/* set the "DeviceName" for a given SCSI address */
void set_scsi_device_name( SCSI_ADDRESS *scsi_addr, const UNICODE_STRING *dev )
{
HKEY lun_key;
WCHAR *buffer;
ULONG length;
lun_key = get_scsi_device_lun_key( scsi_addr );
buffer = memchrW( dev->Buffer+1, '\\', dev->Length )+1;
length = dev->Length - (buffer - dev->Buffer)*sizeof(WCHAR);
RegSetValueExW( lun_key, devnameW, 0, REG_SZ, (const BYTE *)buffer, length );
RegCloseKey( lun_key );
}
/* 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, const char *disk_serial )
enum device_type type, const GUID *guid, const char *disk_serial,
const struct scsi_info *scsi_info )
{
struct volume *volume;
NTSTATUS status = STATUS_SUCCESS;
@ -1524,6 +1483,7 @@ NTSTATUS add_volume( const char *udi, const char *device, const char *mount_poin
found:
if (!status) status = set_volume_info( volume, NULL, device, mount_point, type, guid, disk_serial );
if (!status && scsi_info) create_scsi_entry( volume, scsi_info );
if (volume) release_volume( volume );
LeaveCriticalSection( &device_section );
return status;
@ -1551,7 +1511,7 @@ NTSTATUS remove_volume( const char *udi )
/* create a new dos drive */
NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
const char *mount_point, enum device_type type, const GUID *guid,
UNICODE_STRING *devname )
const struct scsi_info *scsi_info )
{
char *path, *p;
HKEY hkey;
@ -1626,8 +1586,7 @@ found:
}
if (udi) notify = drive->drive;
if (devname) *devname = volume->device->name;
if (scsi_info) create_scsi_entry( volume, scsi_info );
done:
if (volume) release_volume( volume );

View File

@ -65,13 +65,11 @@ static void appeared_callback( DADiskRef disk, void *context )
const void *ref;
char device[64];
char mount_point[PATH_MAX];
char model[64];
size_t model_len = 0;
GUID guid, *guid_ptr = NULL;
enum device_type type = DEVICE_UNKNOWN;
UINT pdtype = 0;
SCSI_ADDRESS scsi_addr;
UNICODE_STRING devname;
struct scsi_info scsi_info = { 0 };
BOOL removable = FALSE;
int fd;
if (!dict) return;
@ -98,13 +96,13 @@ static void appeared_callback( DADiskRef disk, void *context )
if (!CFStringCompare( ref, CFSTR("IOCDMedia"), 0 ))
{
type = DEVICE_CDROM;
pdtype = 5;
scsi_info.type = 5;
}
if (!CFStringCompare( ref, CFSTR("IODVDMedia"), 0 ) ||
!CFStringCompare( ref, CFSTR("IOBDMedia"), 0 ))
{
type = DEVICE_DVD;
pdtype = 5;
scsi_info.type = 5;
}
if (!CFStringCompare( ref, CFSTR("IOMedia"), 0 ))
type = DEVICE_HARDDISK;
@ -114,41 +112,38 @@ static void appeared_callback( DADiskRef disk, void *context )
{
CFIndex i;
CFStringGetCString( ref, model, sizeof(model), kCFStringEncodingASCII );
CFStringGetCString( ref, scsi_info.model, sizeof(scsi_info.model), kCFStringEncodingASCII );
model_len += CFStringGetLength( ref );
/* Pad to 8 characters */
for (i = 0; i < (CFIndex)8 - CFStringGetLength( ref ); ++i)
model[model_len++] = ' ';
scsi_info.model[model_len++] = ' ';
}
if ((ref = CFDictionaryGetValue( dict, CFSTR("DADeviceModel") )))
{
CFIndex i;
CFStringGetCString( ref, model+model_len, sizeof(model)-model_len, kCFStringEncodingASCII );
CFStringGetCString( ref, scsi_info.model+model_len, sizeof(scsi_info.model)-model_len, kCFStringEncodingASCII );
model_len += CFStringGetLength( ref );
/* Pad to 16 characters */
for (i = 0; i < (CFIndex)16 - CFStringGetLength( ref ); ++i)
model[model_len++] = ' ';
scsi_info.model[model_len++] = ' ';
}
if ((ref = CFDictionaryGetValue( dict, CFSTR("DADeviceRevision") )))
{
CFIndex i;
CFStringGetCString( ref, model+model_len, sizeof(model)-model_len, kCFStringEncodingASCII );
CFStringGetCString( ref, scsi_info.model+model_len, sizeof(scsi_info.model)-model_len, kCFStringEncodingASCII );
model_len += CFStringGetLength( ref );
/* Pad to 4 characters */
for (i = 0; i < (CFIndex)4 - CFStringGetLength( ref ); ++i)
model[model_len++] = ' ';
scsi_info.model[model_len++] = ' ';
}
TRACE( "got mount notification for '%s' on '%s' uuid %s\n",
device, mount_point, wine_dbgstr_guid(guid_ptr) );
devname.Buffer = NULL;
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, NULL );
if ((ref = CFDictionaryGetValue( dict, CFSTR("DAMediaRemovable") )))
removable = CFBooleanGetValue( ref );
if (!access( device, R_OK ) &&
(fd = open( device, O_RDONLY )) >= 0)
@ -157,18 +152,21 @@ static void appeared_callback( DADiskRef disk, void *context )
if (ioctl( fd, DKIOCSCSIIDENTIFY, &dsi ) >= 0)
{
scsi_addr.PortNumber = dsi.bus;
scsi_addr.PathId = dsi.port;
scsi_addr.TargetId = dsi.target;
scsi_addr.Lun = dsi.lun;
/* FIXME: get real controller Id for SCSI */
/* FIXME: get real driver name */
create_scsi_entry( &scsi_addr, 255, "WINE SCSI", pdtype, model, &devname );
scsi_info.addr.PortNumber = dsi.bus;
scsi_info.addr.PathId = dsi.port;
scsi_info.addr.TargetId = dsi.target;
scsi_info.addr.Lun = dsi.lun;
scsi_info.init_id = 255; /* FIXME */
strcpy( scsi_info.driver, "WINE SCSI" ); /* FIXME */
}
close( fd );
}
if (removable)
add_dos_device( -1, device, device, mount_point, type, guid_ptr, &scsi_info );
else
if (guid_ptr) add_volume( device, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr, NULL, &scsi_info );
done:
CFRelease( dict );
}

View File

@ -18,6 +18,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_MOUNTMGR_H
#define __WINE_MOUNTMGR_H
#include <stdarg.h>
#include "ntstatus.h"
@ -52,21 +55,10 @@ enum device_type
DEVICE_RAMDISK
};
extern NTSTATUS add_volume( const char *udi, const char *device, const char *mount_point,
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,
UNICODE_STRING *devname ) DECLSPEC_HIDDEN;
extern NTSTATUS remove_dos_device( int letter, const char *udi ) DECLSPEC_HIDDEN;
extern NTSTATUS query_unix_drive( void *buff, SIZE_T insize, SIZE_T outsize,
IO_STATUS_BLOCK *iosb ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI serial_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI parallel_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) DECLSPEC_HIDDEN;
/* SCSI entry functions */
enum scsi_device_type
{
SCSI_DISK_PERIPHERAL = 0x00,
@ -92,10 +84,25 @@ enum scsi_device_type
SCSI_UNKNOWN_PERIPHERAL = ~0
};
extern void create_scsi_entry( SCSI_ADDRESS *scsi_addr, UINT init_id,
const char *driver, UINT type, const char *drive,
const UNICODE_STRING *devname ) DECLSPEC_HIDDEN;
extern void set_scsi_device_name( SCSI_ADDRESS *scsi_addr, const UNICODE_STRING *devname ) DECLSPEC_HIDDEN;
struct scsi_info
{
enum scsi_device_type type;
SCSI_ADDRESS addr;
UINT init_id;
char driver[64];
char model[64];
};
extern NTSTATUS add_volume( const char *udi, const char *device, const char *mount_point,
enum device_type type, const GUID *guid, const char *disk_serial,
const struct scsi_info *info ) 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,
const struct scsi_info *info ) DECLSPEC_HIDDEN;
extern NTSTATUS remove_dos_device( int letter, const char *udi ) DECLSPEC_HIDDEN;
extern NTSTATUS query_unix_drive( void *buff, SIZE_T insize, SIZE_T outsize,
IO_STATUS_BLOCK *iosb ) DECLSPEC_HIDDEN;
/* mount point functions */
@ -110,3 +117,4 @@ extern void set_mount_point_id( struct mount_point *mount, const void *id, unsig
extern ULONG get_dhcp_request_param( const char *unix_name, struct mountmgr_dhcp_request_param *param,
char *buf, ULONG offset, ULONG size ) DECLSPEC_HIDDEN;
#endif /* __WINE_MOUNTMGR_H */