How to Modify VxD in VKD_Define_Hot_Key to Detect All KeysID: Q153380
|
In Windows 95, the keyboard input is handled by the keyboard driver and is virtualized by the VxD called (default) VKD.VXD. At ring 0, a VxD can call VKD_Define_Hot_Key to set a call back on certain keystrokes. This may seem not to work on some key combinations or events. This article provides sample code showing how to modify the VKD source code supplied with the Windows 95 DDK to trace the hot key evaluation and see all the scan codes as they are typed. With modification, this should also work in the Windows version 3.1 DDK sample.
The VxDCall VKD_Define_Hot_Key uses the VMM list services to create a list
of all hot keys currently set. When a key is changed (pressed or released)
the routine Chk_Hot_Keys in VKDHK.ASM is called to compare it to the list.
Certain key combinations do not register as a single event, so drivers that
need to detect them must keep track of the key history. The following
sample code, replacing the first part of Chk_Hot_Keys, sends out the exact
scan code and shift state for reference on every key event as well as
advisory messages as to hot key detection.
The code was tested by building in the SDK95/DDK95/MASM6.11 environment,
using WDEB386 as the debugger. Note the use of conditional trace outs.
Remember also, that you will most likely be calling VKD_Reflect_Hot_Key ("I
am not doing anything with this key now but pass it on") or
VKD_Cancel_Hot_Key ("I have handled this key - no further system action")
as part of your call back routine.
BeginProc Chk_Hot_Keys
;!!! key trace
trace_out "Chk_Hot_Keys key #AX"
;!!! end
VK_HK_Queue_Out "Chk_Hot_Keys key scan code = #AX ..."
push eax
;!!! key trace
mov eax,[vkd_gbl_shift_state]
trace_out "Chk_Hot_Keys ... shift state = #AX"
pop eax
push eax
;!!! end
test [VKD_gbl_shift_state], SS_Shift_mask + SS_Toggle_Dn_mask
;Q: are any shift state keys down?
;!!! key trace
trace_outNZ "---------- Shift State keys DOWN"
;!!! end
jnz short chkhk_1 ; Y:
and eax, (NOT SC_Break AND 0FFh) OR VK_Extended
; clear all but Extended bit &
; base scan code
cmp eax, Pause_HK ;Q: special single key hot key?
;!!! key trace
trace_outZ "---------- NO CHECK performed (special key)"
;!!! end
jz DEBFAR je_don_t_check ; N: (chained short jumps)
chkhk_0:
mov eax, [esp] ; retrieve saved eax value
chkhk_1:
IFDEF DEBUG
push ebx
mov ebx, [esp+8]
VK_HK_Queue_Out 'Chk_Hot_Keys #ax, called from ?ebx'
pop ebx
ENDIF
test al, SC_Break ;Q: key being released?
jz short continue_check
TestMem [VKD_flags], VKDf_HK_hold ;Q: already in hot key state?
je_don_t_check:
je DEBFAR don_t_check ; N: don't enter hot key state
; on just the release!
continue_check:
;!!! key trace
trace_out "---------- CHECK performed"
;!!! end
pushad
mov edi, esi ; point edi at CB data
mov cx, ax ; save virtual key
mov esi, [Hot_Key_List]
VMMCall List_Get_First
jz short no_hot_keys ; jump if no hot keys defined
;
; if extended, is all we need to know
; so leave VK_Extended bit in modifier byte and NON SC_Break bits in the
; scan code byte
;
and cx, VK_Extended + (0FFh XOR SC_Break)
.errnz (VK_Extended + (0FFh XOR SC_Break)) - 807Fh
chk_key:
cmp cl, [eax.Hot_Key_scan_code] ;Q: scan codes match?
jne short no_key ; N:
cmp [eax.Hot_Key_extended], AllowExtended_B ;Q: ignore extended flag?
je short accept_key ; Y:
cmp ch, [eax.Hot_Key_extended] ;Q: same ext status?
jne short no_key ; N:
accept_key:
mov ebx, [VKD_gbl_shift_state]
and bx, [eax.Hot_Key_SS_Mask]
cmp bx, [eax.Hot_Key_SS_Compare] ;Q: correct shift state?
je short hot_key_fnd ; Y:
no_key:
VMMCall List_Get_Next ; EAX is next key definition
jnz chk_key
no_hot_keys:
clc ; failed!
jmp short chk_exit
hot_key_fnd:
;!!! key trace
trace_out "---------- HOT KEY found! = #EAX"
;!!! end
VK_HK_Queue_Out "Chk_Hot_Keys Hot key detected #eax"
mov ebx, [eax.Hot_Key_Local_Flag]
bt [edi.disabled_hot_keys], ebx ;Q: key disabled?
jnc short hot_not_disabled ; N: match found
test byte ptr [esp.Pushad_EAX], SC_Break ;Q: release hot key?
IFDEF DEBUG
jnz SHORT D00_handle_up_on_disabled
VK_HK_Queue_Out "Chk_Hot_Keys Hot key disabled"
jmp no_key
D00_handle_up_on_disabled:
ELSE
jz no_key
ENDIF
and [eax.Hot_Key_call_mask], NOT Hot_Key_Down ; flag as key up
mov bl, byte ptr [esp.Pushad_EAX]
mov [VKD_last_key], bl
jmp no_key
hot_not_disabled:
TestMem [eax.Hot_Key_call_mask], Monitor_Key ; monitoring only?
jnz Hot_Key_Activate_Monitor ; Y: Handle internally
stc
mov [esp.Pushad_EBX], eax ; return handle of hot key
chk_exit:
popad
don_t_check:
pop eax
ret
EndProc Chk_Hot_Keys
Windows 95 DDK
sample code in KEYB\SAMPLES\VKD
related sample in KEYB\SAMPLES\VKXD
Keywords : kbcode kbDDK kbInput kbHID
Version : 4.00
Platform : WINDOWS
Issue type :
Last Reviewed: March 5, 1999