【发布时间】:2022-02-01 04:02:27
【问题描述】:
在驱动程序初始化期间,在 32 位 Windows 10 21H2(操作系统在 NTVDM.exe 下构建 19044.1466)?此时我只是想模拟“按任意键继续...”
我已经尝试过 DOS API AH=08h INT 21h 和 BIOS API AH=00h INT 16h,但两者似乎都冻结且未检测到输入。
代码:
; *******************************************************************
; * Press Any Key To Continue DRIVER *
; *******************************************************************
cseg segment para public 'code'
presskey proc far
assume cs:cseg,es:cseg,ds:cseg
; *******************************************************************
; * MAIN PROCEDURE CODE *
; *******************************************************************
begin:
; *******************************************************************
; * DEVICE HEADER - REQUIRED BY DOS *
; *******************************************************************
next_dev dd -1 ; no other device drivers
attribute dw 8000h ; character device
strategy dw dev_strategy ; address of 1st dos call
interrupt dw dev_interrupt ; address of 2nd dos call
dev_name db 'PRESSKEY$ ' ; name of the driver
; *******************************************************************
; * WORK SPACE FOR THE DEVICE DRIVER *
; *******************************************************************
rh_ofs dw ? ; request header offset
rh_seg dw ? ; request header segment
msg1 db 07h
db 'Press any key to continue...'
db 0dh,0ah,07h,'$'
; *******************************************************************
; * THE STRATEGY PROCEDURE *
; *******************************************************************
dev_strategy: ; first call from DOS
mov cs:rh_seg,es ; save request header ptr segment
mov cs:rh_ofs,bx ; save request header ptr offset
ret
; *******************************************************************
; * THE INTERRUPT PROCEDURE *
; *******************************************************************
dev_interrupt: ; second call from DOS
cld ; save machine state on entry
push ds
push es
push ax
push bx
push cx
push dx
push di
push si
; perform branch based on the command passed in the req header
mov al,es:[bx]+2 ; get command code
cmp al,0 ; check for 0
jnz exit3 ; no - exit go to error exit
rol al,1 ; get offset into table
lea di,cmdtab ; get address of command table
mov ah,0 ; clear hi order
add di,ax ; add offset
jmp word ptr[di] ; jump indirect
; command table
; the command code field of the static request
; field contains the function to be performed
cmdtab label byte ;
dw init ; initialization
; *******************************************************************
; * LOCAL PROCEDURES *
; *******************************************************************
initial proc near
lea dx,msg1 ; initialization
mov ah,9 ; message
int 21h ; dos call
mov ah,0 ; wait for key press
int 16h
ret ; return
initial endp
; *******************************************************************
; * DOS COMMAND PROCESSING *
; *******************************************************************
;command 0 initialization
init: call initial ; display a message
lea ax,exit ; get end address (offset)
mov es:[bx]+0eh,ax ; store offset address
push cs ; get end
pop ax ; address (segment)
mov es:[bx]+10h,ax ; store in break address
jmp exit2
; *******************************************************************
; * ERROR EXIT *
; *******************************************************************
; Set the done flag, error flag, and unknown command error code
exit3: mov es:word ptr 3[bx],8103h
jmp exit1 ; restore environment
; *******************************************************************
; * COMMON EXIT *
; *******************************************************************
; common exits fall thru code
; 2 sets status to done and no error
; 1 restore callers es:bx
; 0 restore machine state and exit
exit2: ; set done flag and no error
mov es:word ptr 3[bx],0100h
exit1: mov bx,cs:rh_ofs ; restore req hdr to bx and es
mov es,cs:rh_seg ; as saved by dev_Strategy
exit0: pop si ; restore all registers
pop di
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
ret
exit:
; *******************************************************************
; * END OF PROGRAM *
; *******************************************************************
presskey endp
cseg ends
end begin
; that's all folks!
我正在使用 masm 构建:
masm presskey.asm
link presskey
exe2bin presskey.exe presskey.sys
【问题讨论】:
-
如果重要的话,您测试的是哪个版本的 Windows?我对这个问题中的 Windows 和 DOS 细节知之甚少,我自己也没有任何线索。
-
如果您注释掉对
initial的调用会怎样?如果可行,您可以尝试注释掉调用以打印提示。可能不支持在加载驱动程序时回调到 DOS (int 21h)。但这只是一个模糊的猜测。 -
调用 int 21h 打印字符串很好,只是从键盘读取似乎冻结了
-
嗯。从缓冲区(int 16/0)读取输入字符似乎是一项非常简单的任务。我想不出为什么会挂起。但也许将字符添加到缓冲区的 ISR 可以被
cli阻止?由于我们正在加载设备驱动程序,我想在我们完成之前禁用中断可能是有意义的。你能检查FLAGS吗?出于教育目的:在 INT 16 之前(即不是之前的行)将 STI 称为几个语句怎么样?显然是另一个模糊的猜测。
标签: assembly driver dos x86-16 ntvdm