From 1680ba67efdea211fdcdc45aa6a173a893c9ab5c Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 17 Oct 2008 20:09:31 +0200 Subject: [PATCH] mountmgr: Store mount points as a list instead of an array. --- dlls/mountmgr.sys/mountmgr.c | 155 +++++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 79 deletions(-) diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c index 6df95283e63..e3b02a019c3 100644 --- a/dlls/mountmgr.sys/mountmgr.c +++ b/dlls/mountmgr.sys/mountmgr.c @@ -37,6 +37,7 @@ #include "ddk/mountmgr.h" #include "wine/library.h" #include "wine/unicode.h" +#include "wine/list.h" #include "wine/debug.h" #include "mountmgr.h" @@ -44,7 +45,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(mountmgr); #define MIN_ID_LEN 4 #define MAX_DOS_DRIVES 26 -#define MAX_MOUNT_POINTS (2 * MAX_DOS_DRIVES) /* extra info for disk devices, stored in DeviceExtension */ struct disk_device_info @@ -55,13 +55,14 @@ struct disk_device_info struct mount_point { - DEVICE_OBJECT *device; + struct list entry; /* entry in mount points list */ + DEVICE_OBJECT *device; /* disk device */ UNICODE_STRING link; /* DOS device symlink */ void *id; /* device unique id */ unsigned int id_len; }; -static struct mount_point mount_points[MAX_MOUNT_POINTS]; +static struct list mount_points_list = LIST_INIT(mount_points_list); static HKEY mount_key; static inline UNICODE_STRING *get_device_name( DEVICE_OBJECT *dev ) @@ -180,68 +181,58 @@ static void set_mount_point_id( struct mount_point *mount, const void *id, unsig else mount->id_len = 0; } -static NTSTATUS add_mount_point( DRIVER_OBJECT *driver, DWORD type, int drive, - const void *id, unsigned int id_len ) +static struct mount_point *add_mount_point( DEVICE_OBJECT *device, UNICODE_STRING *device_name, + const WCHAR *link, const void *id, unsigned int id_len ) +{ + struct mount_point *mount; + WCHAR *str; + UINT len = (strlenW(link) + 1) * sizeof(WCHAR); + + if (!(mount = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*mount) + len ))) return NULL; + + str = (WCHAR *)(mount + 1); + strcpyW( str, link ); + RtlInitUnicodeString( &mount->link, str ); + mount->device = device; + mount->id = NULL; + list_add_tail( &mount_points_list, &mount->entry ); + + IoCreateSymbolicLink( &mount->link, device_name ); + set_mount_point_id( mount, id, id_len ); + + TRACE( "created %s id %s for %s\n", debugstr_w(mount->link.Buffer), + debugstr_a(mount->id), debugstr_w(device_name->Buffer) ); + return mount; +} + +/* create the DosDevices mount point symlink for a new device */ +static struct mount_point *add_dosdev_mount_point( DEVICE_OBJECT *device, UNICODE_STRING *device_name, + int drive, const void *id, unsigned int id_len ) { static const WCHAR driveW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\','%','c',':',0}; + WCHAR link[sizeof(driveW)]; + + sprintfW( link, driveW, 'A' + drive ); + return add_mount_point( device, device_name, link, id, id_len ); +} + +/* create the Volume mount point symlink for a new device */ +static struct mount_point *add_volume_mount_point( DEVICE_OBJECT *device, UNICODE_STRING *device_name, + int drive, const void *id, unsigned int id_len ) +{ static const WCHAR volumeW[] = {'\\','?','?','\\','V','o','l','u','m','e','{', '%','0','8','x','-','%','0','4','x','-','%','0','4','x','-', '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x', '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','}',0}; - WCHAR *drive_link, *volume_link; - NTSTATUS status; + WCHAR link[sizeof(volumeW)]; GUID guid; - UINT i; - struct mount_point *mount_drive = NULL, *mount_volume = NULL; - - /* find two free mount points */ - - for (i = 0; i < MAX_MOUNT_POINTS; i++) - { - if (mount_points[i].device) continue; - if (!mount_drive) - { - mount_drive = &mount_points[i]; - continue; - } - mount_volume = &mount_points[i]; - break; - } - if (!mount_volume) return STATUS_NO_MEMORY; - - /* create the volume */ memset( &guid, 0, sizeof(guid) ); /* FIXME */ guid.Data4[7] = 'A' + drive; - - drive_link = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(driveW) ); - volume_link = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(volumeW) ); - sprintfW( drive_link, driveW, 'A' + drive ); - sprintfW( volume_link, volumeW, guid.Data1, guid.Data2, guid.Data3, + sprintfW( link, volumeW, guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); - - RtlInitUnicodeString( &mount_drive->link, drive_link ); - RtlInitUnicodeString( &mount_volume->link, volume_link ); - status = create_disk_device( driver, type, &mount_drive->device ); - if (status) - { - RtlFreeUnicodeString( &mount_drive->link ); - RtlFreeUnicodeString( &mount_volume->link ); - return status; - } - - mount_volume->device = mount_drive->device; /* FIXME: incr ref count */ - set_mount_point_id( mount_drive, id, id_len ); - set_mount_point_id( mount_volume, id, id_len ); - - IoCreateSymbolicLink( &mount_drive->link, get_device_name(mount_drive->device) ); - IoCreateSymbolicLink( &mount_volume->link, get_device_name(mount_volume->device) ); - - TRACE( "created device %s symlinks %s %s\n", debugstr_w(get_device_name(mount_drive->device)->Buffer), - debugstr_w(mount_drive->link.Buffer), debugstr_w(mount_volume->link.Buffer) ); - - return STATUS_SUCCESS; + return add_mount_point( device, device_name, link, id, id_len ); } /* check if a given mount point matches the requested specs */ @@ -275,10 +266,11 @@ static BOOL matching_mount_point( const struct mount_point *mount, const MOUNTMG static NTSTATUS query_mount_points( const void *in_buff, SIZE_T insize, void *out_buff, SIZE_T outsize, IO_STATUS_BLOCK *iosb ) { - UINT i, j, pos, size; + UINT count, pos, size; const MOUNTMGR_MOUNT_POINT *input = in_buff; MOUNTMGR_MOUNT_POINTS *info = out_buff; UNICODE_STRING *dev_name; + struct mount_point *mount; /* sanity checks */ if (input->SymbolicLinkNameOffset + input->SymbolicLinkNameLength > insize || @@ -289,17 +281,17 @@ static NTSTATUS query_mount_points( const void *in_buff, SIZE_T insize, input->DeviceNameOffset + input->DeviceNameLength < input->DeviceNameOffset) return STATUS_INVALID_PARAMETER; - for (i = j = size = 0; i < MAX_MOUNT_POINTS; i++) + count = size = 0; + LIST_FOR_EACH_ENTRY( mount, &mount_points_list, struct mount_point, entry ) { - if (!mount_points[i].device) continue; - if (!matching_mount_point( &mount_points[i], input )) continue; - size += get_device_name(mount_points[i].device)->Length; - size += mount_points[i].link.Length; - size += mount_points[i].id_len; + if (!matching_mount_point( mount, input )) continue; + size += get_device_name(mount->device)->Length; + size += mount->link.Length; + size += mount->id_len; size = (size + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1); - j++; + count++; } - pos = FIELD_OFFSET( MOUNTMGR_MOUNT_POINTS, MountPoints[j] ); + pos = FIELD_OFFSET( MOUNTMGR_MOUNT_POINTS, MountPoints[count] ); size += pos; if (size > outsize) @@ -309,29 +301,29 @@ static NTSTATUS query_mount_points( const void *in_buff, SIZE_T insize, return STATUS_MORE_ENTRIES; } - info->NumberOfMountPoints = j; - for (i = j = 0; i < MAX_MOUNT_POINTS; i++) + info->NumberOfMountPoints = count; + count = 0; + LIST_FOR_EACH_ENTRY( mount, &mount_points_list, struct mount_point, entry ) { - if (!mount_points[i].device) continue; - if (!matching_mount_point( &mount_points[i], input )) continue; + if (!matching_mount_point( mount, input )) continue; - dev_name = get_device_name( mount_points[i].device ); - info->MountPoints[j].DeviceNameOffset = pos; - info->MountPoints[j].DeviceNameLength = dev_name->Length; + dev_name = get_device_name( mount->device ); + info->MountPoints[count].DeviceNameOffset = pos; + info->MountPoints[count].DeviceNameLength = dev_name->Length; memcpy( (char *)out_buff + pos, dev_name->Buffer, dev_name->Length ); pos += dev_name->Length; - info->MountPoints[j].SymbolicLinkNameOffset = pos; - info->MountPoints[j].SymbolicLinkNameLength = mount_points[i].link.Length; - memcpy( (char *)out_buff + pos, mount_points[i].link.Buffer, mount_points[i].link.Length ); - pos += mount_points[i].link.Length; + info->MountPoints[count].SymbolicLinkNameOffset = pos; + info->MountPoints[count].SymbolicLinkNameLength = mount->link.Length; + memcpy( (char *)out_buff + pos, mount->link.Buffer, mount->link.Length ); + pos += mount->link.Length; - info->MountPoints[j].UniqueIdOffset = pos; - info->MountPoints[j].UniqueIdLength = mount_points[i].id_len; - memcpy( (char *)out_buff + pos, mount_points[i].id, strlen(mount_points[i].id) + 1 ); - pos += mount_points[i].id_len; + info->MountPoints[count].UniqueIdOffset = pos; + info->MountPoints[count].UniqueIdLength = mount->id_len; + memcpy( (char *)out_buff + pos, mount->id, mount->id_len ); + pos += mount->id_len; pos = (pos + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1); - j++; + count++; } info->Size = pos; iosb->Information = pos; @@ -421,6 +413,7 @@ static void create_drive_mount_points( DRIVER_OBJECT *driver ) const char *config_dir = wine_get_config_dir(); char *buffer, *p, *link; unsigned int i; + DEVICE_OBJECT *device; if ((buffer = RtlAllocateHeap( GetProcessHeap(), 0, strlen(config_dir) + sizeof("/dosdevices/a:") ))) @@ -433,7 +426,11 @@ static void create_drive_mount_points( DRIVER_OBJECT *driver ) { *p = 'a' + i; if (!(link = read_symlink( buffer ))) continue; - add_mount_point( driver, DRIVE_FIXED, i, link, strlen(link) + 1 ); + if (!create_disk_device( driver, DRIVE_FIXED, &device )) + { + add_dosdev_mount_point( device, get_device_name(device), i, link, strlen(link) + 1 ); + add_volume_mount_point( device, get_device_name(device), i, link, strlen(link) + 1 ); + } RtlFreeHeap( GetProcessHeap(), 0, link ); } RtlFreeHeap( GetProcessHeap(), 0, buffer ); -- 2.11.4.GIT