[Back to DRIVES SWAG index] [Back to Main SWAG index] [Original]
{ ###################################################################
Extends the Windows function GetDriveType()
and provides the same function for Dos...
This code by: K Campbell CompuServe [100064,1751]
Some sections hacked out of code by:
Dr. Peter Below CIS [100113.1101]
&
Extended GetDriveType for Windows 3.0/3.1.
Code ported from the C in Microsoft PSS document Q105922.
by Doug Wegscheid 3/22/94.
No warrenties given! (Don't blame them, blame me.)
Note:
1) this uses the convention: Drive 1 = A and not Drive 0 = A
which the original GetDriveType() uses!!!
2) works OK with CDRoms and RAMDisks, but I can't test on a
network (as I'm not on one!) If you use it on a networked
drive or a removable drive, let me know if it works!
This code is released to the public domain!
################################################################### }
unit TestDrive;
interface
{$IFDEF WINDOWS}
uses WinProcs, WinDos, Strings;
{$ELSE}
uses Dos, Strings;
{$ENDIF}
const dt_NotFound = 0; { Not detected }
dt_Removable = 1; { Unknown removable type }
dt_HardDisk = 2; { Standard hard disk }
dt_Networked = 3; { Remote drive on a network }
dt_CDRom = 4; { CD Rom drive }
dt_Floppy = 5; { Floppy drive }
dt_RAMDisk = 6; { RAM disk }
type DeviceParams = record
bSpecFunc : byte; { Special functions }
bDevType : byte; { Device type }
wDevAttr : word; { Device attributes }
wCylinders : word; { Number of cylinders }
bMediaType : byte; { Media type }
{ Beginning of BIOS parameter block (BPB) }
wBytesPerSec : word; { Bytes per sector }
bSecPerClust : byte; { Sectors per cluster }
wResSectors : word; { Number of reserved sectors }
bFATs : byte; { Number of FATs }
wRootDirEnts : word; { Number of root-directory entries }
wSectors : word; { Total number of sectors }
bMedia : byte; { Media descriptor }
wFATsecs : word; { Number of sectors per FAT }
wSecPerTrack : word; { Number of sectors per track }
wHeads : word; { Number of heads }
dwHiddenSecs : longint; { Number of hidden sectors }
dwHugeSectors : longint; { Number of sectors if wSectors == 0 }
{ End of BIOS parameter block (BPB) }
end;
function GetDeviceParameters(Drive : word ; var dp : DeviceParams) : boolean;
function GetDriveTypeEx(D : byte) : byte;
function IsCDRomDrive(D : Byte) : boolean;
implementation
function GetDeviceParameters(Drive : word ; var dp : DeviceParams) : boolean;
{$IFDEF WINDOWS}
var Reg : TRegisters;
{$ELSE}
var Reg : Registers;
{$ENDIF}
begin
FillChar(Reg, SizeOf(Reg), #0); { clean up registers to avoid GPF }
Reg.ax := $440D; { IOCTL }
Reg.ch := $08; { block device }
Reg.cl := $60; { get device parameters }
Reg.bx := Drive; { 1 = A:, 2 = B:, etc... }
Reg.ds := seg(dp);
Reg.dx := ofs(dp);
MSDos(Reg);
GetDeviceParameters := (Reg.flags and fCarry) = 0
end;
function GetDriveTypeEx(D : byte) : byte;
{$IFNDEF WINDOWS}
var Reg : Registers;
{$ENDIF}
var Result, uType : byte;
dp : DeviceParams;
begin
Result := dt_NotFound;
FillChar (dp, SizeOf(dp), #0); { clear the DPB }
{$IFDEF WINDOWS}
uType := GetDriveType(D - 1); { make a rough guess }
{$ELSE}
uType := 0;
FillChar(Reg, SizeOf(Reg), #0);
Reg.ax := $4408; { IOCTL is drive changeable function }
Reg.bl := D;
MSDos(Reg);
if (fCarry and Reg.Flags) <> 0 then
{ error, check error code in ax }
begin
{ Driver does not support this call, so guess as a hard disk }
if Reg.ax = 1 then uType := 3;
end
else
begin
if Reg.ax = 0 then { media changeable, floppy, WORM or MO }
uType := 2
else { else hard disk, ramdisk or CD-ROM }
uType := 3;
end;
{ check if drive is remote }
Reg.ax := $4409; { IOCTL is redirected device function }
Reg.bl := D;
MSDos(Reg);
if (not ((fCarry and Reg.Flags) <> 0)) and (Reg.dx = $1000) then uType := 4;
{$ENDIF}
case uType of
2 : { Removable }
{ 0=320/360kb floppy, 1=1.2Mb, 2=720kb, 3=8" single density,
4=8" double density, 7=1.44Mb, 8=optical, 9=2.88Mb.}
if GetDeviceParameters(D, dp) and (dp.bDevType in [0..4,7,9]) then
Result := dt_Floppy
else
Result := dt_Removable;
3 : { Fixed }
if GetDeviceParameters(D, dp) and (dp.bDevType = 5) then
Result := dt_HardDisk
else
Result := dt_RAMDisk;
4 : { Remote }
if IsCDRomDrive(D) then
Result := dt_CDRom
else
Result := dt_Networked;
end;
GetDriveTypeEx := Result;
end;
{ Returns TRUE if Drive is a CD-ROM drive, FALSE if it isn't.}
function IsCDRomDrive(D : Byte) : boolean;
{$IFDEF WINDOWS}
var Reg : TRegisters;
{$ELSE}
var Reg : Registers;
{$ENDIF}
begin
FillChar(Reg, SizeOf(Reg), #0);
Reg.ax := $150B; { MSCDEX installation check }
Reg.cx := (D - 1); { D: 1 = A:, 2 = B:, etc... }
Intr ($2F, Reg); { do it }
IsCDRomDrive := (Reg.bx = $ADAD) and (Reg.ax <> 0);
end;
end.
[Back to DRIVES SWAG index] [Back to Main SWAG index] [Original]