[Back to WIN-OS2 SWAG index] [Back to Main SWAG index] [Original]

    {+------------------------------------------------------------
     | Unit PBCDInt
     |
     | Version: 1.0  Last modified: 02/27/95, 22:09:07
     | Author : P. Below  CIS [100113,1101]
     | Project: Common utilities
     | Description:
     |   This DLL exports a number of functions of the MSCDEX interface
     |	 for the use of other Windows programs. Was originally written
     |	 for a Visual Basic app that needed a method do detect whether
     |	 a given drive is a CD-ROM and whether it contains a CD or not.
     |
     |   Released to public domain
     +------------------------------------------------------------}
    Library PBCDINT;

    Uses WinTypes, WinProcs, Utils;

    Const
      CD_ERROR = -1;
      CD_NOTACDDRIVE = 0;
      CD_DRIVEEMPTY = 1;
      CD_CDFOUND = 2;

    (* returns TRUE if MSCDEX is loaded, False otherwise *)
    FUNCTION Is_MSCDEX_loaded: BOOLEAN; assembler;
      ASM
        mov AX, $1500   (* MSCDEX installed check *)
        xor BX, BX
        int $2F
        xor ax, ax      (* set default return value to false *)
        or  BX, BX      (* returns bx <> 0 if MSCDEX installed *)
        jz  @no_mscdex
        mov al, TRUE
      @no_mscdex:
      END;

    (* returns -1 ( VB True ) if drive is CD-ROM, 0 otherwise.
       drivenum = 1 for A:, 2 for B: etc. *)
    Function CDDriveIsCD( drivenum: Integer): Integer; export;
      Begin
        ASM
          mov AX, $150B (* MSCDEX check drive function *)
          mov CX, drivenum
          sub BX,BX
          int $2F
          cmp bx, $ADAD
          jne @no_cdrom
          or  AX, AX
          jz  @no_cdrom
          mov @result, $FFFF
          jmp @exit
        @no_cdrom:
          mov @result, 0
        @exit:
        END;
      End;

    (* returns one of the CD_xxx constants.
       drivenum = 1 for A:, 2 for B: etc. *)
    Function CDDriveStatus( drivenum: integer ): integer; export;
      Var
        RealModeReg: TRealModeReg;
        dwGlobalDosBuffer: LongInt;
      Begin
        If CDDriveIsCD( drivenum ) = 0 Then
          CDDriveStatus := CD_NOTACDDRIVE
        Else Begin
          CDDriveStatus := CD_ERROR;
          { alloc a buffer for the MSCDEX call to put the copyright filename into.
            this has to reside in low dos memory since the function needs a real mode
            pointer in es:bx. We ignore the info put into the buffer. }
          dwGlobalDosBuffer := GlobalDosAlloc(40);
          if (dwGlobalDosBuffer <> 0) then Begin
            { initialize the real mode register structure }
            FillChar(RealModeReg, sizeof(RealModeReg), 0);
            RealModeReg.rmEAX := $1502;
            RealModeReg.rmECX := Longint(drivenum);
            RealModeReg.rmES  := HIWORD(dwGlobalDosBuffer);  { real mode segment }
            RealModeReg.rmEBX := 0;         { offset is zero }

            { simulate the real mode interrupt. we have to jump thru these hoops
              because loading a real mode segment value into a register in
              protected mode is a sure recipe for a GPF. }
            if RealInt($2F, RealModeReg) then
              If (LoWord(RealModeReg.rmCPUFlags) and 1) = 0 Then
                { carry clear, CD drive containing a readable CD }
                CDDriveStatus := CD_CDFOUND
              Else
                If LoWord( RealModeReg.rmEAX ) = $F Then
                  { DOS error "invalid drive" }
                  CDDriveStatus := CD_NOTACDDRIVE
                Else
                  { normally DOS error 1Eh: read fault }
                  CDDriveStatus := CD_DRIVEEMPTY;
            GlobalDosFree(LOWORD(dwGlobalDosBuffer));
          End;
        End;
      End;

    (* returns the number of CD drives supported by MSCDEX *)
    Function CDNumberOfDrives: Integer; export;
      Begin
        ASM
          mov AX, $1500   (* MSCDEX installed check *)
          xor BX, BX
          int $2F
          mov @result, bx
        END;
      End;

    (* returns the number of the first drive supported by MSCDEX *)
    Function CDFirstDrive: Integer; export;
      Begin
        ASM
          mov AX, $1500   (* MSCDEX installed check *)
          xor BX, BX
          int $2F
          mov @result, cx
        END;
      End;

    exports
      CDDriveStatus    index 1,
      CDNumberOfDrives index 2,
      CDFirstDrive     index 3,
      CDDriveIsCD      index 4;

    Begin
      (* make the fixed DLL data segment moveable *)
      GlobalPageUnlock( DSeg );
      GlobalReAlloc(DSeg, 0, GMEM_MODIFY or GMEM_MOVEABLE);
    End.

[Back to WIN-OS2 SWAG index] [Back to Main SWAG index] [Original]