Commit bc8dce20 authored by Alexandre Julliard's avatar Alexandre Julliard

mountmgr: Create a separate structure for volume information.

parent 8fb8b2e6
...@@ -66,14 +66,20 @@ struct disk_device ...@@ -66,14 +66,20 @@ struct disk_device
char *unix_mount; /* unix mount point path */ char *unix_mount; /* unix mount point path */
}; };
struct volume
{
struct list entry; /* entry in volumes list */
struct disk_device *device; /* disk device */
char *udi; /* unique identifier for dynamic volumes */
struct mount_point *mount; /* Volume{xxx} mount point */
};
struct dos_drive struct dos_drive
{ {
struct list entry; /* entry in drives list */ struct list entry; /* entry in drives list */
struct disk_device *device; /* disk device */ struct volume *volume; /* volume for this drive */
char *udi; /* unique identifier for dynamic drives */
int drive; /* drive letter (0 = A: etc.) */ int drive; /* drive letter (0 = A: etc.) */
struct mount_point *dosdev; /* DosDevices mount point */ struct mount_point *dosdev; /* DosDevices mount point */
struct mount_point *volume; /* Volume{xxx} mount point */
}; };
static struct list drives_list = LIST_INIT(drives_list); static struct list drives_list = LIST_INIT(drives_list);
...@@ -269,6 +275,41 @@ static void delete_disk_device( struct disk_device *device ) ...@@ -269,6 +275,41 @@ static void delete_disk_device( struct disk_device *device )
IoDeleteDevice( device->dev_obj ); IoDeleteDevice( device->dev_obj );
} }
/* create a disk volume */
static NTSTATUS create_volume( const char *udi, enum device_type type, struct volume **volume_ret )
{
struct volume *volume;
NTSTATUS status;
if (!(volume = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*volume) )))
return STATUS_NO_MEMORY;
if (udi && !(volume->udi = strdupA( udi )))
{
RtlFreeHeap( GetProcessHeap(), 0, volume );
return STATUS_NO_MEMORY;
}
if (!(status = create_disk_device( type, &volume->device )))
{
*volume_ret = volume;
}
else
{
RtlFreeHeap( GetProcessHeap(), 0, volume->udi );
RtlFreeHeap( GetProcessHeap(), 0, volume );
}
return status;
}
/* delete a volume and the corresponding disk device */
static void delete_volume( struct volume *volume )
{
if (volume->mount) delete_mount_point( volume->mount );
delete_disk_device( volume->device );
RtlFreeHeap( GetProcessHeap(), 0, volume->udi );
RtlFreeHeap( GetProcessHeap(), 0, volume );
}
/* create the disk device for a given volume */ /* create the disk device for a given volume */
static NTSTATUS create_dos_device( const char *udi, enum device_type type, struct dos_drive **drive_ret ) static NTSTATUS create_dos_device( const char *udi, enum device_type type, struct dos_drive **drive_ret )
{ {
...@@ -278,25 +319,14 @@ static NTSTATUS create_dos_device( const char *udi, enum device_type type, struc ...@@ -278,25 +319,14 @@ static NTSTATUS create_dos_device( const char *udi, enum device_type type, struc
if (!(drive = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*drive) ))) return STATUS_NO_MEMORY; if (!(drive = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*drive) ))) return STATUS_NO_MEMORY;
drive->drive = -1; drive->drive = -1;
drive->dosdev = NULL; drive->dosdev = NULL;
drive->volume = NULL;
drive->udi = strdupA( udi );
if (udi && !drive->udi) if (!(status = create_volume( udi, type, &drive->volume )))
{
RtlFreeHeap( GetProcessHeap(), 0, drive );
return STATUS_NO_MEMORY;
}
if (!(status = create_disk_device( type, &drive->device )))
{ {
list_add_tail( &drives_list, &drive->entry ); list_add_tail( &drives_list, &drive->entry );
*drive_ret = drive; *drive_ret = drive;
} }
else else RtlFreeHeap( GetProcessHeap(), 0, drive );
{
RtlFreeHeap( GetProcessHeap(), 0, drive->udi );
RtlFreeHeap( GetProcessHeap(), 0, drive );
}
return status; return status;
} }
...@@ -305,9 +335,7 @@ static void delete_dos_device( struct dos_drive *drive ) ...@@ -305,9 +335,7 @@ static void delete_dos_device( struct dos_drive *drive )
{ {
list_remove( &drive->entry ); list_remove( &drive->entry );
if (drive->dosdev) delete_mount_point( drive->dosdev ); if (drive->dosdev) delete_mount_point( drive->dosdev );
if (drive->volume) delete_mount_point( drive->volume ); delete_volume( drive->volume );
delete_disk_device( drive->device );
RtlFreeHeap( GetProcessHeap(), 0, drive->udi );
RtlFreeHeap( GetProcessHeap(), 0, drive ); RtlFreeHeap( GetProcessHeap(), 0, drive );
} }
...@@ -316,11 +344,12 @@ static void set_drive_letter( struct dos_drive *drive, int letter ) ...@@ -316,11 +344,12 @@ static void set_drive_letter( struct dos_drive *drive, int letter )
{ {
void *id = NULL; void *id = NULL;
unsigned int id_len = 0; unsigned int id_len = 0;
struct disk_device *device = drive->device; struct volume *volume = drive->volume;
struct disk_device *device = volume->device;
if (drive->drive == letter) return; if (drive->drive == letter) return;
if (drive->dosdev) delete_mount_point( drive->dosdev ); if (drive->dosdev) delete_mount_point( drive->dosdev );
if (drive->volume) delete_mount_point( drive->volume ); if (volume->mount) delete_mount_point( volume->mount );
drive->drive = letter; drive->drive = letter;
if (letter == -1) return; if (letter == -1) return;
if (device->unix_mount) if (device->unix_mount)
...@@ -329,7 +358,7 @@ static void set_drive_letter( struct dos_drive *drive, int letter ) ...@@ -329,7 +358,7 @@ static void set_drive_letter( struct dos_drive *drive, int letter )
id_len = strlen( device->unix_mount ) + 1; id_len = strlen( device->unix_mount ) + 1;
} }
drive->dosdev = add_dosdev_mount_point( device->dev_obj, &device->name, letter, id, id_len ); drive->dosdev = add_dosdev_mount_point( device->dev_obj, &device->name, letter, id, id_len );
drive->volume = add_volume_mount_point( device->dev_obj, &device->name, letter, id, id_len ); volume->mount = add_volume_mount_point( device->dev_obj, &device->name, letter, id, id_len );
} }
static inline int is_valid_device( struct stat *st ) static inline int is_valid_device( struct stat *st )
...@@ -420,7 +449,8 @@ static BOOL set_unix_mount_point( struct dos_drive *drive, const char *mount_poi ...@@ -420,7 +449,8 @@ static BOOL set_unix_mount_point( struct dos_drive *drive, const char *mount_poi
{ {
char *path, *p; char *path, *p;
BOOL modified = FALSE; BOOL modified = FALSE;
struct disk_device *device = drive->device; 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 FALSE;
p[0] = 'a' + drive->drive; p[0] = 'a' + drive->drive;
...@@ -438,7 +468,7 @@ static BOOL set_unix_mount_point( struct dos_drive *drive, const char *mount_poi ...@@ -438,7 +468,7 @@ static BOOL set_unix_mount_point( struct dos_drive *drive, const char *mount_poi
RtlFreeHeap( GetProcessHeap(), 0, device->unix_mount ); RtlFreeHeap( GetProcessHeap(), 0, device->unix_mount );
device->unix_mount = strdupA( mount_point ); device->unix_mount = strdupA( mount_point );
if (drive->dosdev) set_mount_point_id( drive->dosdev, mount_point, strlen(mount_point) + 1 ); if (drive->dosdev) set_mount_point_id( drive->dosdev, mount_point, strlen(mount_point) + 1 );
if (drive->volume) set_mount_point_id( drive->volume, mount_point, strlen(mount_point) + 1 ); if (volume->mount) set_mount_point_id( volume->mount, mount_point, strlen(mount_point) + 1 );
} }
else else
{ {
...@@ -446,7 +476,7 @@ static BOOL set_unix_mount_point( struct dos_drive *drive, const char *mount_poi ...@@ -446,7 +476,7 @@ static BOOL set_unix_mount_point( struct dos_drive *drive, const char *mount_poi
RtlFreeHeap( GetProcessHeap(), 0, device->unix_mount ); RtlFreeHeap( GetProcessHeap(), 0, device->unix_mount );
device->unix_mount = NULL; device->unix_mount = NULL;
if (drive->dosdev) set_mount_point_id( drive->dosdev, NULL, 0 ); if (drive->dosdev) set_mount_point_id( drive->dosdev, NULL, 0 );
if (drive->volume) set_mount_point_id( drive->volume, NULL, 0 ); if (volume->mount) set_mount_point_id( volume->mount, NULL, 0 );
} }
HeapFree( GetProcessHeap(), 0, path ); HeapFree( GetProcessHeap(), 0, path );
...@@ -496,8 +526,8 @@ static void create_drive_devices(void) ...@@ -496,8 +526,8 @@ static void create_drive_devices(void)
if (!create_dos_device( NULL, drive_type, &drive )) if (!create_dos_device( NULL, drive_type, &drive ))
{ {
drive->device->unix_mount = link; drive->volume->device->unix_mount = link;
drive->device->unix_device = device; drive->volume->device->unix_device = device;
set_drive_letter( drive, i ); set_drive_letter( drive, i );
} }
else else
...@@ -533,9 +563,9 @@ NTSTATUS add_dos_device( int letter, const char *udi, const char *device, ...@@ -533,9 +563,9 @@ NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
LIST_FOR_EACH_ENTRY_SAFE( drive, next, &drives_list, struct dos_drive, entry ) LIST_FOR_EACH_ENTRY_SAFE( drive, next, &drives_list, struct dos_drive, entry )
{ {
if (udi && drive->udi && !strcmp( udi, drive->udi )) if (udi && drive->volume->udi && !strcmp( udi, drive->volume->udi ))
{ {
if (type == drive->device->type) goto found; if (type == drive->volume->device->type) goto found;
delete_dos_device( drive ); delete_dos_device( drive );
continue; continue;
} }
...@@ -545,8 +575,8 @@ NTSTATUS add_dos_device( int letter, const char *udi, const char *device, ...@@ -545,8 +575,8 @@ NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
if (create_dos_device( udi, type, &drive )) return STATUS_NO_MEMORY; if (create_dos_device( udi, type, &drive )) return STATUS_NO_MEMORY;
found: found:
RtlFreeHeap( GetProcessHeap(), 0, drive->device->unix_device ); RtlFreeHeap( GetProcessHeap(), 0, drive->volume->device->unix_device );
drive->device->unix_device = strdupA( device ); drive->volume->device->unix_device = strdupA( device );
set_drive_letter( drive, letter ); set_drive_letter( drive, letter );
set_unix_mount_point( drive, mount_point ); set_unix_mount_point( drive, mount_point );
...@@ -590,8 +620,8 @@ NTSTATUS remove_dos_device( int letter, const char *udi ) ...@@ -590,8 +620,8 @@ NTSTATUS remove_dos_device( int letter, const char *udi )
if (letter != -1 && drive->drive != letter) continue; if (letter != -1 && drive->drive != letter) continue;
if (udi) if (udi)
{ {
if (!drive->udi) continue; if (!drive->volume->udi) continue;
if (strcmp( udi, drive->udi )) continue; if (strcmp( udi, drive->volume->udi )) continue;
} }
if (drive->drive != -1) if (drive->drive != -1)
...@@ -625,7 +655,7 @@ NTSTATUS query_dos_device( int letter, enum device_type *type, ...@@ -625,7 +655,7 @@ NTSTATUS query_dos_device( int letter, enum device_type *type,
LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry ) LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry )
{ {
if (drive->drive != letter) continue; if (drive->drive != letter) continue;
disk_device = drive->device; disk_device = drive->volume->device;
if (type) *type = disk_device->type; if (type) *type = disk_device->type;
if (device) *device = disk_device->unix_device; if (device) *device = disk_device->unix_device;
if (mount_point) *mount_point = disk_device->unix_mount; if (mount_point) *mount_point = disk_device->unix_mount;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment