• 大小: 5KB
    文件类型: .rar
    金币: 1
    下载: 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


评论

共有 条评论

相关资源