I noticed earlier today that DOSfs is not correctly handling removable media drives. In particular floppies will get a permissions error message regardless of the actual permissions if there is no media in the drive. Presumeably Jazz type drives would do the same.
I have made the assumption that the fact that there is no media in the drive needs to be stored and have added a new value to the drive flags for this. If someone knows better that it cannot be used or clashes with something I have not spotted then please say so.
================================================================ Index: files/drive.c =================================================================== RCS file: /home/wine/wine/files/drive.c,v retrieving revision 1.64 diff -u -u -r1.64 drive.c --- files/drive.c 2002/01/13 01:44:00 1.64 +++ files/drive.c 2002/01/28 16:41:26 @@ -7,6 +7,7 @@ * Label & serial number read support. * (c) 1999 Petr Tomasek [email protected] * (c) 2000 Andreas Mohr (changes) + * (c) 2002 Keith Matthews (changes) * */
@@ -508,21 +509,95 @@ #define DRIVE_SUPER 96 int fd; off_t offs; + struct stat dev_data; + uid_t user; + gid_t group;
if (memset(buff,0,DRIVE_SUPER)!=buff) return -1; - if ((fd=open(DOSDrives[drive].device,O_RDONLY)) == -1) + + if (!DOSDrives[drive].device) { - struct stat st; - if (!DOSDrives[drive].device) - ERR("No device configured for drive %c: !\n", 'A'+drive); - else - ERR("Couldn't open device '%s' for drive %c: ! (%s)\n", DOSDrives[drive].device, 'A'+drive, - (stat(DOSDrives[drive].device, &st)) ? - "not available or symlink not valid ?" : "no permission"); - ERR("Can't read drive volume info ! Either pre-set it or make sure the device to read it from is accessible !\n"); + ERR("No Device Configured for drive %c: !\n",'A'+drive); PROFILE_UsageWineIni(); return -1; } + + if (( stat(DOSDrives[drive].device,&dev_data)) == -1) + { + if (errno == ENOENT || errno == ENOTDIR || errno == ELOOP || errno == ENAMETOOLONG ) + { + ERR("Device ('%s) Configured for drive %c: is not a valid device path!\n",DOSDrives[drive].device,'A'+drive); + } else if ( errno == EACCES ) + ERR("Permissions problem on device for drive %c: !\n", 'A'+drive); + PROFILE_UsageWineIni(); + return -1; + } else + { + user = getuid(); + group = getgid(); + if ( user == dev_data.st_uid) + { + /* We are running as the device owner - check those perms */ + if ( (dev_data.st_mode & S_IRUSR) == 0 ) + { + /* owner does not have read perms - stupid but */ + ERR("Permissions problem on device for drive %c: - user does not have read access !\n", 'A'+drive); + PROFILE_UsageWineIni(); + return -1; + } + } else if ( group == dev_data.st_gid ) + { + if ( (dev_data.st_mode & S_IRGRP) == 0 ) + { + /* group does not have read perms */ + ERR("Permissions problem on device for drive %c: - group does not have read access !\n", 'A'+drive); + PROFILE_UsageWineIni(); + return -1; + } + + } else if ( (dev_data.st_mode & S_IROTH) == 0 ) + { + /* not owning user or group and no perms */ + ERR("Permissions problem on device for drive %c: - effective user does not have read access !\n", 'A'+drive); + PROFILE_UsageWineIni(); + return -1; + + } + } + + if ((fd=open(DOSDrives[drive].device,O_RDONLY)) == -1) + { + if (DOSDrives[drive].type == DRIVE_REMOVABLE ) + { + /***************************************************************************** + * OK, we've checked just about everything we can, it's a removeable media + * device, so assume no media since that gives same response + * + * Wrong if not running as root and user does not have read to device but + * we've already checked for that above + * + **************************************************************************/ + + DOSDrives[drive].flags = DOSDrives[drive].flags | DRIVE_NO_MEDIA; + return 0; + +/* ++++++++++++++++ should we be down here for CD's also ? also what about Jazz drives etc ?+++++++++++++++++++++++ */ + + } else { + /**************************************************************************** + * + * Not removeable media device - must be permissions problem + * + ***************************************************************************/ + ERR("Couldn't open device '%s' for drive %c: ! (%s)\n", DOSDrives[drive].device, 'A'+drive, + "no permission"); + ERR("Can't read drive volume info ! Either pre-set it or make sure the device to read it from is accessible !\n"); + PROFILE_UsageWineIni(); + return -1; + + } + } +
Index: include/drive.h =================================================================== RCS file: /home/wine/wine/include/drive.h,v retrieving revision 1.8 diff -u -u -r1.8 drive.h --- include/drive.h 2000/12/12 00:44:43 1.8 +++ include/drive.h 2002/01/28 16:41:57 @@ -19,6 +19,7 @@ #define DRIVE_CASE_PRESERVING 0x0008 /* Drive fs is case preserving */ #define DRIVE_FAIL_READ_ONLY 0x0010 /* Fail opening read-only files for writing */ #define DRIVE_READ_VOL_INFO 0x0020 /* Try to read volume info from the device? */ +#define DRIVE_NO_MEDIA 0x0040 /* no media in drive */
extern int DRIVE_Init(void); extern int DRIVE_IsValid( int drive );
-- Keith Matthews Frequentous Consultants - Linux Services, Oracle development & database administration