How to Modify VxD in VKD_Define_Hot_Key to Detect All Keys

ID: 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

;!!! 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 


REFERENCES

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
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.