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