from
http://www.xploiter.com/programming/delphi/tips4.shtml#tip37
Tip 37
//Is there any function can detect the current status of the CDROM door, (that is, opened or closed)? //You may use the MediaPlayer for this:
if MediaPlayer.Mode = mpOpen then
CDTrayOpen
else
CDTrayClosed; //Another way is to trap WM_DEVICECHANGE message: procedure WMDeviceChange(var Msg: TMsg); message WM_DEVICECHANGE; procedure TForm1.WMDeviceChange(var Msg: TMsg);
begin
if Msg.wParam = DBT_DEVICEREMOVEPENDING then
// user has started to eject CD
// Tell Windows it's OK.
Msg.Result := True;
end; (*See also:
DBT_DEVICEARRIVAL
DBT_DEVICEREMOVECOMPLETE Where is DBT_DEVICEREMOVEPENDING defined? -- I can't find any hint
of this (except in the help files.....)
Sorry, seems that there isn't any declaration in Delphi. dbt_
constants are declared in dbt.h, in Delphi it would be: const
DBT_QUERYCHANGECONFIG = $0017;
DBT_CONFIGCHANGED = $0018;
DBT_CONFIGCHANGECANCELED = $0019;
DBT_DEVICEARRIVAL = $8000;
DBT_DEVICEQUERYREMOVE = $8001;
DBT_DEVICEQUERYREMOVEFAILED = $8002;
DBT_DEVICEREMOVEPENDING = $8003;
DBT_DEVICEREMOVECOMPLETE = $8004;
DBT_DEVICETYPESPECIFIC = $8005;
DBT_USERDEFINED = $FFFF;
*)
http://www.xploiter.com/programming/delphi/tips4.shtml#tip37
Tip 37
//Is there any function can detect the current status of the CDROM door, (that is, opened or closed)? //You may use the MediaPlayer for this:
if MediaPlayer.Mode = mpOpen then
CDTrayOpen
else
CDTrayClosed; //Another way is to trap WM_DEVICECHANGE message: procedure WMDeviceChange(var Msg: TMsg); message WM_DEVICECHANGE; procedure TForm1.WMDeviceChange(var Msg: TMsg);
begin
if Msg.wParam = DBT_DEVICEREMOVEPENDING then
// user has started to eject CD
// Tell Windows it's OK.
Msg.Result := True;
end; (*See also:
DBT_DEVICEARRIVAL
DBT_DEVICEREMOVECOMPLETE Where is DBT_DEVICEREMOVEPENDING defined? -- I can't find any hint
of this (except in the help files.....)
Sorry, seems that there isn't any declaration in Delphi. dbt_
constants are declared in dbt.h, in Delphi it would be: const
DBT_QUERYCHANGECONFIG = $0017;
DBT_CONFIGCHANGED = $0018;
DBT_CONFIGCHANGECANCELED = $0019;
DBT_DEVICEARRIVAL = $8000;
DBT_DEVICEQUERYREMOVE = $8001;
DBT_DEVICEQUERYREMOVEFAILED = $8002;
DBT_DEVICEREMOVEPENDING = $8003;
DBT_DEVICEREMOVECOMPLETE = $8004;
DBT_DEVICETYPESPECIFIC = $8005;
DBT_USERDEFINED = $FFFF;
*)
如:金山影霸、豪杰超级解霸2001,Power DVD,就连Windows 也只提供了“弹出 CD-ROM”而没有类似的功能,不知道是什么原因。如果有那位知道可一定不要忘了我们这帮兄弟呀。
var
var
dwTemp1,dwTemp2: DWord;
NResult: DWORD;
begin
new(NResult);
GetVolumeInformation(PChar('g:\'), Nil, 0, @Result, dwTemp1, dwTemp2, Nil, 0);
if Result = 0 then
ShowMessage('CDROM is not Ready!');
end;
procedure TForm1.OpenCDRomClick(Sender: TObject);
begin
mciSendString('Set cdaudio door open wait', nil, 0, handle);
end;关闭光驱
procedure TForm1.CloseCDRomClick(Sender: TObject);
begin
mciSendString('Set cdaudio door closed wait', nil, 0, handle);
end;另外先在uses后加上MMSystem
karma(无为)的答案,只有在开机是光驱就处于关闭状态,再用一个变量记录光驱状态,才可以确定光驱的状态。
请大家提供一点有用的东西。我是连中断都试过的,这几个函数我也搞过。
karma(无为)的答案,只有在开机是光驱就处于关闭状态,再用一个变量记录光驱状态,才可以确定光驱的状态。
请大家提供一点有用的东西。我是连中断都试过的,这几个函数我也搞过。
不知道,关注!
00H 字节 1AH
01H 字节 00H
02H 字节 03H
03H 字节 11 DUP(?)
0EH 双字 缓冲区地址
12H 字 缓冲区长度
14H 字节 6 DUP(?) 2. IOCTL output 的格式:偏移量 类型 内容
00H 字节 1AH
01H 字节 00H
02H 字节 0CH
03H 字节 11 DUP(?)
0EH 双字 缓冲区地址
12H 字 缓冲区长度
14H 字节 6 DUP(?) 3. 在缓冲区中填入命令再用 INT 2fH 的 1510H 便可以实现 CD-ROM 的各种功能,缓冲的一些命令格式如下:作用 长度 格式
出盒 1 00
解锁 2 01,00
加锁 2 01,01
入盒 1 05
取CD-ROM 状态 5 06,0,0,0,0
返回:06,xx,xx,0,0
xx,xx为状态字
位0:1 门开,0门关
位1:1未锁,0门锁
位B:1无盘,0有盘 4. 检测 CD-ROM 驱动程序的存在:AX = 1500H
BX = 0
INT 2fH
返回:BX = CD-ROM 个数
CX = 起始CD-ROM 盘符,0=A:,1=B:等等5. 发送 Device Driver Request:AX = 1510H
ES:BX=请求头地址
CX = CD-ROM 的盘号源程序如下:; CD-ROM eject/load progrm
; Ver 1.20 ------ Jan 6,1996CODE SEGMENT
ASSUME CS:CODE,DS:CODE
ORG 100H
START:
jmp install
COPYRIGHT DB 'CD-ROM drive eject/close prg. V1.20',0dh,0ah
DB 'Copyright (c) by Luo Yun Bin, Jan 6,1996',0dh,0ah
DB 'http://asm.yeah.net,Email: [email protected]'
DB 0dh,0ah,0ah,24h
D_HELP DB 'Usage: EJ [drive:] [/?|/L|/U]',0dh,0ah
DB ' /? -------- Display this help',0dh,0ah
DB ' /L -------- Lock door',0dh,0ah
DB ' /U -------- Unlock door',0dh,0ah,24h
MESS_WAIT DB '[ENTER] to close, [Esc] to quit.',24h
MESS_ESC DB 'tray keep open...',0dh,0ah,24h
MESS_NO_CD DB 'MSCDEX not installed!',0dh,0ah,24h
MESS_STATUS DB 'There are '
DRV_NUMBER DB '0 CD-ROM drive(s) starting at '
DRV DB 'A:',0dh,0ah,24h
MESS_DRV DB 0dh,' ',0dh
DB 'drive '
DRV1 DB 'A: ',24h
MESS_EJECT DB 'ejecting....',24h
MESS_CLOSE DB 'closing ....',24h
MESS_LOCK DB 'locking ....',24h
MESS_UNLOCK DB 'unlocking...',24h
MESS_DONE DB ' Done!',0dh,0ah,24h
CD_DRV DW ?
FLAG DB ?
;======================================================
REQ_HEAD DB 1ah,0 ;IOCTL input
REQ_CMD DB 3
REQ_ERR DW ?
DB 9 dup (0)
BUF_OFF DW buffer
BUF_SEG DW ?
BUF_LEN DW ?
DB 6 dup (0)
;======================================================
BUFFER DB 5 dup (0) ;Max used 5 bytes
CMD_LINE PROC
mov si,81h ;处理命令行参数
mov di,80h
cld
cmd_reload:
lodsb
cmp al,0dh
jz conv_end ;将命令行小写字母换成大写
cmp al,'a'
jb conv_ok
cmp al,'z'
ja conv_ok
sub al,20h
conv_ok:
stosb
jmp short cmd_reload
conv_end:
xor al,al
stosb
mov si,80h
cmd_reload1:
lodsb
or al,al
jz cmd_end
cmp al,'/'
jz cmd_switch
cmp al,':'
jnz cmd_reload1
mov al,[si-2]
cmp al,'A'
jb cmd_end
cmp al,'Z'
ja cmd_end
sub al,'A'
xor ah,ah
mov cd_drv,ax
jmp short cmd_reload1
cmd_switch:
lodsb
cmp al,'?'
jz cmd_help
cmp al,'L'
jz cmd_lock
cmp al,'U'
jz cmd_unlock
jmp short cmd_reload1
cmd_end:
ret
cmd_help:
mov dx,offset d_help
call print
int 20h
cmd_lock:
or flag,1
jmp short cmd_reload1
cmd_unlock:
or flag,2
jmp short cmd_reload1
CMD_LINE ENDP
CD_INT PROC
mov ax,1510h
mov buf_seg,cs
mov bx,offset req_head
mov cx,cd_drv
int 2fh
ret
CD_INT ENDP
GET_STATUS PROC
mov buffer,6
mov buf_len,5
mov req_cmd,3
call cd_int
ret
GET_STATUS ENDP
EJECT_DISK PROC
mov dx,offset mess_drv
call print
mov dx,offset mess_eject
call print
mov buffer,0
mov buf_len,1
mov req_cmd,0ch
call cd_int
mov dx,offset mess_done
call print
ret
EJECT_DISK ENDP
CLOSE_TRAY PROC
mov dx,offset mess_drv
call print
mov dx,offset mess_close
call print
mov buffer,5
mov buf_len,1
mov req_cmd,0ch
call cd_int
mov dx,offset mess_done
call print
ret
CLOSE_TRAY ENDP
LOCK_DOOR PROC
mov dx,offset mess_drv
call print
mov dx,offset mess_lock
call print
mov word ptr buffer,0101h
mov buf_len,2
mov req_cmd,0ch
call cd_int
mov dx,offset mess_done
call print
ret
LOCK_DOOR ENDP
UNLOCK_DOOR PROC
mov dx,offset mess_drv
call print
mov dx,offset mess_unlock
call print
mov word ptr buffer,0001h
mov buf_len,2
mov req_cmd,0ch
call cd_int
mov dx,offset mess_done
call print
ret
UNLOCK_DOOR ENDP
CHECK_CDROM PROC
mov ax,1500h
xor bx,bx
int 2fh
or bx,bx ;BX = CD-ROM numbers
jnz mscdex_installed
mov dx,offset mess_no_cd
call print
int 20h
mscdex_installed:
mov bp,cx
xor bh,bh
add bp,bx
dec bp
cmp cd_drv,cx
jb re_set
cmp cd_drv,bp
jbe par_ok
re_set:
mov cd_drv,cx
par_ok:
add drv_number,bl
add drv,cl
mov cx,cd_drv
add drv1,cl
mov dx,offset mess_status
call print
ret
CHECK_CDROM ENDP
PRINT PROC
mov ah,9
int 21h
ret
PRINT ENDP
install:
mov dx,offset copyright
call print
call cmd_line
call check_cdrom ;检测 CD-ROM 状态
test flag,1 ;如果 /L 参数则 Lock_door
jz ins1
call lock_door
int 20h
ins1:
test flag,2 ;如果 /U 参数则 unlock_door
jz ins2
call unlock_door
int 20h
ins2:
call get_status
test word ptr buffer+1,1 ;如果现在在出盒状态则转入盒
jnz close_it
call eject_disk ;打开 CD-ROM
mov dx,offset mess_wait ;等待
call print
xor ax,ax
int 16h
cmp al,1bh
jz _esc_quit
close_it:
call close_tray ;关闭 CD-ROM
int 20h
_esc_quit:
mov dx,offset mess_drv
call print
mov dx,offset mess_esc
call print
int 20h
CODE ENDS
END START
重申一点我讨论的是光驱的门是不是打开的,而不是弹出打开光驱。