配备驱动程序通知应用程序的几种植艺术

笔者: 北京航空航天大学 周正干 李和平 安振刚
来源:http://www.mesnet.com.cn/htm/article_view.asp?id=1023

章代码下载地址:长距离下载  本地下载

  于DOS操作系统被,应用程序可以一直跟硬件打交道,包括I/O端口读写、中断请求与响应和DMA操作等[1]。这种对硬件过于直白的操作方
式给软件设计提供了迟早之便民,但也时有发生它自己的部分通病。首先,一些非法操作有或改写某些硬件寄存器的情,导致操作系统崩溃,从而使操作系统变得无安
全,性能不安宁;其次,应用程序的可移植性变差。为了保证操作系统的安全性与安乐和应用程序的可移植性,Windows操作系统不同意应用程序直接看
问系统的硬件资源,而是必须依相应的设备驱动程序。设备驱动程序可以一直操作硬件,如果应用程序和配备驱动程序之间实现了双向通信,也即直达了采取程
序控制底层硬件设施的目的。它们中间的通信包括个别独面:一方面是应用程序传送给设备驱动程序的数码;另一方面是设备驱动程序发送给应用程序的信。前者
的兑现比较易,通过CreateFile()函数获取装备驱动程序的句子柄后,就足以用Win32函数,如DeviceIoControl()、
ReadFile()或WriteFile()等实现应用程序与设备驱动程序之间的通信[2]。DDK和MSDN对它有详尽的叙述,读者可参考相关资
料。后者的兑现多较前者复杂,同时介绍这上面情况的稿子于少。这不齐说它不紧要,相反,它于微应用场合表达在至关重要的意向。例如,在数据搜集系统遭到,应
用程序向设备驱动程序发送采集数据的命令后,建立一个助线程等待数收集完成,而应用程序本身则可承干别的劳作。设备驱动程序完成多少的采访工作
后,需要这通知应用程序,以便应用程序能够立刻以数据获得走并拓展处理。诸如此类情况,不一而足。

  鉴于设备驱动程序通知应用程序的重要性,作者结合一些历及就有的资料[3~5],对其进行了总结,归纳出5种植方式:异步过程调用(APC)、
事件方(VxD)、消息方式、异步I/O方式和波方(WDM)。下面分别证实及时几种方式的法则,并吃来实现的有些源代码。

1  异步过程调用(APC)

  Win32应用程序使用CreateFile()函数动态加载设备驱动程序,然后定义一个回调函数backFunc(),并且以回调函数的地
址&backFunc()作为参数,通过DeviceIoControl()传送给装备驱动程序。设备驱动程序获得回调函数的地点后,将其保存在
一个全局变量(如callback)中,同时调用Get_Cur_Thread_Handle()函数获取其的应用程序线程的句柄,并且用该词柄保存在一
个全局变量(如appthread)中。当条件成熟时,设备驱动程序调用_VWIN32_QueueUserApc()函数,向Win32应用程序发送消
息。这个函数带有三只参数:第一独参数为回调函数的地址(已经注册);第二个参数为传送让回调函数的信息;第三只参数为调用者的线程句柄(已经注册)。
Win32应用程序收到信后,自动调用回调函数(实际是由于装备驱动程序调用)。回调函数的输入参数是由装备驱动程序填入的,回调函数在此地要是本着信息
进行处理。

2  事件方(VxD)

  首先,Win32应用程序创建一个风波之句柄,称其为Ring3句柄。由于虚拟设备驱动程序使用事件之Ring0词柄,因此,需要创造
Ring0词柄。用LoadLibrary()函数加载未公开的动态链接库Kernel32.dll,获得动态链接库的句柄。然后,调用
GetProcAddress(),
找到函数OpenVxDHandle()在动态链接库中的职务。接着,用OpenVxDHandle()函数将Ring3事件句柄转化为Ring0事变句
柄。Win32应用程序用CreateFile()函数加载设备驱动程序。如果加载成功,则调用DeviceIoControl()函数将Ring0事件
句柄传被VxD;同时,创建一个相助线程等待信号变成有信号状态,本身虽然只是去干别的政工。当条件成熟时,VxD置Ring0事件也来信号状态(调用
_VWIN32_SetWin32Event()函数),这立即触发对应之Ring3波呢发出信号状态。一旦Ring3轩然大波句柄为有信号状态,Win32
应用程序的相助线程就对这信息进行对应的拍卖。

