ITEEDU

第1章 Iczelion的Win32汇编教程

第2章 Iczelion的ODBC教程

第3章 Iczelion的VxD教程

第4章 Iczelion的PE教程

第5章 罗云彬的Win32汇编教程

第6章 Win32ASM经验点滴

第7章 X86汇编语言编程

第8章 加密解密

第9章 病毒的分析和防治

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