Security Descryptor

Thanks. Mr. Bond.

UINT nEventSend = 0;
 while (1) {
        UINT nEvtSnd = nEventSend & MASKA;
        res = WaitForSingleObject(hEventSend[nEvtSnd], INFINITE);
        switch (res) {
//        case WAIT_ABANDONED: std::cout << "WaitForSingleObjects returns  WAIT_ABANDONED " << std::endl; return -1;
        case WAIT_FAILED: std::cout << "WaitForSingleObjects returns  WAIT_FAILED " << GetLastError() << std::endl; return -1;
//because  of INFINITE parameter   can not be   
//case WAIT_TIMEOUT: std::cout << "WaitForSingleObjects returns  WAIT_TIMEOUT Error: Look to driver code" << std::endl;  return -1;
        case WAIT_OBJECT_0:
            CallConvert(BufferSend[nEvtSnd], nEvtSnd);  //its my program to alter the BufferSend[nEvtSnd]
            ResetEvent(hEventSend[nEvtSnd]);
            if (DeviceIoControl(hDevice, IOCTL_NETBUFFER_SEND, inBuffer, inBufLength, BufferSend[nEvtSnd], BUFFER_SIZE, &junk, &OverlappedSend[nEvtSnd])) {
                std::cout << "DeviceIoControl Direct returns" << std::endl;
                SetEvent(hEventSend[nEvtSnd]);
            }
            else {
                switch (GetLastError()) {
                case ERROR_IO_PENDING:
                    break;
                default:
                    std::cout << "DeviceIoControl default Error" << std::endl;
                    return -1;
                }
            }
            nEventSend++;
            break;
        default:
            std::cout << "WaitForSingleObject default Error" << std::endl;
            return -1;
        }
    }

Where to put GetOverlappedResult. It is working fine without GetOverlappedResult.

As the first thing in the “WAIT_OBJECT_0” case. As we’ve said before, if you don’t do that, you don’t know if the request actually succeeded.

Thank You very much. Mr. Tim_Robers. I will think about it.

Mr Tim_Robers. I finished the driver. It works well. But there is a nuance. Installs fine.
Change adapter settings->Ethernet->Properties->Install->Service->choose my driver
But when I try to uninstall the driver it hangs. How to understand why? Maybe I let some garbage in (not freed memory or not completed Irp. I don’t know). Please help me understand. What tools should I use to find out what the problem is

And the second question. As I said, I’ve been getting DPC_WATCHDOG_VIOLATION when using NdisFSendNetBufferLists() in a driver dispatch routine (a single DPC or ISR has exceeded its time limit. The offending component can usually be identified with a stack trace).
After I raised Irql before NdisFSendNetBufferLists() and lowered it after it in the dispatch procedure(level 0). And the problem is gone. Is this a good decision. Thank you

In my program, two times I make large copies. One from the outgoing payload buffer to the IRP buffer, and the second from the IRP buffer to the outgoing payload buffer. whether to think about DMA. Can I use DMA instead of NdisMoveMemory()?

But when I try to uninstall the driver it hangs.

Is the driver still in use when it hangs? Have you run this in a debugger to find out what’s going on?

