mountmgr: Make the device type more specific than what is possible with the standard Win32 drive types.

This commit is contained in:
Alexandre Julliard 2008-11-12 10:47:49 +01:00
parent b901c8db5a
commit a2feb0f8e4
5 changed files with 98 additions and 49 deletions

View File

@ -43,13 +43,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(mountmgr);
static const WCHAR drive_types[][8] = static const WCHAR drive_types[][8] =
{ {
{ 0 }, /* DRIVE_UNKNOWN */ { 0 }, /* DEVICE_UNKNOWN */
{ 0 }, /* DRIVE_NO_ROOT_DIR */ { 0 }, /* DEVICE_HARDDISK */
{'f','l','o','p','p','y',0}, /* DRIVE_REMOVABLE */ {'h','d',0}, /* DEVICE_HARDDISK_VOL */
{'h','d',0}, /* DRIVE_FIXED */ {'f','l','o','p','p','y',0}, /* DEVICE_FLOPPY */
{'n','e','t','w','o','r','k',0}, /* DRIVE_REMOTE */ {'c','d','r','o','m',0}, /* DEVICE_CDROM */
{'c','d','r','o','m',0}, /* DRIVE_CDROM */ {'n','e','t','w','o','r','k',0}, /* DEVICE_NETWORK */
{'r','a','m','d','i','s','k',0} /* DRIVE_RAMDISK */ {'r','a','m','d','i','s','k',0} /* DEVICE_RAMDISK */
}; };
static const WCHAR drives_keyW[] = {'S','o','f','t','w','a','r','e','\\', static const WCHAR drives_keyW[] = {'S','o','f','t','w','a','r','e','\\',
@ -60,7 +60,7 @@ struct dos_drive
struct list entry; /* entry in drives list */ struct list entry; /* entry in drives list */
char *udi; /* unique identifier for dynamic drives */ char *udi; /* unique identifier for dynamic drives */
int drive; /* drive letter (0 = A: etc.) */ int drive; /* drive letter (0 = A: etc.) */
DWORD type; /* drive type */ enum device_type type; /* drive type */
DEVICE_OBJECT *device; /* disk device allocated for this drive */ DEVICE_OBJECT *device; /* disk device allocated for this drive */
UNICODE_STRING name; /* device name */ UNICODE_STRING name; /* device name */
UNICODE_STRING symlink; /* device symlink if any */ UNICODE_STRING symlink; /* device symlink if any */
@ -143,38 +143,42 @@ static void send_notify( int drive, int code )
} }
/* create the disk device for a given drive */ /* create the disk device for a given drive */
static NTSTATUS create_disk_device( const char *udi, DWORD type, struct dos_drive **drive_ret ) static NTSTATUS create_disk_device( const char *udi, enum device_type type, struct dos_drive **drive_ret )
{ {
static const WCHAR harddiskvolW[] = {'\\','D','e','v','i','c','e', static const WCHAR harddiskvolW[] = {'\\','D','e','v','i','c','e',
'\\','H','a','r','d','d','i','s','k','V','o','l','u','m','e','%','u',0}; '\\','H','a','r','d','d','i','s','k','V','o','l','u','m','e','%','u',0};
static const WCHAR harddiskW[] = {'\\','D','e','v','i','c','e','\\','H','a','r','d','d','i','s','k','%','u',0}; static const WCHAR harddiskW[] = {'\\','D','e','v','i','c','e','\\','H','a','r','d','d','i','s','k','%','u',0};
static const WCHAR cdromW[] = {'\\','D','e','v','i','c','e','\\','C','d','R','o','m','%','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}; static const WCHAR floppyW[] = {'\\','D','e','v','i','c','e','\\','F','l','o','p','p','y','%','u',0};
static const WCHAR ramdiskW[] = {'\\','D','e','v','i','c','e','\\','R','a','m','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}; static const WCHAR physdriveW[] = {'\\','?','?','\\','P','h','y','s','i','c','a','l','D','r','i','v','e','%','u',0};
UINT i, first = 0; UINT i, first = 0;
NTSTATUS status = 0; NTSTATUS status = 0;
const WCHAR *format; const WCHAR *format = NULL;
UNICODE_STRING name; UNICODE_STRING name;
DEVICE_OBJECT *dev_obj; DEVICE_OBJECT *dev_obj;
struct dos_drive *drive; struct dos_drive *drive;
switch(type) switch(type)
{ {
case DRIVE_REMOVABLE: case DEVICE_UNKNOWN:
case DEVICE_HARDDISK:
case DEVICE_NETWORK: /* FIXME */
format = harddiskW;
break;
case DEVICE_HARDDISK_VOL:
format = harddiskvolW;
first = 1; /* harddisk volumes start counting from 1 */
break;
case DEVICE_FLOPPY:
format = floppyW; format = floppyW;
break; break;
case DRIVE_CDROM: case DEVICE_CDROM:
format = cdromW; format = cdromW;
break; break;
case DRIVE_FIXED: case DEVICE_RAMDISK:
default: /* FIXME */ format = ramdiskW;
if (udi) format = harddiskW;
else
{
format = harddiskvolW;
first = 1; /* harddisk volumes start counting from 1 */
}
break; break;
} }
@ -211,20 +215,20 @@ static NTSTATUS create_disk_device( const char *udi, DWORD type, struct dos_driv
} }
switch (type) switch (type)
{ {
case DRIVE_REMOVABLE: case DEVICE_FLOPPY:
case DEVICE_RAMDISK:
drive->devnum.DeviceType = FILE_DEVICE_DISK; drive->devnum.DeviceType = FILE_DEVICE_DISK;
drive->devnum.DeviceNumber = i; drive->devnum.DeviceNumber = i;
drive->devnum.PartitionNumber = ~0u; drive->devnum.PartitionNumber = ~0u;
break; break;
case DRIVE_CDROM: case DEVICE_CDROM:
drive->devnum.DeviceType = FILE_DEVICE_CD_ROM; drive->devnum.DeviceType = FILE_DEVICE_CD_ROM;
drive->devnum.DeviceNumber = i; drive->devnum.DeviceNumber = i;
drive->devnum.PartitionNumber = ~0u; drive->devnum.PartitionNumber = ~0u;
break; break;
case DRIVE_FIXED: case DEVICE_UNKNOWN:
default: /* FIXME */ case DEVICE_HARDDISK:
drive->devnum.DeviceType = FILE_DEVICE_DISK; case DEVICE_NETWORK: /* FIXME */
if (udi)
{ {
UNICODE_STRING symlink; UNICODE_STRING symlink;
@ -235,14 +239,15 @@ static NTSTATUS create_disk_device( const char *udi, DWORD type, struct dos_driv
symlink.Length = strlenW(symlink.Buffer) * sizeof(WCHAR); symlink.Length = strlenW(symlink.Buffer) * sizeof(WCHAR);
if (!IoCreateSymbolicLink( &symlink, &name )) drive->symlink = symlink; if (!IoCreateSymbolicLink( &symlink, &name )) drive->symlink = symlink;
} }
drive->devnum.DeviceType = FILE_DEVICE_DISK;
drive->devnum.DeviceNumber = i; drive->devnum.DeviceNumber = i;
drive->devnum.PartitionNumber = 0; drive->devnum.PartitionNumber = 0;
} }
else break;
{ case DEVICE_HARDDISK_VOL:
drive->devnum.DeviceNumber = 0; drive->devnum.DeviceType = FILE_DEVICE_DISK;
drive->devnum.PartitionNumber = i; drive->devnum.DeviceNumber = 0;
} drive->devnum.PartitionNumber = i;
break; break;
} }
list_add_tail( &drives_list, &drive->entry ); list_add_tail( &drives_list, &drive->entry );
@ -307,7 +312,7 @@ static inline int is_valid_device( struct stat *st )
} }
/* find or create a DOS drive for the corresponding device */ /* find or create a DOS drive for the corresponding device */
static int add_drive( const char *device, DWORD type ) static int add_drive( const char *device, enum device_type type )
{ {
char *path, *p; char *path, *p;
char in_use[26]; char in_use[26];
@ -320,12 +325,20 @@ static int add_drive( const char *device, DWORD type )
memset( in_use, 0, sizeof(in_use) ); memset( in_use, 0, sizeof(in_use) );
first = 2; switch (type)
last = 26;
if (type == DRIVE_REMOVABLE)
{ {
case DEVICE_FLOPPY:
first = 0; first = 0;
last = 2; last = 2;
break;
case DEVICE_CDROM:
first = 3;
last = 26;
break;
default:
first = 2;
last = 26;
break;
} }
while (avail != -1) while (avail != -1)
@ -415,7 +428,7 @@ static void create_drive_devices(void)
struct dos_drive *drive; struct dos_drive *drive;
unsigned int i; unsigned int i;
HKEY drives_key; HKEY drives_key;
DWORD drive_type; enum device_type drive_type;
WCHAR driveW[] = {'a',':',0}; WCHAR driveW[] = {'a',':',0};
if (!(path = get_dosdevices_path( &p ))) return; if (!(path = get_dosdevices_path( &p ))) return;
@ -429,7 +442,7 @@ static void create_drive_devices(void)
p[2] = ':'; p[2] = ':';
device = read_symlink( path ); device = read_symlink( path );
drive_type = i < 2 ? DRIVE_REMOVABLE : DRIVE_FIXED; drive_type = i < 2 ? DEVICE_FLOPPY : DEVICE_HARDDISK_VOL;
if (drives_key) if (drives_key)
{ {
WCHAR buffer[32]; WCHAR buffer[32];
@ -445,6 +458,7 @@ static void create_drive_devices(void)
drive_type = j; drive_type = j;
break; break;
} }
if (drive_type == DEVICE_FLOPPY && i >= 2) drive_type = DEVICE_HARDDISK;
} }
} }
@ -466,7 +480,7 @@ static void create_drive_devices(void)
/* create a new dos drive */ /* create a new dos drive */
NTSTATUS add_dos_device( int letter, const char *udi, const char *device, NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
const char *mount_point, DWORD type ) const char *mount_point, enum device_type type )
{ {
struct dos_drive *drive, *next; struct dos_drive *drive, *next;
@ -519,6 +533,7 @@ found:
WCHAR name[3] = {'a',':',0}; WCHAR name[3] = {'a',':',0};
name[0] += drive->drive; name[0] += drive->drive;
if (!type_name[0] && type == DEVICE_HARDDISK) type_name = drive_types[DEVICE_FLOPPY];
if (type_name[0]) if (type_name[0])
RegSetValueExW( hkey, name, 0, REG_SZ, (const BYTE *)type_name, RegSetValueExW( hkey, name, 0, REG_SZ, (const BYTE *)type_name,
(strlenW(type_name) + 1) * sizeof(WCHAR) ); (strlenW(type_name) + 1) * sizeof(WCHAR) );
@ -569,7 +584,8 @@ NTSTATUS remove_dos_device( int letter, const char *udi )
} }
/* query information about an existing dos drive, by letter or udi */ /* query information about an existing dos drive, by letter or udi */
NTSTATUS query_dos_device( int letter, DWORD *type, const char **device, const char **mount_point ) NTSTATUS query_dos_device( int letter, enum device_type *type,
const char **device, const char **mount_point )
{ {
struct dos_drive *drive; struct dos_drive *drive;
@ -641,7 +657,7 @@ NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *pa
driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = harddisk_ioctl; driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = harddisk_ioctl;
/* create a harddisk0 device that isn't assigned to any drive */ /* create a harddisk0 device that isn't assigned to any drive */
create_disk_device( "harddisk0 placeholder", DRIVE_FIXED, &drive ); create_disk_device( "harddisk0 placeholder", DEVICE_HARDDISK, &drive );
create_drive_devices(); create_drive_devices();

View File

@ -42,7 +42,7 @@ static void appeared_callback( DADiskRef disk, void *context )
const void *ref; const void *ref;
char device[64]; char device[64];
char mount_point[PATH_MAX]; char mount_point[PATH_MAX];
DWORD type = DRIVE_UNKNOWN; enum device_type type = DEVICE_UNKNOWN;
if (!dict) return; if (!dict) return;
@ -64,7 +64,7 @@ static void appeared_callback( DADiskRef disk, void *context )
{ {
if (!CFStringCompare( ref, CFSTR("cd9660"), 0 ) || if (!CFStringCompare( ref, CFSTR("cd9660"), 0 ) ||
!CFStringCompare( ref, CFSTR("udf"), 0 )) !CFStringCompare( ref, CFSTR("udf"), 0 ))
type = DRIVE_CDROM; type = DEVICE_CDROM;
} }
TRACE( "got mount notification for '%s' on '%s'\n", device, mount_point ); TRACE( "got mount notification for '%s' on '%s'\n", device, mount_point );

View File

@ -113,7 +113,7 @@ static void new_device( LibHalContext *ctx, const char *udi )
char *mount_point = NULL; char *mount_point = NULL;
char *device = NULL; char *device = NULL;
char *type = NULL; char *type = NULL;
DWORD drive_type; enum device_type drive_type;
p_dbus_error_init( &error ); p_dbus_error_init( &error );
@ -132,8 +132,9 @@ static void new_device( LibHalContext *ctx, const char *udi )
if (!(type = p_libhal_device_get_property_string( ctx, parent, "storage.drive_type", &error ))) if (!(type = p_libhal_device_get_property_string( ctx, parent, "storage.drive_type", &error )))
p_dbus_error_free( &error ); /* ignore error */ p_dbus_error_free( &error ); /* ignore error */
if (type && !strcmp( type, "cdrom" )) drive_type = DRIVE_CDROM; if (type && !strcmp( type, "cdrom" )) drive_type = DEVICE_CDROM;
else drive_type = DRIVE_REMOVABLE; /* FIXME: default to removable */ else if (type && !strcmp( type, "floppy" )) drive_type = DEVICE_FLOPPY;
else drive_type = DEVICE_UNKNOWN;
add_dos_device( -1, udi, device, mount_point, drive_type ); add_dos_device( -1, udi, device, mount_point, drive_type );

View File

@ -254,9 +254,18 @@ static NTSTATUS define_unix_drive( const void *in_buff, SIZE_T insize )
if (input->type != DRIVE_NO_ROOT_DIR) if (input->type != DRIVE_NO_ROOT_DIR)
{ {
enum device_type type = DEVICE_UNKNOWN;
TRACE( "defining %c: dev %s mount %s type %u\n", TRACE( "defining %c: dev %s mount %s type %u\n",
letter, debugstr_a(device), debugstr_a(mount_point), input->type ); letter, debugstr_a(device), debugstr_a(mount_point), input->type );
return add_dos_device( letter - 'a', NULL, device, mount_point, input->type ); switch (input->type)
{
case DRIVE_REMOVABLE: type = (letter >= 'c') ? DEVICE_HARDDISK : DEVICE_FLOPPY; break;
case DRIVE_REMOTE: type = DEVICE_NETWORK; break;
case DRIVE_CDROM: type = DEVICE_CDROM; break;
case DRIVE_RAMDISK: type = DEVICE_RAMDISK; break;
}
return add_dos_device( letter - 'a', NULL, device, mount_point, type );
} }
else else
{ {
@ -275,11 +284,22 @@ static NTSTATUS query_unix_drive( const void *in_buff, SIZE_T insize,
int letter = tolowerW( input->letter ); int letter = tolowerW( input->letter );
NTSTATUS status; NTSTATUS status;
DWORD size, type; DWORD size, type;
enum device_type device_type;
char *ptr; char *ptr;
if (letter < 'a' || letter > 'z') return STATUS_INVALID_PARAMETER; if (letter < 'a' || letter > 'z') return STATUS_INVALID_PARAMETER;
if ((status = query_dos_device( letter - 'a', &type, &device, &mount_point ))) return status; if ((status = query_dos_device( letter - 'a', &device_type, &device, &mount_point ))) return status;
switch (device_type)
{
case DEVICE_UNKNOWN: type = DRIVE_UNKNOWN; break;
case DEVICE_HARDDISK: type = DRIVE_REMOVABLE; break;
case DEVICE_HARDDISK_VOL: type = DRIVE_FIXED; break;
case DEVICE_FLOPPY: type = DRIVE_REMOVABLE; break;
case DEVICE_CDROM: type = DRIVE_CDROM; break;
case DEVICE_NETWORK: type = DRIVE_REMOTE; break;
case DEVICE_RAMDISK: type = DRIVE_RAMDISK; break;
}
size = sizeof(*output); size = sizeof(*output);
if (device) size += strlen(device) + 1; if (device) size += strlen(device) + 1;

View File

@ -40,10 +40,22 @@ extern void initialize_diskarbitration(void);
/* device functions */ /* device functions */
enum device_type
{
DEVICE_UNKNOWN,
DEVICE_HARDDISK,
DEVICE_HARDDISK_VOL,
DEVICE_FLOPPY,
DEVICE_CDROM,
DEVICE_NETWORK,
DEVICE_RAMDISK
};
extern NTSTATUS add_dos_device( int letter, const char *udi, const char *device, extern NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
const char *mount_point, DWORD type ); const char *mount_point, enum device_type type );
extern NTSTATUS remove_dos_device( int letter, const char *udi ); extern NTSTATUS remove_dos_device( int letter, const char *udi );
extern NTSTATUS query_dos_device( int letter, DWORD *type, const char **device, const char **mount_point ); extern NTSTATUS query_dos_device( int letter, enum device_type *type,
const char **device, const char **mount_point );
extern NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path ); extern NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path );
/* mount point functions */ /* mount point functions */