为什么我的键盘过滤启动后,第一个被按下的按键的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 );
}
该键盘过滤目的是屏蔽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 );
}
断点触发,跟踪下去就是Up的信息,根本没有Down的信息。
估计是:
挂接过滤驱动之前,键盘的底层驱动已经投递给物理驱动一个IRP请求,但该请求触发不会调用
过滤驱动CompleteRoutine,因为该IRP请求时在挂接之前投递。所以一旦按下按键,物理驱动就会
完成该IRP请求,并接受下个IRP请求,下个IRP请求就会触发CompleteRoutine。如果以上原因成立,那怎么解决这个问题?