zoukankan      html  css  js  c++  java
  • ssdt-hook实现鼠标2个键互换

    最近对驱动比较感兴趣,所以打算做个windows下面的驱动,正好自己电脑的鼠标左键的单击有的时候会变双击,所有打算弄个鼠标的过滤驱动来解决这个问题。

    网上找了一下,原来早就有人做了这个功能 http://download.csdn.net/detail/guijc1/5263421(不是故意给这个打广告的),所以我的代码基本都是仿照这里的源码。

    这篇文章的重点是如何动手写一个过滤驱动,不是驱动的技术细节。还有就是驱动需要支持32和64系统的问题,安装驱动的问题。

    以下很多都是从网络上面获取的资料。我会把链接都放到文章里面。

    1.开发环境的搭建

     vs2008+GRMWDK_EN_7600_1.ISO,这些直接安装就行了 注意如果要64位版本需要安装vs2008的64编译环境,接下来就是环境的配置了。我参照的是

    http://jacky-dai.iteye.com/blog/1536456  以及http://blog.csdn.net/huangxy10/article/details/15284881

    (1)打开vs2008,选择“工具--选项--项目和解决方案”在右侧平台选择“win32”--“包含文件”,然后在下面添加自己的wdk中的inc相关路径 
    D:WINDDK7600.16385.1incwdfkmdf1.9 
    D:WINDDK7600.16385.1incapi 
    D:WINDDK7600.16385.1inccrt 
    D:WINDDK7600.16385.1incddk

    注意:vc包含文件的D:WinDDK7600.16385.1incapi不一定是放最前面,编译不过去的时候可以放到$(VCInstallDir)include的后面。

    然后选择“win32”--“库文件”添加自己的WDK中LIB路径 
    D:WINDDK7600.16385.1libwdfkmdfi3861.9 
    D:WINDDK7600.16385.1libwxpi386

    如果是64位的需要添加的库文件是

    D:WINDDK7600.16385.1libwdfkmdfamd641.9 
    D:WINDDK7600.16385.1libwin7amd64

    (2) 工程配置

    新建一个win32的控制台工程,把里面带的文件都删除掉

    右键工程,选择属性

         点击“c/c++”-- 

         选择“常规”,“调试信息”选:“C7 兼容(/Z7)”,“警告等级”--“3级(/w3)”,“将警告视为错误”--选“是” (这个需要看情况设置)

         选择“优化”,“优化”选“禁用(/0d)” 

         选择“预处理器”,“预处理器定义”输入“WIN32=100;_X86_=1;DBG=1”  如果是64的则把_X86_=1 替换为_AMD64_=1

         选择“高级”,“调用约定”选“__stdcall (/Gz)” 

         点击“连接器”-- 

         选择“常规”,“输出文件”输入“$(OutDir)$(ProjectName)32.sys”(64位的修改为"$(OutDir)$(ProjectName)64.sys"),“启用增量连接”,选“否(/INCREMENTAL:NO)”,“附加库目录”输入“D:WINDDK7600.16385.0libwxpi386”

    如果是64的修改为"D:WinDDK7600.16385.1libwin7amd64”

         选择“输入”,“附加依赖项”输入“ntoskrnl.lib $(NOINHERIT)”,“忽略所有默认库”选“是(/NODEFAULTLIB)” 

         选择“清单文件”,“启用用户账户控制(UAC)”选“否” 

         选择“调试”,“生成调试信息”选择“是”,“生成程序数据库文件”输入“MyChecked_Driver$(ProjectName).pdb” 

         选择“系统”,“子系统”选“本机(/SUBSYSTEM:NATIVE)”,“堆栈保留大小”输入“40000”,“堆栈提交大小”输入“1000”,“驱动程序”选“驱动程序(/DRIVER)” 

         选择“高级”,“入口点”输入“DriverEntry”,“基址”输入“0x10000”,“随机基址”选“默认值”,“数据执行保护(DEP)”选“默认值”,“目标计算机”选“MachineX86 (/MACHINE:X86)”  如果是64的就选择"MachineX64 (/MACHINE:X64)"

    2.下面是工程源码  解决鼠标单击变双击的问题
    MouseLeftKeyFilter.h

    #pragma once
    
    #define DEVICE_NAME          L"\Device\MouseFilter"
    #define DOS_DEVICE_NAME      L"\DosDevices\MouseFilter"
    
    #define POOL_TAG             'tsiL'
    
    #ifdef __cplusplus   
    extern "C"  
    {   
    #endif
        //一类是不支持即插即用功能的NT式的驱动程序
        //NT式的驱动程序要导入的头文件时NTDDK.H,而WDM式的驱动要导入的头文件为WDM.H.
        #include <ntddk.h> 
    
        typedef NTSTATUS (*READ_DISPATCH)(__in PDEVICE_OBJECT pDeviceObject, __in PIRP Irp);
    
        typedef struct _DEVICE_EXTENSION {
            PDEVICE_OBJECT  pDeviceObject;  
        } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
    
        typedef struct _MOUSE_FILTER_DATA{
            PDRIVER_OBJECT  pMouseDriverObject; // "\Driver\Mouclass" 的指针
            READ_DISPATCH OldRead; // 原来的IRP_MJ_READ 派遣例程
            ULONG LeftDownTime; // 上次鼠标左键按下的时刻 
            KMUTEX ReadMutex; // Read互斥体
            SINGLE_LIST_ENTRY ListHead;// 保存Pending IRP的链表
            SINGLE_LIST_ENTRY CancelHead;// 用来对上面链表的进行复制
        }MOUSE_FILTER_DATA, *PMOUSE_FILTER_DATA;
    
        typedef struct _PENDING_IRP_LIST{
            SINGLE_LIST_ENTRY SingleListEntry;    
            PIRP PendingIrp;
        }PENDING_IRP_LIST, *PPENDING_IRP_LIST;
    
        extern POBJECT_TYPE *IoDriverObjectType;
    
        extern NTSTATUS ObReferenceObjectByName(
            PUNICODE_STRING ObjectName,
            ULONG Attributes,
            PACCESS_STATE AccessState,
            ACCESS_MASK DesiredAccess,
            POBJECT_TYPE ObjectType,
            KPROCESSOR_MODE AccessMode,
            PVOID ParseContext,
            PVOID *Object
            );
    
        NTSTATUS DriverEntry (IN  PDRIVER_OBJECT  pDeviceObject,
            IN  PUNICODE_STRING RegistryPath
            );
        VOID DriverUnload(IN PDRIVER_OBJECT pDeviceObject);
    
        NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT pDeviceObject,
            IN PIRP Irp
            );
        NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT pDeviceObject,
            IN PIRP Irp
            );
        NTSTATUS MyDispatchRead(IN PDEVICE_OBJECT pDeviceObject,
            IN PIRP Irp
            );
        NTSTATUS MyDispatchReadComplete(IN PDEVICE_OBJECT pDeviceObject,
            IN PIRP Irp, 
            IN PVOID Context ) ;
    
        VOID CleanUP(IN PDEVICE_OBJECT pDeviceObject);
        VOID CancelPendingIrp();
        BOOLEAN IsFakeDoubleClick ();
        
    #ifdef __cplusplus   
    };   
    #endif 
    
    //#ifdef ALLOC_PRAGMA   
    //#pragma alloc_text(INIT, DriverEntry)   
    //#pragma alloc_text(PAGE, testDriverUnload)   
    //#endif

    下面是MouseLeftKeyFilter.cpp

    #include "MouseLeftKeyFilter.h"
    #include <ntddmou.h>
    
    MOUSE_FILTER_DATA gFilterData = {0};
    
    
    NTSTATUS DriverEntry (IN  PDRIVER_OBJECT  pDeviceObject,
                 IN  PUNICODE_STRING RegistryPath
                 )
    {
        NTSTATUS  status = STATUS_SUCCESS;
        UNICODE_STRING  DeviceName;
        UNICODE_STRING  SymbolicLinkName;
        UNICODE_STRING  MouseDriver;
        PDEVICE_OBJECT  DeviceObject = NULL;
        PDEVICE_EXTENSION   deviceExtension = NULL;
    
        //告诉编译器,已经使用了该变量,不必检测警告
        UNREFERENCED_PARAMETER (RegistryPath);
    
        KdPrint(("Entered DriverEntry =================== 
    "));
    
        KeInitializeMutex(&gFilterData.ReadMutex, 0);
        gFilterData.ListHead.Next = NULL;
        gFilterData.CancelHead.Next = NULL;
    
        pDeviceObject->MajorFunction [IRP_MJ_CREATE] =
        pDeviceObject->MajorFunction [IRP_MJ_CLOSE] =  DispatchCreateClose;
        pDeviceObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;    
        pDeviceObject->DriverUnload = DriverUnload;
    
        //创建设备对象
        RtlInitUnicodeString(&DeviceName, DEVICE_NAME);    
        status = IoCreateDevice( 
            pDeviceObject,
            sizeof(DEVICE_EXTENSION),
            &DeviceName,
            FILE_DEVICE_UNKNOWN,
            FILE_DEVICE_SECURE_OPEN,
            FALSE,
            &DeviceObject
            );
        if (!NT_SUCCESS(status))
        {
            KdPrint(("IoCreateDevice failed, 0x%0x!
    ", status));
            return status;
        }   
    
        //创建符号链接
        RtlInitUnicodeString(&SymbolicLinkName, DOS_DEVICE_NAME);
        status = IoCreateSymbolicLink(&SymbolicLinkName, &SymbolicLinkName);
        if(!NT_SUCCESS(status))
        {
            KdPrint(("IoCreateSymbolicLink failed, 0x%0x!
    ", status));
            CleanUP(DeviceObject);
            return status;
        }
    
        deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
        RtlZeroMemory(deviceExtension, sizeof(DEVICE_EXTENSION));
    
        deviceExtension->pDeviceObject = DeviceObject;
    
        //DeviceObject->Flags |= DO_BUFFERED_IO;
        DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    
    
        //取得鼠标驱动对象
        RtlInitUnicodeString(&MouseDriver, L"\Driver\Mouclass");
        status = ObReferenceObjectByName (
            &MouseDriver,
            OBJ_CASE_INSENSITIVE,
            NULL,
            0,
            *IoDriverObjectType,
            KernelMode,
            NULL,
            (PVOID *)&gFilterData.pMouseDriverObject
            );
    
        if(!NT_SUCCESS(status))
        {
            KdPrint(("Get mouse object failed, 0x%0x
    ", status));
            CleanUP(DeviceObject);
            return status;
        }
    
    
        //保存原来的IRP_MJ_READ 派遣例程
        gFilterData.OldRead = gFilterData.pMouseDriverObject->MajorFunction[IRP_MJ_READ];
    
        if(gFilterData.OldRead) // IRP HOOK
        {
            InterlockedExchange(
                (PLONG)&gFilterData.pMouseDriverObject->MajorFunction[IRP_MJ_READ],
                (LONG)MyDispatchRead
                );
        }
        else
        {
            CleanUP(DeviceObject);
            return STATUS_UNSUCCESSFUL;
        }    
    
        return status;
    }
    
    //IRP_MJ_READ 完成函数
    NTSTATUS MyDispatchReadComplete(IN PDEVICE_OBJECT pDeviceObject,
                            IN PIRP Irp, 
                            IN PVOID Context ) 
    {
        ULONG_PTR i,num;
        PMOUSE_INPUT_DATA data;
        PSINGLE_LIST_ENTRY pSingleListEntry = &gFilterData.ListHead;
        PPENDING_IRP_LIST PendingList = NULL;
    
        if( NT_SUCCESS( Irp->IoStatus.Status ) ) 
        {
            data = (PMOUSE_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
            num = Irp->IoStatus.Information / sizeof(MOUSE_INPUT_DATA);
    
            for( i = 0; i < num; i++ ) 
            {
                ////去除假的鼠标左键双击事件
                //if(data[i].ButtonFlags & MOUSE_LEFT_BUTTON_DOWN )
                //{ 
                //    // 鼠标左键按下
                //    if(IsFakeDoubleClick() )
                //    {   //假双击
                //        KdPrint(("Got a Fake Double CLick!! ================= 
    "));
                //        data[i].ButtonFlags = 0; //忽略掉
                //    }
                //    else
                //    {
                //        //KdPrint(("Left Button Down"));
                //    }
                //}
    
                //下面是实现左右互换的功能
                if(data[i].ButtonFlags &MOUSE_LEFT_BUTTON_DOWN )
                {
                    data[i].ButtonFlags = data[i].ButtonFlags&0xfff0;
                    data[i].ButtonFlags = data[i].ButtonFlags|MOUSE_RIGHT_BUTTON_DOWN;
                }
                else if (data[i].ButtonFlags &MOUSE_LEFT_BUTTON_UP)
                {
                    data[i].ButtonFlags = data[i].ButtonFlags&0xfff0;
                    data[i].ButtonFlags = data[i].ButtonFlags|MOUSE_RIGHT_BUTTON_UP;
                }
                else if (data[i].ButtonFlags &MOUSE_RIGHT_BUTTON_DOWN)
                {
                    data[i].ButtonFlags = data[i].ButtonFlags&0xfff0;
                    data[i].ButtonFlags = data[i].ButtonFlags|MOUSE_LEFT_BUTTON_DOWN;
                }
                else if (data[i].ButtonFlags &MOUSE_RIGHT_BUTTON_UP)
                {
                    data[i].ButtonFlags = data[i].ButtonFlags&0xfff0;
                    data[i].ButtonFlags = data[i].ButtonFlags|MOUSE_LEFT_BUTTON_UP;
                }
            }
        }
    
        KeWaitForMutexObject(&gFilterData.ReadMutex, Executive, KernelMode, FALSE, NULL);
    
        for(; pSingleListEntry->Next; pSingleListEntry = pSingleListEntry->Next)        
        {
            PendingList = CONTAINING_RECORD(pSingleListEntry->Next, PENDING_IRP_LIST, SingleListEntry);
    
            if(PendingList->PendingIrp == Irp)
            {// 从链表中移除
                pSingleListEntry->Next = pSingleListEntry->Next->Next;
                ExFreePoolWithTag(PendingList, POOL_TAG); 
                break;
            }
        }
    
        KeReleaseMutex(&gFilterData.ReadMutex, FALSE);       
    
        //KdPrint(("MyReadComplete ============ Irp= 0x%X, 0x%X", Irp,  Irp->IoStatus.Status));    
    
        //调用原来的完成函数
        if ((Irp->StackCount > 1) && (Context != NULL))
        {
            return ((PIO_COMPLETION_ROUTINE)Context)(pDeviceObject, Irp, NULL);
        }
        else
        {
            return Irp->IoStatus.Status;
        }
    }
    
    
    NTSTATUS MyDispatchRead(IN PDEVICE_OBJECT pDeviceObject,
           IN PIRP Irp
           )
    {
        PPENDING_IRP_LIST PendingList = NULL;
        PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
    
        //KdPrint(("MyDispatchRead ================ Irp= 0x%p ", Irp)); 
    
        PendingList = (PPENDING_IRP_LIST)ExAllocatePoolWithTag(NonPagedPool, sizeof(PENDING_IRP_LIST), POOL_TAG);    
    
        if(PendingList)
        {
            PendingList->PendingIrp = Irp;
    
            KeWaitForMutexObject( &gFilterData.ReadMutex, Executive, KernelMode, FALSE, NULL);                
            PushEntryList(&gFilterData.ListHead, &PendingList->SingleListEntry);
            KeReleaseMutex(&gFilterData.ReadMutex, FALSE); 
    
            // 按理说,应该调用IoSetCompletionRoutine来设置完成例程的
            // 但是,那样会导致完成例程根本不会被执行,Why?
            irpSp->Control = SL_INVOKE_ON_SUCCESS|SL_INVOKE_ON_ERROR|SL_INVOKE_ON_CANCEL;
    
            //保留原来的完成函数
            irpSp->Context = irpSp->CompletionRoutine;
            irpSp->CompletionRoutine = (PIO_COMPLETION_ROUTINE)MyDispatchReadComplete;
        }
    
        return  gFilterData.OldRead(pDeviceObject, Irp); 
    }
    
    NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT pDeviceObject,
                IN PIRP Irp
                )
    {
        //IoGetCurrentIrpStackLocation 需要在项目设置里面添加 hal.lib
        PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
    
        UNREFERENCED_PARAMETER(pDeviceObject);
    
        PAGED_CODE();
    
        KdPrint(("Entered ================ IRP_MJ_%s
    ", (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 DispatchDeviceControl(IN PDEVICE_OBJECT pDeviceObject,
                  IN PIRP Irp
                  )
    {
        PAGED_CODE();
    
        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest (Irp,IO_NO_INCREMENT);
    
        return Irp->IoStatus.Status;
    }
    
    VOID DriverUnload(IN PDRIVER_OBJECT pDeviceObject)
    {
        PAGED_CODE ();
    
        KdPrint(("Entered ================== Unload
    "));
    
        CleanUP(pDeviceObject->DeviceObject);
    
        CancelPendingIrp();
    
        //等待所有的IRP 完成    
        while (gFilterData.ListHead.Next) 
        {
            LARGE_INTEGER lDelay;
            lDelay.QuadPart = -10 * 1000 * 1000; // 1秒
            KeDelayExecutionThread(KernelMode, FALSE, &lDelay);
        }       
    }
    
    VOID CleanUP(IN PDEVICE_OBJECT pDeviceObject)
    {
        UNICODE_STRING  SymbolicLinkName;
    
        if(!pDeviceObject)
            return;
    
        // 删除符号链接和设备对象
        RtlInitUnicodeString(&SymbolicLinkName, DOS_DEVICE_NAME);
        IoDeleteSymbolicLink(&SymbolicLinkName);       
        IoDeleteDevice(pDeviceObject);
    
        //恢复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 会调用MyDispatchReadComplete 这个完成例程回调,
        // 而MyDispatchReadComplete里面又对链表进行操作,这样会破坏链表的结构
        pSingleListEntry = PopEntryList(&gFilterData.CancelHead);
        while(pSingleListEntry)
        {
            CancelList = CONTAINING_RECORD(pSingleListEntry, PENDING_IRP_LIST, SingleListEntry);
            if(CancelList)
            {
                KdPrint(("CancelPendingIrp = 0x%x", CancelList->PendingIrp));
    
                if(!CancelList->PendingIrp->Cancel)
                {// 在这里,取出复制链表中的IRP,然后进行取消
                    IoCancelIrp(CancelList->PendingIrp);
                }
                ExFreePoolWithTag(CancelList, POOL_TAG);        
                pSingleListEntry = PopEntryList(&gFilterData.CancelHead);
            }
        }
    }
    
    //判断是否是假双击,根据时间间隔判断
    BOOLEAN IsFakeDoubleClick ()
    {
        LARGE_INTEGER CurrentTime;
        BOOLEAN Flag = FALSE;
    
        KeQueryTickCount(&CurrentTime);
    
        CurrentTime.QuadPart *= KeQueryTimeIncrement();  
        CurrentTime.QuadPart /=  10000;
    
        //两次点击时间间隔小于100ms,视为假双击
        if( CurrentTime.LowPart - gFilterData.LeftDownTime < 100)
        {
            Flag = TRUE;
        }
    
        InterlockedExchange((volatile LONG *)&gFilterData.LeftDownTime, CurrentTime.LowPart);
        return Flag;
    }

    上面就是全部的代码。如果编译没有错误就会生成对应的sys文件。

    3.安装驱动

    安装过滤驱动有两种方式,一种是写服务来安装,这个网上也有源码,还有就是inf文件  在cmd里面执行rundll32 SETUPAPI.DLL,InstallHinfSection DefaultInstall 132 +inf路径

    这里贴出来一个完整的inf 鼠标过滤驱动的文件

    ; HHD Software USB Monitoring Filter Driver
    ; Part of Device Monitoring Studio
    ;
    ; Copyright HHD Software Ltd.
    [Version]
    signature = "$Windows NT$"
    DriverPackageType=ClassFilter
    Class=Mouse
    ClassGUID={59D5B0A2-8479-4333-BCFE-3EB1F6BD506D}
    Provider=%ClasFilt.Provider%
    DriverVer=12/03/2010,5.25.0.3036
    
    ;
    [SourceDisksNames]
    1 = %ClasFilt.MediaDesc%
    
    [SourceDisksFiles]
    MyMouseDrive32.sys = 1
    MyMouseDrive64.sys = 1
    
    [DestinationDirs]
    DefaultDestDir = 12    ; DIRID_DRIVERS
    
    [DefaultInstall.ntx86]
    CopyFiles = @MyMouseDrive32.sys
    AddReg = ClassFilter_AddReg.ntx86
     
    [DefaultInstall.ntamd64]
    CopyFiles = @MyMouseDrive64.sys
    AddReg = ClassFilter_AddReg.ntamd64
     
    ; 指定过滤驱动对应的注册表项
    [ClassFilter_AddReg.ntx86]
    HKLM, SystemCurrentControlSetControlClass{4D36E96F-E325-11CE-BFC1-08002BE10318}, UpperFilters, 0x00010008, MyMouseDrive32
    
          
    [ClassFilter_AddReg.ntamd64]
    HKLM, SystemCurrentControlSetControlClass{4D36E96F-E325-11CE-BFC1-08002BE10318}, UpperFilters, 0x00010008, MyMouseDrive64
    
    
    [DefaultInstall.ntx86.Services]
    AddService = MyMouseDrive32, , clasfilt_Service_Inst.ntx86, clasfilt_EventLog_Inst.ntx86
    
    [DefaultInstall.ntamd64.Services]
    AddService = MyMouseDrive64, , clasfilt_Service_Inst.ntamd64, clasfilt_EventLog_Inst.ntamd64
    
    [clasfilt_Service_Inst.ntx86]
    DisplayName    = %ClasFilt.SvcDesc%
    ServiceType    = %SERVICE_KERNEL_DRIVER%
    StartType      = %SERVICE_DEMAND_START%
    ErrorControl   = %SERVICE_ERROR_IGNORE%
    ServiceBinary  = %12%MyMouseDrive32.sys
    
    [clasfilt_Service_Inst.ntamd64]
    DisplayName    = %ClasFilt.SvcDesc%
    ServiceType    = %SERVICE_KERNEL_DRIVER%
    StartType      = %SERVICE_DEMAND_START%
    ErrorControl   = %SERVICE_ERROR_IGNORE%
    ServiceBinary  = %12%MyMouseDrive64.sys
    
    [clasfilt_EventLog_Inst.ntx86]
    AddReg = clasfilt_EventLog_AddReg.ntx86
    
    [clasfilt_EventLog_Inst.ntamd64]
    AddReg = clasfilt_EventLog_AddReg.ntamd64
    
    [clasfilt_EventLog_AddReg.ntx86]
    HKR,,EventMessageFile, %REG_EXPAND_SZ%,"%%SystemRoot%%System32IoLogMsg.dll;%%SystemRoot%%System32driversMyMouseDrive32.sys"
    HKR,,TypesSupported, %REG_DWORD%, 7
    
    [clasfilt_EventLog_AddReg.ntamd64]
    HKR,,EventMessageFile, %REG_EXPAND_SZ%,"%%SystemRoot%%System32IoLogMsg.dll;%%SystemRoot%%System32driversMyMouseDrive64.sys"
    HKR,,TypesSupported, %REG_DWORD%, 7
    
    [Strings]
    ; 不同的过滤驱动下面的信息要修改
    ;Note: the following must be modified, if it is other filter drivers 
    ClasFilt.SvcDesc="MyMouse Filter Driver"
    ClasFilt.MediaDesc="MyMouse Filter Package"
    ClasFilt.Provider="MyMouse Software Ltd."
    
    ;下面这个信息不需要修改
    ; Useful constants
    SERVICE_KERNEL_DRIVER = 1
    SERVICE_DEMAND_START  = 3
    SERVICE_ERROR_IGNORE  = 0
    REG_EXPAND_SZ         = 0x00020000
    REG_DWORD             = 0x00010001
        
  • 相关阅读:
    Lexical Sign Sequence
    (UPCOJ暑期训练)Tally Counters
    (2019hdu多校第十场) Welcome Party
    (2019hdu多校第十场1003) Valentine's Day
    更新,线段树模板(支持相关基本操作)
    linux(deepin)下Clion的安装及环境配置
    2019牛客第7场——C(Governing sand)
    【数论】数论之旅:N!分解素因子及若干问题
    [二分]Kayaking Trip
    [数论之旅]数学定理
  • 原文地址:https://www.cnblogs.com/mayingkun/p/7758472.html
Copyright © 2011-2022 走看看