[PATCH 1/3] mountmgr: Return the disk serial from IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE.
Hans Leidekker
hans at codeweavers.com
Mon May 18 02:49:39 CDT 2020
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/mountmgr.sys/dbus.c | 13 +++++----
dlls/mountmgr.sys/device.c | 55 ++++++++++++++++++++++++++++++------
dlls/mountmgr.sys/mountmgr.c | 17 +++++++++--
dlls/mountmgr.sys/mountmgr.h | 6 ++--
include/ddk/mountmgr.h | 1 +
5 files changed, 73 insertions(+), 19 deletions(-)
diff --git a/dlls/mountmgr.sys/dbus.c b/dlls/mountmgr.sys/dbus.c
index 27b35acd9ca..98b2a47ba6d 100644
--- a/dlls/mountmgr.sys/dbus.c
+++ b/dlls/mountmgr.sys/dbus.c
@@ -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 );
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index a6794fa6ac4..babdaa3e884 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -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->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 );
+ if (disk_device->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),
@@ -1656,7 +1692,8 @@ enum mountmgr_fs_type get_mountmgr_fs_type(enum fs_type fs_type)
/* query information about an existing dos drive, by letter or udi */
NTSTATUS query_dos_device( int letter, enum device_type *type, enum mountmgr_fs_type *fs_type,
- DWORD *serial, char **device, char **mount_point, WCHAR **label )
+ DWORD *serial, char **device, char **mount_point, WCHAR **label,
+ char **disk_serial )
{
NTSTATUS status = STATUS_NO_SUCH_DEVICE;
struct dos_drive *drive;
@@ -1673,6 +1710,7 @@ NTSTATUS query_dos_device( int letter, enum device_type *type, enum mountmgr_fs_
if (device) *device = strdupA( disk_device->unix_device );
if (mount_point) *mount_point = strdupA( disk_device->unix_mount );
if (label) *label = strdupW( drive->volume->label );
+ if (disk_serial) *disk_serial = strdupA( disk_device->serial );
status = STATUS_SUCCESS;
break;
}
@@ -1683,7 +1721,7 @@ NTSTATUS query_dos_device( int letter, enum device_type *type, enum mountmgr_fs_
/* query information about an existing unix device, by dev_t */
NTSTATUS query_unix_device( ULONGLONG unix_dev, enum device_type *type,
enum mountmgr_fs_type *fs_type, DWORD *serial, char **device,
- char **mount_point, WCHAR **label )
+ char **mount_point, WCHAR **label, char **disk_serial )
{
NTSTATUS status = STATUS_NO_SUCH_DEVICE;
struct volume *volume;
@@ -1706,6 +1744,7 @@ NTSTATUS query_unix_device( ULONGLONG unix_dev, enum device_type *type,
if (device) *device = strdupA( disk_device->unix_device );
if (mount_point) *mount_point = strdupA( disk_device->unix_mount );
if (label) *label = strdupW( volume->label );
+ if (disk_serial) *disk_serial = strdupA( disk_device->serial );
status = STATUS_SUCCESS;
break;
}
diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c
index cf12f03a73b..bd967793057 100644
--- a/dlls/mountmgr.sys/mountmgr.c
+++ b/dlls/mountmgr.sys/mountmgr.c
@@ -291,7 +291,7 @@ static NTSTATUS query_unix_drive( void *buff, SIZE_T insize,
{
const struct mountmgr_unix_drive *input = buff;
struct mountmgr_unix_drive *output = NULL;
- char *device, *mount_point;
+ char *device, *mount_point, *disk_serial;
int letter = tolowerW( input->letter );
NTSTATUS status;
DWORD size, type = DEVICE_UNKNOWN, serial;
@@ -303,7 +303,7 @@ static NTSTATUS query_unix_drive( void *buff, SIZE_T insize,
if (!letter)
{
if ((status = query_unix_device( input->unix_dev, &device_type, &fs_type,
- &serial, &device, &mount_point, &label )))
+ &serial, &device, &mount_point, &label, &disk_serial )))
return status;
}
else
@@ -311,7 +311,7 @@ static NTSTATUS query_unix_drive( void *buff, SIZE_T insize,
if (letter < 'a' || letter > 'z') return STATUS_INVALID_PARAMETER;
if ((status = query_dos_device( letter - 'a', &device_type, &fs_type, &serial, &device,
- &mount_point, &label )))
+ &mount_point, &label, &disk_serial )))
return status;
}
@@ -330,6 +330,7 @@ static NTSTATUS query_unix_drive( void *buff, SIZE_T insize,
size = sizeof(*output);
if (device) size += strlen(device) + 1;
if (mount_point) size += strlen(mount_point) + 1;
+ if (disk_serial) size += strlen(disk_serial) + 1;
input = NULL;
output = buff;
@@ -341,6 +342,7 @@ static NTSTATUS query_unix_drive( void *buff, SIZE_T insize,
output->mount_point_offset = 0;
output->device_offset = 0;
output->label_offset = 0;
+ output->disk_serial_offset = 0;
if (size > outsize)
{
@@ -385,6 +387,14 @@ static NTSTATUS query_unix_drive( void *buff, SIZE_T insize,
}
else output->label_offset = 0;
+ if (disk_serial)
+ {
+ output->disk_serial_offset = ptr - (char *)output;
+ strcpy( ptr, disk_serial );
+ ptr += strlen(disk_serial) + 1;
+ }
+ else output->disk_serial_offset = 0;
+
TRACE( "returning %c: dev %s mount %s type %u\n",
letter, debugstr_a(device), debugstr_a(mount_point), type );
@@ -393,6 +403,7 @@ done:
RtlFreeHeap( GetProcessHeap(), 0, device );
RtlFreeHeap( GetProcessHeap(), 0, mount_point );
RtlFreeHeap( GetProcessHeap(), 0, label );
+ RtlFreeHeap( GetProcessHeap(), 0, disk_serial );
return status;
}
diff --git a/dlls/mountmgr.sys/mountmgr.h b/dlls/mountmgr.sys/mountmgr.h
index 82d783a7a04..6462d8719c6 100644
--- a/dlls/mountmgr.sys/mountmgr.h
+++ b/dlls/mountmgr.sys/mountmgr.h
@@ -51,17 +51,17 @@ 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,
UNICODE_STRING *devname ) DECLSPEC_HIDDEN;
extern NTSTATUS remove_dos_device( int letter, const char *udi ) DECLSPEC_HIDDEN;
extern NTSTATUS query_dos_device( int letter, enum device_type *type, enum mountmgr_fs_type *fs_type, DWORD *serial,
- char **device, char **mount_point, WCHAR **label ) DECLSPEC_HIDDEN;
+ char **device, char **mount_point, WCHAR **label, char **disk_serial ) DECLSPEC_HIDDEN;
extern NTSTATUS query_unix_device( ULONGLONG unix_dev, enum device_type *type,
DWORD *serial, enum mountmgr_fs_type *fs_type, char **device,
- char **mount_point, WCHAR **label ) DECLSPEC_HIDDEN;
+ char **mount_point, WCHAR **label, char **disk_serial ) 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;
diff --git a/include/ddk/mountmgr.h b/include/ddk/mountmgr.h
index 13829a53954..aa1e7eaee80 100644
--- a/include/ddk/mountmgr.h
+++ b/include/ddk/mountmgr.h
@@ -72,6 +72,7 @@ struct mountmgr_unix_drive
USHORT mount_point_offset;
USHORT device_offset;
USHORT label_offset;
+ USHORT disk_serial_offset;
};
#define IOCTL_MOUNTMGR_QUERY_DHCP_REQUEST_PARAMS CTL_CODE(MOUNTMGRCONTROLTYPE, 64, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
--
2.20.1
More information about the wine-devel
mailing list