[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]