Signed-off-by: Hans Leidekker hans@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)