Drive Letter to Bios Number to Physical Drive

Drive Letter to Bios Number to Physical Drive

Post by Paul Johnso » Sat, 23 Dec 2000 06:26:08



   I'm trying to match up Physical Drives (ide primary/master,
secondary/master, etc) to BIOS drive numbers (80h, 81h, 82h..) to DOS
drive letters (c: d: e:). I've been looking at the BIOS and DOS
interrupts and haven't found an easy way to do this. I'm planning on
using Int 21/AX=7305 to read the boot sector and random sector of each
drive letter, then parse the drive partition tables with int 13 and
attempt to match drive letters to bios drive numbers. As for the
physical drive to bios drive matching, perhaps sending an ata command to
read a sector off each drive and doing something similar. Is there an
easier way of doing this, such as a map in memory that links all three
together? Or any interrupts I have not found yet to do this?

Sent via Deja.com
http://www.deja.com/

 
 
 

Drive Letter to Bios Number to Physical Drive

Post by Paul Schlyt » Sat, 23 Dec 2000 17:47:05


In article <91tsh8$r4...@nnrp1.deja.com>,
Paul Johnson  <paulj...@yahoo.com> wrote:

> I'm trying to match up Physical Drives (ide primary/master,
> secondary/master, etc) to BIOS drive numbers (80h, 81h, 82h..) to DOS
> drive letters (c: d: e:). I've been looking at the BIOS and DOS
> interrupts and haven't found an easy way to do this. I'm planning on
> using Int 21/AX=7305 to read the boot sector and random sector of each
> drive letter, then parse the drive partition tables with int 13 and
> attempt to match drive letters to bios drive numbers. As for the
> physical drive to bios drive matching, perhaps sending an ata command to
> read a sector off each drive and doing something similar. Is there an
> easier way of doing this, such as a map in memory that links all three
> together? Or any interrupts I have not found yet to do this?

You might find the code below of some interest.  Among other things
it maps DOS drive letters to BIOS drive numbers.

--------------------------------------------------------------------------

/*

DRIVES.C -- find out which disk drives are available on system

A quick hack by Paul Schlyter, 1994-04-27

1995-03-14  PS  Now also outputs true drive names (network etc)
1996-04-09  PS  Local HD cluster size, free & total space output added

*/

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include <dos.h>

typedef unsigned char  byte;
typedef unsigned short word;
typedef unsigned long  dword;

#define BIT(n)  ( 1 << (n) )

char startup_drive(void)
{
    union REGS r;
    r.x.ax = 0x3305;
    intdos( &r, &r );
    return  r.h.dl + '@';

}  /* startup_drive */

char default_drive(void)
{
    union REGS r;
    r.h.ah = 0x19;
    intdos( &r, &r );
    return r.h.al + 'A';

}  /* default_drive */

int is_removable( char drive )
{
    union REGS r;
    r.x.ax = 0x4408;
    r.h.bl = drive - '@';
    intdos( &r, &r );
    if ( r.x.cflag )
        return -1;
    else
        return  r.x.ax == 0;  /* AX == 0 ==> removable media */

}  /* is_removable */

int host_drive( char drive )
{
    union REGS r;
    r.x.bx = 1;            /* DSGetDriveMapping */
    r.h.dl = drive - 'A';  /* Drive */
    r.x.ax = 0x4A11;       /* DoubleSpace multiplex function */
    int86( 0x2F, &r, &r );
    if ( r.x.ax != 0 )
        return -1;         /* Error */
    if ( (r.h.bl & 0x80) == 0 )
        return 0;          /* Not compressed */
    else
        return  (r.h.bl & 0x7F) + 'A';

}  /* host_drive */

int drivetype( char drive )
{
    union REGS r;
    r.x.ax = 0x4409;
    r.h.bl = drive - '@';
    intdos( &r, &r );
    if ( r.x.cflag )
        return -1;
    else
        return  r.x.dx;
    /*
     *  DX now contains:
     *
     * Bit  1:  1=Drive uses 32-bit sector addressing
     * Bit  6:  1=Drive accepts Generic IOCTL, GET/SET Logical Drive Map
     *             (Functions 440Dh, 440Eh, 440Fh)
     * Bit  7:  1=Drive accepts Query IOCTL (Function 4411h)
     * Bit  9:  1=Drive is local but shared by others on the network
     * Bit 11:  1=Drive accepts Does Device Use Removable Media (Func 4408h)
     * Bit 12:  1=Drive is remote
     * Bit 13:  1=Drive requires media descriptor in FAT
     * Bit 14:  1=Drive accepts Send/Receive Control Data To/From Block
                    Device (Functions 4404h, 4405h)
     * Bit 15:  1=Substitution Drive
     *
     */

}  /* drivetype */

