GUI 应用程序和设备驱动程序之间的通信






4.83/5 (26投票s)
2002年3月27日
2分钟阅读

285337

5724
一篇关于 GUI 应用程序和设备驱动程序之间通信的文章。
背景
最近我读到一篇好文章,作者编写了一个设备驱动程序和一个GUI程序,他想在设备驱动程序中发生某些事件时通知GUI应用程序。在他的文章中,当创建一个新进程时,会调用驱动程序中的一个回调函数,它会通知GUI应用程序并立即显示有关新进程的一些信息。在设备驱动程序中,作者创建了一个命名事件,并在GUI应用程序中打开了它。然后,当事件发生时,他这样处理它:
KeSetEvent(Event, 0, FALSE);
KeClearEvent(Event);
此时,GUI应用程序正在等待该事件。在两个函数的间隔之间,应用程序必须获得新进程的信息。它可以工作,但我不认为这是一个好的解决方案。
为什么作者要这样编码?因为,如果我们在内核模式下创建一个事件,我们无法在用户模式下修改它的状态,我们只能检查它的状态。但是通常,我们希望GUI应用程序将事件修改为未触发状态,并且它可以再次等待该事件。我认为这是处理此问题的合格IPC模型。
关于我的解决方案
内核模式比用户模式具有更高的优先级。在内核模式下,我们可以方便地修改用户模式下的数据。因此,我在用户模式下创建一个事件对象,并在内核模式下引用它。现在,设备驱动程序和GUI应用程序都可以检查和修改事件对象的状态。
如何将其集成到您的应用程序中
在您的应用程序中,您必须首先打开设备对象,然后这样编码:
- 创建一个事件对象并将其传递给驱动程序。
HANDLE m_hCommEvent = CreateEvent(NULL, false, false, NULL); //download event object to device driver, m_hCommDevice is the device object DeviceIoControl(m_hCommDevice, IO_REFERENCE_EVENT, (LPVOID) m_hCommEvent, 0, NULL, 0, &dwReturn, NULL);
- 等待事件对象被触发。
while(true) { WaitForSingleObject(m_hCommEvent, INFINITE); //After this function, the event is set to non signaled. //Get information and deal with it. }
在设备驱动程序中,代码如下:
- 在 IRP_MJ_DEVICE_CONTROL 主要例程中
case IO_REFERENCE_EVENT: hEvent = (HANDLE) irpStack->Parameters.DeviceIoControl.Type3InputBuffer; status = ObReferenceObjectByHandle( hEvent, GENERIC_ALL, NULL, KernelMode, &gpEventObject, &objHandleInfo);
gpEventObject 是一个 PRKEVENT 对象,因此我们可以使用 KeEventXXX 和 KeWaitForXXX 来操作它。
- 当对象事件发生时
KeSetEvent(gpEventObject, 0, FALSE);
- 当我们不需要它时,我们应该取消引用它
case IO_DEREFERENCE_EVENT: if(gpEventObject) ObDereferenceObject(gpEventObject);
我已经在个人防火墙产品中测试了我的解决方案。 它运行良好。当我的IP过滤驱动程序获得一个IP数据包时,它会根据我的安全规则检查IP头。 如果数据包将被拦截,它会报告给我的GUI应用程序。
示例下载包括两个项目:一个GUI应用程序和一个设备驱动程序。 GUI应用程序是一个基于对话框的MFC应用程序。 它有一个日志窗口,可以记录事件对象上的操作。 设备驱动程序只是一个非常简单的内核模式设备驱动程序。 它可以按照GUI应用程序的要求操作事件对象。 如果您想运行此演示,您必须首先安装并启动驱动程序。
因为有很多工具可以安装和启动设备驱动程序,所以我没有包含执行此工作的代码。
如果您有任何问题和建议,请通知我。