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 <tomasek(a)etf.cuni.cz>
* (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