我获取了示例 ndislwf 6.0 示例并进行了一些更改,例如将唯一传入的 ARP 数据包放入链接列表中。我可以通过 IOCTL 命令从用户空间获取所有数据。这么多就好了。
现在,我想要一个正在运行的应用程序;一旦我的驱动程序收到一个 ARP 数据包,它应该向客户端应用程序发送一些通知或信号。然后客户端应用程序将发出另一个请求,该请求将获取最新数据。
我找到了三种方法:
- 有一个事件并在客户端应用程序中等待它
- 有一个待处理的 IRP,并且
- 使用命名管道。
我通过逐字复制 ..winddk...\src\general\event 项目的实现来实现第一个。
现在,因为我没有使用计时器,所以我很困惑。问题是这样的:
事件并等待它,需要 IOCTL 命令。ARP 缓存随着新的 ARP 数据包到达并添加到列表中而更新。只有当它被添加到列表中时,我才需要发出信号。但这是基于中断的。
那么,如何将这两者结合起来,以便在来自 NDIS 的中断时通知客户端应用程序。
我这样做了:
在我正在处理将当前请求放入 DPC 的传入 IOCTL 请求的函数中
registerEvent->DueTime.QuadPart = -30;
KeInitializeDpc(¬ifyRecord->Dpc, // Dpc
CustomTimerDPC, // DeferredRoutine
notifyRecord // DeferredContext
);
KeAcquireSpinLock(&deviceExtension->QueueLock, &oldIrql);
InsertTailList(&deviceExtension->EventQueueHead,
¬ifyRecord->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(¬ifyRecord->Timer, // Timer
registerEvent->DueTime, // DueTime
¬ifyRecord->Dpc // Dpc
);
return STATUS_SUCCESS;
现在,发生的情况是来自用户空间客户端应用程序的第一个请求有时会成功,但后续请求会导致错误。
在调试时,我发现它指向我添加的代码,即 if else 和 KeSetTimer() 调用。并且错误与 IRQL 不小于或等于有关。
我不知道如何做到这一点以及发生了什么崩溃。代码不会在其他任何地方崩溃,但仅在此函数中。
谢谢。