From b2ebab9f6fc20ec0ddee172d4d4925887aca351b Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 23 Oct 2008 15:44:18 +0200 Subject: [PATCH] mountmgr: Allow to specify the drive letter explicitly when creating/removing a drive. --- dlls/mountmgr.sys/device.c | 44 ++++++++++++++++++++++++++++++++------------ dlls/mountmgr.sys/diskarb.c | 4 ++-- dlls/mountmgr.sys/hal.c | 4 ++-- dlls/mountmgr.sys/mountmgr.h | 5 +++-- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c index 3ed689fe986..9036654832c 100644 --- a/dlls/mountmgr.sys/device.c +++ b/dlls/mountmgr.sys/device.c @@ -464,16 +464,30 @@ static void create_drive_devices(void) RtlFreeHeap( GetProcessHeap(), 0, path ); } -BOOL add_dos_device( const char *udi, const char *device, const char *mount_point, DWORD type ) +/* create a new dos drive */ +NTSTATUS add_dos_device( int letter, const char *udi, const char *device, + const char *mount_point, DWORD type ) { struct dos_drive *drive, *next; - int letter = add_drive( device, type ); - if (letter == -1) return FALSE; + if (letter == -1) /* auto-assign a letter */ + { + letter = add_drive( device, type ); + if (letter == -1) return STATUS_OBJECT_NAME_COLLISION; + } + else /* simply reset the device symlink */ + { + char *path, *p; + + if (!(path = get_dosdevices_path( &p ))) return STATUS_NO_MEMORY; + *p = 'a' + letter; + unlink( path ); + if (device) symlink( device, path ); + } LIST_FOR_EACH_ENTRY_SAFE( drive, next, &drives_list, struct dos_drive, entry ) { - if (drive->udi && !strcmp( udi, drive->udi )) + if (udi && drive->udi && !strcmp( udi, drive->udi )) { if (type == drive->type) goto found; delete_disk_device( drive ); @@ -482,7 +496,7 @@ BOOL add_dos_device( const char *udi, const char *device, const char *mount_poin if (drive->drive == letter) delete_disk_device( drive ); } - if (create_disk_device( udi, type, &drive )) return FALSE; + if (create_disk_device( udi, type, &drive )) return STATUS_NO_MEMORY; found: RtlFreeHeap( GetProcessHeap(), 0, drive->unix_device ); @@ -513,19 +527,25 @@ found: RegCloseKey( hkey ); } - send_notify( drive->drive, DBT_DEVICEARRIVAL ); + if (udi) send_notify( drive->drive, DBT_DEVICEARRIVAL ); } - return TRUE; + return STATUS_SUCCESS; } -BOOL remove_dos_device( const char *udi ) +/* remove an existing dos drive, by letter or udi */ +NTSTATUS remove_dos_device( int letter, const char *udi ) { HKEY hkey; struct dos_drive *drive; LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry ) { - if (!drive->udi || strcmp( udi, drive->udi )) continue; + if (letter != -1 && drive->drive != letter) continue; + if (udi) + { + if (!drive->udi) continue; + if (strcmp( udi, drive->udi )) continue; + } if (drive->drive != -1) { @@ -540,12 +560,12 @@ BOOL remove_dos_device( const char *udi ) RegCloseKey( hkey ); } - if (modified) send_notify( drive->drive, DBT_DEVICEREMOVECOMPLETE ); + if (modified && udi) send_notify( drive->drive, DBT_DEVICEREMOVECOMPLETE ); } delete_disk_device( drive ); - return TRUE; + return STATUS_SUCCESS; } - return FALSE; + return STATUS_NO_SUCH_DEVICE; } /* handler for ioctls on the harddisk device */ diff --git a/dlls/mountmgr.sys/diskarb.c b/dlls/mountmgr.sys/diskarb.c index 90ced5e8f2f..a469ee67ff2 100644 --- a/dlls/mountmgr.sys/diskarb.c +++ b/dlls/mountmgr.sys/diskarb.c @@ -69,7 +69,7 @@ static void appeared_callback( DADiskRef disk, void *context ) TRACE( "got mount notification for '%s' on '%s'\n", device, mount_point ); - add_dos_device( device, device, mount_point, type ); + add_dos_device( -1, device, device, mount_point, type ); done: CFRelease( dict ); } @@ -98,7 +98,7 @@ static void disappeared_callback( DADiskRef disk, void *context ) TRACE( "got unmount notification for '%s'\n", device ); - remove_dos_device( device ); + remove_dos_device( -1, device ); done: CFRelease( dict ); } diff --git a/dlls/mountmgr.sys/hal.c b/dlls/mountmgr.sys/hal.c index 0f21e99be5e..e1d3da124f2 100644 --- a/dlls/mountmgr.sys/hal.c +++ b/dlls/mountmgr.sys/hal.c @@ -135,7 +135,7 @@ static void new_device( LibHalContext *ctx, const char *udi ) if (type && !strcmp( type, "cdrom" )) drive_type = DRIVE_CDROM; else drive_type = DRIVE_REMOVABLE; /* FIXME: default to removable */ - add_dos_device( udi, device, mount_point, drive_type ); + add_dos_device( -1, udi, device, mount_point, drive_type ); /* add property watch for mount point */ p_libhal_device_add_property_watch( ctx, udi, &error ); @@ -155,7 +155,7 @@ static void removed_device( LibHalContext *ctx, const char *udi ) TRACE( "removed %s\n", wine_dbgstr_a(udi) ); - if (remove_dos_device( udi )) + if (!remove_dos_device( -1, udi )) { p_dbus_error_init( &error ); p_libhal_device_remove_property_watch( ctx, udi, &error ); diff --git a/dlls/mountmgr.sys/mountmgr.h b/dlls/mountmgr.sys/mountmgr.h index ac163db1865..57c7b38954c 100644 --- a/dlls/mountmgr.sys/mountmgr.h +++ b/dlls/mountmgr.sys/mountmgr.h @@ -39,8 +39,9 @@ extern void initialize_diskarbitration(void); /* device functions */ -extern BOOL add_dos_device( const char *udi, const char *device, const char *mount_point, DWORD type ); -extern BOOL remove_dos_device( const char *udi ); +extern NTSTATUS add_dos_device( int letter, const char *udi, const char *device, + const char *mount_point, DWORD type ); +extern NTSTATUS remove_dos_device( int letter, const char *udi ); extern NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ); /* mount point functions */ -- 2.11.4.GIT