Alexandre Julliard : mountmgr: Add a helper function to update symlinks.

Alexandre Julliard julliard at winehq.org
Thu Jul 23 09:59:12 CDT 2009


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jul 22 17:57:08 2009 +0200

mountmgr: Add a helper function to update symlinks.

---

 dlls/mountmgr.sys/device.c |   71 ++++++++++++++++++++++++-------------------
 1 files changed, 40 insertions(+), 31 deletions(-)

diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index 682808a..e0f9705 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -148,6 +148,20 @@ static char *read_symlink( const char *path )
     }
 }
 
+/* update a symlink if it changed; return TRUE if updated */
+static void update_symlink( const char *path, const char *dest, const char *orig_dest )
+{
+    if (dest && dest[0])
+    {
+        if (!orig_dest || strcmp( orig_dest, dest ))
+        {
+            unlink( path );
+            symlink( dest, path );
+        }
+    }
+    else unlink( path );
+}
+
 /* send notification about a change to a given drive */
 static void send_notify( int drive, int code )
 {
@@ -517,42 +531,32 @@ done:
     return drive;
 }
 
-static BOOL set_unix_mount_point( struct dos_drive *drive, const char *mount_point )
+static void set_unix_mount_point( struct dos_drive *drive, const char *mount_point )
 {
     char *path, *p;
-    BOOL modified = FALSE;
     struct volume *volume = drive->volume;
     struct disk_device *device = volume->device;
 
-    if (!(path = get_dosdevices_path( &p ))) return FALSE;
+    if (!(path = get_dosdevices_path( &p ))) return;
     p[0] = 'a' + drive->drive;
     p[2] = 0;
+    update_symlink( path, mount_point, device->unix_mount );
+
+    RtlFreeHeap( GetProcessHeap(), 0, device->unix_mount );
+    device->unix_mount = strdupA( mount_point );
 
     if (mount_point && mount_point[0])
     {
-        /* try to avoid unlinking if already set correctly */
-        if (!device->unix_mount || strcmp( device->unix_mount, mount_point ))
-        {
-            unlink( path );
-            symlink( mount_point, path );
-            modified = TRUE;
-        }
-        RtlFreeHeap( GetProcessHeap(), 0, device->unix_mount );
-        device->unix_mount = strdupA( mount_point );
         if (drive->mount) set_mount_point_id( drive->mount, mount_point, strlen(mount_point) + 1 );
         if (volume->mount) set_mount_point_id( volume->mount, mount_point, strlen(mount_point) + 1 );
     }
     else
     {
-        if (unlink( path ) != -1) modified = TRUE;
-        RtlFreeHeap( GetProcessHeap(), 0, device->unix_mount );
-        device->unix_mount = NULL;
         if (drive->mount) set_mount_point_id( drive->mount, NULL, 0 );
         if (volume->mount) set_mount_point_id( volume->mount, NULL, 0 );
     }
 
     HeapFree( GetProcessHeap(), 0, path );
-    return modified;
 }
 
 /* create devices for mapped drives */
@@ -662,8 +666,7 @@ NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
 
         if (!(path = get_dosdevices_path( &p ))) return STATUS_NO_MEMORY;
         *p = 'a' + letter;
-        unlink( path );
-        if (device) symlink( device, path );
+        update_symlink( path, device, NULL );
     }
 
     LIST_FOR_EACH_ENTRY_SAFE( drive, next, &drives_list, struct dos_drive, entry )
@@ -721,31 +724,37 @@ NTSTATUS remove_dos_device( int letter, const char *udi )
 {
     HKEY hkey;
     struct dos_drive *drive;
+    char *path, *p;
 
     LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry )
     {
-        if (letter != -1 && drive->drive != letter) continue;
         if (udi)
         {
             if (!drive->volume->udi) continue;
             if (strcmp( udi, drive->volume->udi )) continue;
         }
+        else if (drive->drive != letter) continue;
 
-        if (drive->drive != -1)
+        if ((path = get_dosdevices_path( &p )))
         {
-            BOOL modified = set_unix_mount_point( drive, NULL );
-
-            /* clear the registry key too */
-            if (!RegOpenKeyW( HKEY_LOCAL_MACHINE, drives_keyW, &hkey ))
-            {
-                WCHAR name[3] = {'a',':',0};
-                name[0] += drive->drive;
-                RegDeleteValueW( hkey, name );
-                RegCloseKey( hkey );
-            }
+            p[0] = 'a' + drive->drive;
+            p[2] = 0;
+            unlink( path );
+            RtlFreeHeap( GetProcessHeap(), 0, path );
+        }
 
-            if (modified && udi) send_notify( drive->drive, DBT_DEVICEREMOVECOMPLETE );
+        /* clear the registry key too */
+        if (!RegOpenKeyW( HKEY_LOCAL_MACHINE, drives_keyW, &hkey ))
+        {
+            WCHAR name[3] = {'a',':',0};
+            name[0] += drive->drive;
+            RegDeleteValueW( hkey, name );
+            RegCloseKey( hkey );
         }
+
+        if (udi && drive->volume->device->unix_mount)
+            send_notify( drive->drive, DBT_DEVICEREMOVECOMPLETE );
+
         delete_dos_device( drive );
         return STATUS_SUCCESS;
     }




More information about the wine-cvs mailing list