如何从windows ndislwf驱动程序通知用户模式应用程序?

时间:2014-04-08 11:28:14

标签: crash driver ndis

我采用了ndislwf 6.0示例示例并进行了一些更改,例如将唯一传入的ARP数据包放入链接列表中。我可以通过IOCTL命令从用户空间获取所有数据。这很好。

现在,我希望有一个正在运行的应用程序;一旦我的驱动程序收到ARP数据包,它应该向客户端应用程序发送一些通知或信号。然后,客户端应用程序将发出另一个将获取最新数据的请求。

我发现了三种方法:

  1. 在客户端应用程序中有一个事件并等待它
  2. 有待处理的IRP,
  3. 使用命名管道。
  4. 我通过复制..winddk ... \ src \ general \ event项目的实现逐字实现了第一个。

    现在,由于我没有使用计时器,我很困惑。问题是:

    事件并等待它,需要IOCTL命令。 ARP缓存在新的ARP数据包到达并添加到列表时更新。只有当它被添加到列表中时,我才需要发出信号。但这是基于中断的。

    那么,我如何将这两者结合起来,以便在来自NDIS的中断时,我通知客户端应用程序。

    我这样做了:

    在我正在处理将当前请求放入DPC的传入IOCTL请求的函数中

        registerEvent->DueTime.QuadPart = -30;
        KeInitializeDpc(&notifyRecord->Dpc, // Dpc
                        CustomTimerDPC,     // DeferredRoutine
                        notifyRecord        // DeferredContext
                       );
        KeAcquireSpinLock(&deviceExtension->QueueLock, &oldIrql);
    
        InsertTailList(&deviceExtension->EventQueueHead,
                       &notifyRecord->ListEntry);
    
        KeReleaseSpinLock(&deviceExtension->QueueLock, oldIrql);
        // check. Arp cache changed or not since last time.
        // timer: 0 = delay
        if(IsARPCacheModified()){
    //if ARP cache is modified, it will return true and end up here.
            DbgPrint("ARP Cache modified. Signal.");
            // due time is -30. is it relative 30*100ns = 3 secs?
        } else{
    // if ARP Cache is not modified, it will end up here.
            registerEvent->DueTime.QuadPart = -1000;
        }
         KeSetTimer(&notifyRecord->Timer,   // Timer
                        registerEvent->DueTime, // DueTime
                        &notifyRecord->Dpc      // Dpc
                  );
        return STATUS_SUCCESS;
    

    现在,发生的事情是来自用户空间客户端应用程序的第一个请求有时会成功,但后续请求会导致错误。

    在调试时,我发现它指向我添加的代码,即if else和KeSetTimer()调用。和错误与IRQL不相关或相等。

    我不知道如何做到这一点以及发生了什么事。代码在其他任何地方都不会崩溃,但仅限于此功能。

    感谢。

1 个答案:

答案 0 :(得分:0)

听起来您需要在将新项目添加到数据队列时通知usermode。这是一个普遍的需求,普遍接受的解决方案被称为"倒置呼叫" 模型。我认为这是您列表中的选项#2。在网上搜索"倒置呼叫"了解这是什么以及如何使用它。

至于您所看到的崩溃 - 我不知道您的代码使用计时器或DPC的原因。你应该能够在没有定时器或DPC的情况下完成这项工作。

请注意,DueTime.QuadPart以100 nano 秒为单位进行测量,因此相对时间-30表示3 micro 秒。

我建议你摆脱计时器并执行倒置呼叫。如果您真的希望有人帮助您解决计时器中的崩溃问题,您应该:

  1. 在您的驱动程序上启用驱动程序验证程序,然后重试。 Verifier通常会提供更好的错误消息。
  2. 如果您尝试过验证程序并且它仍然没有意义,请发布"!analyze -v"的输出。加载适当的符号。包含代码的相关部分。 (例如,notifyRecord分配在哪里?CustomTimerDPC会发生什么?)