I took the sample ndislwf 6.0 sample and made some changes like putting unique-incoming ARP packets in a linked list. I can fetch all of the data from user space via IOCTL command. This much is fine.
Now, I want to have a running application; and as soon as my driver receives an ARP packet, it should send some notification or signal to the client application. Client application then will issue another request which will fetch latest data.
I found three methods:
- Have an event and wait for it in client application
- Have an pending IRP, and
- Use named pipe.
I implemented first one by copying ..winddk...\src\general\event project's implementation verbatim.
now, since I am not using a timer, I am confused. Problem is this:
Event and waiting for it, requires IOCTL command. ARP cache is updated as new ARP packet reaches and added to the list. Only when it is added to the list, I need to signal. But this is interrupt based.
So, how do I combine these two so that on interrupt from NDIS, I notify client application.
I did this:
in the function where I am handling incoming IOCTL request that puts current request in DPC
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;
Now, what's happening is that first request from user space client application sometimes succeeds but subsequent requests result in error.
While debugging, I found that it is pointing to my code that I have added, i.e. if else and KeSetTimer() call. and error is related to IRQL being not less or equal.
I have no clue, how to do this and what's crashing. Code doesn't crash anywhere else, but in this function only.
Thanks.