最近对驱动比较感兴趣,所以打算做个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:\WINDDK\7600.16385.1\inc\wdf\kmdf\1.9
D:\WINDDK\7600.16385.1\inc\api
D:\WINDDK\7600.16385.1\inc\crt
D:\WINDDK\7600.16385.1\inc\ddk
注意:vc包含文件的D:\WinDDK\7600.16385.1\inc\api不一定是放最前面,编译不过去的时候可以放到$(VCInstallDir)include的后面。
然后选择“win32”--“库文件”添加自己的WDK中LIB路径
D:\WINDDK\7600.16385.1\lib\wdf\kmdf\i386\1.9
D:\WINDDK\7600.16385.1\lib\wxp\i386
如果是64位的需要添加的库文件是
D:\WINDDK\7600.16385.1\lib\wdf\kmdf\amd64\1.9
D:\WINDDK\7600.16385.1\lib\win7\amd64
(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:\WINDDK\7600.16385.0\lib\wxp\i386”
如果是64的修改为"D:\WinDDK\7600.16385.1\lib\win7\amd64”
选择“输入”,“附加依赖项”输入“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(