int isCDROMdrive( char drive )
{
    union REGS r;

    r.x.ax = 0x1500;        /* First test for presence of MSCDEX */
    r.x.bx = 0;
    int86( 0x2F, &r, &r );
    if ( r.x.bx == 0 )
        return 0;           /* MSCDEX not there, so return FALSE */
    r.x.ax = 0x150B;        /* MSCDEX driver check API */
    r.x.cx = drive - 'A';
    int86( 0x2F, &r, &r );
    return  r.x.ax != 0;    /* Drive is CDROM if AX nonzero */

}  /* isCDROMdrive */

int truename( char far *src, char far *dst )
{
    union REGS r;
    struct SREGS s;
    char far *s2;

    /* INT 21h AH=60h doesn't like leading or trailing blanks */
    while (isspace(*src))
        src++;
    s2 = src;
    while (*s2)
        s2++;
    s2--;
    while (isspace(*s2))
        *s2-- = 0;

    s.ds = FP_SEG(src);
    s.es = FP_SEG(dst);
    r.x.si = FP_OFF(src);
    r.x.di = FP_OFF(dst);
    r.h.ah = 0x60;
    intdosx( &r, &r, &s );

    return  r.x.cflag ? -1 : 0;

}  /* truename */

char *truedrive( char drive )
{
    static char src[20] = "X:\\", dst[80];

    src[0] = toupper(drive);
    if ( truename( src, dst ) < 0 )
        return  NULL;
    else if ( strcmp( src, dst ) == 0 )
        return NULL;
    else
        return dst;

}  /* truedrive */

char logdrvmap( char drive )
{
    union REGS r;
    r.x.ax = 0x440E;   /* MS-DOS Get Logical Drive Map function */
    r.h.bl = (char) (drive - 'A' + 1);
    intdos( &r, &r );
    if ( r.x.cflag )
        return  r.h.al;  /*   1 = drive remote or cannot be shared
                          *   5 = device driver returns error
                          * 0xF = drive invalid
                          */
    else if ( r.h.al )
        return  (char) (r.h.al - 1 + 'A');  /* Drive shared with ... */
    else
        return 0;        /* Drive not shared */

}  /* logdrvmap */

struct unit_tab
{
    void far * next;
    byte       drvno;       /* DL while calling int 13h */
    byte       DOS_drvno;   /* 0-based DOS drive number */
    byte       BPB[0x19];   /* BIOS Parameter Block for this drive */
    byte       fsf;         /* File System Flags for HD partitions:  
                             * 00h = 12-bit FAT
                             * 40h = 16-bit FAT
                             * 80h = unsupported partition
                             */
    word       opens;       /* # Open's without matching Close's */
    byte       dev_type;    /* Form factor:  
                             * 00h = floppy, 40 cyl's, <= 9 sect/trk  
                             * 01h = floppy, 80 cyl's, 15 sect/trk
                             * 02h = floppy, 80 cyls, 9 sect/trk
                             * 05h = hard disk
                             * 07h = other type of floppy
                             * 09h = floppy, 80 cyls, 36 sect/trk
                             */
    word       status;      /* Status flags for the drive:
                             * 0001h  non-removable media
                             * 0002h  change-line detection supp. by BIOS
                             * 0004h  disk PBP (at offset 06h) locked
                             * 0008h  good track layout, sect's equally sized
                             * 0010h  shares whole phys.dev w other LUN's
                             * 0020h  active unit for shared phys. dev
                             * 0040h  disk change detected
                             * 0080h  set DASD before format
                             * 0100h  disk reformat detected
                             * 0200h  read/write disabled
                             */
    word       cylinders;   /* Number of cylinders spanning the drive/part */
    byte   def_BPB[0x1F];   /* BPB repr. default disk format for drive */
    byte       cyl8;        /* Low 8bits of cyl # for last giid rd/wr/ver */
    dword      clk_corr;    /* Remov. disk: clock count of last good access */
                            /* Fixed disk: minidisk cyl corr to complete
                               reduction of drive parameters logic==>physic */
    byte   vollab[0x0C];    /* 11-byte volume label + NUL terminator */
    dword      serial_no;   /* Disk serial number */
    byte       filesys[9];  /* 8-byte file system label + NUL:
                               "FAT12" or "FAT16", padded with spaces */

};

