键盘过滤驱动 NT(解决unload后再按键蓝屏问题)

来源:互联网 发布:剑灵数据库下载 编辑:程序博客网 时间:2024/06/05 15:53

.h如下

#define KEY_UP         1#define KEY_DOWN       0#define LCONTROL       ((USHORT)0x1D)#define CAPS_LOCK      ((USHORT)0x3A)//// Print macro that only turns on when checked builds are on//#if DBG#define DbgPrint(arg) DbgPrint arg#else#define DbgPrint(arg)#endiftypedef struct _DEVICE_EXTENSION{    PDEVICE_OBJECT  TopOfStack;} DEVICE_EXTENSION, *PDEVICE_EXTENSION;NTSTATUS DriverEntry(    IN PDRIVER_OBJECT  DriverObject,    IN PUNICODE_STRING RegistryPath     );VOIDCtrl2capUnload(   IN PDRIVER_OBJECT Driver   );NTSTATUS Ctrl2capInit(     IN PDRIVER_OBJECT DriverObject     );NTSTATUS Ctrl2capDispatchRead(     IN PDEVICE_OBJECT DeviceObject,     IN PIRP Irp     );NTSTATUS Ctrl2capDispatchGeneral(    IN PDEVICE_OBJECT DeviceObject,    IN PIRP           Irp     );#define DELAY_ONE_MICROSECOND (-10)#define DELAY_ONE_MILLISECOND(DELAY_ONE_MICROSECOND*1000)VOID MySleep(LONG msec){LARGE_INTEGER my_interval;my_interval.QuadPart = DELAY_ONE_MILLISECOND;my_interval.QuadPart *= msec;KeDelayExecutionThread(KernelMode,0,&my_interval);}


 

.c如下

#include "ntddk.h"#include <ntddkbd.h>#include "stdarg.h"#include "stdio.h"#include "Header.h"#include "ntddkbd.h"#ifdef ALLOC_PRAGMA#pragma alloc_text (INIT, DriverEntry)#pragma alloc_text (PAGE, Ctrl2capDispatchGeneral)#pragma alloc_text (PAGE, Ctrl2capUnload)#endifDWORD32 indexForUnload = 0;NTSTATUS DriverEntry(IN PDRIVER_OBJECT  DriverObject,IN PUNICODE_STRING RegistryPath ){ULONG                  i;UNREFERENCED_PARAMETER(DriverObject);UNREFERENCED_PARAMETER(RegistryPath);DbgPrint (("Ctrl2cap.SYS: entering DriverEntry\n"));for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {DriverObject->MajorFunction[i] = Ctrl2capDispatchGeneral;}DriverObject->MajorFunction[IRP_MJ_READ] = Ctrl2capDispatchRead;DriverObject->DriverUnload = Ctrl2capUnload;return Ctrl2capInit( DriverObject );}NTSTATUS Ctrl2capInit(IN PDRIVER_OBJECT DriverObject){UNICODE_STRING    ntUnicodeString;UNICODE_STRING    devName;PDEVICE_OBJECT    device;NTSTATUS          status;PDEVICE_EXTENSION devExt;RtlInitUnicodeString(&devName,L"\\Device\\delete1");RtlInitUnicodeString(&ntUnicodeString,L"\\Device\\KeyboardClass0");status = IoCreateDevice( DriverObject,sizeof(DEVICE_EXTENSION),&devName,FILE_DEVICE_KEYBOARD,0,FALSE,&device );if( !NT_SUCCESS(status) ) {DbgPrint(("Ctrl2cap: Keyboard hook failed to create device!\n"));return status;}RtlZeroMemory(device->DeviceExtension, sizeof(DEVICE_EXTENSION));devExt = (PDEVICE_EXTENSION) device->DeviceExtension;device->Flags |= DO_BUFFERED_IO;device->Flags &= ~DO_DEVICE_INITIALIZING;status = IoAttachDevice( device, &ntUnicodeString, &devExt->TopOfStack );DbgPrint(("In Init :Top of Stack : %x \n",devExt->TopOfStack));if( !NT_SUCCESS(status) ) {IoDeleteDevice( device );     return status;}DbgPrint (("Leave Entry .ookk\n"));return STATUS_SUCCESS;}VOID Ctrl2capUnload(IN PDRIVER_OBJECT Driver){PDEVICE_EXTENSION devExt;UNREFERENCED_PARAMETER(Driver);DbgPrint(("Enter Unload"));devExt = (PDEVICE_EXTENSION)Driver->DeviceObject->DeviceExtension;DbgPrint(("In Ctrl2capUnload :Top of Stack : %x \n",devExt->TopOfStack));IoDetachDevice(devExt->TopOfStack);IoDeleteDevice(Driver->DeviceObject);indexForUnload = 1;while(indexForUnload){MySleep(100);}DbgPrint(("Leave Unload"));}NTSTATUS Ctrl2capReadComplete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp,IN PVOID Context ){PIO_STACK_LOCATION        IrpSp;PKEYBOARD_INPUT_DATA      KeyData;int                       numKeys, i;UNREFERENCED_PARAMETER(DeviceObject);UNREFERENCED_PARAMETER(Irp);UNREFERENCED_PARAMETER(Context);DbgPrint(("Ctrl2capReadComplete Enter"));IrpSp = IoGetCurrentIrpStackLocation( Irp );if( NT_SUCCESS( Irp->IoStatus.Status ) ) {KeyData = Irp->AssociatedIrp.SystemBuffer;numKeys = Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);for( i = 0; i < numKeys; i++ ) {DbgPrint(("ScanCode: %x %s", KeyData[i].MakeCode, KeyData[i].Flags ? "Up" : "Down" ));//KeyData[i].MakeCode--;改变按键值//           if( KeyData[i].MakeCode == CAPS_LOCK) {//              KeyData[i].MakeCode = LCONTROL;//} }}if( Irp->PendingReturned ) {IoMarkIrpPending( Irp );}indexForUnload = 0;DbgPrint(("Ctrl2capReadComplete Leave"));return Irp->IoStatus.Status;}NTSTATUS Ctrl2capDispatchRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ){PDEVICE_EXTENSION   devExt;NTSTATUSntStatus;DbgPrint(("Ctrl2capDispatchRead Enter"));devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;IoCopyCurrentIrpStackLocationToNext(Irp);  IoSetCompletionRoutine( Irp, Ctrl2capReadComplete,DeviceObject, TRUE, TRUE, TRUE );ntStatus = IoCallDriver( devExt->TopOfStack, Irp );DbgPrint(("Ctrl2capDispatchRead - %x",ntStatus));//STATUS_PENDING == 0x103DbgPrint(("Ctrl2capDispatchRead Leave"));return ntStatus;}NTSTATUS Ctrl2capDispatchGeneral(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ){DbgPrint(("Ctrl2capDispatchGeneral Enter"));IoSkipCurrentIrpStackLocation(Irp);DbgPrint(("Ctrl2capDispatchGeneral Leave"));return IoCallDriver(((PDEVICE_EXTENSION) DeviceObject->DeviceExtension)->TopOfStack, Irp);}


 


注意:其中的1个全局参数
DWORD32 indexForUnload = 0;

目的是为了解决“unload后,在按键的蓝屏问题”

 

参考文献为:<<Windows驱动开发技术详解>>   22.2

                    <<寒江独钓-*******>>        第4章

                  

原创粉丝点击