'Here is some code snippets to do it using MSCDEX.
'Get the whole CD player at
'that has CD Eject and close.
DEFINT A-Z
SUB SCDEject
'ejects a CD
Preprh 12
Prepcb 0
Call10
END SUB
SUB Preprh (command%) STATIC
' Prepares the request header for a given command code
'
' ARGS: command% - command code
' RET: - correctly dimensioned request header rh()
' - correctly filled in fields for basic request
' header
SELECT CASE command%
CASE 3, 12 'IOCTL Input , IOCTL Output
rhlength% = 26
CASE 132 'Play
rhlength% = 22
CASE 133, 136 'Pause, Resume
rhlength% = 13
END SELECT
REDIM rh(1 TO rhlength%) AS STRING * 1
rh(1) = CHR$(rhlength%)
rh(2) = CHR$(drivearray(Drive, 2))
rh(3) = CHR$(command%)
END SUB
'$INCLUDE: 'qb.bi'
DIM SHARED inregsx AS RegTypeX
DIM SHARED outregsx AS RegTypeX
TYPE tracktype
start AS LONG
length AS LONG
ctrlinfo AS INTEGER
END TYPE
TYPE disktype
Low AS INTEGER
High AS INTEGER
Leadout AS LONG
END TYPE
'$DYNAMIC
'----------------------------------------------------------------
COMMON SHARED Baseport% 'for Sound Blaster card
COMMON SHARED SBMyVol% 'volume setting
COMMON SHARED CDDEBUG%
'env/status vars
COMMON SHARED CDDoorOpen% 'is cd tray/door open? Door in CDLIB
COMMON SHARED playing AS INTEGER 'is CD playing?
COMMON SHARED paused AS INTEGER
COMMON SHARED Stopped AS INTEGER
COMMON SHARED Drive AS INTEGER 'default drive
COMMON SHARED drv% 'current drive
COMMON SHARED rhlength% 'length of request header
COMMON SHARED cblength% 'length of control block
COMMON SHARED max& 'length of control block
COMMON SHARED numdrives AS INTEGER
COMMON SHARED first AS INTEGER 'drive letter of first CD drive : int
DIM SHARED drivearray(X, Y) AS INTEGER
DIM SHARED rh(Z) AS STRING * 1 'request header - dynamic array
DIM SHARED cb(Z) AS STRING * 1 'command block - dynamic array
DIM SHARED trackinfo(Z) AS tracktype
DIM SHARED diskinfo(Z) AS disktype
'Define some default values
ver$ = "4.60"
CONST frameto100 = 1.333
CONST true = 1, false = 0
CONST skiplength& = 750&
paused1% = false
CDDoorOpen% = false
CDDEBUG% = false: 'A crude form of error correction in subs
max& = 0:
trlen& = 1
Baseport% = &H210
SBMyVol% = 8
vbar$ = CHR$(179)
r1 = 5: c1 = 1: c2 = 45: 'position of track info
SUB Prepcb (code%) STATIC
' Prepares the control block for a given subfunction
' Checks whether cb() is used for IOCTL INPUT or OUTPUT
'
' ARGS: code% - control block code
' RET: - correctly dimensioned control block cb()
' - correctly filled in fields for entire request
' header
IF ASC(rh(3)) = 3 THEN
SELECT CASE code%
CASE 1
length% = 6
CASE 4
length% = 9
CASE 6
length% = 5
CASE 9
length% = 2
CASE 10, 11
length% = 7
CASE 12, 15
length% = 11
END SELECT
ELSE
SELECT CASE code%
CASE 0, 2, 5
length% = 1
CASE 1
length% = 2
CASE 3
length% = 9
END SELECT
END IF
REDIM cb(1 TO length%) AS STRING * 1
cb(1) = CHR$(code%)
'Update address of cb() in rh()
rh(15) = CHR$(lbyte(VARPTR(cb(1))))
rh(16) = CHR$(hbyte(VARPTR(cb(1))))
rh(17) = CHR$(lbyte(VARSEG(cb(1))))
rh(18) = CHR$(hbyte(VARSEG(cb(1))))
'Number of bytes to transfer
rh(19) = CHR$(lbyte(length%))
rh(20) = CHR$(hbyte(length%))
END SUB