0
votes

Starting with the ndisprot sample from Microsoft I try to write a NDIS protocol driver. From User space I try to read and write to the device simultaneous (out of two threads). Since I don't receive any packets, the ReadFile system call blocks. I'm not able to complete a WriteFile system call in this state.

CHAR            NdisProtDevice[] = "\\\\.\\\\NDISprot";
CHAR *          pNdisProtDevice = &NdisProtDevice[0];

this.iHandle = CreateFile(pNdisProtDevice,
            GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

// Blocks, because no frames arrive

bSuccess = (BOOLEAN)ReadFile(Handle,
                             (LPVOID)pReadBuf,
                             PacketLength,
                             &BytesRead,
                             NULL);

...
// Called some seconds later from another thread, while ReadFile still blocking...
bSuccess = (BOOLEAN)WriteFile(Handle,
                              pWriteBuf,
                              PacketLength,
                              &BytesWritten,
                              NULL); 

I added some debug messages and discovered that the driver function associated with IRP_MJ_WRITE (NdisprotWrite) gets not even called! Something between the user space application and the driver blocks concurrent access to the device \Device\NDISprot.

How can I concurrent Read and Write to the file?

1
If ReadFile isn't called until several seconds after WriteFile, how can it be responsible for the write blocking? - Harry Johnston
Because the ReadFile is still blocking... As soon as I send a packet to that machine, ReadFile succeed, and WriteFile is immediately executed... - falstaff
Improved code comment - falstaff
I've some interesting findings: The NdisprotRead function (which is bound to IRP_MJ_READ) returns STATUS_PENDING. The IoCompleteRequest, which will complete this IO request is executed later when a new Network frame arrive. The question remains: How can use the WriteFile system call while the driver is in Pending state? Is there a way to make the File read and writeable synchronously? Or do I need to add another File (e.g. one for Reads, one for Writes)? - falstaff
Your code now says that ReadFile is called while ReadFile is still blocking. Are you making two calls to ReadFile? What is the actual order of events? Have you tried opening two handles, one for reading and one for writing? - Harry Johnston

1 Answers

2
votes

By default, you can only have one outstanding I/O request per usermode handle. Either open multiple handles, or open your one handle with FILE_FLAG_OVERLAPPED. (Once you use FILE_FLAG_OVERLAPPED, you also generally need to use OVERLAPPED structures - make sure you've got the gist of it by skimming this and this.)