#ifndef MK_FP
#define MK_FP(seg,ofs)  (void far *) ( ((long)(seg) << 16) + (ofs) )
#endif

struct unit_tab far *next_unit_tab( struct unit_tab far *t )
{
    if ( t == NULL )
    {
        union REGS r;
        struct SREGS s;
        r.x.ax = 0x0800;
        int86( 0x2F, &r, &r );
        if ( r.h.al != 0xFF )
            return  NULL;           /* Unit Table chain not available */
        r.x.ax = 0x0803;
        int86x( 0x2F, &r, &r, &s );
        t = MK_FP( s.ds, r.x.di );  /* Get first entry to Unit Table chain */
    }
    else
        t = t->next;                /* Get next entry to Unit Table chain */
    if ( FP_OFF(t) == 0xFFFF )
        t = NULL;                   /* End of chain */
    return t;

}  /* next_unit_tab */

struct unit_tab far *int13unit( int DOSvol )
{
    struct unit_tab far *t = NULL;
    for(;;)
    {
        t = next_unit_tab( t );
        if ( t == NULL )
            return  NULL;
        if ( DOSvol == (t->DOS_drvno + 'A') )
            return  t;
    }

}  /* int13unit */

char read_cmos( int addr )
{
    outp( 0x70, addr );
    return  inp( 0x71 );

}  /* read_cmos */

char *floppytype( int int13drive )
{
    int cmos_10h = read_cmos( 0x10 );
    if ( int13drive < 0 || int13drive > 1 )
        return "";
    if ( int13drive == 0 )
        cmos_10h >>= 4;
    cmos_10h &= 0x0F;
    switch( cmos_10h )
    {
        case 0:  return  "(no floppy)";
        case 1:  return  "5.25\" 360 kB";
        case 2:  return  "5.25\" 1.2 MB";
        case 3:  return  "3.5\"  720 kB";
        case 4:  return  "3.5\" 1.44 MB";
        case 5:  return  "3.5\" 2.88 MB";
        default: return  "";
    }

}  /* floppytype */

