65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (26投票s)

2002年3月27日

2分钟阅读

viewsIcon

285337

downloadIcon

5724

一篇关于 GUI 应用程序和设备驱动程序之间通信的文章。

背景

最近我读到一篇好文章,作者编写了一个设备驱动程序和一个GUI程序,他想在设备驱动程序中发生某些事件时通知GUI应用程序。在他的文章中,当创建一个新进程时,会调用驱动程序中的一个回调函数,它会通知GUI应用程序并立即显示有关新进程的一些信息。在设备驱动程序中,作者创建了一个命名事件,并在GUI应用程序中打开了它。然后,当事件发生时,他这样处理它:

KeSetEvent(Event, 0, FALSE);
KeClearEvent(Event);

此时,GUI应用程序正在等待该事件。在两个函数的间隔之间,应用程序必须获得新进程的信息。它可以工作,但我不认为这是一个好的解决方案。

为什么作者要这样编码?因为,如果我们在内核模式下创建一个事件,我们无法在用户模式下修改它的状态,我们只能检查它的状态。但是通常,我们希望GUI应用程序将事件修改为未触发状态,并且它可以再次等待该事件。我认为这是处理此问题的合格IPC模型。

关于我的解决方案

内核模式比用户模式具有更高的优先级。在内核模式下,我们可以方便地修改用户模式下的数据。因此,我在用户模式下创建一个事件对象,并在内核模式下引用它。现在,设备驱动程序和GUI应用程序都可以检查和修改事件对象的状态。

如何将其集成到您的应用程序中

在您的应用程序中,您必须首先打开设备对象,然后这样编码:

  1. 创建一个事件对象并将其传递给驱动程序。
    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);
  2. 等待事件对象被触发。
    while(true)
    {
    	WaitForSingleObject(m_hCommEvent, INFINITE);
    	//After this function, the event is set to non signaled. 
    	//Get information and deal with it.
    }     

在设备驱动程序中,代码如下:

  1. 在 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 对象,因此我们可以使用 KeEventXXXKeWaitForXXX 来操作它。

  2. 当对象事件发生时
    KeSetEvent(gpEventObject, 0, FALSE);
  3. 当我们不需要它时,我们应该取消引用它
    case IO_DEREFERENCE_EVENT:
    	if(gpEventObject)
                  ObDereferenceObject(gpEventObject); 

我已经在个人防火墙产品中测试了我的解决方案。 它运行良好。当我的IP过滤驱动程序获得一个IP数据包时,它会根据我的安全规则检查IP头。 如果数据包将被拦截,它会报告给我的GUI应用程序。

示例下载包括两个项目:一个GUI应用程序和一个设备驱动程序。 GUI应用程序是一个基于对话框的MFC应用程序。 它有一个日志窗口,可以记录事件对象上的操作。 设备驱动程序只是一个非常简单的内核模式设备驱动程序。 它可以按照GUI应用程序的要求操作事件对象。 如果您想运行此演示,您必须首先安装并启动驱动程序。

因为有很多工具可以安装和启动设备驱动程序,所以我没有包含执行此工作的代码。

如果您有任何问题和建议,请通知我。

GUI应用程序和设备驱动程序之间的通信 - CodeProject - 代码之家
© . All rights reserved.