home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / pascal / swag / win-os2.swg / 0009_Extended GetDriveType.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-05-25  |  7.6 KB  |  219 lines

  1. (*
  2.         Extended GetDriveType for Windows 3.0/3.1.
  3.  
  4.         Code ported the C in Microsoft PSS document Q105922.
  5.  
  6.         Doug Wegscheid 3/22/94.
  7. *)
  8.  
  9. {$DEFINE TEST}        { undefine to make a unit }
  10.  
  11. {$IFDEF TEST}
  12. program drivetyp;
  13. uses wincrt, windos, winprocs, wintypes;
  14. {$ELSE TEST}
  15. unit drivetyp;
  16.  
  17. interface
  18. {$ENDIF}
  19.  
  20. { Return values of GetDriveTypeEx(). }
  21. const
  22.  EX_DRIVE_INVALID    = 0;
  23.  EX_DRIVE_REMOVABLE  = 1;
  24.  EX_DRIVE_FIXED      = 2;
  25.  EX_DRIVE_REMOTE     = 3;
  26.  EX_DRIVE_CDROM      = 4;
  27.  EX_DRIVE_FLOPPY     = 5;
  28.  EX_DRIVE_RAMDISK    = 6;
  29.  
  30. {$IFNDEF TEST}
  31. function GetDriveTypeEx (nDrive : integer) : integer;
  32.  
  33. implementation
  34. uses windos, winprocs, wintypes;
  35. {$ENDIF}
  36.  
  37. {
  38.  See the "MS-DOS Programmer's Reference" for further information
  39.  about this structure. It is the structure returned with an IOCTL
  40.  $0D function, $60 subfunction (get device parameters).
  41. }
  42. type
  43.  DeviceParams = record
  44.   bSpecFunc        : byte;                { Special functions }
  45.   bDevType        : byte;                { Device type }
  46.   wDevAttr        : word;         { Device attributes }
  47.   wCylinders        : word;                { Number of cylinders }
  48.   bMediaType        : byte;                { Media type }
  49.   { Beginning of BIOS parameter block (BPB) }
  50.   wBytesPerSec        : word;                { Bytes per sector }
  51.   bSecPerClust        : byte;                { Sectors per cluster }
  52.   wResSectors        : word;              { Number of reserved sectors }
  53.   bFATs                : byte;         { Number of FATs }
  54.   wRootDirEnts        : word;             { Number of root-directory entries }
  55.   wSectors        : word;         { Total number of sectors }
  56.   bMedia        : byte;         { Media descriptor }
  57.   wFATsecs        : word;         { Number of sectors per FAT }
  58.   wSecPerTrack        : word;             { Number of sectors per track }
  59.   wHeads        : word;         { Number of heads }
  60.   dwHiddenSecs        : longint;             { Number of hidden sectors }
  61.   dwHugeSectors        : longint;            { Number of sectors if wSectors == 0 }
  62.   { End of BIOS parameter block (BPB) }
  63.  end;
  64.  
  65. function GetDeviceParameters (nDrive : integer; var dp : DeviceParams) : boolean;
  66. (*
  67.  //-----------------------------------------------------------------
  68.  // GetDeviceParameters()
  69.  //
  70.  // Fills a DeviceParams struct with info about the given drive.
  71.  // Calls DOS IOCTL Get Device Parameters (440Dh, 60h) function.
  72.  //
  73.  // Parameters
  74.  //   nDrive   Drive number  0 = A, 1 = B, 2 = C, and so on.
  75.  //   dp       A structure that will contain the drive's parameters.
  76.  //
  77.  // Returns TRUE if it succeeded, FALSE if it failed.
  78.  //-----------------------------------------------------------------
  79. *)
  80. var
  81.  r                : TRegisters;
  82. begin
  83.  fillchar(r,sizeof(r),#0);        { clean up registers to avoid GPF }
  84.  r.ax := $440d;                        { IOCTL }
  85.  r.ch := $08;                        { block device }
  86.  r.cl := $60;                        { get device parameters }
  87.  r.bx := nDrive + 1;                { 1 = A:, 2 = B:, etc... }
  88.  r.ds := seg(dp); r.dx := ofs(dp);        { where... }
  89.  msdos(r);
  90.  GetDeviceParameters := (r.flags and fCarry) = 0
  91. end;
  92.  
  93. function IsCDRomDrive (nDrive : integer) : boolean;
  94. (*
  95.  //-----------------------------------------------------------------
  96.  // IsCDRomDrive()
  97.  //
  98.  // Determines if a drive is a CD-ROM. Calls MSCDEX and checks
  99.  // that MSCDEX is loaded, and that MSCDEX reports the drive is a
  100.  // CD-ROM.
  101.  //
  102.  // Parameters
  103.  //    nDrive    Drive number  0 = A, 1 = B, 2 = C, and so forth.
  104.  //
  105.  // Returns TRUE if nDrive is a CD-ROM drive, FALSE if it isn't.
  106.  //-----------------------------------------------------------------
  107. *)
  108. var
  109.  r        : TRegisters;
  110. begin
  111.  fillchar(r,sizeof(r),#0);        { clean up registers to avoid GPF and
  112.                                   to ensure that BX = $ADAD would not
  113.                                   be by accident }
  114.  r.ax := $150b;                        { MSCDEX installation check }
  115.  {
  116.    This function returns whether or not a drive letter is a CD-ROM
  117.    drive supported by MSCDEX. If the extensions are installed, BX
  118.    will be set to ADADh. If the drive letter is supported by
  119.    MSCDEX, then AX is set to a non-zero value. AX is set to zero
  120.    if the drive is not supported. One must be sure to check the
  121.    signature word to know that MSCDEX is installed and that AX
  122.    has not been modified by another INT 2Fh handler.
  123.  }
  124.  r.cx := nDrive;                { 0 = A:, 1 = B:, etc... }
  125.  intr ($2f, r);                        { do it }
  126.  IsCDRomDrive := (r.bx = $adad) and (r.ax <> 0)
  127. end;
  128.  
  129. (*
  130.  //-----------------------------------------------------------------
  131.  // GetDriveTypeEx()
  132.  //
  133.  // Determines the type of a drive. Calls Windows's GetDriveType
  134.  // to determine if a drive is valid, fixed, remote, or removeable,
  135.  // then breaks down these categories further to specific device
  136.  // types.
  137.  //
  138.  // Parameters
  139.  //    nDrive    Drive number  0 = A, 1 = B, 2 = C, etc.
  140.  //
  141.  // Returns one of:
  142.  //    EX_DRIVE_INVALID         -- Drive not detected
  143.  //    EX_DRIVE_REMOVABLE       -- Unknown removable-media type drive
  144.  //    EX_DRIVE_FIXED           -- Hard disk drive
  145.  //    EX_DRIVE_REMOTE          -- Remote drive on a network
  146.  //    EX_DRIVE_CDROM           -- CD-ROM drive
  147.  //    EX_DRIVE_FLOPPY          -- Floppy disk drive
  148.  //    EX_DRIVE_RAMDISK         -- RAM disk
  149.  //-----------------------------------------------------------------
  150. *)
  151. function GetDriveTypeEx (nDrive : Integer) : integer;
  152. var
  153.  dp        : DeviceParams;
  154.  utype        : integer;
  155. begin
  156.  fillchar (dp, sizeof(dp), #0);        { clear the DPB }
  157.  uType := GetDriveType(nDrive);        { make a rough guess }
  158.  case uType of
  159.  
  160.   DRIVE_REMOTE:
  161.    { GetDriveType() reports CD-ROMs as Remote drives. Need
  162.      to see if the drive is a CD-ROM or a network drive. }
  163.    if IsCDRomDrive (nDrive)
  164.     then GetDriveTypeEx := EX_DRIVE_CDROM
  165.     else GetDriveTypeEx := EX_DRIVE_REMOTE;
  166.  
  167.   DRIVE_REMOVABLE:
  168.    {
  169.      Check for a floppy disk drive. If it isn't, then we
  170.      don't know what kind of removable media it is.
  171.      For example, could be a Bernoulli box or something new...
  172.  
  173.      DOS 6.0 Reference says devicetype 0=320/360kb floppy,
  174.      1=1.2Mb, 2=720kb, 3=8" single density, 4=8" double density,
  175.      7=1.44Mb, 8=optical, 9=2.88Mb. Code in Q105922 didn't pick
  176.      up bDevType=9.
  177.    }
  178.    if GetDeviceParameters (nDrive, dp) and (dp.bDevType in [0..4,7..9])
  179.     then GetDriveTypeEx := EX_DRIVE_FLOPPY
  180.     else GetDriveTypeEx := EX_DRIVE_REMOVABLE;
  181.  
  182.   DRIVE_FIXED:
  183.    {
  184.      GetDeviceParameters returns a device type of 0x05 for
  185.      hard disks. Because hard disks and RAM disks are the two
  186.      types of fixed-media drives, we assume that any fixed-
  187.      media drive that isn't a hard disk is a RAM disk.
  188.    }
  189.    if GetDeviceParameters (nDrive, dp) and (dp.bDevType = 5)
  190.     then GetDriveTypeEx := EX_DRIVE_FIXED
  191.     else GetDriveTypeEx := EX_DRIVE_RAMDISK;
  192.  
  193.   else
  194.    GetDriveTypeEx := EX_DRIVE_INVALID
  195.  end
  196. end;
  197.  
  198. {$IFDEF TEST}
  199. var
  200.  i, d        : integer;
  201. begin
  202.  for i := 0 to 25
  203.   do begin
  204.    d := GetDriveTypeEx(i);
  205.    if d <> EX_DRIVE_INVALID
  206.     then begin
  207.      write (chr(i + ord('A')), ': ');
  208.      case GetDriveTypeEx(i) of
  209.       EX_DRIVE_REMOVABLE:        Writeln ('Removable');
  210.       EX_DRIVE_FIXED:                Writeln ('Harddisk');
  211.       EX_DRIVE_REMOTE:                Writeln ('Network');
  212.       EX_DRIVE_CDROM:                Writeln ('CDROM');
  213.       EX_DRIVE_FLOPPY:                Writeln ('Floppy');
  214.       EX_DRIVE_RAMDISK:                Writeln ('RAMdisk')
  215.      end
  216.     end
  217.   end
  218. {$ENDIF}
  219. end.