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