Patch amended as previously discused Changelog: 1 - Fix incorrect reporting of no media in floppy drive as permissions problem. 2 - Provide partial workaround for very long delays (c. 40 sec per lookup, about 7 minutes to set up file browser) on lookups to floppy drive not physically present (e.g. laptop with floppy or CD setup) Index: files/drive.c =================================================================== RCS file: /home/wine/wine/files/drive.c,v retrieving revision 1.74 diff -u -u -r1.74 drive.c --- files/drive.c 20 Jun 2002 23:21:27 -0000 1.74 +++ files/drive.c 10 Jul 2002 17:40:49 -0000 @@ -7,6 +7,7 @@ * Label & serial number read support. * (c) 1999 Petr Tomasek <tomasek@etf.cuni.cz> * (c) 2000 Andreas Mohr (changes) + * (c) 2002 Keith Matthews (changes) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -36,6 +37,7 @@ #include <fcntl.h> #include <errno.h> #include <unistd.h> +#include <time.h> #ifdef HAVE_SYS_PARAM_H # include <sys/param.h> @@ -541,26 +543,103 @@ #define DRIVE_SUPER 96 int fd; off_t offs; + struct stat dev_data; + time_t call_start, call_end; + double time_diff; int ret = 0; if (memset(buff,0,DRIVE_SUPER)!=buff) return -1; - if ((fd=open(DOSDrives[drive].device,O_RDONLY)) == -1) + + if ((DOSDrives[drive].flags & DRIVE_DISABLED)) + return 0; /* should not get DEIVE_DISABLED here except as part of + * non-existing floppy kludge + */ + 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); + return -1; + } else if ( errno == EACCES ) + ERR("Permissions problem on device for drive %c: !\n", 'A'+drive); + PROFILE_UsageWineIni(); + return -1; + } + + time(&call_start); + /******************************************************************************* + * start of kludge to trap situation where attempt is made to address /dev/fd0 + * (or some such) and it is not actually present. Should never happen in + * desktop machine but could well happen on laptop. + * + * Kludge only necessary as open thinks it can really open the file and + * takes 39 seconds to do it. + * + *******************************************************************************/ + + if ((fd=open(DOSDrives[drive].device,O_RDONLY)) == -1) + { + if (errno == 13 ) + { + /************************************************** + * permissions problem - don't understand how + * we can get here with the checks made above + * but we can so trap it + ****************************************************/ + + ERR("Permissions problem on device for drive %c: - effective user does not have read access !\n", 'A'+drive); + PROFILE_UsageWineIni(); + return -1; + } else if ((errno == 6) && (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 + * + **************************************************************************/ + + +/* ++++++++++++++++ should we be down here for CD's also ? also what about Jazz drives etc ?+++++++++++++++++++++++ */ + + } else { + /**************************************************************************** + * + * Not removeable media device so no idea how we could get + * down here - assume hardware problem + * + ***************************************************************************/ + ERR("Couldn't open device '%s' for drive %c: ! (%s)\n", DOSDrives[drive].device, 'A'+drive, + strerror(errno)); + ERR("Can't read drive volume info ! correct it or make sure the device to read it from is accessible !\n"); + PROFILE_UsageWineIni(); + return -1; + + } + } + + time(&call_end); + time_diff = difftime(call_end, call_start); + if (time_diff > 5 ) + { + /* open took more that 5 sec. - error situation described above */ + DOSDrives[drive].flags = DOSDrives[drive].flags | DRIVE_DISABLED; + return 0; /* no point in erroring, act as if no media */ + } + switch(DOSDrives[drive].type) { case DRIVE_REMOVABLE: + /* leaves offs unset - is this critical ? */ case DRIVE_FIXED: offs = 0; break; @@ -572,15 +651,16 @@ break; } - if ((offs) && (lseek(fd,offs,SEEK_SET)!=offs)) - { - ret = -4; - goto the_end; - } - if (read(fd,buff,DRIVE_SUPER)!=DRIVE_SUPER) + if ((offs) && (lseek(fd,offs,SEEK_SET)!=offs)) return -4; + if (read(fd,buff,DRIVE_SUPER)!=DRIVE_SUPER) { - ret = -2; - goto the_end; + if (DOSDrives[drive].type != DRIVE_REMOVABLE) + { + return -2; + } else { + return 0; + } + } switch(DOSDrives[drive].type)