[Back to DRIVES SWAG index] [Back to Main SWAG index] [Original]
{
(replaces old DRIVE DETECT source posted and written by Andrew Eigus and
placed in one of the last SWAG archives)
Howdy Everyone!
The DRVTYPES.PAS Borland (Turbo) Pascal 6+ code gives you a possibility to
get the specified drive type. Version 1.1 currently supports detection of
fixed, removable, remote, compressed, CD-ROM and RAM-emulated disk drives.
Program DRIVES.PAS demonstrates the use of the DrvTypes unit.
Code written by Mr. Byte (aeigus@fgate.castle.riga.lv)
Stacker4 implementation and bug fixes by Bobby Z.
RAM drive check code by Janis Smits
All bugfix reports, comments, wishes, support code please send to:
E-mail: aeigus@fgate.castle.riga.lv Mr. Byte
Fido: 2:5100/33
Thanks and we hope you enjoy this code,
Mr. Byte
P.S. DISCLAIMER: NO WARRANTIES ARE PROVIDED, AND AS-IS BASIS IS ASSUMED.
23.01.95
DRVTYPES.PAS - a unit
{$S-,R-,I-,X+}
unit DrvTypes;
{ drive types }
interface
const
dtError = $00; { Bad drive }
dtFixed = $01; { Fixed drive }
dtRemovable = $02; { Removeable (floppy) drive }
dtRemote = $03; { Remote (network) drive }
dtCDROM = $04; { MSCDEX V2.00+ driven CD-ROM drive }
dtDblSpace = $05; { DoubleSpace compressed drive }
dtSUBST = $06; { SUBST'ed drive }
dtStacker4 = $07; { Stacker 4 compressed drive }
dtRAM = $08; { RAM drive }
function GetDriveType(Drive : Byte) : Byte;
implementation
type
ControlBlk25 = record { control block for INT 25 extended call }
StartSector : LongInt; { start sector to read }
Count : Word; { number of sectors to read }
BufferOffs : Word; { data buffer offset }
BufferSeg : Word; { data buffer segment }
end;
const
checkABforStacker : boolean = False;
function checkStacker4( Drive : Byte ) : Boolean; assembler;
{ returns True if Drive is Stacker 4 compressed volume, False otherwise.
This also may return True with previous versions of Stacker - I didn't
check it. /Bobby Z. 29/11/94 }
var CB : ControlBlk25;
Boot : array[1..512] of Byte;
asm
push ds
mov al,Drive
or checkABforStacker,0 { check A: & B: for Stacker volume? }
jnz @@1
cmp al,1
ja @@1
sub al,al
jmp @@Q
@@1:
push ss
pop ds
lea bx,CB
sub ax,ax
mov word ptr ds:ControlBlk25[bx].StartSector,ax
mov word ptr ds:ControlBlk25[bx].StartSector[2],ax
mov word ptr ds:ControlBlk25[bx].Count,1
lea dx,Boot
mov word ptr ds:ControlBlk25[bx].BufferOffs,dx
mov word ptr ds:ControlBlk25[bx].BufferSeg,ds
mov al,Drive
sub cx,cx
dec cx
mov si,sp
int 25h
cli
mov sp,si
sti
pushf
lea si,Boot
add si,1F0h { Stacker signature CD13CD14CD01CD03 should }
sub al,al { appear at offset 1F0 of boot sector. }
popf
jc @@Q { was error reading boot sector - assume }
{ not Stacker drive }
cmp word ptr ds:[si],13CDh
jnz @@Q
cmp word ptr ds:[si][2],14CDh
jnz @@Q
cmp word ptr ds:[si][4],01CDh
jnz @@Q
cmp word ptr ds:[si][6],03CDh
jnz @@Q
mov al,1
@@Q:
pop ds
end;
function GetDriveType; assembler;
{ Detects the type of a specified drive. Drive is a drive number, where
0=default (current) drive, 1=drive A, 2=B, ... This function will return
one of the dtXXX-constants.
Note: Function will work under DOS version 3.1 or later
THIS CODE IS PUBLIC DOMAIN
Written by Mr. Byte, 12/08/94
Additions and fixes by Bobby Z., 29/11/94
RAM drive check code by Janis Smits, 07/12/94 }
asm
cmp Drive,0
jne @@1
mov ah,19h { get active drive number in al }
int 21h
inc al
mov Drive,al
@@1:
mov ax,1500h { check for CD-ROM v2.00+ }
sub bx,bx
int 2Fh
or bx,bx
jz @@2
mov ax,150Bh
sub ch,ch
mov cl,Drive
int 2Fh
cmp bx,0ADADh
jne @@2
or ax,ax
jz @@2
mov bl,dtCDROM
jmp @@7
@@2:
mov ax,4409h { check for SUBST'ed drive }
mov bl,Drive
int 21h
jc @@9
test dh,10000000b
jz @@9
mov bl,dtSUBST
jmp @@7
@@9:
mov ax,4A11h { check for DoubleSpace drive }
mov bx,1
mov dl,Drive
dec dl
int 2Fh
sub cl,cl { mov cl,False }
or ax,ax { is DoubleSpace loaded? }
jnz @@3
cmp dl,bl { if a host drive equal to compressed, then get out... }
je @@3
test bl,10000000b { bit 7=1: DL=compressed,BL=host
=0: DL=host,BL=compressed }
jz @@3 { so avoid host drives, assume host=fixed :) }
inc dl
cmp Drive,dl
jne @@3
mov bl,dtDblSpace
jmp @@7
@@3:
mov ax,4409h { check for remote drive }
mov bl,Drive
int 21h
jc @@5
and dx,1000h { this is correct way to check if drive is remote
one, Andrew. Your version didn't work...
/Bobby Z., 29/11/94 }
jz @@4
mov bl,dtRemote
jmp @@7
@@4:
mov al,Drive { check for Stacker 4 volume }
or al,al
jz @@getDrv
dec al
@@goStac:
push ax
call checkStacker4
or al,al
jz @@8
mov bl,dtStacker4
jmp @@7
@@8:
mov ax,4408h { check for fixed (hard) drive }
mov bl,Drive
int 21h
jc @@5
or al,al
jz @@6
push ds { check for RAM drive }
mov ax,ss
mov ds,ax
mov si,sp
sub sp,28h { allocate 28h bytes on stack }
mov dx,sp
mov ax,440Dh { generic IOCTL }
mov cx,860h { get device parameters }
mov bl,Drive
int 21h { RAMDrive and VDISK don't support this command }
mov sp,si
pop ds
mov bl,dtRAM
jc @@7
mov bl,dtFixed
jmp @@7
@@5:
sub bl,bl { mov bl,dtError cuz dtError=0 }
jmp @@7
@@getDrv:
mov ah,19h
int 21h
jmp @@goStac
@@6:
mov bl,dtRemovable { else - removeable media }
@@7:
mov al,bl
end; { GetDriveType }
end.
{$S-,I-,R-}
uses DrvTypes;
var C : Char;
function FloppyDrives : byte; assembler;
asm
int 11h
test al,00000001b
jz @@1
{$IFOPT G+}
shr al,6
{$ELSE}
mov cl,6
shr al,cl
{$ENDIF}
and al,3
inc al
retn
@@1:
xor al,al
end;
begin
WriteLn('Drive Map Version 1.1 Written by Andrew Eigus and Bobby Z.'#13#10);
for C := 'A' to 'Z' do
case GetDriveType(Byte(C)-Byte('A')+1) of
dtCDROM: WriteLn('Drive ', C, ': is CD-ROM drive');
dtSUBST: WriteLn('Drive ',C,': is SUBST''ed drive');
dtRAM: WriteLn('Drive ', C, ': is RAM drive');
dtRemote: WriteLn('Drive ', C, ': is remote (network) drive');
dtFixed: WriteLn('Drive ', C, ': is local hard drive');
dtRemovable:
if (Byte(C) - Byte('A') + 1) in [1..FloppyDrives] then WriteLn('Drive ',
C, ': is removable (floppy) drive'); dtDblSpace: WriteLn('Drive ', C, ': is
DoubleSpace compressed drive'); dtStacker4: WriteLn('Drive ', C, ': is
','Stacker 4 compressed drive'); end
end.
[Back to DRIVES SWAG index] [Back to Main SWAG index] [Original]