为什么我的键盘过滤启动后,第一个被按下的按键的DOWN消息不能被检测到?
该键盘过滤目的是屏蔽Ctrl+Alt+Delete、Start、Alt+Esc等操作系统功能键。
我的代码如下,#include "dsKeyBoard.h"
#include <stdio.h>
#include <string.h>#define EPROCESS_SIZE            1
#define PEB_OFFSET               2  
#define FILE_NAME_OFFSET         3  
#define PROCESS_LINK_OFFSET      4  
#define PROCESS_ID_OFFSET        5  
#define EXIT_TIME_OFFSET         6  
#define TRUE 1
#define FALSE 0
#pragma PAGEDCODEPIRP pNextIrp = NULL;
BOOLEAN CancelIrp(PIRP pIrp)   
{   
    if(pIrp==NULL)   
    { 
        return FALSE;   
    }   
    if(pIrp->Cancel || pIrp->CancelRoutine==NULL)   
    {    
        return FALSE;   
    }   
    if(FALSE==IoCancelIrp(pIrp))   
    {    
        return FALSE;   
    }   

    //?????????   
    IoSetCancelRoutine(pIrp,NULL);   
    return TRUE;   
}  
#pragma PAGEDCODE
NTSTATUS ShutDownProc(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{

IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}#pragma PAGEDCODE
NTSTATUS PowerProc(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{  PDEVICE_EXTENSION_KB pdx = (PDEVICE_EXTENSION_KB)DeviceObject->DeviceExtension;
  PoStartNextPowerIrp(Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}#pragma PAGEDCODE
VOID
Unload(IN PDRIVER_OBJECT pDriverObject)
{    
KTIMER kTimer;   
    LARGE_INTEGER timeout;     
    PDEVICE_EXTENSION_KB pdx = (PDEVICE_EXTENSION_KB) pDriverObject->DeviceObject->DeviceExtension;    if ( pdx->bAttached )   
    {   
        IoDetachDevice ( pdx->TopOfStack ) ;   
        pdx->bAttached = FALSE ;   
    }       timeout.QuadPart = 1000000; //1s   
    KeInitializeTimer(&kTimer);       // ??????IRP,   
    while (pdx->uIrpPenddingCount > 1)   
    {   
        KeSetTimer (&kTimer, timeout, NULL) ;   
        KeWaitForSingleObject ( &kTimer, Executive, KernelMode, FALSE, NULL ) ;   
    }  
if(pdx->uIrpPenddingCount == 1)
{
CancelIrp(pNextIrp);
pdx->uIrpPenddingCount--;
} IoDeleteDevice(pDriverObject->DeviceObject);
}#pragma PAGEDCODE
NTSTATUS CompleteRoutine(IN PDEVICE_OBJECT DeviceObject,
 IN PIRP Irp,
 IN PVOID Context
 )
{
    PDEVICE_EXTENSION_KB pdx = (PDEVICE_EXTENSION_KB)DeviceObject->DeviceExtension;   
    PIO_STACK_LOCATION IrpSp;
    PKEYBOARD_INPUT_DATA KeyData;
    int nKeys = 0;
int i = 0;
int nDeleteIndex = -1;
int nTabIndex = -1;
int nEscIndex = -1;
    IrpSp = IoGetCurrentIrpStackLocation( Irp );
    if(NT_SUCCESS(Irp->IoStatus.Status)) 
{

        KeyData = (PKEYBOARD_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
        nKeys = Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);

        for( i = 0; i < nKeys; i++ ) 
{
DbgPrint("ScanCode = %d, Flags = %d", KeyData[i].MakeCode, KeyData[i].Flags);    if(pdx->bFirstDetect)
{
KeyData[i].MakeCode = 0;
continue;
}
            switch(KeyData[i].MakeCode)
{
            case 0x1d:
                if(KeyData[i].Flags == 1 || KeyData[i].Flags == 3)
{
                    pdx->bCtrlState = FALSE;
}
else if(KeyData[i].Flags == 0 || KeyData[i].Flags == 2)
{
pdx->bCtrlState = TRUE;
}
                break;
case 0x38:
                if(KeyData[i].Flags == 1 || KeyData[i].Flags == 3)
{
                    pdx->bAltState = FALSE;
}
else if(KeyData[i].Flags == 0 || KeyData[i].Flags == 2)
{
                    pdx->bAltState = TRUE;
}
                break;
case 0x53:
nDeleteIndex = i;
break;
case 0x0F:
nTabIndex = i;
break;
case 0x01:
nEscIndex = i;
break; case 0x5B:
case 0x5C:
case 0x5D:
KeyData[i].MakeCode = 0;
break;
default:
break;
            }

        } if(pdx->bCtrlState && pdx->bAltState) 
{
if(nDeleteIndex != -1)
{
KeyData[nDeleteIndex].MakeCode = 0;
DbgPrint("Ctrl+Alt+Delete are pressed!") ; 
} } if(pdx->bCtrlState || pdx->bAltState)
{
if(nEscIndex != -1)
{
KeyData[nEscIndex].MakeCode = 0;
}
} if(pdx->bAltState)
{
if(nTabIndex != -1)
{
KeyData[nTabIndex].MakeCode = 0;
}
} pdx->bFirstDetect = FALSE;
    }

    if( Irp->PendingReturned ) 
{
        IoMarkIrpPending( Irp );
    }    pdx->uIrpPenddingCount --;
    return Irp->IoStatus.Status;
}#pragma PAGEDCODE
NTSTATUS DispatchRead(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp )
{
    PDEVICE_EXTENSION_KB pdx = (PDEVICE_EXTENSION_KB)DeviceObject->DeviceExtension ; 
    PIO_STACK_LOCATION currentIrpStack;
    PIO_STACK_LOCATION nextIrpStack;    currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
    nextIrpStack = IoGetNextIrpStackLocation(Irp);   
    *nextIrpStack = *currentIrpStack;

    IoSetCompletionRoutine( Irp, CompleteRoutine, DeviceObject, TRUE, TRUE, TRUE );
pdx->uIrpPenddingCount ++;   
pNextIrp = Irp;
    return IoCallDriver( pdx->TopOfStack, Irp );
}
#pragma PAGEDCODE
NTSTATUS DispatchProc(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP           Irp
  )
{
    Irp->CurrentLocation++;
    Irp->Tail.Overlay.CurrentStackLocation++;
    return IoCallDriver(((PDEVICE_EXTENSION_KB) DeviceObject->DeviceExtension)->TopOfStack, Irp);
}
#pragma INITCODE
NTSTATUS 
InitKB(IN PDRIVER_OBJECT DriverObject)
{
    CCHAR              ntNameBuffer[64];
    STRING              ntNameString;
    UNICODE_STRING    ntUnicodeString;
    PDEVICE_OBJECT    device;
    NTSTATUS          status;
    PDEVICE_EXTENSION_KB devExt;    sprintf( ntNameBuffer, "\\Device\\KeyboardClass0" );
    RtlInitAnsiString( &ntNameString, ntNameBuffer );
    RtlAnsiStringToUnicodeString( &ntUnicodeString, &ntNameString, TRUE );

    status = IoCreateDevice( DriverObject,
sizeof(DEVICE_EXTENSION_KB),
NULL,
FILE_DEVICE_KEYBOARD,
0,
FALSE,
&device );

    if( !NT_SUCCESS(status) ) 
{
        RtlFreeUnicodeString( &ntUnicodeString );
        return STATUS_SUCCESS;
    }    RtlZeroMemory(device->DeviceExtension, sizeof(PDEVICE_EXTENSION_KB));

    devExt = (PDEVICE_EXTENSION_KB) device->DeviceExtension;
    device->Flags |= DO_BUFFERED_IO;
    device->Flags &= ~DO_DEVICE_INITIALIZING;
    status = IoAttachDevice( device, &ntUnicodeString, &devExt->TopOfStack );

    if( !NT_SUCCESS(status) ) 
{
        IoDeleteDevice( device );
        RtlFreeUnicodeString( &ntUnicodeString );
        return STATUS_SUCCESS;
    }
devExt->uIrpPenddingCount = 0;
devExt->bAttached = TRUE ;  
devExt->bCtrlState = FALSE;
devExt->bAltState = FALSE;
devExt->bFirstDetect = TRUE;
    RtlFreeUnicodeString( &ntUnicodeString );
IoRegisterShutdownNotification(device);
     return STATUS_SUCCESS;}#pragma INITCODE
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
 IN PUNICODE_STRING RegistryPath
 )
{    ULONG i;
    for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) 
{
        DriverObject->MajorFunction[i] = DispatchProc;
    }
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = ShutDownProc;
DriverObject->MajorFunction[IRP_MJ_POWER] = PowerProc;
    DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
    DriverObject->DriverUnload = Unload;

    return InitKB( DriverObject );

解决方案 »

  1.   

    在挂接过滤驱动前就在CompleteRoutine设定了断点,挂接完过滤驱动,此时按下按键,
    断点触发,跟踪下去就是Up的信息,根本没有Down的信息。
    估计是:
    挂接过滤驱动之前,键盘的底层驱动已经投递给物理驱动一个IRP请求,但该请求触发不会调用
    过滤驱动CompleteRoutine,因为该IRP请求时在挂接之前投递。所以一旦按下按键,物理驱动就会
    完成该IRP请求,并接受下个IRP请求,下个IRP请求就会触发CompleteRoutine。如果以上原因成立,那怎么解决这个问题?