资源简介
鼠标经常在单击时变成双击,所以打算写一个鼠标过滤驱动来修复硬件的BUG
鼠标过滤驱动能修复这个Bug的原理是:
鼠标在点击时,会触发一个硬件中断,然后发消息给过滤驱动,这时我在驱动中判断两次点击的时间间隔,如果小于100ms则认为是硬件故障,屏蔽掉该此操作
关于鼠标过滤,这里主要说一下IRP的取消。取消IRP还真是花费了我很多时间,原因是IoCancelIrp这个函数会直接回调完成例程,然后破坏了链表的结构,导致了蓝屏。(我在MyRead例程里面把IRP插入到一个链表里面,然后在MyReadComplete里面,从链表里面移除该IRP)
这样只好,在取消IRP时,复制一个新的链表,在新的链表里面对IRP进行取消,这样总算是OK了
好了,废话说完了,大家看代码吧:
代码片段和文件信息
#include
#include
#include “MouseFilter.h“
MOUSE_FILTER_DATA gFilterData = {0};
NTSTATUS
CreateClose(
__in PDEVICE_object Deviceobject
__in PIRP Irp
)
{
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
UNREFERENCED_PARAMETER(Deviceobject);
PAGED_CODE();
KdPrint((“Entered IRP_MJ_%s\n“ (irpStack->MajorFunction == IRP_MJ_CREATE) ? “CREATE“ : “CLOSE“ ));
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
NTSTATUS
DeviceControl(
IN PDEVICE_object Deviceobject
IN PIRP Irp
)
{
PAGED_CODE();
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpIO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
VOID CleanUP(__in PDEVICE_object Deviceobject)
{
UNICODE_STRING SymboliclinkName;
if(!Deviceobject)
return;
// 删除符号链接和设备对象
RtlInitUnicodeString(&SymboliclinkName DOS_DEVICE_NAME);
IoDeleteSymboliclink(&SymboliclinkName);
IoDeleteDevice(Deviceobject);
//恢复IRP hook
if(gFilterData.OldRead)
{
InterlockedExchange(
(PLONG)&gFilterData.pMouseDriverobject->MajorFunction[IRP_MJ_READ]
(LONG)gFilterData.OldRead
);
}
if(gFilterData.pMouseDriverobject)
{
ObDereferenceobject(gFilterData.pMouseDriverobject);
}
}
// 取消等待的IRP
VOID CancelPendingIrp()
{
PPENDING_IRP_LIST PendingList = NULL CancelList = NULL;
PSINGLE_LIST_ENTRY pSingleListEntry = NULL;
// 获取互斥体,保护链表gFilterData.ListHead
KeWaitForMutexobject(&gFilterData.ReadMutex Executive KernelMode FALSE NULL);
pSingleListEntry = gFilterData.ListHead.Next;
while(pSingleListEntry)
{
PendingList = CONTAINING_RECORD(pSingleListEntry PENDING_IRP_LIST SingleListEntry);
KdPrint((“Copy Single List = 0x%x“ PendingList));
// 复制链表,然后将取消IRP的操作放到新的链表中处理
CancelList = (PPENDING_IRP_LIST)ExAllocatePoolWithTag(NonPagedPool sizeof(PENDING_IRP_LIST) POOL_TAG);
if(CancelList)
{
RtlCopyMemory(CancelList PendingList sizeof(PENDING_IRP_LIST));
PushEntryList(&gFilterData.CancelHead &CancelList->SingleListEntry);
}
pSingleListEntry = pSingleListEntry->Next;
}
// 释放互斥体
KeReleaseMutex(&gFilterData.ReadMutex FALSE);
// 之所以要复制一个新的链表来取消IRP (通过调用IoCancelIrp),
// 是因为IoCancelIrp 会调用MyReadComplete 这个完成例程回调,
// 而MyReadComplete里面又对链表进行操作,这样会破坏链表的结构
pSingleListEntry = PopEntryList(&gFilterData.CancelHead);
while(pSingleListEntry)
{
CancelList = CONTAINING_RECORD(pSingleListEntry PENDING_IRP_LIST SingleListEntry);
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 640 2012-08-14 16:55 Clean.bat
文件 267 1996-08-09 04:30 MAKEFILE
文件 10363 2012-09-12 11:09 MouseFilter.c
文件 1325 2012-09-12 11:02 MouseFilter.h
文件 84 2012-09-08 16:34 SOURCES
----------- --------- ---------- ----- ----
12679 5
- 上一篇:IMU姿态解算
- 下一篇:MSP430系列16位超低功耗单片机实践与系统设计_光盘
评论
共有 条评论