Alexandre Julliard : mountmgr: Add support for creating volumes without an associated drive.

Alexandre Julliard julliard at winehq.org
Wed Jul 22 09:33:23 CDT 2009


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Jul 21 20:30:43 2009 +0200

mountmgr: Add support for creating volumes without an associated drive.

---

 dlls/mountmgr.sys/device.c   |   91 ++++++++++++++++++++++++++++++++++++++++++
 dlls/mountmgr.sys/mountmgr.h |    3 +
 2 files changed, 94 insertions(+), 0 deletions(-)

diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index 56c6446..efbbb33 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -84,6 +84,7 @@ struct dos_drive
 };
 
 static struct list drives_list = LIST_INIT(drives_list);
+static struct list volumes_list = LIST_INIT(volumes_list);
 
 static DRIVER_OBJECT *harddisk_driver;
 
@@ -300,6 +301,7 @@ static NTSTATUS create_volume( const char *udi, enum device_type type, struct vo
     }
     if (!(status = create_disk_device( type, &volume->device )))
     {
+        list_add_tail( &volumes_list, &volume->entry );
         *volume_ret = volume;
     }
     else
@@ -313,6 +315,7 @@ static NTSTATUS create_volume( const char *udi, enum device_type type, struct vo
 /* delete a volume and the corresponding disk device */
 static void delete_volume( struct volume *volume )
 {
+    list_remove( &volume->entry );
     if (volume->mount) delete_mount_point( volume->mount );
     delete_disk_device( volume->device );
     RtlFreeHeap( GetProcessHeap(), 0, volume->udi );
@@ -348,6 +351,60 @@ static void delete_dos_device( struct dos_drive *drive )
     RtlFreeHeap( GetProcessHeap(), 0, drive );
 }
 
+/* change the information for an existing volume */
+static NTSTATUS set_volume_info( struct volume *volume, const char *device, const char *mount_point,
+                                 enum device_type type, const GUID *guid )
+{
+    struct disk_device *disk_device = volume->device;
+    NTSTATUS status;
+
+    if (type != disk_device->type)
+    {
+        if ((status = create_disk_device( type, &disk_device ))) return status;
+        if (volume->mount)
+        {
+            delete_mount_point( volume->mount );
+            volume->mount = NULL;
+        }
+        delete_disk_device( volume->device );
+        volume->device = disk_device;
+    }
+    else
+    {
+        RtlFreeHeap( GetProcessHeap(), 0, disk_device->unix_device );
+        RtlFreeHeap( GetProcessHeap(), 0, disk_device->unix_mount );
+    }
+    disk_device->unix_device = strdupA( device );
+    disk_device->unix_mount = strdupA( mount_point );
+
+    if (memcmp( &volume->guid, guid, sizeof(volume->guid) ))
+    {
+        volume->guid = *guid;
+        if (volume->mount)
+        {
+            delete_mount_point( volume->mount );
+            volume->mount = NULL;
+        }
+    }
+
+    if (!volume->mount)
+        volume->mount = add_volume_mount_point( disk_device->dev_obj, &disk_device->name, &volume->guid );
+
+    if (volume->mount)
+    {
+        void *id = NULL;
+        unsigned int id_len = 0;
+
+        if (disk_device->unix_mount)
+        {
+            id = disk_device->unix_mount;
+            id_len = strlen( disk_device->unix_mount ) + 1;
+        }
+        set_mount_point_id( volume->mount, id, id_len );
+    }
+    return STATUS_SUCCESS;
+}
+
 /* set or change the drive letter for an existing drive */
 static void set_drive_letter( struct dos_drive *drive, int letter )
 {
@@ -551,6 +608,40 @@ static void create_drive_devices(void)
     RtlFreeHeap( GetProcessHeap(), 0, path );
 }
 
+/* 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 )
+{
+    struct volume *volume;
+    NTSTATUS status;
+
+    TRACE( "adding %s device %s mount %s type %u uuid %s\n", debugstr_a(udi),
+           debugstr_a(device), debugstr_a(mount_point), type, debugstr_guid(guid) );
+
+    LIST_FOR_EACH_ENTRY( volume, &volumes_list, struct volume, entry )
+        if (volume->udi && !strcmp( udi, volume->udi )) goto found;
+
+    if ((status = create_volume( udi, type, &volume ))) return status;
+
+found:
+    return set_volume_info( volume, device, mount_point, type, guid );
+}
+
+/* create a new disk volume */
+NTSTATUS remove_volume( const char *udi )
+{
+    struct volume *volume;
+
+    LIST_FOR_EACH_ENTRY( volume, &volumes_list, struct volume, entry )
+    {
+        if (!volume->udi || strcmp( udi, volume->udi )) continue;
+        delete_volume( volume );
+        return STATUS_SUCCESS;
+    }
+    return STATUS_NO_SUCH_DEVICE;
+}
+
+
 /* create a new dos drive */
 NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
                          const char *mount_point, enum device_type type, const GUID *guid )
diff --git a/dlls/mountmgr.sys/mountmgr.h b/dlls/mountmgr.sys/mountmgr.h
index d61bb7d..0ba1086 100644
--- a/dlls/mountmgr.sys/mountmgr.h
+++ b/dlls/mountmgr.sys/mountmgr.h
@@ -51,6 +51,9 @@ enum device_type
     DEVICE_RAMDISK
 };
 
+extern NTSTATUS add_volume( const char *udi, const char *device, const char *mount_point,
+                            enum device_type type, const GUID *guid );
+extern NTSTATUS remove_volume( const char *udi );
 extern NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
                                 const char *mount_point, enum device_type type, const GUID *guid );
 extern NTSTATUS remove_dos_device( int letter, const char *udi );




More information about the wine-cvs mailing list