DOSfs - removable media drives.

Keith Matthews keith_m at sweeney.demon.co.uk
Mon Jan 28 12:41:20 CST 2002


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 at 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






More information about the wine-devel mailing list