How to Determine Drive Types in Windows

ID: Q105922

3.10 WINDOWS kbprg

The information in this article applies to:

SUMMARY

The Windows versions 3.0 and 3.1 GetDriveType() function is useful for determining whether a given drive is on a network or uses fixed or removable media, but does not determine the specific type of device that is associated with the drive. This article presents a function, GetDriveTypeEx(), that can determine whether a given drive exists and whether it is one of the following types of devices:

   Hard disk drive
   RAM disk drive
   CD-ROM drive
   Floppy disk drive
   Remote network drive
   Other removable media drive (such as a Bernoulli box)

The function prototype for GetDriveTypeEx() is:

   UINT GetDriveTypeEx(int nDrive);  // 0=A, 1=B, 2=C, etc.

The return value of GetDriveTypeEx() is one of the following constants:

   EX_DRIVE_REMOVABLE       EX_DRIVE_FIXED
   EX_DRIVE_REMOTE          EX_DRIVE_CDROM
   EX_DRIVE_FLOPPY          EX_DRIVE_RAMDISK
   EX_DRIVE_INVALID

IMPORTANT NOTE: GetDriveTypeEx() is designed only for 16-bit applications and dynamic-link libraries (DLLs) for Windows; it will not work in 32-bit applications or DLLs written for the Win32 application programming interface (API).

The Windows 32-bit API version of the GetDriveType() function determines whether a drive is a RAM disk or a CD-ROM in addition to categorizing the drive as either removable media, fixed media, or remote. See the Microsoft Win32 SDK for further information about how to use GetDriveType() in Win32 applications and DLLs.

MORE INFORMATION

GetDriveTypeEx() works by first calling the Windows GetDriveType() function to categorize the drive as being either fixed, removable, remote (network), or not present. If the drive is remote, it could be either a CD-ROM drive or a network drive because CD-ROM drives are mapped by the MS-DOS network redirector. The best way to determine whether a drive is a CD-ROM drive is to call the Microsoft CD-ROM Extensions (MSCDEX) CD-ROM Drive Check function.

If the drive uses fixed media, it could be either a hard disk or a RAM disk. A good way to determine whether the drive is a hard disk is to call the MS-DOS Get Device Parameters IOCTL function and then check the device type byte in the returned structure. If the drive is not a hard disk, it can be assumed to be a RAM disk because these are the only two fixed media devices.

Finally, if the drive uses removable media, it could be a floppy disk drive or some other device, such as a Bernoulli box. The MS-DOS Get Device Parameters IOCTL function can be used to determine whether the drive is a floppy disk drive; if it is not, it could be a Bernoulli box or some other less common device.

The following code for Microsoft C compilers implements GetDriveTypeEx() and its support functions and all required structures:

Sample Code

#include <windows.h>
#include <string.h>

   // Return values of GetDriveTypeEx().
#define EX_DRIVE_INVALID    0
#define EX_DRIVE_REMOVABLE  1
#define EX_DRIVE_FIXED      2
#define EX_DRIVE_REMOTE     3
#define EX_DRIVE_CDROM      4
#define EX_DRIVE_FLOPPY     5
#define EX_DRIVE_RAMDISK    6

   // See the "MS-DOS Programmer's Reference" for further information
   // about this structure.

typedef struct tagDEVICEPARAMS
   {
   BYTE  bSpecFunc;        // Special functions
   BYTE  bDevType;         // Device type
   WORD  wDevAttr;         // Device attributes
   WORD  wCylinders;       // Number of cylinders
   BYTE  bMediaType;       // Media type
                        // Beginning of BIOS parameter block (BPB)
   WORD  wBytesPerSec;     // Bytes per sector
   BYTE  bSecPerClust;     // Sectors per cluster
   WORD  wResSectors;      // Number of reserved sectors
   BYTE  bFATs;            // Number of FATs
   WORD  wRootDirEnts;     // Number of root-directory entries
   WORD  wSectors;         // Total number of sectors
   BYTE  bMedia;           // Media descriptor
   WORD  wFATsecs;         // Number of sectors per FAT
   WORD  wSecPerTrack;     // Number of sectors per track
   WORD  wHeads;           // Number of heads
   DWORD dwHiddenSecs;     // Number of hidden sectors
   DWORD dwHugeSectors;    // Number of sectors if wSectors == 0
                        // End of BIOS parameter block (BPB)
   } DEVICEPARAMS, FAR * LPDEVICEPARAMS;

   // Function prototypes

BOOL GetDeviceParameters (int nDrive, LPDEVICEPARAMS dp); BOOL IsCDRomDrive (int nDrive); UINT GetDriveTypeEx (int nDrive);

