Microsoft KB Archive/153380

{|
 * width="100%"|

How to Modify VxD in VKD_Define_Hot_Key to Detect All Keys

 * }

Q153380

-

The information in this article applies to:


 * Microsoft Win32 Device Driver Kit (DDK) Windows 95

-

SUMMARY
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.

MORE INFORMATION
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.

Sample Code
BeginProc Chk_Hot_Keys

trace_out "Chk_Hot_Keys key #AX"
 * !!! key trace
 * !!! end

VK_HK_Queue_Out "Chk_Hot_Keys key scan code = #AX ..."

push eax

mov  eax,[vkd_gbl_shift_state] trace_out "Chk_Hot_Keys ... shift state = #AX" pop  eax push eax
 * !!! key trace
 * !!! end

test [VKD_gbl_shift_state], SS_Shift_mask + SS_Toggle_Dn_mask ;Q: are any shift state keys down? trace_outNZ "-- Shift State keys DOWN"
 * !!! key trace
 * !!! 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? trace_outZ "-- NO CHECK performed (special key)" jz DEBFAR je_don_t_check      ; N: (chained short jumps)
 * !!! key trace
 * !!! end

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: trace_out "-- CHECK performed" 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
 * !!! key trace
 * !!! end

and  cx, VK_Extended + (0FFh XOR SC_Break) .errnz (VK_Extended + (0FFh XOR SC_Break)) - 807Fh
 * 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
 * scan code byte

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: trace_out "-- HOT KEY found! = #EAX" VK_HK_Queue_Out "Chk_Hot_Keys Hot key detected #eax"
 * !!! key trace
 * !!! end

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