Contributor: K. CAMPBELL
{ ###################################################################
	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 := 440ドルD;								{ 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 := 150ドルB;			{ MSCDEX installation check }
	Reg.cx := (D - 1);		{ D: 1 = A:, 2 = B:, etc... }
	Intr (2ドルF, Reg);			{ do it }
	IsCDRomDrive := (Reg.bx = $ADAD) and (Reg.ax  0);
end;
end.

AltStyle によって変換されたページ (->オリジナル) /