//-----------------------------------------------------------------
// GetDeviceParameters()
// 
// Fills a DEVICEPARAMS struct with info about the given drive.
// Calls DOS IOCTL Get Device Parameters (440Dh, 60h) function.
// 
// Parameters
//   nDrive   Drive number  0 = A, 1 = B, 2 = C, and so on.
//   dp       Pointer to a structure that will contain the drive's
//            parameters.
// 
// Returns TRUE if it succeeded, FALSE if it failed.
//-----------------------------------------------------------------
BOOL GetDeviceParameters (int nDrive, LPDEVICEPARAMS dp)
   {
   BOOL bResult = TRUE;      // Assume success
   __asm {
         push ds
         mov  bx, nDrive
         inc  bx           // Convert 0-based #'s to 1-based #s
         mov  ch, 08h      // Device category--must be 08h
         mov  cl, 60h      // MS-DOS IOCTL Get Device Parameters
         lds  dx, dp
         mov  ax, 440Dh
         int  21h
         jnc  gdp_done     // CF SET if error
         mov  bResult, FALSE
      gdp_done:
         pop  ds
         }
   return (bResult);
   }

//-----------------------------------------------------------------
// IsCDRomDrive()
// 
// Determines if a drive is a CD-ROM. Calls MSCDEX and checks
// that MSCDEX is loaded, and that MSCDEX reports the drive is a
// CD-ROM.
// 
// Parameters
//    nDrive    Drive number  0 = A, 1 = B, 2 = C, and so forth.
// 
// Returns TRUE if nDrive is a CD-ROM drive, FALSE if it isn't.
//-----------------------------------------------------------------
BOOL IsCDRomDrive (int nDrive)
   {
   BOOL bResult = FALSE;      // Assume not a CD-ROM drive
   __asm {
         mov  ax, 150Bh       // MSCDEX CD-ROM Drive Check
         xor  bx, bx
         mov  cx, nDrive
         int  2Fh
         cmp  bx, 0ADADh      // Check MSCDEX signature
         jne  not_cd_drive
         or   ax, ax          // Check the drive type
         jz   not_cd_drive    // 0 (zero) means not CD-ROM
         mov  bResult, TRUE
      not_cd_drive:
         }
   return (bResult);
   }

//-----------------------------------------------------------------
// GetDriveTypeEx()
// 
// Determines the type of a drive. Calls Windows's GetDriveType
// to determine if a drive is valid, fixed, remote, or removeable,
// then breaks down these categories further to specific device
// types.
// 
// Parameters
//    nDrive    Drive number  0 = A, 1 = B, 2 = C, etc.
// 
// Returns one of:
//    EX_DRIVE_INVALID         -- Drive not detected
//    EX_DRIVE_REMOVABLE       -- Unknown removable-media type drive
//    EX_DRIVE_FIXED           -- Hard disk drive
//    EX_DRIVE_REMOTE          -- Remote drive on a network
//    EX_DRIVE_CDROM           -- CD-ROM drive
//    EX_DRIVE_FLOPPY          -- Floppy disk drive
//    EX_DRIVE_RAMDISK         -- RAM disk
//-----------------------------------------------------------------
UINT GetDriveTypeEx (int nDrive)
   {
   DEVICEPARAMS dp;
   UINT uType;

   _fmemset (&dp, 0, sizeof(dp));    // Init device params struct
   uType = GetDriveType (nDrive);

   switch (uType)
      {
      case DRIVE_REMOTE:
            // GetDriveType() reports CD-ROMs as Remote drives. Need
            // to see if the drive is a CD-ROM or a network drive.
         if (IsCDRomDrive (nDrive))
            return (EX_DRIVE_CDROM);
         else
            return (EX_DRIVE_REMOTE);
         break;

      case DRIVE_REMOVABLE:
            // Check for a floppy disk drive. If it isn't, then we
            // don't know what kind of removable media it is.
            // For example, could be a Bernoulli box or something new...
         if (GetDeviceParameters (nDrive, &dp))
            switch (dp.bDevType)
               {
                  // Floppy disk drive types
               case 0x0: case 0x1: case 0x2: case 0x3:
               case 0x4: case 0x7: case 0x8:
                  return (EX_DRIVE_FLOPPY);
               }
         return (EX_DRIVE_REMOVABLE);  // Unknown removable media type
         break;

      case DRIVE_FIXED:
            // GetDeviceParameters returns a device type of 0x05 for
            // hard disks. Because hard disks and RAM disks are the two
            // types of fixed-media drives, we assume that any fixed-
            // media drive that isn't a hard disk is a RAM disk.
         if (GetDeviceParameters (nDrive, &dp) && dp.bDevType == 0x05)
            return (EX_DRIVE_FIXED);
         else
            return (EX_DRIVE_RAMDISK);
         break;
      }
   return (EX_DRIVE_INVALID);   // Drive is invalid if we get here.
   }

Additional reference words: 3.00 3.10 KBCategory: kbprg KBSubcategory: KrDsk Keywords : kb16bitonly

Last Reviewed: July 24, 1997