3  消息方式

  Win32应用程序调用CreateFile()函数动态加载虚拟设备驱动程序。加载成功后,通过调用DeviceIoControl()函数
将窗体句柄传送给VxD,VxD利用这个句子柄向窗体发信息。当规则满足时,VxD调用SHELL_PostMessage()函数向Win32应用程序发
送信息。要给该函数使用成功,必须用#define来自定义一个音,并且为要是还是在应用程序中定义它;还要当信循环中动用ON_MESSAGE()来
定义音对应的信处理函数,以便消息发出时,能够调用消息处理函数。SHELL_PostMessage()函数的第一只参数为Win32窗体句子柄,第
亚独参数为信息ID号,第三、四个参数为发送给消息处理函数的参数,第五、六单参数为回调函数和污染为其的参数。Win32应用程序收到信息继,对信息进行
处理。

4  异步I/O方式

  Win32应用程序首先调用CreateFile()函数加载设备驱动程序。在调用该函数时,将倒数第2个参数设置为
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_
OVERLAPPED,表示以后好针对文本进行重叠I/O操作。当设备驱动程序文件创建成功后,创建一个新始态为无信号、需要手动复位的风波,并且用之
事件传于项目也OVERLAPPED的数据结构(如Overlapped)。然后,将Overlapped作为一个参数,传被
DeviceIoControl()函数。设备驱动程序把这I/O请求包(IRP)设置为挂于状态,并且安装一个撤回例程。如果手上IRP队列为空,则
将以此IRP传送给StartIo()例程;否则,将其放到IRP队列中。设备驱动程序做得了这些干活儿晚,结束之DeviceIoControl()的介乎
理,于是Win32应用程序可能不等待IRP处理终结,就从DeviceIoControl()的调用中归。通过判断返回值,得到IRP的拍卖情况。如果
当前IRP处于挂于状态,则主程序先做片其它的行事,然后调用WaitForSingleObject()或
WaitForMultipleObject()函数等待Overlapped中之轩然大波成为有信号状态。设备驱动程序在适合的上处理排队的IRP,处理
完成后,调用IoCompleteRequest()函数。该函数将Overlapped中之轩然大波设置为发出信号状态。Win32应用程序对这个波立即进
行响应,退出等状态,并且用事件复位为无信号状态,然后调用GetOverlappedResult()函数获取IRP的处理结果。

5  事件措施(WDM)

  Win32应用程序首先创建一个事件,然后将该事件句柄传被装备驱动程序,接着创建一个协助线程,等待事件之发生信号状态,自己虽随着干别事
情。设备驱动程序获得该事件之词柄后,将它换成为能利用的风波指针,并且将她寄存起来,以便后面使用。当极抱有后,设备驱动程序将事件设置为来信号状
态,这样应用程序的支援线程马上知道者信息,于是进行相应的拍卖。当设备驱动程序不再采取是波时,应该排除该事件的指针。

  本刊网络补充版(http://www.dpj.com.cn)中,介绍了各组成部分实现之片段代码。

结语

  以当下风靡的Windows操作系统被,设备驱动程序是决定硬件的无比底部软件接口。它发展提供以及硬件无关的用户接口,向下直开展I/O、硬件
中断、DMA和内存访问等操作。它用应用程序与硬件细节屏蔽开来,使软件不依靠让硬件并且可于差不多只不等之阳台内移植。本文介绍了5种植装备驱动程序通知应
用程序的主意,其中前3种方法要用以VxD中,后2栽艺术主要用于WDM。这5种植艺术都由此实际测试。测试结果表明,它们还能够及设备驱动程序通知应
用程序的目的。

参考文献

1  欧青立,徐建波,李方敏,等. 虚拟设备驱动程序VxD的研讨与付出[J].
计算机工程,2003,28(3): 45~46
2  (美)Chris Cant. Windows WDM设备驱动程序开发指南[M]. 孙义, 马莉波,
国雪飞等译. 北京: 机械工业出版社, 2000. 20~50
3  Karen Hazzan. Windows VxD与设施驱动权威指南[M]. 孙喜明译. 北京:
中国电力出版社, 1999. 28~100
4  Walter Oney. Programming the Microsoft Windows Driver Model[M].
(美)Microsoft Press, 1999. 35~180
5  李和平. 基于DSP的ICT图像重建系统钻研[D]. 北京:
北京航空航天大学机械工程及自动化学院, 2002

发表评论

电子邮件地址不会被公开。 必填项已用*标注