From 875715acb04d474e26430d314af90b0ab1e54efc Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 6 Mar 2008 17:23:55 -0800 Subject: [PATCH] mountmgr.sys: Allow for adding separate physical hard drives --- dlls/mountmgr.sys/mountmgr.c | 99 +++++++++++++++++++++++++++++------------- 1 files changed, 69 insertions(+), 30 deletions(-) diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c index b2da055..dd40f6a 100644 --- a/dlls/mountmgr.sys/mountmgr.c +++ b/dlls/mountmgr.sys/mountmgr.c @@ -61,6 +61,7 @@ struct disk_device_info { UNICODE_STRING name; /* device name */ STORAGE_DEVICE_NUMBER devnum; /* device number info */ + ULONG partitioncount; /* extension for primary harddisk: Keep track of partition count */ }; struct mount_point @@ -82,6 +83,7 @@ static struct list drives_list = LIST_INIT(drives_list); static struct mount_point mount_points[MAX_MOUNT_POINTS]; static HKEY mount_key; +static ULONG globaldevicenumber; static inline UNICODE_STRING *get_device_name( DEVICE_OBJECT *dev ) { @@ -117,14 +119,14 @@ static char *read_symlink( const char *path ) } } -static NTSTATUS create_disk_device( DRIVER_OBJECT *driver, DWORD type, DEVICE_OBJECT **dev_obj ) +static NTSTATUS create_disk_device( DRIVER_OBJECT *driver, DWORD type, DEVICE_OBJECT **dev_obj, ULONG devicenumber, ULONG disknumber ) { static const WCHAR harddiskW[] = {'\\','D','e','v','i','c','e', '\\','H','a','r','d','d','i','s','k','V','o','l','u','m','e','%','u',0}; static const WCHAR cdromW[] = {'\\','D','e','v','i','c','e','\\','C','d','R','o','m','%','u',0}; static const WCHAR floppyW[] = {'\\','D','e','v','i','c','e','\\','F','l','o','p','p','y','%','u',0}; - UINT i, first = 0; + UINT i; NTSTATUS status = 0; const WCHAR *format; UNICODE_STRING name; @@ -141,13 +143,12 @@ static NTSTATUS create_disk_device( DRIVER_OBJECT *driver, DWORD type, DEVICE_OB case DRIVE_FIXED: default: /* FIXME */ format = harddiskW; - first = 1; /* harddisk volumes start counting from 1 */ break; } name.MaximumLength = (strlenW(format) + 10) * sizeof(WCHAR); name.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, name.MaximumLength ); - for (i = first; i < 32; i++) + for (i = 0; i < 32; i++) { sprintfW( name.Buffer, format, i ); name.Length = strlenW(name.Buffer) * sizeof(WCHAR); @@ -162,21 +163,17 @@ static NTSTATUS create_disk_device( DRIVER_OBJECT *driver, DWORD type, DEVICE_OB { case DRIVE_REMOVABLE: info->devnum.DeviceType = FILE_DEVICE_DISK; - info->devnum.DeviceNumber = i; - info->devnum.PartitionNumber = ~0u; break; case DRIVE_CDROM: info->devnum.DeviceType = FILE_DEVICE_CD_ROM; - info->devnum.DeviceNumber = i; - info->devnum.PartitionNumber = ~0u; break; case DRIVE_FIXED: default: /* FIXME */ info->devnum.DeviceType = FILE_DEVICE_DISK; - info->devnum.DeviceNumber = 0; - info->devnum.PartitionNumber = i; break; } + info->devnum.DeviceNumber = devicenumber; + info->devnum.PartitionNumber = disknumber; } else { @@ -187,7 +184,7 @@ static NTSTATUS create_disk_device( DRIVER_OBJECT *driver, DWORD type, DEVICE_OB } -static NTSTATUS add_mount_point( DRIVER_OBJECT *driver, DWORD type, int drive, +static NTSTATUS add_mount_point( DEVICE_OBJECT *device, DRIVER_OBJECT *driver, DWORD type, 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}; @@ -200,6 +197,9 @@ static NTSTATUS add_mount_point( DRIVER_OBJECT *driver, DWORD type, int drive, GUID guid; UINT i; struct mount_point *mount_drive = NULL, *mount_volume = NULL; + struct disk_device_info *info = device->DeviceExtension; + LONG devnumberused; + LONG partnumberused = ~0u; /* find two free mount points */ @@ -230,7 +230,15 @@ static NTSTATUS add_mount_point( DRIVER_OBJECT *driver, DWORD type, int drive, RtlInitUnicodeString( &mount_drive->link, drive_link ); RtlInitUnicodeString( &mount_volume->link, volume_link ); - status = create_disk_device( driver, type, &mount_drive->device ); + if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM) + devnumberused = globaldevicenumber++; + else + { + devnumberused = info->devnum.DeviceNumber; + partnumberused = ++(info->partitioncount); + } + + status = create_disk_device( driver, type, &mount_drive->device, devnumberused, partnumberused ); if (status) { RtlFreeUnicodeString( &mount_drive->link ); @@ -426,7 +434,7 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp ) } /* create mount points for mapped drives */ -static void create_drive_mount_points( DRIVER_OBJECT *driver ) +static void create_drive_mount_points( DEVICE_OBJECT *device, DRIVER_OBJECT *driver ) { const char *config_dir = wine_get_config_dir(); char *buffer, *p, *link; @@ -443,48 +451,79 @@ 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) ); + add_mount_point( device, driver, DRIVE_FIXED, i, link, strlen(link) ); RtlFreeHeap( GetProcessHeap(), 0, link ); } RtlFreeHeap( GetProcessHeap(), 0, buffer ); } } +static NTSTATUS WINAPI create_harddisk( DRIVER_OBJECT *driver, DEVICE_OBJECT **dev_obj ) +{ + static const WCHAR harddiskW[] = {'\\','D','e','v','i','c','e','\\','H','a','r','d','d','i','s','k','%','u',0}; + static const WCHAR physdriveW[] = {'\\','?','?','\\','P','h','y','s','i','c','a','l','D','r','i','v','e','%','u',0}; + + UINT i; + NTSTATUS status = 0; + UNICODE_STRING harddiskname, physdrivename; + struct disk_device_info *info; + + harddiskname.MaximumLength = (strlenW(harddiskW) + 10) * sizeof(WCHAR); + harddiskname.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, harddiskname.MaximumLength ); + physdrivename.MaximumLength = (strlenW(physdriveW) + 10) * sizeof(WCHAR); + physdrivename.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, physdrivename.MaximumLength ); + for (i = 0; i < 32; i++) + { + sprintfW( harddiskname.Buffer, harddiskW, i ); + harddiskname.Length = strlenW(harddiskname.Buffer) * sizeof(WCHAR); + status = IoCreateDevice( driver, sizeof(*info), &harddiskname, 0, 0, FALSE, dev_obj ); + if (status != STATUS_OBJECT_NAME_COLLISION) break; + } + if (!status) + { + sprintfW( physdrivename.Buffer, physdriveW, i ); + physdrivename.Length = strlenW(physdrivename.Buffer) * sizeof(WCHAR); + status = IoCreateSymbolicLink( &physdrivename, &harddiskname ); + } + RtlFreeUnicodeString( &physdrivename ); + if (!status) + { + info = (*dev_obj)->DeviceExtension; + info->name = harddiskname; + info->devnum.DeviceType = FILE_DEVICE_DISK; + info->devnum.DeviceNumber = globaldevicenumber++; + info->devnum.PartitionNumber = 0; + info->partitioncount = 0; + } + else + { + FIXME( "IoCreateDevice %s got %x\n", debugstr_w(harddiskname.Buffer), status ); + RtlFreeUnicodeString( &harddiskname ); + } + return status; +} + /* driver entry point for the harddisk driver */ static NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) { static const WCHAR mounted_devicesW[] = {'S','y','s','t','e','m','\\', 'M','o','u','n','t','e','d','D','e','v','i','c','e','s',0}; - static const WCHAR harddisk0W[] = {'\\','D','e','v','i','c','e', - '\\','H','a','r','d','d','i','s','k','0',0}; - static const WCHAR physdrive0W[] = {'\\','?','?','\\','P','h','y','s','i','c','a','l','D','r','i','v','e','0',0}; - - UNICODE_STRING nameW, linkW; DEVICE_OBJECT *device; NTSTATUS status; - struct disk_device_info *info; driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = harddisk_ioctl; RegCreateKeyExW( HKEY_LOCAL_MACHINE, mounted_devicesW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &mount_key, NULL ); - RtlInitUnicodeString( &nameW, harddisk0W ); - RtlInitUnicodeString( &linkW, physdrive0W ); - if (!(status = IoCreateDevice( driver, sizeof(*info), &nameW, 0, 0, FALSE, &device ))) - status = IoCreateSymbolicLink( &linkW, &nameW ); + status = create_harddisk( driver, &device ); if (status) { FIXME( "failed to create device error %x\n", status ); return status; } - info = device->DeviceExtension; - info->name = nameW; - info->devnum.DeviceType = FILE_DEVICE_DISK; - info->devnum.DeviceNumber = 0; - info->devnum.PartitionNumber = 0; - create_drive_mount_points( driver ); + create_drive_mount_points( device, driver ); return status; } -- 1.5.4.1