-
大小: 5KB文件類型: .rar金幣: 2下載: 0 次發(fā)布日期: 2021-06-10
- 語(yǔ)言: 其他
- 標(biāo)簽: DoubleClick??Fix??
資源簡(jiǎn)介
鼠標(biāo)經(jīng)常在單擊時(shí)變成雙擊,所以打算寫一個(gè)鼠標(biāo)過濾驅(qū)動(dòng)來修復(fù)硬件的BUG
鼠標(biāo)過濾驅(qū)動(dòng)能修復(fù)這個(gè)Bug的原理是:
鼠標(biāo)在點(diǎn)擊時(shí),會(huì)觸發(fā)一個(gè)硬件中斷,然后發(fā)消息給過濾驅(qū)動(dòng),這時(shí)我在驅(qū)動(dòng)中判斷兩次點(diǎn)擊的時(shí)間間隔,如果小于100ms則認(rèn)為是硬件故障,屏蔽掉該此操作
關(guān)于鼠標(biāo)過濾,這里主要說一下IRP的取消。取消IRP還真是花費(fèi)了我很多時(shí)間,原因是IoCancelIrp這個(gè)函數(shù)會(huì)直接回調(diào)完成例程,然后破壞了鏈表的結(jié)構(gòu),導(dǎo)致了藍(lán)屏。(我在MyRead例程里面把IRP插入到一個(gè)鏈表里面,然后在MyReadComplete里面,從鏈表里面移除該IRP)
這樣只好,在取消IRP時(shí),復(fù)制一個(gè)新的鏈表,在新的鏈表里面對(duì)IRP進(jìn)行取消,這樣總算是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;
????//?刪除符號(hào)鏈接和設(shè)備對(duì)象
????RtlInitUnicodeString(&SymboliclinkName?DOS_DEVICE_NAME);
????IoDeleteSymboliclink(&SymboliclinkName);???????
????IoDeleteDevice(Deviceobject);
????
????//恢復(fù)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;
????//?獲取互斥體,保護(hù)鏈表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));
????????//?復(fù)制鏈表,然后將取消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);
????
????//?之所以要復(fù)制一個(gè)新的鏈表來取消IRP?(通過調(diào)用IoCancelIrp),
????//?是因?yàn)镮oCancelIrp?會(huì)調(diào)用MyReadComplete?這個(gè)完成例程回調(diào),
????//?而MyReadComplete里面又對(duì)鏈表進(jìn)行操作,這樣會(huì)破壞鏈表的結(jié)構(gòu)
????pSingleListEntry?=?PopEntryList(&gFilterData.CancelHead);
????while(pSingleListEntry)
????{
????????CancelList?=?CONTAINING_RECORD(pSingleListEntry?PENDING_IRP_LIST?SingleListEntry);
???????
?屬性????????????大小?????日期????時(shí)間???名稱
-----------?---------??----------?-----??----
?????文件????????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
評(píng)論
共有 條評(píng)論