个人备案的网站做企业内容,山西省住房建设厅网站,郑州专门做喷绘安装的网站,电商运营培训课程有哪些文章目录 概述注意源码参考资料 概述
irp请求会从io管理器中传递到设备栈中依次向下发送#xff0c;当到达底层真实设备处理完成后#xff0c;会依次返回#xff0c;这时如果在设备栈中有我们自己注册的设备#xff0c;就可以起到一个过滤的功能。键盘过滤驱动就是如此当到达底层真实设备处理完成后会依次返回这时如果在设备栈中有我们自己注册的设备就可以起到一个过滤的功能。键盘过滤驱动就是如此通过附加到原本存在的设备KeyboardClass0中这时当发生按键时irp也会返回到我们的设备中进而实现起响应。
注意
在整个键盘响应过程中有一个名为csrss.exe的程序其会不断的向KeyboardClass0发送读取类型的irp请求如果我们直接通过断开设备附加再卸载我们的驱动时就会蓝屏。原因是csrss.exe最终发送的读irp请求已经通过我们最先注册的过滤驱动向下传递了这时我们卸载了我们自己的驱动底层返回的irp找不到回调这时就会蓝屏所以代码中应该对irp的数量做一个统计保证其正确处理。
源码
#includentifs.htypedef struct
{PDEVICE_OBJECT LowerKbdDevice;
}DEVICE_EXTENTION,*PDEVICE_EXTENTION;PDEVICE_OBJECT myKbdDevice NULL;typedef struct _KEYBOARD_INPUT_DATA {USHORT UnitId;USHORT MakeCode;USHORT Flags;USHORT Reserved;ULONG ExtraInformation;
} KEYBOARD_INPUT_DATA, * PKEYBOARD_INPUT_DATA;
//IRP等待处理的数量
ULONG pendingkey 0;VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{LARGE_INTEGER interval { 0 };PDEVICE_OBJECT DeviceObject DriverObject-DeviceObject;IoDetachDevice(((PDEVICE_EXTENTION)DeviceObject-DeviceExtension)-LowerKbdDevice);interval.QuadPart -10 * 1000 * 1000;//判断是否还有未处理的IRPwhile (pendingkey){KeDelayExecutionThread(KernelMode, FALSE, interval);}IoDeleteDevice(myKbdDevice);KdPrint((驱动卸载结束\n));
}NTSTATUS ReadComplete(PDEVICE_OBJECT DeviceObject, PIRP irp, PVOID Context)
{PKEYBOARD_INPUT_DATA KeyBuffer irp-AssociatedIrp.SystemBuffer;char* key[4] { KeyDown,KeyUp,E0,E1 };int structnum irp-IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);if (irp-IoStatus.Status STATUS_SUCCESS){for (int i 0; i structnum; i){KdPrint((MakeCode %x,Flags %s\n, KeyBuffer-MakeCode, key[KeyBuffer-Flags]));}}//处理完成需要将标志位设置以声明以完成此irp的返回处理if (irp-PendingReturned){IoMarkIrpPending(irp);}pendingkey--;return irp-IoStatus.Status;
}NTSTATUS DispatchPass(PDEVICE_OBJECT pDeviceObject,PIRP irp)
{IoCopyCurrentIrpStackLocationToNext(irp);return IoCallDriver(((PDEVICE_EXTENTION)pDeviceObject-DeviceExtension)-LowerKbdDevice, irp);
}NTSTATUS DispatchRead(PDEVICE_OBJECT pDeviceObject, PIRP irp)
{IoCopyCurrentIrpStackLocationToNext(irp);IoSetCompletionRoutine(irp,ReadComplete,NULL,TRUE,TRUE,TRUE,TRUE);pendingkey;return IoCallDriver(((PDEVICE_EXTENTION)pDeviceObject-DeviceExtension)-LowerKbdDevice, irp);
}NTSTATUS MyAttachDevice(PDRIVER_OBJECT pDriverObject)
{UNICODE_STRING kbdName RTL_CONSTANT_STRING(L\\Device\\KeyboardClass0);NTSTATUS status IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENTION), NULL, 0, FILE_DEVICE_KEYBOARD, NULL, myKbdDevice);if (!NT_SUCCESS(status)){return status;}myKbdDevice-Flags | DO_BUFFERED_IO;myKbdDevice-Flags ~DO_DEVICE_INITIALIZING;RtlZeroMemory(myKbdDevice-DeviceExtension,sizeof(DEVICE_EXTENTION));status IoAttachDevice(myKbdDevice, kbdName, ((PDEVICE_EXTENTION)myKbdDevice-DeviceExtension)-LowerKbdDevice);if (!NT_SUCCESS(status)){IoDeleteDevice(myKbdDevice);return status;}return STATUS_SUCCESS;
}NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{int i 0;NTSTATUS Status STATUS_SUCCESS;for (i 0; i IRP_MJ_MAXIMUM_FUNCTION; i){pDriverObject-MajorFunction[i] DispatchPass;}pDriverObject-MajorFunction[IRP_MJ_READ] DispatchRead;Status MyAttachDevice(pDriverObject);if (!NT_SUCCESS(Status)){KdPrint((AttachDevice ERROR!\n));}else{KdPrint((AttachDevice SUCCESS!\n));}pDriverObject-DriverUnload DriverUnload;return Status;
}
参考资料
Windows Driver Development Tutorial