VXD,将迫使键盘消息进入当前前台获取FOCUS的APP.
作者:陆麟
转载请征得作者同意.
1999.9.20


今天同时在网易和SINA上看到同样的问题问键盘输入的问题.正好为别人也写了个.那就贴在这里.大家有兴趣看看.我的注解是全E文的.需要耐心才看得下去.:)
;*****************************************************************************
;DYKBD.ASM Written by Lu Lin. (C) 1999.9.10
;*****************************************************************************
        .386p
        .XLIST
        INCLUDE VMM.Inc
        INCLUDE VKD.Inc
        .LIST
;******************************************************************************
;                V I R T U A L   D E V I C E   D E C L A R A T I O N
;******************************************************************************
 

Declare_Virtual_Device DYKBD,1,01,DYKBD_Control,6060,80000000H,,
 

;******************************************************************************
;                  I N I T I A L I Z A T I O N   C O D E
;******************************************************************************

DYKBD_IO equ 1

VxD_ICODE_SEG

BeginProc DYKBD_Device_Dynamic_Init
        clc
        ret
EndProc DYKBD_Device_Dynamic_Init

BeginProc DYKBD_Device_Dynamic_EXIT
 clc
 ret
EndProc  DYKBD_Device_Dynamic_EXIT

VxD_ICODE_ENDS

;******************************************************************************

VxD_CODE_SEG

;******************************************************************************
;
;   DYKBD_Control
;
;   DESCRIPTION:
;
;       This is a call-back routine to handle the messages that are sent
;       to VxD's to control system operation.
;
;
;==============================================================================

BeginProc DYKBD_Control

    Control_Dispatch SYS_DYNAMIC_DEVICE_INIT, DYKBD_Device_Dynamic_Init
    Control_Dispatch SYS_DYNAMIC_DEVICE_EXIT, DYKBD_Device_Dynamic_EXIT
    Control_Dispatch W32_DEVICEIOCONTROL, DYKBD_DEVICE_IO
    clc
    ret

EndProc DYKBD_Control

;==============================================================================
; Device IO interface:
; ecx = Service No
; ebx = DDB
; edx = hDevice ,it is opened by a ring3 application
; esi = lpDIOCParms,passed from DeviceIoControl
;==============================================================================
BeginProc DYKBD_DEVICE_IO
 cmp ecx,DIOC_OPEN  ;;Must return 0 to tell WIN32 that this VxD supports DEVIOCTL
 jz Normal_Exit
 cmp ecx,DIOC_CLOSEHANDLE ;;sent when VxD is unloaded just before SYS_DYNAMIC_EXIT
 jz Normal_Exit
        cmp ecx,DYKBD_IO
 jz Run_IO
 mov eax,32h ;;error:not supported
 ret
Normal_Exit:
 mov eax,0
 ret
Run_io:
 mov ebx,esi
        mov esi,[ebx+16]
        mov ecx,[ebx+20]
 VxDcall VKD_Force_Keys
 jnc Run_io1
 jmp AbNormal_Exit
Run_io1:
 cld
        mov esi,[ebx+16]
        mov ecx,[ebx+20]
RepChg:
 lodsb
 xor al,80h
 mov ds:[esi-1],al
 loop RepChg
        mov esi,[ebx+16]
        mov ecx,[ebx+20]
 VxDcall VKD_Force_Keys
 jc AbNormal_Exit
 jmp Normal_Exit
AbNormal_Exit:
 mov eax,1 ;; error: invalid function
 ret
EndProc DYKBD_DEVICE_IO

VxD_CODE_ENDS

    END
以下是README.也就是APP调用指南.
DYKBD.VXD
SAMPLE VXD FOR LUO.
USAGE:
HANDLE hvxd;
hvxd=CreateFile("\\\\.\\DYKBD",0,0,0,0,0,0);
if (hvxd==-1) {error codes};
DeviceIoControl(hvxd,1,buffer,cbbuffer,0,0,&rtn,0);

DYKBD ONLY SUPPORTS FUNC 1 now, buffer is a pointer to
scancode array. cbbuffer is length of buffer in byte.
other parameters are ignored.
Do careful with this vxd. Any wrong input could lead
to crash of system.
If you want to generate a CTL+ALT+DEL. Just put
29,56,83 into array and make cbbuffer 3. call use above
func. system will popup a dialoguo box of running process
as expected.
This func is the only way to simulate CAD input and will
never be sent into application's input queue.
Any question, contact me.
陆麟