转载请标明是引用于 http://blog.csdn.net/chenyujing1234
欢迎大家提出意见,一起讨论!
代码及EzDriverInstaller下载地址 :
http://www.rayfile.com/zh-cn/files/9376d678-b9e1-11e1-9cc9-0015c55db73d/
(编译环境:VS2008+DDK库(参考:Window XP驱动开发(十六) XP下新建驱动程序工程并编译的第二种方法))
在驱动程序开发中,经常需要一个驱动程序调用另一个驱动程序。
例如:
虚拟串口转USB设备的驱动程序,这种驱动程序首先创建一个虚拟串口设备,对这个虚拟串口设备的读写请求会转到一个USB设备上去,
这时需要在虚拟串口驱动程序中调用USB驱动程序。
1、 以文件句柄形式调用其他驱动程序
这种方法类似于在应用程序中调用驱动程序。这种方法使用简单,不需要程序员对Windows底层了解过多知识。
1、1 准备一个标准驱动DriverA
这个“目标”驱动程序创建一个模拟设备,模拟设备支持异步读取操作。事先规定每次对设备读取要耗时3S,因为这样可以很好地演示异步读取操作。
对于这样的驱动程序,应该设置一个定时器,定时器的间隔为3S。另外在IRP_MJ_READ的派遣函数中不结束IRP请求,而是将IRP请求挂起,并且在派遣函数
退出前开启定时器。这样3S后就会进入定时器的回调函数中,并在回调函数中结束IRP请求。
我们把这个“目标”驱动程序命名为DriverA,调用DriverA的驱动程序被命名为DriverB,以下列出DriverA的部分代码:
首先是DriverA的IRP_MJ_READ派遣函数。
DriverA的超时回调DPC例程,此例程在CreateDevice创建设备时安装的。
以上就是准备的“目标”驱动程序DriverA ,为了演示DriverB调用DriverA,并使读者可以清楚log消息来源于哪个驱动程序,我们
让DriverA在输出log信息上加“DriverA:”这个前缀,而让DriverB在输出log信息之前加上“DriverB:”这个前缀。
DriverB有多种方法调用DriverA,这些方法可以是同步调用,也可以是异步调用。
1、1、1 DriverA的安装文件Inf的书写
1、2 以文件句柄形式调用其他驱动程序的知识点
1、2、1 获得设备句柄的两种方法
(1) 通过ZwCreateFile,以设备名来打开
在驱动程序中,打开设备使用ZwCreateFile内核函数,它会返回设备句柄。这里要讨论一下如何用
ZwCreateFile内核函数打开“同步”设备和“异步”设备。ZwCreateFile内核函数声明如下:
(2)
很多情况下,使用都不容易知道具体的设备名,而只知道符号链接。例如“C:"代表第一个硬件分区,而“C:”就是第一个符号链接,
它指向第一个磁盘分区设备。尤其在WDM驱动设备中,通过符号链接打开设备是经常遇到的。
利用ZwOpenSymbolicLinkObject内核函数先得到符号链接的句柄,
然后使用ZwQuerySymbolicLinkObject内核函数查找到设备名。
通过设备名就可以方便地打开设备。
1、2、2 打开方式的两种方式
现在我们介绍打开“同步”和“异步”设备的区别。
(1)如果打开“同步”设备,第二个参数DesiredAccess需要设置为SYNCHRONIZE,
且倒数第三个参数CreateOptions需要指定为FILE_SYNCHRONOUS_IO_NONALERT或FILE_SYNCHRONOUS_IO_ALERT。
(2) 如果打开“异步”设备,第二个参数DesiredAccess不能设置为SYNCHRONIZE,并且倒数第三个参数CreateOptions不能指定为
FILE_SYNCHRONOUS_IO_NONALERT或FILE_SYNCHRONOUS_IO_ALERT。
1、3 以文件句柄形式调用的第一种方法:同步调用
在应用程序中,ReadFile函数既可以来读取文件,又可以来读取设备。同样,在驱动程序中,ZwReadFile内核函数既可以来读文件,也可以来读设备。
如果用ZwReadFile内核函数同步读取设备,操作对应的IRP_MJ_READ请求被结束后,函数才会返回。否则这个函数会一直等待IRP_MJ_READ请求被结束。
如果用ZwReadFile内核函数异步读取设备,即使操作对应的IRP_MJ_READ请求没有被结束,函数也会立即返回。
本节介绍的DriverB是利用同步读取的方法调用DriverA,如用ZwReadFile内核函数同步读取DriverA的设备,它的内部操作过程如下:
(1)在DriverB中用ZwReadFile内核函数读取DriverA的设备对象。ZwReadFile内核函数内部会创建IRP_MJ_READ类型的IRP,然后将这个IRP
当做参数传递给DriverA的派遣函数。
(2)DriverA的派遣函数没有结束IRP请求,而是将IRP请求“挂起”。
(3)ZwReadFile函数会一直等待IRP中的一个事件,此时当前线程进入睡眠状态。
(4)3S后,触发DriverA 的定时器例器,这里IRP请求被结束,IRP中的相关事件也被设置。
(5)由于相应事件被设置,刚才休眠的线程恢复运行,ZwReadFile内核函数退出。
1、3、1 DriverB设计
我们是采用同步打开设备的方式。
1、3、2 应用程序设计
另外,DriverB还需要做应用程序的客户端,因此DriverB的派遣函数还需要结束来自应用程序的IRP请求。
1、3、3DriverB的安装文件inf的书写
1、3、4 加载驱动测试
由于DriverA与DriverB都是虚拟设备,通过设备管理器里的硬件更新向导加载驱动是可以的。
但是为了方便我们通过EzDriverInstaller工具。它是DriverStudio自带的一个工具软件,用于快速安装WDM程序。
(1)打开EzDriverInstaller,选择“File”|“Open”,在弹出的对话框中,选择需要的inf文件。
(2)然后点击“Add New Device”。
此时就会提示成功,并在列表中显示我们的设备名:
打开我们的设备管器看看效果吧:
(3) 运行应用程序,用DebugView查看打印信息。
注:网上很多人反映KdPrint打印不能在DebugView上显示出来。开始我也怀疑KdPrint这个函数不对。
后来才知道是DebugView没设置好。确保Capture菜单下的Log Boot选择已经勾选。
1、4 以文件句柄形式调用的第二种方法:异步调用
1、4、1 异步调用方法一
异步读取主要是指ZwReadFile内核函数没有等待DriverA真正结束IRP请求时,就已经退出。如果用ZwReadFile内核函数异步读取DriverA的设备,
它的内部操作过程如下:
(1)ZwReadFile内核函数内部创建IRP_MJ_READ类型的IRP,然后将这个IRP传递给DriverA的派遣函数。
(2)DriverA派遣函数没有结束IRP请求,而是将IRP"挂起”
(3)ZwReadFile内核函数发现DriverA将IRP_MJ_READ“挂起”,于是它直接返回,返回值是STATUS_PENDING,这就代表读取操作正在进行。
ZwReadFile内核函数退出后,无法得到“挂起”的IRP何时被结束。
因此在调用ZwReadFile内核函数前,可以为IRP设置一个完成例程。当IRP结束时触发这个完成例程。
以下是完成例程的代码。完成例程主要是用一个事件通知IRP请求结束。
1、4、2 异步调用方法二
第二种异步方法和每一种异步方法略有不同。第一种异步读取时,将一个事件的句柄传递给ZwReadFile内核函数,这个事件可以用来通知读取操作何时完成。
而这里介绍的方法不用将事件句柄传递给ZwCreateFile函数,而是将通过文件对象判断读取是否完毕。
每打开一个设备,都会伴随存在一个关联的文件对象(FILE_OBJECT)。利用内核函数ObReferenceObjectByHandle可以获得和设备相关的文件对象指针。
当IRP_MJ_READ请求被结束后,文件对象的子域Event会被设置,因此用文件对象的Event子域可以当做同步点使用。
这里利用文件对象的子域Event,即FileObject->Event作为同步点。以下是代码:
分享到:
相关推荐
第10章驱动程序调用驱动程序1小时3节 第四十七课 通过设备句柄调用驱动程序 第四十八课 设备指针调用驱动程序 第四十九课 自定义irp与ObReferenceObject 第11章分层过滤驱动 第五十课 分层驱动:枚举设备栈上的...
如何修改simulink中示波器所显示的波形,将这个程序放在MATLAB主命令窗口里运行一下,就能调用示波器仿真图形的句柄工具
PCI、USB、虚拟串口、虚拟摄像头、SDIO等驱动程序的开发,归纳了多种调试驱动程序的高级技巧,如 用WinDBG和VMWARE软件对驱动进行源码级调试,深入Windows操作系统的底层和内核,透析Windows驱动 开发的本质。 ...
从Windows最基本的两类驱动程序的编译、安装、调试入手讲解,非常容易上手,用实例详细讲解PCI、USB、虚拟串口、虚拟摄像头、SDIO等驱动程序的开发,归纳了多种调试驱动程序的高级技巧,如用WinDBG和VMWARE软件对...
其中描述了大量常见错误并为驱动程序开发人员提供了查找、纠正和防止这些错误的建议方法。 本白皮书包括以下内容: • 内核模式代码中的用户模式地址 • 探测 • METHOD_NEITHER IOCTL 和 FSCTL 中传递的地址 ...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 软件名称:驱动加载工具(InstDrv - 中文版) 软件版本:V1.0版 软件类型:个人免费版(无插件) 运行环境:Windows操作系统 开发作者:...
第1章 驱动程序开发环境 第2章 测试驱动程序 第一部分 一般内核模式 第1章Windows 2000和WDM驱动程序 第2章 分层的I/O、IRP和I/O对象 第3章 系统定义的对象和对驱动程序的支持 第4章 驱动程序...
c#调用api运用句柄关闭鼠标所在位置程序 根据鼠标位置判断鼠标下方程序句柄 显示程序标题 句柄id 程序类名 根据句柄关闭程序
第十二章 带WDM低级接口的微端口驱动程序 174 12.1 WDM低层微端口 174 12.2 注册WDM低层的微端口函数 174 12.3 初始化WDM低层微端口 175 12.4 发布命令与远程设备通信 176 12.4.1 在总线上发送包 176 12.4.2 在总线...
查看window文件句柄信息有用工具。协助开发人员查看句柄使用情况。
易语言根据文件句柄取文件路径源码,根据文件句柄取文件路径,文件句柄取文件路径名,lopen,ZwQueryObject,WToM,lclose,QueryDosDevice,StrCmpNI
压缩包中的“MySYS.sys”文件为测试驱动程序,支持加载、启动、停止、卸载驱动等功能,可以使用“Dbgview”工具查看驱动输出的提示信息。 ------------------------------------------------- 详细的中文提示信息...
windows程序开发中常用的定义,包括各种句柄类型,windows框架下的消息类型,位图应用
本程序是完整的项目文件,在VS2008下运行成功,程序功能:通过传递主窗体句柄,然后打开子窗体,在子窗体中可对主窗体的控件或函数进行操作,改变其控件属性 ,调用主窗体的函数,(注:在调用前要修改主窗体被调用控件或函数...
有时外部程序调用SAP 的RFC, 实现与SAP程序的接口, 是以外部程序为主; 现在终于找到以SAP程序为主调用外部程序的方法了. 就是SAP 的ABAP语言调用 DLL文件中的函数实现一些功能, 例如可以用DLL文件连接外部数据库...
Windows桌面平台下的驱动加载工具,能够快速加载写好的驱动文件 方便调试
HViewer是一款专门用来进行Windows程序的句柄资源监测的软件,但不能对指定进程的句柄资源进行自动的监测,为此我写了一个HViewerSpy程序来辅助进行自动监测。使用方法是启动HViewer程序,并选择好需要进行监测的...
从打开的文件句柄获得文件的路径.根据HANDLE获得文件路径
用自带的手机USB驱动,用Window句柄获取驱动安装的按钮,实现自动安装
ODBC跟踪允许创建调用 ODBC 驱动程序的日志,以供技术支持人员查看,也有助于您调试应用程序。Visual Studio 跟踪启用Microsoft Visual Studio的ODBC跟踪。 连接池允许应用程序重用打开连接句柄 ,此操作将节省到...