void criterr( int install )
/*
 *  Install/deinstall Int 24h Critical Error Handler that just
 *  returns "fail".  Input:  1=installs, 0=deinstalls
 */
{
    static short i24_seg, i24_ofs;
    static char int24_handler[] =
    {
        0xB0, 0x03,   /* mov al, 03h */
        0xCF          /* iret */
    };
    union REGS r;
    struct SREGS s;

    if ( install )
    {
        /* First get -- and remember -- the old interrupt vector */
        segread(&s);
        r.x.ax = 0x3524;
        intdosx( &r, &r, &s );
        i24_seg = s.es, i24_ofs = r.x.bx;

        /* Now install our own Int 24h
...

read more »

 
 
 

Drive Letter to Bios Number to Physical Drive

Post by d-fenc » Fri, 29 Dec 2000 07:27:46


Hi,

If I understand your problem, it's not a godd idea to try that because any
letter could be on any physical drive.
DOS drive letters are only logical. You have to analyze partitions tables to
find what kind of partition is on which physical drive.

By the way, if you find anything interresting on reading sectors on large
drives (more than 8 Gb), I'm really interrested.
I failed in programming Int 13h extensions.

As far as I know, drive letters are decided by the OS which is booting (For
example, try to make a booting CD-ROM and you'll find that CD-ROM has drive
letter A: and your floppy is now b:). So, if you boot with a "boot manager",
a partition with W98 will be 'c:' when you boot on it but on the other hand,
assume that you have another partition with DOS, it will be "another" 'c:'
partition if you boot on it. And at the end, try to boot LINUX and there is
no more c or d or whatever partition but only 'hda', 'hdb' and so on for IDE
drives !

So, letters are only logical and it's impossible to know which one is 'c' or
'd' because it depends on many factors and 'c' doens't means anything until
the boot process is finished.

Further more, the letters used in BIOS configuration systems are there only
to help newbies but are not real (just like the spoon in Matrix)

The linux way is better because HDA is always the primary master IDE, and
have the number 80h. In DOS, 'c:' is only the first 'recognized' partition
(try to boot with a floppy and without any HD DOS partition and you'll see
that there is no 'c:' even if a HD is present).

Bye
D-fence
d-fe...@swing.be

Paul Schlyter <pau...@saaf.se> a crit dans le message :
91v4e9$5m...@merope.saaf.se...

> In article <91tsh8$r4...@nnrp1.deja.com>,
> Paul Johnson  <paulj...@yahoo.com> wrote:

> > I'm trying to match up Physical Drives (ide primary/master,
> > secondary/master, etc) to BIOS drive numbers (80h, 81h, 82h..) to DOS
> > drive letters (c: d: e:). I've been looking at the BIOS and DOS
> > interrupts and haven't found an easy way to do this. I'm planning on
> > using Int 21/AX=7305 to read the boot sector and random sector of each
> > drive letter, then parse the drive partition tables with int 13 and
> > attempt to match drive letters to bios drive numbers. As for the
> > physical drive to bios drive matching, perhaps sending an ata command to
> > read a sector off each drive and doing something similar. Is there an
> > easier way of doing this, such as a map in memory that links all three
> > together? Or any interrupts I have not found yet to do this?

> You might find the code below of some interest.  Among other things
> it maps DOS drive letters to BIOS drive numbers.

> --------------------------------------------------------------------------

> /*

> DRIVES.C -- find out which disk drives are available on system

> A quick hack by Paul Schlyter, 1994-04-27

> 1995-03-14  PS  Now also outputs true drive names (network etc)
> 1996-04-09  PS  Local HD cluster size, free & total space output added

> */

> #include <stdio.h>
> #include <string.h>
> #include <ctype.h>

> #include <dos.h>

> typedef unsigned char  byte;
> typedef unsigned short word;
> typedef unsigned long  dword;

> #define BIT(n)  ( 1 << (n) )

> char startup_drive(void)
> {
>     union REGS r;
>     r.x.ax = 0x3305;
>     intdos( &r, &r );
>     return  r.h.dl + '@';
> }  /* startup_drive */

> char default_drive(void)
> {
>     union REGS r;
>     r.h.ah = 0x19;
>     intdos( &r, &r );
>     return r.h.al + 'A';
> }  /* default_drive */

> int is_removable( char drive )
> {
>     union REGS r;
>     r.x.ax = 0x4408;
>     r.h.bl = drive - '@';
>     intdos( &r, &r );
>     if ( r.x.cflag )
>         return -1;
>     else
>         return  r.x.ax == 0;  /* AX == 0 ==> removable media */
> }  /* is_removable */

> int host_drive( char drive )
> {
>     union REGS r;
>     r.x.bx = 1;            /* DSGetDriveMapping */
>     r.h.dl = drive - 'A';  /* Drive */
>     r.x.ax = 0x4A11;       /* DoubleSpace multiplex function */
>     int86( 0x2F, &r, &r );
>     if ( r.x.ax != 0 )
>         return -1;         /* Error */
>     if ( (r.h.bl & 0x80) == 0 )
>         return 0;          /* Not compressed */
>     else
>         return  (r.h.bl & 0x7F) + 'A';
> }  /* host_drive */

> int drivetype( char drive )
> {
>     union REGS r;
>     r.x.ax = 0x4409;
>     r.h.bl = drive - '@';
>     intdos( &r, &r );
>     if ( r.x.cflag )
>         return -1;
>     else
>         return  r.x.dx;
>     /*
>      *  DX now contains:
>      *
>      * Bit  1:  1=Drive uses 32-bit sector addressing
>      * Bit  6:  1=Drive accepts Generic IOCTL, GET/SET Logical Drive Map
>      *             (Functions 440Dh, 440Eh, 440Fh)
>      * Bit  7:  1=Drive accepts Query IOCTL (Function 4411h)
>      * Bit  9:  1=Drive is local but shared by others on the network
>      * Bit 11:  1=Drive accepts Does Device Use Removable Media (Func
4408h)
>      * Bit 12:  1=Drive is remote
>      * Bit 13:  1=Drive requires media descriptor in FAT
>      * Bit 14:  1=Drive accepts Send/Receive Control Data To/From Block
>                     Device (Functions 4404h, 4405h)
>      * Bit 15:  1=Substitution Drive
>      *
>      */
> }  /* drivetype */

> int isCDROMdrive( char drive )
> {
>     union REGS r;

>     r.x.ax = 0x1500;        /* First test for presence of MSCDEX */
>     r.x.bx = 0;
>     int86( 0x2F, &r, &r );
>     if ( r.x.bx == 0 )
>         return 0;           /* MSCDEX not there, so return FALSE */
>     r.x.ax = 0x150B;        /* MSCDEX driver check API */
>     r.x.cx = drive - 'A';
>     int86( 0x2F, &r, &r );
>     return  r.x.ax != 0;    /* Drive is CDROM if AX nonzero */
> }  /* isCDROMdrive */

> int truename( char far *src, char far *dst )
> {
>     union REGS r;
>     struct SREGS s;
>     char far *s2;

>     /* INT 21h AH=60h doesn't like leading or trailing blanks */
>     while (isspace(*src))
>         src++;
>     s2 = src;
>     while (*s2)
>         s2++;
>     s2--;
>     while (isspace(*s2))
>         *s2-- = 0;

>     s.ds = FP_SEG(src);
>     s.es = FP_SEG(dst);
>     r.x.si = FP_OFF(src);
>     r.x.di = FP_OFF(dst);
>     r.h.ah = 0x60;
>     intdosx( &r, &r, &s );

>     return  r.x.cflag ? -1 : 0;

> }  /* truename */

> char *truedrive( char drive )
> {
>     static char src[20] = "X:\\", dst[80];

>     src[0] = toupper(drive);
>     if ( truename( src, dst ) < 0 )
>         return  NULL;
>     else if ( strcmp( src, dst ) == 0 )
>         return NULL;
>     else
>         return dst;
> }  /* truedrive */

> char logdrvmap( char drive )
> {
>     union REGS r;
>     r.x.ax = 0x440E;   /* MS-DOS Get Logical Drive Map function */
>     r.h.bl = (char) (drive - 'A' + 1);
>     intdos( &r, &r );
>     if ( r.x.cflag )
>         return  r.h.al;  /*   1 = drive remote or cannot be shared
>                           *   5 = device driver returns error
>                           * 0xF = drive invalid
>                           */
>     else if ( r.h.al )
>         return  (char) (r.h.al - 1 + 'A');  /* Drive shared with ... */
>     else
>         return 0;        /* Drive not shared */
> }  /* logdrvmap */

> struct unit_tab
> {
>     void far * next;
>     byte       drvno;       /* DL while calling int 13h */
>     byte       DOS_drvno;   /* 0-based DOS drive number */
>     byte       BPB[0x19];   /* BIOS Parameter Block for this drive */
>     byte       fsf;         /* File System Flags for HD partitions:
>                              * 00h = 12-bit FAT
>                              * 40h = 16-bit FAT
>                              * 80h = unsupported partition
>                              */
>     word       opens;       /* # Open's without matching Close's */
>     byte       dev_type;    /* Form factor:
>                              * 00h = floppy, 40 cyl's, <= 9 sect/trk
>                              * 01h = floppy, 80 cyl's, 15 sect/trk
>                              * 02h = floppy, 80 cyls, 9 sect/trk
>                              * 05h = hard disk
>                              * 07h = other type of floppy
>                              * 09h = floppy, 80 cyls, 36 sect/trk
>                              */
>     word       status;      /* Status flags for the drive:
>                              * 0001h  non-removable media
>                              * 0002h  change-line detection supp. by BIOS
>                              * 0004h  disk PBP (at offset 06h) locked
>                              * 0008h  good track layout, sect's equally
sized
>                              * 0010h  shares whole phys.dev w other LUN's
>                              * 0020h  active unit for shared phys. dev
>                              * 0040h  disk change detected
>                              * 0080h  set DASD before format
>                              * 0100h  disk reformat detected
>                              * 0200h  read/write disabled
>                              */
>     word       cylinders;   /* Number of cylinders spanning the drive/part
*/
>     byte   def_BPB[0x1F];   /* BPB repr. default disk format for drive */
>     byte       cyl8;        /* Low 8bits of cyl # for last giid rd/wr/ver
*/
>     dword      clk_corr;    /* Remov. disk: clock count of last good
access */
>                             /* Fixed disk: minidisk cyl corr to complete
>                                reduction of drive parameters
logic==>physic */
>     byte   vollab[0x0C];    /* 11-byte volume label + NUL terminator */
>     dword      serial_no;   /* Disk serial number */
>     byte       filesys[9];  /* 8-byte file system label + NUL:
>                                "FAT12" or "FAT16", padded with spaces */

> };

> #ifndef MK_FP
> #define MK_FP(seg,ofs)  (void far *) ( ((long)(seg) << 16) + (ofs) )
> #endif

> struct unit_tab far *next_unit_tab( struct unit_tab far *t )
> {
>     if ( t == NULL )
>     {

...

read more »

 
 
 

Drive Letter to Bios Number to Physical Drive

Post by Paul Schlyt » Fri, 29 Dec 2000 16:15:43


In article <92dq1l$k5...@news1.skynet.be>, d-fence <d-fe...@swing.be> wrote:
> If I understand your problem, it's not a godd idea to try that because
> any letter could be on any physical drive.
> DOS drive letters are only logical. You have to analyze partitions tables
> to find what kind of partition is on which physical drive.

That's not enough, because the partitionl tables by themselves will only
tell you which partitions are there, not how they are assigned to DOS
drive letters, which may vary between different versions of DOS.

> By the way, if you find anything interresting on reading sectors on large
> drives (more than 8 Gb), I'm really interrested.
> I failed in programming Int 13h extensions.

> As far as I know, drive letters are decided by the OS which is booting (For
> example, try to make a booting CD-ROM and you'll find that CD-ROM has drive
> letter A: and your floppy is now b:).

And what will then happen to your second floppy which was B: -- did it
become C: ????

> So, if you boot with a "boot manager", a partition with W98 will be 'c:'
> when you boot on it but on the other hand, assume that you have another
> partition with DOS, it will be "another" 'c:' partition if you boot on
> it.

True -- the booting OS decides on which DOS drive letters are assigned
to which partitions, and that may vary between OS'es.

> And at the end, try to boot LINUX and there is no more c or d or whatever
> partition but only 'hda', 'hdb' and so on for IDE drives !

Well, that's different!  UNIX don't have "drive letters" but
considers all drives to reside within the same directory tree.  hda,
hdb and friends are physical hard drives and will correspond to drive
0x80 and 0x81 if you access the drive through BIOS Int 13h.
Win-95/98/ME/NT/2000 won't allow any access to Int 13h directly but
instead has device names corresponding to the physical drives.  Don't
remember these names right now, but there is an equivalence to hda,
hdb in the Win3 API.

Also, on UNIX you must mount any new drive you want to access: a floppy
or a CD, or if you want to access extra harddisk partitions (e.g. a
FAT partition from Linux), and in the commandline to the mount command
you will specify under what subdirectory that new drive/partition will
appear to reside -- thus in this case it's the user, not the OS, which
decides this.

> So, letters are only logical and it's impossible to know which one is 'c' or
> 'd' because it depends on many factors

If it's "impossible", how come the OS can "know" this?

> and 'c' doens't means anything until the boot process is finished.

Of course !!!!!!!!!!!!!!!!!!!!!

And my program below (which works only on DOS btw) won't run until the
boot process is finished....   <g>    ...also this program queries the
OS about the drive assignments, it does not merely examine the partition
tables and try to figure out the DOS drive letter assignments from that
only.  Therefore this program will be able to figure out drive letter
assignments not merely for physical floppy and harddisks, but also
for CD-ROM drives and other network drives, SUBST'ed drives, and host
drives for DOUBLESPACE/DRIVESPACE.

> Further more, the letters used in BIOS configuration systems are there only
> to help newbies but are not real (just like the spoon in Matrix)

> The linux way is better because HDA is always the primary master IDE, and
> have the number 80h.

You're confusing physical drives and partitions here.  HDA refers to the
entire drive, not just to one single partition.  And the first harddrive
will have the number 0x80 in DOS as well as in Linux, because it's given
the number 0x80 by the BIOS.

> In DOS, 'c:' is only the first 'recognized' partition (try to boot with
> a floppy and without any HD DOS partition and you'll see that there is
> no 'c:' even if a HD is present).

Well, that depends -- there might be a CD-ROM drive assigned to C:,
or there may be a network drive assigned to C:.  If there is no HD,
C: can be used for other purposes.  There have even been some systems
having more than two floppy drives, which assigned the floppy drives
to A:, B:, C:, D:, etc....
> Bye
> D-fence
> d-fe...@swing.be

> Paul Schlyter <pau...@saaf.se> a icrit dans le message :
> 91v4e9$5m...@merope.saaf.se...
>> In article <91tsh8$r4...@nnrp1.deja.com>,
>> Paul Johnson  <paulj...@yahoo.com> wrote:

>>> I'm trying to match up Physical Drives (ide primary/master,
>>> secondary/master, etc) to BIOS drive numbers (80h, 81h, 82h..) to DOS
>>> drive letters (c: d: e:). I've been looking at the BIOS and DOS
>>> interrupts and haven't found an easy way to do this. I'm planning on
>>> using Int 21/AX=7305 to read the boot sector and random sector of each
>>> drive letter, then parse the drive partition tables with int 13 and
>>> attempt to match drive letters to bios drive numbers. As for the
>>> physical drive to bios drive matching, perhaps sending an ata command to
>>> read a sector off each drive and doing something similar. Is there an
>>> easier way of doing this, such as a map in memory that links all three
>>> together? Or any interrupts I have not found yet to do this?

>> You might find the code below of some interest.  Among other things
>> it maps DOS drive letters to BIOS drive numbers.

>> --------------------------------------------------------------------------

>> /*

>> DRIVES.C -- find out which disk drives are available on system

>> A quick hack by Paul Schlyter, 1994-04-27

>> 1995-03-14  PS  Now also outputs true drive names (network etc)
>> 1996-04-09  PS  Local HD cluster size, free & total space output added

>> */

>> #include <stdio.h>
>> #include <string.h>
>> #include <ctype.h>

>> #include <dos.h>

>> typedef unsigned char  byte;
>> typedef unsigned short word;
>> typedef unsigned long  dword;

>> #define BIT(n)  ( 1 << (n) )

>> char startup_drive(void)
>> {
>>     union REGS r;
>>     r.x.ax = 0x3305;
>>     intdos( &r, &r );
>>     return  r.h.dl + '@';
>> }  /* startup_drive */

>> char default_drive(void)
>> {
>>     union REGS r;
>>     r.h.ah = 0x19;
>>     intdos( &r, &r );
>>     return r.h.al + 'A';
>> }  /* default_drive */

>> int is_removable( char drive )
>> {
>>     union REGS r;
>>     r.x.ax = 0x4408;
>>     r.h.bl = drive - '@';
>>     intdos( &r, &r );
>>     if ( r.x.cflag )
>>         return -1;
>>     else
>>         return  r.x.ax == 0;  /* AX == 0 ==> removable media */
>> }  /* is_removable */

>> int host_drive( char drive )
>> {
>>     union REGS r;
>>     r.x.bx = 1;            /* DSGetDriveMapping */
>>     r.h.dl = drive - 'A';  /* Drive */
>>     r.x.ax = 0x4A11;       /* DoubleSpace multiplex function */
>>     int86( 0x2F, &r, &r );
>>     if ( r.x.ax != 0 )
>>         return -1;         /* Error */
>>     if ( (r.h.bl & 0x80) == 0 )
>>         return 0;          /* Not compressed */
>>     else
>>         return  (r.h.bl & 0x7F) + 'A';
>> }  /* host_drive */

>> int drivetype( char drive )
>> {
>>     union REGS r;
>>     r.x.ax = 0x4409;
>>     r.h.bl = drive - '@';
>>     intdos( &r, &r );
>>     if ( r.x.cflag )
>>         return -1;
>>     else
>>         return  r.x.dx;
>>     /*
>>      *  DX now contains:
>>      *
>>      * Bit  1:  1=Drive uses 32-bit sector addressing
>>      * Bit  6:  1=Drive accepts Generic IOCTL, GET/SET Logical Drive Map
>>      *             (Functions 440Dh, 440Eh, 440Fh)
>>      * Bit  7:  1=Drive accepts Query IOCTL (Function 4411h)
>>      * Bit  9:  1=Drive is local but shared by others on the network
>>      * Bit 11:  1=Drive accepts Does Device Use Removable Media (Func
> 4408h)
>>      * Bit 12:  1=Drive is remote
>>      * Bit 13:  1=Drive requires media descriptor in FAT
>>      * Bit 14:  1=Drive accepts Send/Receive Control Data To/From Block
>>                     Device (Functions 4404h, 4405h)
>>      * Bit 15:  1=Substitution Drive
>>      *
>>      */
>> }  /* drivetype */

>> int isCDROMdrive( char drive )
>> {
>>     union REGS r;

>>     r.x.ax = 0x1500;        /* First test for presence of MSCDEX */
>>     r.x.bx = 0;
>>     int86( 0x2F, &r, &r );
>>     if ( r.x.bx == 0 )
>>         return 0;           /* MSCDEX not there, so return FALSE */
>>     r.x.ax = 0x150B;        /* MSCDEX driver check API */
>>     r.x.cx = drive - 'A';
>>     int86( 0x2F, &r, &r );
>>     return  r.x.ax != 0;    /* Drive is CDROM if AX nonzero */
>> }  /* isCDROMdrive */

>> int truename( char far *src, char far *dst )
>> {
>>     union REGS r;
>>     struct SREGS s;
>>     char far *s2;

>>     /* INT 21h AH=60h doesn't like leading or trailing blanks */
>>     while (isspace(*src))
>>         src++;
>>     s2 = src;
>>     while (*s2)
>>         s2++;
>>     s2--;
>>     while (isspace(*s2))
>>         *s2-- = 0;

>>     s.ds = FP_SEG(src);
>>     s.es = FP_SEG(dst);
>>     r.x.si = FP_OFF(src);
>>     r.x.di = FP_OFF(dst);
>>     r.h.ah = 0x60;
>>     intdosx( &r, &r, &s );

>>     return  r.x.cflag ? -1 : 0;

>> }  /* truename */

>> char *truedrive( char drive )
>> {
>>     static char src[20] = "X:\\", dst[80];

>>     src[0] = toupper(drive);
>>     if ( truename( src, dst ) < 0 )
>>         return  NULL;
>>     else if ( strcmp( src, dst ) == 0 )
>>         return NULL;
>>     else
>>         return dst;
>> }  /* truedrive */

>> char logdrvmap( char drive )
>> {
>>     union REGS r;
>>     r.x.ax = 0x440E;   /* MS-DOS Get Logical Drive Map function */
>>     r.h.bl = (char) (drive - 'A' + 1);
>>     intdos( &r, &r );
>>     if ( r.x.cflag )
>>         return  r.h.al;  /*   1 = drive remote or cannot be shared
>>                           *   5 = device driver returns error
>>                           * 0xF = drive invalid
>>                           */
>>     else if ( r.h.al )
>>         return  (char) (r.h.al - 1 + 'A');  /* Drive shared with ... */
>>     else
>>         return 0;        /* Drive not shared */

...

read more »

 
 
 

1. Swap CDROM drive letter with a hard-drive partition drive letter

My computer came with one hard drive (C:) and one CDROM (D:), and a lot of
programs installed.  In addition, I have installed several more CDROM
programs.  Now, I added a second hard drive and partitioned it into two
partitions.  Unfortunately, now my CDROM drive letter is F: and my CD
programs won't work.  I'd like to move my CDROM drive letter back to D:.  I
am looking for a utility which will swap my F: CDROM drive letter with my
D: drive, so that my CDROM will be on drive D: and my hard drives will be
C:, E:, and F:.

Yes, I know that I can re-install the CDROM programs, but that is a lot of
work.  A utility as described above would be easier.
--

2. ICPP '94 Panel on Interconnection Networks

3. Converting DOS drive letters to physical drives....

4. 64K on XE? NOT!

5. Map drive letters to phyical drive numbers and partitions

6. Low priced SIMMs (again)

7. Which physical drive does a logical drive exist on ?

8. Send alert for interface errors

9. Logical Drive to Physical Drive?

10. Getting physical drive number

11. Disabling drive letter B: on one-floppy drive machines

12. removable drives, drive letters

13. # Virtual drives/non-existent Drive letters under DOS? #