Search the FAQ Archives

3 - A - B - C - D - E - F - G - H - I - J - K - L - M
N - O - P - Q - R - S - T - U - V - W - X - Y - Z
faqs.org - Internet FAQ Archives

comp.os.msdos.programmer FAQ part 3/5
Section - - Which real and virtual disk drives are valid?

( Part1 - Part2 - Part3 - Part4 - Part5 - Single Page )
[ Usenet FAQs | Web FAQs | Documents | RFC Index | Cities ]


Top Document: comp.os.msdos.programmer FAQ part 3/5
Previous Document: - How can I boot from drive B:?
Next Document: - How can I make my single floppy drive both a: and b:?
See reader questions & answers on this topic! - Help others by sharing your knowledge

 Use INT 21 AH=29 (parse filename). Point DS:SI at a null- terminated
 ASCII string that contains the drive letter and a colon, point ES:DI at
 a 37-byte dummy FCB buffer, and call INT 21 AX=2900. On return, AL is FF
 if the drive is invalid, something else if the drive is valid. RAM disks
 and SUBSTed drives are considered valid.

 You can detect whether the drive is ASSIGNed by using INT 2F AX=0601. To
 check whether the drive is SUBSTed, use INT 21 AX=4409; or use INT 21
 AH=52 to test for both JOIN and SUBST. See Ralf Brown's interrupt list:
 <Q:02.03> [What and where is Ralf Brown's interrupt list?].

 Unfortunately, the b: drive is considered valid even on a
 single-diskette system. You can check that special case by interrogating
 the BIOS equipment byte at 0040:0010. Bits 7- 6 contain the one less
 than the number of diskette drives, so if those bits are zero you know
 that b: is an invalid drive even though function 29 says it's valid.

 Following is some code originally posted by Doug Dougherty to test valid
 drives (treating SUBSTed and JOINed drives as valid), with my fix for
 the b: special case, tested in Borland C++ 4.5 (in the large model):

   #include <dos.h>
   #include <stdio.h>
   
   void drvlist(void)
   {
     char s[3] = "A:", fcb_buff[37];
     int valid;

     for( ;  *s<='Z';  (*s)++)
     {
       _SI = (unsigned) s;
       _DI = (unsigned) fcb_buff;
       _ES = _DS;
       _AX = 0x2900;

       geninterrupt(0x21);
       valid = _AL != 0xFF;

       if (*s == 'B'  &&  valid)
       {
         char far *equipbyte = (char far *)0x00400010UL;
         valid = (*equipbyte & (3 << 6)) != 0;
       }

       printf("Drive '%s' is %sa valid drive.\n", s, valid ? "" : "not ");
     }
   }

 This code was translated to MSC 7.0 and tested it in small model:

   #include <dos.h>
   #include <stdio.h>

   void drvlist(void)
   {
     char s[3] = "A:", fcb_buff[37], *buff=fcb_buff;
     int valid;

     for (   ;  *s<='Z';  (*s)++)
     {
       __asm mov si,s      __asm mov di,buff
       __asm mov ax,ds     __asm mov es,ax
       __asm mov ax,0x2900 __asm int 21h
       __asm xor ah,ah     __asm mov valid,ax

       valid = (valid != 0xFF);

       if (*s == 'B'  &&  valid)
       {
         char far *equipbyte = (char far *)0x00400010UL;
         valid = (*equipbyte & (3 << 6)) != 0;
       }

       printf("Drive '%s' is %sa valid drive.\n", s, valid ? "" : "not");
     }
   }

User Contributions:

Comment about this article, ask questions, or add new information about this topic:




Top Document: comp.os.msdos.programmer FAQ part 3/5
Previous Document: - How can I boot from drive B:?
Next Document: - How can I make my single floppy drive both a: and b:?

Part1 - Part2 - Part3 - Part4 - Part5 - Single Page

[ Usenet FAQs | Web FAQs | Documents | RFC Index ]

Send corrections/additions to the FAQ Maintainer:
jeffrey@carlyle.org (Jeffrey Carlyle)





Last Update March 27 2014 @ 02:11 PM