Mail Archives: djgpp-workers/1999/01/20/15:19:01
Here is a patch I call FAT32 step 1. It lays the foundation to build
on. It breaks out three functions from mntent.c and adds three, which
will be useful.
It compiles, however _is_fat32() is actually untested. The three from
mntent.c did work fine there so they ought to be good now. The two
_get_*() is tested but outside of libc.
Right,
MartinS
diff -ruN include.org/dos.h include/dos.h
--- include.org/dos.h Mon Sep 7 18:55:40 1998
+++ include/dos.h Tue Jan 19 21:08:06 1999
@@ -134,6 +134,12 @@
unsigned short _get_dos_version(int);
+int _get_fat_size(const int drive);
+int _get_fs_type(const int drive, char *const result_str);
+int _is_cdrom_drive(const int drive);
+int _is_fat32(const int drive);
+int _is_ram_drive(const int drive);
+int _media_type(const int drive);
int int86(int ivec, union REGS *in, union REGS *out);
int int86x(int ivec, union REGS *in, union REGS *out, struct SREGS *seg);
diff -ruN src.org/libc/compat/mntent/mntent.c src/libc/compat/mntent/mntent.c
--- src.org/libc/compat/mntent/mntent.c Sun Nov 15 14:20:56 1998
+++ src/libc/compat/mntent/mntent.c Sun Jan 17 21:51:34 1999
@@ -368,26 +368,6 @@
}
/*
- * Return 1 if this drive is a CD-ROM drive, 0 otherwise. Works
- * with MSCDEX 2.x, but what about other CD-ROM device drivers?
- */
-static int
-is_cdrom_drive(int drive_num)
-{
- __dpmi_regs r;
-
- r.x.ax = 0x150b; /* CD-ROM Drive Check function */
- r.x.cx = drive_num - 1; /* 0 = A: */
- __dpmi_int(0x2f, &r);
-
- /* If MSCDEX installed, BX will hold ADADh; AX will be non-zero
- if this drive is supported by MSCDEX. */
- if (r.x.bx == 0xadad && r.x.ax != 0)
- return 1;
- return 0;
-}
-
-/*
* Return 1 if a CD-ROM drive DRIVE_NUM is ready, i.e. there
* is a disk in the drive and the tray door is closed.
*/
@@ -445,51 +425,6 @@
return 0;
}
-/*
- * Detect a RAM disk. We do this by checking if the number of FAT
- * copies (in the Device Parameter Block) is 1, which is typical of
- * RAM disks. [This doesn't _have_ to be so, but if it's good
- * enough for Andrew Schulman et al (Undocumented DOS, 2nd edition),
- * we can use this as well.]
- */
-static int
-is_ram_drive(int drive_num)
-{
- __dpmi_regs r;
-
- r.h.ah = 0x32; /* Get Device Parameter Block function */
- r.h.dl = drive_num;
- __dpmi_int(0x21, &r);
-
- if (r.h.al == 0)
- {
- /* The pointer to DPB is in DS:BX. The number of FAT copies is at
- offset 8 in the DPB. */
- char fat_copies = _farpeekb(dos_mem_base, MK_FOFF(r.x.ds, r.x.bx) + 8);
-
- return fat_copies == 1;
- }
- return 0;
-}
-
-/*
- * Check if the media in this disk drive is fixed or removable.
- * Should only be called after we're sure this ain't CD-ROM or
- * RAM disk, since these might fool you with this call.
- */
-static int
-media_type(int drive_num)
-{
- __dpmi_regs r;
-
- r.x.ax = 0x4408;
- r.h.bl = drive_num;
- __dpmi_int(0x21, &r);
-
- if (r.x.flags & 1)
- return -1;
- return r.x.ax; /* returns 1 for fixed disks, 0 for removable */
-}
/* Exported library functions. */
@@ -700,11 +635,11 @@
*/
if (mnt_type[0] == '?')
{
- int disk_type = media_type(drive_number);
+ int disk_type = _media_type(drive_number);
- if (is_ram_drive(drive_number))
+ if (_is_ram_drive(drive_number))
mnt_type = NAME_ram;
- else if (is_cdrom_drive(drive_number))
+ else if (_is_cdrom_drive(drive_number))
{
/* Empty CD-ROM drives do NOT fail _truename(),
so we must see if there is a disk in the drive. */
diff -ruN src.org/libc/compat/sys/vfs/statfs.c src/libc/compat/sys/vfs/statfs.c
--- src.org/libc/compat/sys/vfs/statfs.c Sun Dec 13 13:09:46 1998
+++ src/libc/compat/sys/vfs/statfs.c Sat Jan 16 19:00:58 1999
@@ -4,6 +4,7 @@
#include <string.h>
#include <dpmi.h>
#include <go32.h>
+#include <dos.h>
#include <libc/farptrgs.h>
#include <errno.h>
#include <unistd.h>
@@ -17,7 +18,9 @@
__dpmi_regs regs;
int drive_number;
int cdrom_calls_used = 0;
- int blocks = 0;
+ long blocks = 0;
+ long free = 0;
+ long bsize = 0;
/* Get the drive number, including the case of magic
names like /dev/c/foo. */
@@ -44,7 +47,7 @@
if ((regs.x.flags & 1) == 0 && regs.x.bx == 0xadad && regs.x.ax != 0)
{
unsigned char request_header[0x14];
- int status, i = 2, bsize = 0;
+ int status, i = 2;
/* Construct the request header for the CD-ROM device driver. */
memset (request_header, 0, sizeof request_header);
@@ -89,9 +92,8 @@
if (_farpeekw (_dos_ds, __tb + 8) == 0x100
&& _farpeekw (_dos_ds, __tb + 5 + 0x12) == 5)
{
- regs.x.ax = 1; /* fake: sectors per cluster */
- regs.x.cx = bsize;
- regs.x.bx = 0; /* no free space: cannot add data to CD-ROM */
+ /* bsize has been set some lines above. */
+ free = 0; /* no free space: cannot add data to CD-ROM */
blocks = _farpeekl (_dos_ds, __tb + 1);
cdrom_calls_used = 1;
}
@@ -100,26 +102,70 @@
if (!cdrom_calls_used)
{
- /* Get free space info from DOS. */
- regs.h.ah = 0x36; /* DOS Get Free Disk Space call */
- regs.h.dl = drive_number + 1;
- __dpmi_int(0x21, ®s);
+ /* Get free space info from DOS. */
+ regs.h.ah = 0x36; /* DOS Get Free Disk Space call */
+ regs.h.dl = drive_number + 1;
+ __dpmi_int(0x21, ®s);
- /* Check for errors */
- if ((regs.x.ax & 0xffff) == 0xffff)
+ /* Check for errors */
+ if ((regs.x.ax & 0xffff) == 0xffff)
+ {
+ errno = ENODEV;
+ return -1;
+ }
+ bsize = regs.x.cx * regs.x.ax;
+ free = regs.x.bx;
+ blocks = regs.x.dx;
+#if 0
+ printf("First: bsize = %ld, free = %ld, blocks = %ld.\n"
+ , bsize
+ , free
+ , blocks
+ );
+#endif
+
+ if( 7 <= (_get_dos_version(1) >> 8) /* Is FAT32 supported? */
+ && _is_fat32(drive_number + 1) /* Is it a FAT32 drive? */
+ && blocks <= free /* Has free maxed out? */
+ )
{
- errno = ENODEV;
- return -1;
+ /* Get free space info from Extended Drive Parameter Block. */
+ regs.x.ax = 0x7302;
+ regs.h.dl = drive_number + 1;
+ regs.x.es = __tb_segment;
+ regs.x.di = __tb_offset;
+ regs.x.cx = 0x100; /* 256 bytes should be enough (RBIL says 0x3f). */
+ __dpmi_int(0x21, ®s);
+
+ /* Errors? */
+ if( regs.x.flags & 1 )
+ {
+ errno = ENODEV;
+ return( -1 );
+ }
+
+ bsize = _farpeekw (_dos_ds, __tb + 0x2 + 0x2) *
+ ( _farpeekb (_dos_ds, __tb + 0x2 + 0x4) + 1 );
+ free = _farpeekw (_dos_ds, __tb + 0x2 + 0x1f) +
+ 65536 * _farpeekw (_dos_ds, __tb + 0x2 + 0x21);
+ blocks = _farpeekl( _dos_ds, __tb + 0x2 + 0x2d);
+#if 0
+ printf("Second: bsize = %ld, free = %ld, blocks = %ld.\n"
+ , bsize
+ , free
+ , blocks
+ );
+#endif
+
}
- blocks = regs.x.dx;
}
/* Fill in the structure */
- buf->f_bavail = regs.x.bx;
- buf->f_bfree = regs.x.bx;
+ buf->f_bavail = free;
+ buf->f_bfree = free;
buf->f_blocks = blocks;
- buf->f_bsize = regs.x.cx * regs.x.ax;
- buf->f_ffree = regs.x.bx;
+ buf->f_bsize = bsize;
+ buf->f_ffree = free;
buf->f_files = blocks;
buf->f_type = 0;
buf->f_fsid[0] = drive_number;
diff -ruN src.org/libc/dos/dos/getfatsz.c src/libc/dos/dos/getfatsz.c
--- src.org/libc/dos/dos/getfatsz.c Thu Jan 1 00:00:00 1970
+++ src/libc/dos/dos/getfatsz.c Sat Jan 9 13:29:48 1999
@@ -0,0 +1,38 @@
+/*
+ * File getfatsz.c.
+ *
+ * Copyright (C) 1999 Martin Str”mberg <ams AT ludd DOT luth DOT se>.
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact. There is no warranty on this software.
+ *
+ */
+
+#include <dpmi.h>
+#include <dos.h>
+
+/* Returns number of bits in FAT; 0 == FAT of unknown size; -1 == error. */
+int
+_get_fat_size( const int drive /* drive number (1=A:). */
+ )
+{
+ char s[9];
+ int n;
+ int size;
+
+ if( _get_fs_type( drive, s ) )
+ {
+ if( s[0] == 'F' && s[1] == 'A' && s[2] == 'T' )
+ {
+ size = 0;
+ for(n = 3; n < 8 && ( '0' <= s[n] && s[n] <= '9' ); n++)
+ {
+ size = 10*size + s[n] - '0';
+ }
+
+ return( size );
+ }
+ }
+
+ return( -1 );
+}
diff -ruN src.org/libc/dos/dos/getfatsz.txh src/libc/dos/dos/getfatsz.txh
--- src.org/libc/dos/dos/getfatsz.txh Thu Jan 1 00:00:00 1970
+++ src/libc/dos/dos/getfatsz.txh Sun Jan 10 19:00:42 1999
@@ -0,0 +1,47 @@
+@node _get_fat_size, file system
+@subheading Syntax
+
+@example
+#include <dos.h>
+
+int _get_fat_size( const int drive );
+@end example
+
+@subheading Description
+
+This function tries to determine the number bits used to enumerate the
+clusters by the FAT on drive number @var{drive}. 1 == A:, 2 == B:,
+etc.
+
+This function will not succeed on DOS version < 4.
+
+@subheading Return Value
+
+The number of bits used by the FAT (12, 16 or 32). 0 if the drive was
+formatted with FAT but of unknown size (NT reports that on FAT16). -1
+on error.
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+#include <stdio.h>
+#include <dos.h>
+
+int main(void)
+@{
+ int size;
+
+ size = _get_fs_type( 'C' - 'A' + 1 );
+ if( 0 <= size )
+ @{
+ printf("The size of FAT on C: is %d bits.\n", size);
+ @}
+
+ exit(0);
+@}
+
+@end example
diff -ruN src.org/libc/dos/dos/getfstyp.c src/libc/dos/dos/getfstyp.c
--- src.org/libc/dos/dos/getfstyp.c Thu Jan 1 00:00:00 1970
+++ src/libc/dos/dos/getfstyp.c Sat Jan 9 13:29:04 1999
@@ -0,0 +1,58 @@
+/*
+ * File getfstyp.c.
+ *
+ * Copyright (C) 1999 Martin Str”mberg <ams AT ludd DOT luth DOT se>.
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact. There is no warranty on this software.
+ *
+ */
+
+#include <dos.h>
+#include <go32.h>
+#include <dpmi.h>
+#include <sys/farptr.h>
+
+/* Returns: 0 == error; 1 == result_str filled in. */
+int
+_get_fs_type( const int drive /* drive number (1=A:). */
+ , char *const result_str /* String to put result in. At least 9 chars long. */
+ )
+{
+ int n;
+ __dpmi_regs r;
+
+ /* Check DOZE version and return -1 if too low. */
+ if( ( _get_dos_version(1) >> 8) < 4 )
+ {
+ return( 0 );
+ }
+
+ /* Call INT21, ax==0x6900 i.e. Get Disk Serial Number (sic!). */
+ r.x.ax = 0x6900;
+ r.h.bl = drive;
+ r.h.bh = 0;
+ r.x.ds = __tb >> 4;
+ r.x.dx = __tb & 0x0f;
+ __dpmi_int(0x21, &r);
+ if( (r.x.flags & 1) == 0 )
+ {
+ /* Get the file system type. */
+ for(n = 0; n < 8; n++)
+ {
+ result_str[n] = _farpeekb( _dos_ds, __tb + 0x11 + n);
+ }
+ result_str[8] = 0;
+
+ /* Remove terminating spaces. */
+ for(n = 7; n && result_str[n] == ' '; n-- )
+ {
+ result_str[n] = 0;
+ }
+
+ return( 1 );
+ }
+
+ return( 0 );
+
+}
diff -ruN src.org/libc/dos/dos/getfstyp.txh src/libc/dos/dos/getfstyp.txh
--- src.org/libc/dos/dos/getfstyp.txh Thu Jan 1 00:00:00 1970
+++ src/libc/dos/dos/getfstyp.txh Sun Jan 10 19:00:46 1999
@@ -0,0 +1,48 @@
+@node _get_fs_type, file system
+@subheading Syntax
+
+@example
+#include <dos.h>
+
+int _get_fs_type( const int drive
+ , char *const result_str
+ );
+@end example
+
+@subheading Description
+
+This function tries to extract the file system type of the drive
+number @var{drive}, 1 == A:, 2 == B:, etc. If successful the result
+is put in @var{result_str} which must be at least 9 characters long.
+
+This function will not succeed on DOS version < 4 and is known to have
+trouble detecting the file system type of disks formatted with a later
+version of DOS than on the version it is run on.
+
+@subheading Return Value
+
+1 if the file system type was extracted successfully; otherwise 0.
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+#include <stdio.h>
+#include <dos.h>
+
+int main(void)
+@{
+ char buffer[9];
+
+ if( _get_fs_type( 3, buffer ) )
+ @{
+ printf("The file system on C: is '%s'.\n", buffer);
+ @}
+
+ exit(0);
+@}
+
+@end example
diff -ruN src.org/libc/dos/dos/iscdrom.c src/libc/dos/dos/iscdrom.c
--- src.org/libc/dos/dos/iscdrom.c Thu Jan 1 00:00:00 1970
+++ src/libc/dos/dos/iscdrom.c Sun Jan 17 21:08:36 1999
@@ -0,0 +1,20 @@
+/* Copyright (c) 1995-98 Eli Zaretskii <eliz AT is DOT elta DOT co DOT il> */
+
+#include <dpmi.h>
+#include <dos.h>
+
+int
+_is_cdrom_drive(int drive_num)
+{
+ __dpmi_regs r;
+
+ r.x.ax = 0x150b; /* CD-ROM Drive Check function */
+ r.x.cx = drive_num - 1; /* 0 = A: */
+ __dpmi_int(0x2f, &r);
+
+ /* If MSCDEX installed, BX will hold ADADh; AX will be non-zero
+ if this drive is supported by MSCDEX. */
+ if (r.x.bx == 0xadad && r.x.ax != 0)
+ return 1;
+ return 0;
+}
diff -ruN src.org/libc/dos/dos/iscdrom.txh src/libc/dos/dos/iscdrom.txh
--- src.org/libc/dos/dos/iscdrom.txh Thu Jan 1 00:00:00 1970
+++ src/libc/dos/dos/iscdrom.txh Sun Jan 17 19:57:10 1999
@@ -0,0 +1,45 @@
+@node _is_cdrom_drive, file system
+@subheading Syntax
+
+@example
+#include <dos.h>
+
+int _is_cdrom_drive( const int drive );
+@end example
+
+@subheading Description
+
+This function checks if drive number @var{drive} (1 == A:, 2 == B:,
+etc.) is a CD-ROM drive. Works with MSCDEX 2.x, but what about other
+CD-ROM device drivers?
+
+@subheading Return Value
+
+1 if the drive is a CDROM drive, otherwise 0.
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+#include <stdio.h>
+#include <dos.h>
+
+int main(void)
+@{
+
+ if( _is_cdrom_drive( 'R' - 'A' + 1 ) )
+ @{
+ printf("C: is a CDROM drive.\n");
+ @}
+ else
+ @{
+ printf("C: is not a CDROM drive.\n");
+ @}
+
+ exit(0);
+@}
+
+@end example
diff -ruN src.org/libc/dos/dos/isfat32.c src/libc/dos/dos/isfat32.c
--- src.org/libc/dos/dos/isfat32.c Thu Jan 1 00:00:00 1970
+++ src/libc/dos/dos/isfat32.c Sun Jan 17 21:11:56 1999
@@ -0,0 +1,76 @@
+/*
+ * This is the file isfat32.c.
+ *
+ * Copyright (C) 1999 Martin Str”mberg <ams AT ludd DOT luth DOT se>.
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact. There is no warranty on this software.
+ *
+ */
+
+#include <dos.h>
+
+static unsigned long checked = 0;
+static unsigned long removable = 0;
+static unsigned long fat32 = 0;
+
+/* Returns 1 if the drive is formatted with FAT32; 0 otherwise. */
+int
+_is_fat32( const int drive /* drive number (1=A:). */
+ )
+{
+ unsigned long mask;
+
+ /* Check input. */
+ if( 0 <= drive
+ && drive <= 32
+ )
+ {
+ /* Always check current drive (as we don't know if it's been changed). */
+ if( drive == 0 )
+ {
+ return( _get_fat_size( drive ) == 32 );
+ }
+ else
+ {
+ mask = 1 << ( drive - 1 );
+
+ /* Have we checked this drive for FAT32 yet and it isn't removable? */
+ if( checked & mask
+ && !( removable & mask ) )
+ {
+ return( ( fat32 & mask ) != 0 );
+ }
+
+ /* Always recheck removable drives. */
+ if( removable & mask )
+ {
+ return( _get_fat_size( drive ) == 32 );
+ }
+
+ /* Previously untested drive -> update tables. */
+
+ /* Is this a removable drive? (!_is_*_drive for _media_type problems.) */
+ if( !_is_ram_drive( drive )
+ && !_is_cdrom_drive( drive )
+ && _media_type( drive ) == 0 )
+ {
+ removable |= mask;
+ checked |= mask;
+ return( _get_fat_size( drive ) == 32 );
+ }
+
+ if( _get_fat_size( drive ) == 32 )
+ {
+ fat32 |= mask;
+ }
+
+ checked |= mask;
+
+ return( ( fat32 & mask ) != 0 );
+ }
+ }
+
+ /* Drives that don't exist can't be FAT32. */
+ return( 0 );
+}
diff -ruN src.org/libc/dos/dos/isfat32.txh src/libc/dos/dos/isfat32.txh
--- src.org/libc/dos/dos/isfat32.txh Thu Jan 1 00:00:00 1970
+++ src/libc/dos/dos/isfat32.txh Sun Jan 17 21:04:52 1999
@@ -0,0 +1,47 @@
+@node _is_fat32, file system
+@subheading Syntax
+
+@example
+#include <dos.h>
+
+int _is_fat32( const int drive );
+@end example
+
+@subheading Description
+
+This function checks if drive number @var{drive} (1 == A:, 2 == B:,
+etc.) is formatted with FAT32.
+
+For performance reasons the result is cached, hence if a drive is
+reformatted either from or to FAT32 a DJGPP program must be restarted.
+
+@subheading Return Value
+
+1 if the drive is formatted with FAT32, otherwise 0.
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+#include <stdio.h>
+#include <dos.h>
+
+int main(void)
+@{
+
+ if( _is_fat32( 'C' - 'A' + 1 ) )
+ @{
+ printf("C: is a FAT32 drive.\n");
+ @}
+ else
+ @{
+ printf("C: is not a FAT32 drive.\n");
+ @}
+
+ exit(0);
+@}
+
+@end example
diff -ruN src.org/libc/dos/dos/isramdri.c src/libc/dos/dos/isramdri.c
--- src.org/libc/dos/dos/isramdri.c Thu Jan 1 00:00:00 1970
+++ src/libc/dos/dos/isramdri.c Sun Jan 17 21:36:10 1999
@@ -0,0 +1,33 @@
+/* Copyright (c) 1995-98 Eli Zaretskii <eliz AT is DOT elta DOT co DOT il> */
+
+#include <dpmi.h>
+#include <go32.h>
+#include <sys/farptr.h>
+#include <dos.h>
+
+/* Macro to convert a segment and an offset to a "far offset" suitable
+ for _farxxx() functions of DJGPP. */
+#ifndef MK_FOFF
+#define MK_FOFF(s,o) ((int)((((unsigned long)(unsigned short)(s)) << 4) + \
+ (unsigned short)(o)))
+#endif
+
+int
+_is_ram_drive(int drive_num)
+{
+ __dpmi_regs r;
+
+ r.h.ah = 0x32; /* Get Device Parameter Block function */
+ r.h.dl = drive_num;
+ __dpmi_int(0x21, &r);
+
+ if (r.h.al == 0)
+ {
+ /* The pointer to DPB is in DS:BX. The number of FAT copies is at
+ offset 8 in the DPB. */
+ char fat_copies = _farpeekb(_dos_ds, MK_FOFF(r.x.ds, r.x.bx) + 8);
+
+ return fat_copies == 1;
+ }
+ return 0;
+}
diff -ruN src.org/libc/dos/dos/isramdri.txh src/libc/dos/dos/isramdri.txh
--- src.org/libc/dos/dos/isramdri.txh Thu Jan 1 00:00:00 1970
+++ src/libc/dos/dos/isramdri.txh Sun Jan 17 19:57:46 1999
@@ -0,0 +1,37 @@
+@node _is_ram_drive, file system
+@subheading Syntax
+
+@example
+#include <dos.h>
+
+int _is_ram_drive( const int drive );
+@end example
+
+@subheading Description
+
+This function checks if drive number @var{drive} (1 == A:, 2 == B:,
+etc.) is a RAM disk. It is done by checking if the number of FAT
+copies (in the Device Parameter Block) is 1, which is typical of
+RAM disks. (This doesn't _have_ to be so, but if it's good enough for
+Andrew Schulman et al (Undocumented DOS, 2nd edition), we can use this
+as well.)
+
+@subheading Return Value
+
+1 if the drive is a RAM drive, otherwise 0.
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+#include <stdio.h>
+#include <dos.h>
+
+ int i = 4;
+
+ printf("%c: is a RAM drive: %d.\n", 'A' - 1 + i, _is_ram_drive( i ) )
+
+@end example
diff -ruN src.org/libc/dos/dos/makefile src/libc/dos/dos/makefile
--- src.org/libc/dos/dos/makefile Sun Jun 18 02:50:38 1995
+++ src/libc/dos/dos/makefile Sun Jan 17 19:50:06 1999
@@ -10,6 +10,8 @@
SRC += getdfree.c
SRC += getdinfo.c
SRC += getdos_v.c
+SRC += getfatsz.c
+SRC += getfstyp.c
SRC += getftime.c
SRC += gettime.c
SRC += gettimeo.c
@@ -17,6 +19,10 @@
SRC += int86x.S
SRC += intdos.c
SRC += intdosx.c
+SRC += iscdrom.c
+SRC += isfat32.c
+SRC += isramdri.c
+SRC += mediatyp.c
SRC += osflavor.c
SRC += osmajor.c
SRC += osminor.c
diff -ruN src.org/libc/dos/dos/mediatyp.c src/libc/dos/dos/mediatyp.c
--- src.org/libc/dos/dos/mediatyp.c Thu Jan 1 00:00:00 1970
+++ src/libc/dos/dos/mediatyp.c Sun Jan 17 21:36:06 1999
@@ -0,0 +1,18 @@
+/* Copyright (c) 1995-98 Eli Zaretskii <eliz AT is DOT elta DOT co DOT il> */
+
+#include <dpmi.h>
+#include <dos.h>
+
+int
+_media_type(int drive_num)
+{
+ __dpmi_regs r;
+
+ r.x.ax = 0x4408;
+ r.h.bl = drive_num;
+ __dpmi_int(0x21, &r);
+
+ if (r.x.flags & 1)
+ return -1;
+ return r.x.ax; /* returns 1 for fixed disks, 0 for removable */
+}
diff -ruN src.org/libc/dos/dos/mediatyp.txh src/libc/dos/dos/mediatyp.txh
--- src.org/libc/dos/dos/mediatyp.txh Thu Jan 1 00:00:00 1970
+++ src/libc/dos/dos/mediatyp.txh Sun Jan 17 18:47:42 1999
@@ -0,0 +1,53 @@
+@node _media_type, file system
+@subheading Syntax
+
+@example
+#include <dos.h>
+
+int _media_type( const int drive );
+@end example
+
+@subheading Description
+
+This function checks if drive number @var{drive} (. 1 == A:, 2 == B:,
+etc.) is fixed or removable.
+
+@code{_media_type} should only be called after you are sure the drive
+isn't a CD-ROM or a RAM disk, since these might fool you with this
+call.
+
+For performance reasons the result is cached.
+
+@subheading Return Value
+
+1 if the drive is a fixed disk, 0 if it is removable. -1 on error.
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+#include <stdio.h>
+#include <dos.h>
+
+Some work is needed here.
+
+
+int main(void)
+@{
+
+ if( _is_fat32( 'C' - 'A' + 1 ) )
+ @{
+ printf("C: is a FAT32 drive.\n");
+ @}
+ else
+ @{
+ printf("C: is not a FAT32 drive.\n");
+ @}
+
+ exit(0);
+@}
+
+@end example
- Raw text -