CD-ROM出盒、入盒程序


概述:

     我们在应用程序中常见到用软件控制 CD-ROM 的出、入盒,本文就是实现这种功能的一个例子。主要用到 INT 2FH 的 1510H(Send device driver request) 功能。具体参数详见程序注释。

要用到的几个中断说明如下:

1. IOCTL input 的格式:

偏移量 类型 内容
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,1996

CODE		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: luoyunbin@telekbird.com.cn'
		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




(C) Copyright by LuoYunBin's Win32 ASM Page,http://asm.yeah.net