home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1993 Marc Stern (internet: stern@mble.philips.be) */
-
- #include "tools.h"
- #include "bool.h"
- #include <bios.h>
- #include <fcntl.h>
- #include <sys\stat.h>
- #include <errno.h>
-
-
-
- static int diskError;
-
-
- void interrupt (*oldHandler)(); /* interrupt function pointer */
-
-
- /* For interrupt */
- #if defined(__TURBOC__)
- # pragma warn -par
- # pragma warn -rvl
- #endif
-
- int myHandler( int errval, int ax, int bp, int si )
- {
- diskError = LOWBYTE( errval );
-
- #if 0
- if ( ax < 0 ) /* not a disk error */
- {
- oldHandler();
- hardresume( _AL );
- }
- #endif
-
- hardretn( _HARDERR_ABORT );
- }
-
- #if defined(__TURBOC__)
- # pragma warn .par
- # pragma warn .rvl
- #endif
-
-
- /***
- *
- * Function : test_drive
- *
- * Topics : Test the availability of a drive.
- *
- * Parameters : in int drive 0 = A:, 1 = B:, 2 = C:,...
- *
- * Return code: combination (bitwise OR) of
- * D_READABLE
- * D_WRITEABLE
- * D_NOFORMAT
- * D_INVALID
- * D_NOTINSERTED
- * D_REMOVABLE
- * D_SUBST
- * D_REMOTE
- *
- * OS/Compiler : MS-DOS version >= 3.10
- ***/
-
- int test_drive( int drive )
- {
- char fname[] = "x:\\t.t";
- int fhandle, status = 0;
-
- #define INTR 0x24
- /* save the old Fatal Error Interrupt handler */
- oldHandler = _dos_getvect( INTR );
-
- /* install new Fatal Error Interrupt handler */
- harderr( myHandler );
-
- diskError = -1;
-
- /* Open a file (write) */
- *fname = drive + 'A';
- fhandle = open( fname, O_CREAT, S_IREAD|S_IWRITE );
-
- /* restore the old Fatal Error Interrupt handler */
- _dos_setvect( INTR, oldHandler );
-
- if ( fhandle >= 0 ) close( fhandle );
- else if ( diskError < 0 ) diskError = errno * 100;
-
- if ( diskError < 0 ) unlink( fname );
-
- switch( diskError )
- {
- case -1: status |= D_WRITEABLE;
-
- case EACCES * 100:
- case 0: status |= D_READABLE; break;
-
- case EINVFMT * 100:
- case 12: status |= D_NOFORMAT; break;
-
- case ENMFILE * 100: /* No more files */
- case EMFILE * 100 : /* Too many open files */
- default: status |= D_INVALID;
- }
-
- {
- union REGS regs;
-
- /* Test if drive is remote, subst */
- regs.h.ah = 0x44; /* IOCTL function */
- regs.h.al = 0x09; /* subfunction */
- regs.h.bl = drive + 1;
- intdos( ®s, ®s );
- if ( ! regs.x.cflag )
- {
- if ( regs.x.dx & 0x1000 ) status |= D_REMOTE;
- if ( regs.x.dx & 0x8000 ) status |= D_SUBST;
- }
-
- /* Test if drive is removable */
- regs.h.ah = 0x44; /* IOCTL function */
- regs.h.al = 0x08; /* subfunction */
- regs.h.bl = drive + 1;
- intdos( ®s, ®s );
- if ( ! regs.x.cflag )
- if ( regs.x.ax == 0 ) status |= D_REMOVABLE;
- }
-
- /* Test if disk inserted */
- if ( (status & D_INVALID) && (status & D_REMOVABLE) )
- {
- status |= D_NOTINSERTED;
- status &= ~D_INVALID;
- }
-
- return status;
- }
-