Is it possible to get keyboard input from a driver being loaded by c:\windows\system32\config.nt during the driver's initialization, when being run on 32-bit Windows 10 21H2 (OS Build 19044.1466) under NTVDM.exe? At this point I am just trying to simulate "press any key to continue..."
I've tried DOS APIs AH=08h INT 21h and BIOS API AH=00h INT 16h but both seem to freeze and not detect the input.
Code:
; *******************************************************************
; * 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!
I'm building with masm:
masm presskey.asm
link presskey
exe2bin presskey.exe presskey.sys
It need not be true that the BIOS.WaitKey function 00h freezes the computer. It's probably your driver that freezes it because you forgot to setup a number of registers!
This
assume cs:cseg,es:cseg,ds:cseg
is not enough on its own. You need to make sure that theDS
andES
segment registers get the correct values.For
DS
it is simply a copy fromCS
:And when your dev_interrupt routine is invoked,
ES:BX
needs to be set by your code. That's why we have a dev_strategy routine at all. You didn't do that and as a consequence you are overwriting the wrong memory and not returning 'DONE' to the RequestHeaderStatusWord or letting DOS know where the end of your driver is.Best also change that
rol al,1
into the less confusingshl al,1
for clarity. But that's me of course...