计算机论文
Win32应用程序的辅助线程
时间:2021-12-05 11:03 所属分类:计算机论文 点击次数:
设备驱动是当今流行的Windows操作系统中控制硬件最底层的软件接口。为分享设计设备驱动程序的经验,给出设备驱动程序通知应用程序的5种方法,具体介绍了每一种方法的原理及实现过程,希望能给驱动程序的设计者提供一定的帮助。
为确保系统的平稳稳定,并保证应用程序的可移植性,Windows操作系统不要求应用程序直接访问系统的硬件资源,而应该借助相应的设备驱动程序。该设备驱动程序可以直接操作硬件,如果应用程序与设备驱动程序之间实现双向通信,则应用程序可以控制底层硬件设备。两者间的通讯包括两个方面:一是应用程序向设备驱动程序发送的数据,另一种是由设备驱动程序发送到应用程序的消息。前一种实现比较容易,在设备驱动程序句柄通过CreateFile()函数获得之后,Win32函数可用于DeviceIoControl()、实现应用程序与设备驱动器之间的通信,例如ReadFile()或WriteFile()。后一种方法的实现要比前一种复杂得多,很少有报道。它并不意味着说它不重要,相反,在某些应用中起到了很大的作用。在完成数据采集工作之后,驱动程序需要立即通知应用程序,这样应用程序就可以及时提取和处理数据。这样的例子并不多。
考虑到驱动程序告知应用程序的重要性,我结合自己的经验,总结了5个方面的总结,归纳了5个方面的摘要:异步过程调用(APC)、事件式(VxD)、消息式、异步I/O方式(WDM)。以下分别说明了这些方法的原理,并给出了部分实现源代码。
1非同步过程调用(APC)
Win32应用程序使用CreateFile()功能动态地装载设备驱动程序,接下来定义回调函数backFunc(),而回调函数的地址%26amp;backFunc()作为参数,由DeviceIoControl()发送到设备驱动程序。在设备驱动程序得到这个回调函数的地址之后,将其保存到一个全局变量(比如callback),函数调用Get_Cur_Thread_Handle()获得其应用程序线程的句柄,而且这个句柄也被保存在一个全局变量(比如appthread)中。在条件成熟的情况下,设备驱动程序调用_VWIN32_QueueUserApc()功能,以便向Win32应用程序发送消息。此函数包含三个参数摘要:第一个是回调(已注册)的地址;第二个是传递给回调的消息;第三个是调用程序的线程句柄(已注册)。Win32应用程序在接收到一条消息之后自动调用回调函数(实际上由设备驱动程序调用)。这个回调函数的输入参数由设备驱动程序填充,在这里,它主要处理消息。
2事件模式(VxD)
Win32应用程序首先创建了一个称为Ring3句柄的事件句柄。因为VirtualDriver使用事件的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应用程序接收到该消息之后,处理该消息。