Board index » delphi » Pascal-Code to find the number of floppy-Drives

Pascal-Code to find the number of floppy-Drives

Hi together,
can anybody give me some support for my little programming-problem.
I'm looking for a code (Turbo Pascal 6.0 for DOS) to get the number of
active Floppy-Diskdrives, no matter wether a disk is in or not. The inbuild
commands like DISKFREE or anything else only work when a disk is in the
drive.

Please send me a code.

Greetings from Germany
Volker

 

Re:Pascal-Code to find the number of floppy-Drives


V. Brockhoff <V.Brockh...@ping.de> wrote in article
<01bccf6e$5e54cfe0$LocalHost@brockhoff>...

Quote
> Hi together,
> can anybody give me some support for my little programming-problem.
> I'm looking for a code (Turbo Pascal 6.0 for DOS) to get the number of
> active Floppy-Diskdrives, no matter wether a disk is in or not. The
inbuild
> commands like DISKFREE or anything else only work when a disk is in the
> drive.

> Please send me a code.

Here's a routine that does looks for all disks on a system:

  PROCEDURE DiskDriveSummary;

    VAR
      buffer      :  ARRAY[1..64] OF CHAR;
      available   :  LongInt;
      ClusterBytes:  WORD;
      capacity    :  LongInt;
      DirInfo     :  SearchRec;
      DPB         :  DiskParameterBlock;
      drive       :  BYTE;
      entries     :  WORD;
      floppy      :  BYTE;
      OK          :  BOOLEAN;
      percent     :  REAL;
      rc          :  WORD;
      SectorBytes :  WORD;
      Valid       :  BOOLEAN;

  BEGIN

    WRITELN;
    WRITELN ('Disk Summary');

    DetermineValidDrives;

    WRITELN ('        Local/        B y t e s           Percent ');
    WRITELN ('  Disk    LAN    Capacity   Available   Free  Used    
Current Directory');
    WRITELN ('  ----  ------  ----------  ----------  ----  ----
-------------------------');

    FOR drive := MinDrive TO MaxDrive DO BEGIN   {A..Z}
      IF   ValidDrive[drive]
      THEN BEGIN
        GetFreeDiskSpace (drive, Valid,
                          SectorBytes,ClusterBytes, Capacity,Available);
        IF   Valid
        THEN BEGIN
          WRITE (' ':3);
          IF   drive = DefaultDrive
          THEN WRITE ('*')
          ELSE WRITE (' ');
          WRITE (DriveLetter(drive),'   ');
          WRITE (DiskLocation(drive):6,Capacity:12,Available:12);
          percent := (100.0 * Available) / Capacity;
          WRITE   (percent:6:1,100.0-percent:6:1);
          WRITE ('  ',GetCurrentDirectory(drive));
          WRITELN
        END
        ELSE ValidDrive[drive] := FALSE

      END
    END;

    WRITELN;
    WRITELN ('                                                     Root
Dir');
    WRITELN ('        Media  Bytes/  Sectors/  Bytes/              
Entries');
    WRITELN ('  Disk  Type   Sector   Cluster  Cluster  Clusters   Max  
Now');
    WRITELN ('  ----  -----  ------  --------  -------  --------  ----
----');

    FOR drive := MinDrive TO MaxDrive DO BEGIN   {A..Z}
      IF   ValidDrive[drive]
      THEN BEGIN

        GetDPB (drive, Valid, DPB);
        IF  Valid
        THEN BEGIN
          WRITE (' ':3);
          IF   drive = DefaultDrive
          THEN WRITE ('*')
          ELSE WRITE (' ');
          WRITE (DriveLetter(drive),
                 ' ':3,
                 DPB.MediaType:5,
                 DPB.BytesPerSector:8,
                 DPB.SectorsPerCluster+1:10,
                 DPB.BytesPerSector * (DPB.SectorsPerCluster+1):9,
                 DPB.Clusters-1:10,
                 DPB.RootDirEntries:6);

          entries := 0;    {count root directory entries}
          FindFirst (DriveLetter(drive) + ':\*.*',AnyFile,DirInfo);
          WHILE DOSerror = 0 DO BEGIN
            INC (entries);
            FindNext (DirInfo)
          END;
          WRITE (entries:6);
          WRITELN;
        END
        ELSE ValidDrive[drive] := FALSE
      END
    END;

    WRITELN ('   * = default drive');

  END {DiskDriveSummary};

You'll also need the following UNIT:

UNIT DOSStructures;

 {(C) Copyright 1991, Earl F. Glynn, Overland Park, KS.  Compuserve
73257,3527.

  All Rights Reserved.  This Turbo Pascal UNIT may be freely distributed
  only for non-commercial use.}

INTERFACE

  USES
    DOS;

  TYPE
                              {DOS control blocks follow}
    DiskParameterBlockPointer = ^DiskParameterBlock;
      {See pp. 743-744, "Waite Group's MS-DOS Developer's Guide, Second
       Edition, and pp. 129-133, "PC Tech Journal", February 1989}
    DiskParameterBlock      =
      RECORD                                             { offset }
        Drive               :  BYTE;   {0=A,1=B}         {  0 $00 }
        UnitWithinDriver    :  BYTE;   {0,1,2,...}       {  1 $01 }
        BytesPerSector      :  WORD;                     {  2 $02 }
        SectorsPerCluster   :  BYTE;   {SPC - 1}         {  4 $04 }
        ClusterToSectorShift:  BYTE;                     {  5 $05 }
        ReservedSectors     :  WORD;                     {  6 $06 }
        FATTables           :  BYTE;                     {  8 $08 }
        RootDirEntries      :  WORD;                     {  9 $09 }
        FirstDataSector     :  WORD;                     { 11 $0B }
        Clusters            :  WORD;   {Clusters + 1}    { 13 $0D }
        SectorsPerFAT       :  WORD;   {BYTE in DOS 3.X} { 15 $0F }
        RootDirSector       :  WORD;                     { 17 $11 }
        DeviceHeader        :  pointer;                  { 19 $13 }
        MediaType           :  BYTE;                     { 23 $17 }
        Valid               :  BYTE;                     { 24 $18 }
        NextDPB             :  DiskParameterBlockPointer { 25 $19 }
      END;

    DOSListOfLists      =  {DOS 3.X.  See Waite Group's Guide, p. 746}
      RECORD                                             { offset  }
        FirstMCBSegment :  WORD;                         { -2 -$02 }
        misc1           :  ARRAY[1..16] OF BYTE;         {  0  $00 }
        MaxBytesPerBlock:  WORD;                         { 16  $10 }
        misc2           :  ARRAY[1..4]  OF BYTE;         { 18  $12 }
        BaseDA          :  Pointer;                      { 22  $16 }
        misc3           :  ARRAY[1..6]  OF BYTE;         { 26  $1A }
        NumBlockDevices :  BYTE;                         { 32  $20 }
        LastDrive       :  BYTE  {from CONFIG.SYS}       { 33  $21 }
      END;

  VAR
    ListOfLists:  ^DOSListOfLists;
    MaxDrive   :  WORD;
    MinDrive   :  WORD;
    ValidDrive :  ARRAY[1..26] OF BOOLEAN;

  FUNCTION  NumberOfFloppyDrives:  BYTE;
  FUNCTION  FirstFloppyDrive:  BYTE;         {1=A, 2=B}
  PROCEDURE MakeFirstFloppy (drive:  BYTE);  {1=A, 2=B}

  PROCEDURE DetermineValidDrives;

  FUNCTION DiskLocation (Drive:  BYTE):  STRING;

  FUNCTION DefaultDrive:  BYTE;  {1=A, 2=B, ..., 26=Z}

  FUNCTION DriveLetter (Drive:  BYTE):  CHAR;

  FUNCTION GetCurrentDirectory (Drive:  BYTE):  STRING;

  PROCEDURE GetFreeDiskSpace
                      (Drive:  BYTE;   {1=A, 2=B, ..., 26=Z}
                       VAR Valid                 :  BOOLEAN;
                       VAR SectorSize,ClusterSize:  WORD;
                       VAR Capacity, Available   :  LongInt);

  PROCEDURE GetDPB (Drive:  BYTE;  VAR Valid:  BOOLEAN;
                                   VAR DPB:  DiskParameterBlock);

{??????????????????????????????????????????????????????????????????????}

IMPLEMENTATION

  CONST
    ByteArraySize  =  50000;

  TYPE
    ByteArray      =  ARRAY[0..ByteArraySize] OF BYTE;
    ByteArrayPtr   =  ^ByteArray;

  VAR
    buffer                 :  ARRAY[1..64] OF CHAR;
    DefaultFloppy          :  BYTE;
    ExitSave               :  Pointer;
    r                      :  Registers;
    SingleDriveLogicalDrive:  BYTE ABSOLUTE $0000:$0504;

{?????  Floppy Drives  ????????????????????????????????????????????????}

  {The next two FUNCTIONs and PROCEDURE were derived from ONEDRIVE.PAS,
   PC Magazine, Sept. 26, 1989, pp. 380-381, and Appendix A, "Memory Map",
   "Compute!'s Mapping the IBM PC", pp. 234-235, 246, and Ray Duncan's
   "IBM ROM BIOS".}

  FUNCTION  NumberOfFloppyDrives:  BYTE;
    VAR r:  Registers;
  BEGIN   {BIOS interrupt is "safer" than absolute memory reference}
    Intr ($11,r);       {r.AX contains equipment list code word}
    IF   (r.AX AND $0001) = 1
    THEN NumberOfFloppyDrives := ((r.AX SHR 6) AND $0003)+1
    ELSE NumberOfFloppyDrives := 0
  END {NumberOfFloppyDrives};

  FUNCTION  FirstFloppyDrive:  BYTE;         {1=A, 2=B}
  BEGIN
    IF   NumberOfFloppyDrives > 1
    THEN FirstFloppyDrive := 1
    ELSE FirstFloppyDrive := SingleDriveLogicalDrive + 1
  END {FirstFloppyDrive};

  PROCEDURE MakeFirstFloppy (drive:  BYTE); {1=A, 2=B}
  BEGIN
    IF   NumberOfFloppyDrives = 1
    THEN SingleDriveLogicalDrive := drive-1
  END {MakeFirstFloppy};

{?????  DetermineValidDrives  ?????????????????????????????????????????}

  PROCEDURE DetermineValidDrives;
    VAR
      drive :  BYTE;
      floppy:  BYTE;
      r     :  Registers;
  BEGIN
    MinDrive := 0;
    floppy := FirstFloppyDrive;
    FOR drive := 1 TO 26 DO BEGIN
      IF   (NumberOfFloppyDrives = 1) AND (drive IN [1..2])
      THEN BEGIN
        ValidDrive[drive] := (drive = floppy);
        MakeFirstFloppy (drive)
      END
      ELSE ValidDrive[drive] := TRUE;

      IF   ValidDrive[drive]
      THEN BEGIN
        r.AH := $36;             {DOS 2,3:  Get Free Disk Space}
        r.DL := drive;
        INTR ($21,r);
        ValidDrive[drive] := (r.AX <> $FFFF)
      END;

      IF   ValidDrive[drive]
      THEN BEGIN
        IF   MinDrive  = 0
        THEN MinDrive := drive;
        MaxDrive := drive
      END

    END;
    MakeFirstFloppy (floppy)
  END {DetermineValidDrives};

{?????  Determine if Drive is Local/LAN ???????????????????????????????}

  FUNCTION DiskLocation (Drive:  BYTE):  STRING;
    VAR r:  Registers;
  BEGIN
    r.AH := $44;
    r.AL := $09;    {DOS 3.1 and after}
    r.BL := drive;
    INTR ($21,r);
    IF   (FCarry AND r.Flags) <> 0
    THEN DiskLocation := '??????'
    ELSE
      IF   (r.DX AND $1000) = $1000
      THEN DiskLocation := 'LAN'
      ELSE DiskLocation := 'Local'
  END {DiskLocation};

{?????  DefaultDrive
...

read more »

Re:Pascal-Code to find the number of floppy-Drives


In article <01bccf6e$5e54cfe0$LocalHost@brockhoff>,

Quote
V. Brockhoff <V.Brockh...@ping.de> wrote:
>Hi together,
>can anybody give me some support for my little programming-problem.
>I'm looking for a code (Turbo Pascal 6.0 for DOS) to get the number of
>active Floppy-Diskdrives, no matter wether a disk is in or not. The inbuild
>commands like DISKFREE or anything else only work when a disk is in the
>drive.

>Please send me a code.

Following function can be used to check if a specific drive exists. If
it returns true with 'B' as parameter then you most probably have two
drives.

Function ValidDrive(C:char):Boolean;
var rg:registers;
    FCB_buff:array[0..37] of byte;
    valid:boolean;
    path:string[3];
Begin
   path:=c+':'+#0;
   rg.ax:=$2900;
   rg.si:=ofs(path[1]);
   rg.ds:=sseg;
   rg.es:=sseg;
   rg.di:=ofs(fcb_buff);
   MsDos(rg);
   Valid:=rg.al<>255;
   if ((upcase(c)='B') and valid) then
       valid:=mem[Seg0040:$10] and (3 shl 6)<>0;
   ValidDrive:=valid;
End;

The specific case for B: is because DOS makes B: point to A: when there
is just one floppy.

To further check the matter following code can be used:

Var is286,Dos3:boolean;
type string12=string[12];
...

is286:=Test8086>=1;
Dos3:=lo(dosverson)>=3;

For version 6.0 check Test286 example program for code that detects
286.

Function Removable(C:char):Boolean;
var rg:registers;
Begin
 if dos3 then begin
   rg.ax:=$4408;
   rg.bl:=Ord(upcase(c))-64;
   MsDos(rg);
   Removable:=(rg.flags and fcarry>0) or (rg.ax=0);
 End
 else Removable:=upcase(C)<'C';
End;

Note this message is in ISO-8859-1. When you transfer it to PC you have
to convert it to IBM character set so that the fractions look OK.

  Function DriveType(b:byte):string12;
  Begin
    if not is286 then Drivetype:='Floppy'
    else
     Case b of
        1: DriveType:='5?" DD';
        2: DriveType:='5?" HD';
        3: DriveType:='3?" DD';
        4: DriveType:='3?" HD';
     else DriveType:='Removable'
    End;
  End;
...

    if Is286 then begin
      port[$70]:=16;
      DrByte:=port[$71]
    End;

...

    if validDrive(c) then begin
       if Removable(c) then case c of
                                 'B': st:=DriveType(DrByte and 15);
                                 'A': st:=DriveType(DrByte shr 4);
                            end:

These functions do not cause any action on the floppy.

Osmo

Re:Pascal-Code to find the number of floppy-Drives


In article <01bccf6e$5e54cfe0$LocalHost@brockhoff>, "V. Brockhoff"
<V.Brockh...@ping.de> writes

Quote
>Hi together,
>can anybody give me some support for my little programming-problem.
>I'm looking for a code (Turbo Pascal 6.0 for DOS) to get the number of
>active Floppy-Diskdrives, no matter wether a disk is in or not. The inbuild
>commands like DISKFREE or anything else only work when a disk is in the
>drive.

>Please send me a code.

The following will give you all the disk drives available on a computer
system (up to to 26), Disk Drive returns a string will all available
drives :

{coded in TP5 to allow for most versions - assembler would be quicker}

function LastDrive : char;
var regs : registers;
begin
     regs.ah := $19;
     Intr($21,regs);
     regs.dl := regs.al;
     regs.ah := $0e;
     Intr($21,regs);
     if regs.al > $1a then regs.al := $1a;
     LastDrive := chr(regs.al + $40);
end;

function Diskdrives : string;
var regs : registers;
var i  : byte;
var st : string;
begin
    st := '';
    for I := ord(LastDrive)-64 downto 1 do
    begin
         regs.ax    := $4409;
         regs.flags :=     0;
         regs.bl    :=     I;
         Intr($21,regs);
         If not Odd(Regs.Flags) then
              st := st + chr(i+64);
     end;
     Diskdrives := st;
end;

--
Pedt Scragg <postmas...@pedt.demon.co.uk>

In principle,   is there uncertainty that
Heisenberg was working his best in chaos?

Other Threads