Security Descryptor

I created 4 events for DeviceIoControl() and wait for it with WaitForMultipleObjects() function.
But this last function does not return. It remains in the non-signaled state. I read that when calling CreateEventA () you need to assign the access right “SYNCHRONIZE”.
Can anyone help me how to assign the “SYNCHRONIZE” access right to the CreateEventA() security descriptor.
And the second question.
Do I need to call GetOverlappedResult() after WaitForMultipleObjects()

There is not nearly enough information here. So, you created 4 events. Did you then store those events in 4 OVERLAPPED structures, and submit 4 DeviceIoControl calls using those structures? Did you open the file with FILE_FLAG_OVERLAPPED? What does the WaitForMultipleObjects call look like? Are these calls going to your own driver? You’re sure the requests are being completed?

Check the documentation. CreateEvent, by default, uses EVENT_ALL_ACCESS access rights, which includes SYNCHRONIZE.

Yes, after WFMO returns, you must call GetOverlappedResult. Otherwise, you have no idea whether the request succeeded or failed.

Thank you. Yes, everything you said, I did, and it works correctly. Yes indeed SYNCHRONIZATION was assigned by default. As for GetOverlappedResult, the program works without it. I can not understand why, but I’ll add it. WaitForMultipleObjects returns, when one or more events are signaled. And after it, when I check output buffer from overlapped DeviceIoControl, it is correct. How can I understand, WaitForMultipleObjects and GetOverlappedResult functions are for the same purpose.

Yes, it works without GetOverlappedResult, but without it, you don’t know whether the requests succeeded or not. That’s not very good practice.

OK.

The GetOverlappedResult function exists to extract values from the Internal and InternalHigh members of the OVERLAPPED struct. The usage of these members has become so well know, that Microsoft have even documented them so that they can be used directly. But it is still appropriate to use GetOverlappedResult because there is no reason not to do it properly

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.