Alexandre Julliard : mountmgr: Allow to specify the drive letter explicitly when creating/ removing a drive.

Alexandre Julliard julliard at winehq.org
Fri Oct 24 08:12:20 CDT 2008


Module: wine
Branch: master
Commit: b2ebab9f6fc20ec0ddee172d4d4925887aca351b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b2ebab9f6fc20ec0ddee172d4d4925887aca351b

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Oct 23 15:44:18 2008 +0200

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 3ed689f..9036654 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 90ced5e..a469ee6 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 0f21e99..e1d3da1 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 ac163db..57c7b38 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 */




More information about the wine-cvs mailing list