-
大小: 5KB文件類型: .rar金幣: 2下載: 0 次發布日期: 2021-06-10
- 語言: 其他
- 標簽: DoubleClick??Fix??
資源簡介
鼠標經常在單擊時變成雙擊,所以打算寫一個鼠標過濾驅動來修復硬件的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位超低功耗單片機實踐與系統設計_光盤
評論
共有 條評論