[Back to DRIVES SWAG index] [Back to Main SWAG index] [Original]

    {
     JM>Would you happen to have any example code to determine if a drive is a
     JM>hard disk, cd-rom, ramdrive etc. ?

    Here is a unit that will at least tell you a little about the CD-ROM.   Not all
    MSCDEX functions are implemented, but enough to identify the CD-ROMS.
    }
    unit CDROM;

    {$X+}   { Extended Syntax Rules }

    interface

    type
      CDR_DL_ENTRY = record
        UNITNO  : byte;
        OFFSET  : word;
        SEGMENT : word;
      end;

      CDR_DL_BUFFER   = array[1..26] of CDR_DL_ENTRY;
      CDR_DRIVE_UNITS = array[0..25] of byte;
      CDR_VTOC        = array[1..2048] of byte;

    { 00h } procedure CDR_GET_DRIVE_COUNT   (var COUNT, FIRST: word);
    { 01h } procedure CDR_GET_DRIVE_LIST    (var LIST: CDR_DL_BUFFER);
    { 02h } function  CDR_GET_COPR_NAME     (DRIVE: byte): string;
    { 03h } function  CDR_GET_ABSTRACT_NAME (DRIVE: byte): string;
    { 04h } function  CDR_GET_BIBLIO_NAME   (DRIVE: byte): string;
    { 05h Read VTOC }
    { 06h Reserved }
    { 07h Reserved }
    { 08h Absolute Disk Read }
    { 09h Absolute Disk Write }
    { 0ah Reserved }
    { 0bh } function  CDR_DRIVE_CHECK       (DRIVE: byte): boolean;
    { 0ch } function  CDR_VERSION: word;
    { 0dh } procedure CDR_GET_DRIVE_UNITS   (var BUFFER: CDR_DRIVE_UNITS);
    { 0eh Get or Set VDR }
    { 0fh Get Dir Entry }
    { 10h Send Device Request }

    implementation

    uses dos, strings;

    const
      CDROM_INTERRUPT = $2f;

    var
      REG : registers;

    procedure CDR_GET_DRIVE_COUNT (var COUNT, FIRST: word);
    assembler;

    { Returns the total number of CD-ROM Drives in the system }
    { and the logical drive number of the first drive.        }

    { In a system that contains multiple CD-ROM Drives and is }
    { also networked, the CD-ROM drives might not be assigned }
    { as consecutive logical units.  See also MSCDEX Function }
    { 0Dh (Get CD-ROM Drive Letters)                          }

    asm
      mov ax, 1500h
      xor bx, bx
      int CDROM_INTERRUPT
      les di, COUNT
      mov es:[di], bx
      les di, FIRST
      mov es:[di], cx
    end;

    procedure CDR_GET_DRIVE_LIST (var LIST: CDR_DL_BUFFER);
    assembler;

    { Returns a driver unit identifier for each CD-ROM drive  }
    { in the system, along with the address of the header for }
    { the device driver that controls the drive.              }

    { The driver unit code returned in the buffer is not the  }
    { systemwide logical drive identifier but is the relative }
    { unit for that particular driver.  For example if three  }
    { CD-ROM drivers are installed, each supporting one phy-  }
    { sical drive, the driver unit code in each 5 byte entry  }
    { will be 0.  The systemwide drive identifiers for each   }
    { CD-ROM unit can be obtained with MSCDEX Function 0Dh    }
    { (Get CD-ROM Drive Letters).                             }

    asm
      mov ax, 1501h
      les bx, LIST
      int CDROM_INTERRUPT
    end;

    function  CDR_GET_COPR_NAME (DRIVE: byte): string;

    { Returns the name of the copyright file from the volume  }
    { table of contents (VTOC) of the specified CD-ROM Drive. }

    { CD-ROM Specs allow for a 31 character filename followed }
    { by a semicolon (;) and a 5 digit version number.        }

    { On disks that comply with the High Sierra standard,     }
    { the filename has an MS-DOS compatable (8/3) format.     }

    var
      BUFFER : array[0..38] of char;

    begin
      REG.AX := $1502;
      REG.CX := DRIVE;
      REG.ES := seg(BUFFER);
      REG.BX := ofs(BUFFER);
      intr(CDROM_INTERRUPT, REG);
      CDR_GET_COPR_NAME := strpas(BUFFER);
    end;

    function  CDR_GET_ABSTRACT_NAME (DRIVE: byte): string;

    { Returns the name of the abstract file from the volume   }
    { table of contents (VTOC) for the specified CD-ROM drive.}

    { CD-ROM Specs allow for a 31 character filename followed }
    { by a semicolon (;) and a 5 digit version number.        }

    { On disks that comply with the High Sierra standard,     }
    { the filename has an MS-DOS compatable (8/3) format.     }

    var
      BUFFER : array[0..38] of char;

    begin
      REG.AX := $1503;
      REG.CX := DRIVE;
      REG.ES := seg(BUFFER);
      REG.BX := ofs(BUFFER);
      intr(CDROM_INTERRUPT, REG);
      CDR_GET_ABSTRACT_NAME := strpas(BUFFER);
    end;

    function  CDR_GET_BIBLIO_NAME (DRIVE: byte): string;

    { Returns the name if the bibliographic file from the     }
    { volume table of contents (VTOC) for the specified drive.}

    { CD-ROM Specs allow for a 31 character filename followed }
    { by a semicolon (;) and a 5 digit version number.        }

    { This function is provided for compatability with the    }
    { ISO-9660 standard.  A null string is returned for disks }
    { complying with the High Sierra standard.                }

    var
      BUFFER : array[0..38] of char;

    begin
      REG.AX := $1504;
      REG.CX := DRIVE;
      REG.ES := seg(BUFFER);
      REG.BX := ofs(BUFFER);
      intr(CDROM_INTERRUPT, REG);
      CDR_GET_BIBLIO_NAME := strpas(BUFFER);
    end;

    function CDR_DRIVE_CHECK (DRIVE: byte): boolean;

    { Returns a code indicating whether a particular logical  }
    { unit is supported by the Microsoft CD-ROM Extensions    }
    { module (MSCDEX).                                        }

    begin
      REG.AX := $150b;
      REG.BX := $0000;
      REG.CX := DRIVE;
      intr(CDROM_INTERRUPT, REG);
      CDR_DRIVE_CHECK := (REG.AX <> $0000) and (REG.BX = $adad);
    end;

    function  CDR_VERSION: word;

    { Returns the version number of the Microsoft CD-ROM Extensions }

    { The Major Version number is returned in the High Order byte   }
    { and the Minor Version Number is returned in the Lo order      }
    { byte.  IE if the MSCDEX Version is 2.10, this routine will    }
    { return $0210.                                                 }

    begin
      REG.AX := $150c;
      REG.BX := $0000;
      intr(CDROM_INTERRUPT, REG);

      { Version 1.0 Returns 0 instead of actual Version Number }
      { So we will fix it so that this routine returns 1.0     }

      if REG.BX = 0 then begin
        CDR_VERSION := $0100;
      end else begin
        CDR_VERSION := REG.BX;
      end;
    end;

    procedure CDR_GET_DRIVE_UNITS(var BUFFER: CDR_DRIVE_UNITS);
    assembler;

    { Returns a list of the systemwide logical drive identifers     }
    { that are assigned to CD-ROM drives.                           }

    { Upon return the buffer contains a series of 1 byte entries.   }
    { Each entry is a logical unit code assigned to a CD-ROM drive  }
    { (0 = A, 1 = B, etc); the units might not be consecutive.      }

    { The number of valid entries can be determined by MSCDEX       }
    { function 00h.                                                 }

    asm
      mov ax, 150dh
      les bx, BUFFER
      int CDROM_INTERRUPT
    end;

    end.

[Back to DRIVES SWAG index] [Back to Main SWAG index] [Original]