After I raised Irql before NdisFSendNetBufferLists() and lowered it after it in the dispatch procedure(

The average driver should not be dinking with IRQLs at all. Why do you have to be at dispatch? Is it strictly for using spin locks? Perhaps you should use some other kind of synchronization. A watchdog violation can only happen if you spend too much time at an elevated IRQL.

Can I use DMA instead of NdisMoveMemory?

Not for memory-to-memory moves. DMA refers to having a PCI or PCIe device do the transfers.

(Pedants will note that there now IS a system DMA facility available on some chipsets. I discount that, because (a) it’s not available on most computers, and (b) it is a limited resource and therefore cannot be relied on.)

  1. I’m just learning The Windbg. No, the driver is not running.
  2. I clone all NetBufferLists in FilterSendNetBufferLists, queue them up, and send the payload to the user via a pending IRP. In the send procedure, I receive a payload with already converted data from the user, attach it to NetBufferLists from the queue, and send it to the NIC (NdisFSendNetBufferLists). I’m implementing a mutual access to the problematic data between the dispatch routine(xxxDeviceIoControl) (level 0) and the FilterSendNetBufferLists (level 2) routine by raising an Irql in the dispatch routine and using a spinlock.
xxxDeviceIoControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
.....
......
case IOCTL_NETBUFFER_SEND:
................
................
KIRKL OldIrql;
KeRaiseIrql(2, &OldIrql);
NdisFSendNetBufferLists(pFilter->FilterHandle, pNBL, NDIS_DEFAULT_PORT_NUMBER, SendFlags);
KeLowerIrql(OldIrql);
................
................
KIRQL OldIrql;
KeRaiseIrql(2, &OldIrql);
FILTER_ACQUIRE_LOCK(&pFilter->Lock, TRUE);
pFilter->IrpSpForSend[nSend] = IrpSp; //////////////???????????????
pFilter->pIrpSend[nSend] = Irp;
pFilter->HeadIrpSend++;
FILTER_RELEASE_LOCK(&pFilter->Lock, TRUE);
KeLowerIrql(OldIrql);
..................
...................
}

Thank you Mr. Tim_Roberts.

Well, that’s simply not right. There are essentially NO scenarios in which a driver should call KeRaiseIrql or KeLowerIrql. FILTER_ACQUIRE_LOCK will raise the IRQL for you, if it’s not there already, but there’s no reason why you should need to when you call NdisFSendNetBufferLists. The right answer is to figure out where your crashes are coming from, not randomly patch them.

Well. Thank You Mr. Tim_Roberts.

you should call GetOverlappedResult in your switch case statement in the WAIT_OBJECT_0 case. Or possibly the CallConvert function

KeRaiseIrql may appear to solve your problem, but likely it just masks an underlying problem

Yes. Thank You Mr. MBond2

Mr Mbond2. I took a close look at WaitForSingleObject and GetOverlappedResult. I think they are the same and when you use WaitForSingleObject there is no need to use GetOverlappedResult. I’m sorry, but if I’m wrong, please explain why you should use GetOverlappedResult.
And second.
You say “Or perhaps the CallConvert KeRaiseIrql function could solve your problem, but it’s more likely just masking the underlying problem.”
The xxxDeviceIoControl function is a driver dispatch function, but CallConvert is in a user mode program. They are not related to each other. And in this program I have no problems. My question was about KeRaiseIrql but Mr. Tim_Roberts explained to me.
Thank You.

please explain why you should use GetOverlappedResult.

Because if you don’t, you have no way of knowing whether the request succeeded or failed. It is the the same as calling an API and ignoring its result.

you should call GetOverlappedResult or inspect the now documented members of the OVERLAPPED struct to determine the result of your request

Thanks

Mr. Tim_Roberts and Mr. MBond2. What do you think. Will writing the driver in assembly language (instead of C) will increase the performance?. In 1995 we compared and got about 1.5 (Turbo C and assembler).
Now on my computer I have about 27 for upload and the same for download without my driver. When I push my filter driver into the network stack it is 26.26. It’s good or try to write on assembler.

No. Optimizing compilers have improved to the point that they can outperform all but the most elite assembler experts. I consider myself to be an expert, but I haven’t written an assembler module in more than a decade.

if your code is expected to run on one specific hardware configuration, and you have a LOT of time on your hands, you might be able to hand craft assembly code that out performs the MSVC emitted code. But you need both the certainty of the hardware platform and the sublime skill of a savant to do better. And even if you do, it will not represent an order of magnitude gain, but at most a few percentage points

Certianty of hardware is a VERY important factor. Hardly anyone ever has this. Aerospace and medical applications might, but any commodity hardware never does. And the averages built into optimizers are usually better than hand crafted solutions - especially since the hardware guys optimize the hardware for the commonly emitted patterns

Thank You Mr. Tim_Roberts and Mr. MBond2. I’ve stopped thinking about writing a driver in a lower level language and will try to write a driver for a USB “data converter” to call it from the NDIS Filter driver, instead of sending the data to the user mode and calling the convert function on the USB device there. I think, it will increase performance significantly.