Image Map Image Map
Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: Finding all valid DOS drive letters (unobtrusively)

  1. #1

    Default Finding all valid DOS drive letters (unobtrusively)

    I'm looking for a way to query DOS and enumerate all available drives in the system. My target is MS/PC-DOS 3.0 and above.

    For floppy drives, the sample code at http://www.fysnet.net/getdrvs.htm uses an acceptable method (already discussed here in the past).

    For non-floppy drives however, that same program simply tries to change the current drive (INT 21h function 0Eh) and then access it (function 19h). Another suggestion I've seen is to use function 29h (parse filename into FCB), which returns AL=FFh if the drive letter is invalid.

    What I'd like to know is, what happens if the drive is removable (CD-ROM/Zip/etc.)? Will these methods cause DOS to check for available media (possibly waiting quite a long time) before telling me if the drive letter is valid?

    The idea is to do this as unobtrusively as possible - at this point I only need to know if the drive *letter* is recognized, so I'd like to avoid annoying delays like that.
    int10h.org :: :: :: blog

  2. #2

    Default

    How about INT 21h function 44h (IOCTL) with AL=8 (Device Removable Query)? I think this will return CF=1 if the drive letter doesn't exist. Ultima VI (when run on DOS 3.0+) will enumerate over all 26 drive letters and call this on each one to determine which drives to look at for its disks. I used to play it on a machine with a CD-ROM drive and I don't remember it pausing on start to see if optical media was present. There is a note in HELPPC that "device drivers compatible with DOS 2.0 do not always respond correctly to this query" but that may not matter if it's just the availability of the drive letter that you care about and not the removable status.

  3. #3

    Default

    Thanks, I'll have to give that a test with DOS - I wonder if it's equivalent to the function 29th (FCB) method for my purposes. But yes, I don't need to know if the drive is removable; I just need a list of valid drives handy for a file-system navigation widget. So as long as it doesn't cause DOS to make spurious accesses to the drive, it should work well enough.
    int10h.org :: :: :: blog

  4. #4

    Default

    Just be sure to test on real hardware I made that mistake once, I did a 'stat' on 'con' on all drives, a:\con etc. worked great in dosbox, I got a list of drives that were present or not from a-z... total fail on real hardware!

  5. #5

    Default

    Quote Originally Posted by reenigne View Post
    How about INT 21h function 44h (IOCTL) with AL=8 (Device Removable Query)? I think this will return CF=1 if the drive letter doesn't exist.
    Yeah, that should work fine especially since it is supported from DOS 3.0. In XTIDECFG.COM I used INT 21h AX=4409h (CHECK_IF_BLOCK_DEVICE_REMOTE) which will also return CF set if the drive doesn't exist and it won't access the drive so there are no delays. It does require DOS 3.1 though so might not be suitable in this case.

    See this file if you want to see how it's done in XTIDECFG.COM (I'm not saying this is the best way to do it - In fact, I would very much like to hear any suggestions for improvement).
    Looking for a cache card for the "ICL ErgoPRO C4/66d V"

  6. #6
    Join Date
    Jan 2007
    Location
    Pacific Northwest, USA
    Posts
    31,000
    Blog Entries
    20

    Default

    Does this work on drive letters that are the object of subst?

  7. #7

    Default

    Quote Originally Posted by Chuck(G) View Post
    Does this work on drive letters that are the object of subst?
    Do you mean function 4408h or 4409h? In the case of 4409h then yes, at least according to RBIL. I haven't tried it myself as I don't think it really matters in this use case.
    Looking for a cache card for the "ICL ErgoPRO C4/66d V"

  8. #8

    Default

    Quote Originally Posted by BloodyCactus View Post
    Just be sure to test on real hardware I made that mistake once, I did a 'stat' on 'con' on all drives, a:\con etc. worked great in dosbox, I got a list of drives that were present or not from a-z... total fail on real hardware!
    I don't have any such removable drives to test on the real hardware (to rule out the delays), hence my asking here. I guess PCem, 86box or DOSBox-X might emulate them a little more accurately than DOSBox, but I still don't want to put all my trust in that.

    Quote Originally Posted by Krille View Post
    Yeah, that should work fine especially since it is supported from DOS 3.0. In XTIDECFG.COM I used INT 21h AX=4409h (CHECK_IF_BLOCK_DEVICE_REMOTE) which will also return CF set if the drive doesn't exist and it won't access the drive so there are no delays. It does require DOS 3.1 though so might not be suitable in this case.
    Ah, nice- that makes me somewhat confident that AL=08h would work similarly. A minimum requirement of 3.1 wouldn't be a huge deal actually, but I guess I'll go with the 3.0-supporting alternative.

    Quote Originally Posted by Krille View Post
    See this file if you want to see how it's done in XTIDECFG.COM (I'm not saying this is the best way to do it - In fact, I would very much like to hear any suggestions for improvement).
    Well, I've also been considering the issue with single-floppy systems and those "insert disk for drive A:/B:" DOS prompts. Your chosen solution is good enough for me (reading 0:504h to determine the current logical drive, and "hiding" the other one), but I still wonder if there's a way to go one better.

    What if you intercepted the requested drive number, modified the flag in 0:504h to match it, and only then executed the DOS call? That way DOS *should* play nice with whatever letter the user selects; the advantage is that you don't have to hide a potentially-valid drive letter, or have a weird-looking list starting with B:... assuming there are no other gotchas, of course.
    int10h.org :: :: :: blog

  9. #9

    Default

    Quote Originally Posted by VileR View Post
    Well, I've also been considering the issue with single-floppy systems and those "insert disk for drive A:/B:" DOS prompts. Your chosen solution is good enough for me (reading 0:504h to determine the current logical drive, and "hiding" the other one), but I still wonder if there's a way to go one better.
    There is actually. Almost a month after the other thread I got a PM from Malc where he had discovered this knowledge base article;
    Code:
    Accessing Drive w/o MS-DOS Message on Single Floppy System
    Last reviewed: July 17, 1997
    Article ID: Q71202 
    
    
    5.10 6.00 6.00a 6.00ax 7.00 | 1.00 1.50 
    MS-DOS | WINDOWS
    
    kbprg kbcode 
    
    The information in this article applies to: 
    
    The C Run-time (CRT), included with: 
    
    
    - Microsoft C for MS-DOS, versions 5.1, 6.0, 6.0a, and 6.0ax
    - Microsoft C/C++ for MS-DOS, version 7.0
    - Microsoft Visual C++ for Windows, versions 1.0 and 1.5
    
    
    
    
    SUMMARY
    When writing a program that accesses a floppy disk, the machine the program runs on may have only one floppy drive. In this scenario, the first access to drive B will generate the following message from MS-DOS: 
    
    
    Insert Diskette for Drive B: and press any key when ready
    
    
    This message is generated because MS-DOS allows a single physical floppy drive to be accessed as both the A and B logical drives. Unfortunately, the message will be written to the screen starting at the current cursor position, which may be undesirable in many cases. 
    
    
    MORE INFORMATION
    To avoid this message, you can first determine if only a single floppy drive is present in the system by calling Interrupt 11h. Interrupt 11h returns an equipment list code in AX, where bit zero will be 1 if there are floppy disk drives installed in the system, and bits 6 and 7 will be the number of floppy drives. If you determine that you are working on a single floppy system, then you can call Interrupt 21h, Function 44h, Subfunction 0Fh to indicate the drive you want to access next. 
    
    Once the call to this subfunction is made, MS-DOS will assume the correct disk is in the drive and will not generate the above message. When you want to switch drives again, call the same Subfunction 0Fh with the new drive. The following sample code illustrates this procedure: 
    
    
    
    Sample Code
    
    /* Compile options needed:
    */
    
    #include <dos.h>
    #include <direct.h>
    #include <stdio.h>
    
    
    union REGS inregs, outregs; 
    
    #define TRUE 1
    #define FALSE 0
    #define DRIVE_A 0x01
    #define DRIVE_B 0x02
    
    
    static int SingleFloppy = TRUE; // Assume one floppy. 
    
    void main(void);
    void SetDrive(char);
    
    void main(void)
    
    { 
    // Int 11h returns the equipment list code in AX.
    // Bit 0 indicates whether a floppy is installed.
    // Bits 6 and 7 indicate the number of drives (zero based).
    
    int86(0x11, &inregs, &outregs);
    
    // Do we only have one floppy drive?
    
    if (outregs.x.ax & 0xC0)
    SingleFloppy = FALSE;
    
    // Set the initial logical status to drive A.
    
    SetDrive(DRIVE_A);
    
    // From this point on, MS-DOS thinks that physical drive A is the
    // same as logical drive A. If you want to write to logical drive
    // B, merely call SetDrive() with DRIVE_B instead.
    
    } 
    
    void SetDrive(char DriveNum)
    
    { 
    if (SingleFloppy)
    {
    inregs.x.ax = 0x440f;
    inregs.h.bl = DriveNum;
    intdos(&inregs, &outregs);
    }
    
    } 
    
    
    
    
    --------------------------------------------------------------------------------
    Additional reference words: kbinf 6.00 6.00a 6.00ax 7.00 1.00 1.50
    KBCategory: kbprg kbcode
    KBSubcategory: CRTIss
    Keywords : kb16bitonly
    
    
    THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY. 
    
    Last reviewed: July 17, 1997
    © 1998 Microsoft Corporation. All rights reserved. Terms of Use.
    I haven't tried it yet but I'm sure this is the best way to do it. It requires DOS 3.2 though which isn't mentioned in the article. Sidenote; it's a pity all the old knowledge base articles like this are gone. Does anyone know if they have been saved somewhere?

    What if you intercepted the requested drive number, modified the flag in 0:504h to match it, and only then executed the DOS call? That way DOS *should* play nice with whatever letter the user selects; the advantage is that you don't have to hide a potentially-valid drive letter, or have a weird-looking list starting with B:... assuming there are no other gotchas, of course.
    That might actually be the easiest way to do it. But as I said in the other thread, once you modify this byte MS-DOS 6.22 seemingly ignores it after that point and won't print anything - at least in my (very) limited testing.
    Looking for a cache card for the "ICL ErgoPRO C4/66d V"

  10. #10

    Default

    Whoops - I missed that in the other thread's last post, thanks for the heads up.

    That KB article might help explain your finding with 6.22, too. I'd imagine that around 3.2 (or later), the need arose to apply logical-drive mapping in other scenarios than single-floppy systems. The IOCTL interface got a shiny new expanded structure for that purpose; later DOS versions kept updating the vestigial flag at 0:504h for compatibility, but in case of a mismatch it was simply disregarded.

    If so, maybe some judicious one-two combo (setting the Logical Drive Map for 3.2+, and poking the flag at 0:504h for older versions) could be a neat all-around solution without the need to 'hide' any drive letters. But in my case that would truly be "over-engineering", so the either-or approach is good enough for me.
    int10h.org :: :: :: blog

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •