Hello.
This is my first excursion into both Windows development and Windows drivers.
I use the Microsoft example for NDIS protocol driver (ndisprot630).
Reading and writing ethernet frames with synchronous I/O has not shown any problems.
But what I’m using the driver for needs non-blocking read/write. I only send one frame and receive one frame over and over again so I’ve decided to use asynchronous I/O with callbacks.
This is what I have:
static
VOID
reset_overlap(LPOVERLAPPED lpOverlapped)
{
if (lpOverlapped->hEvent == NULL)
{
lpOverlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (lpOverlapped->hEvent == NULL)
{
DEBUGP("Couldn't create event\n");
}
}
else
{
ResetEvent(lpOverlapped->hEvent);
}
lpOverlapped->Internal = 0;
lpOverlapped->InternalHigh = 0;
lpOverlapped->Offset = 0;
lpOverlapped->OffsetHigh = 0;
}
static
VOID
CALLBACK
read_callback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
{
if (dwErrorCode != 0)
{
DEBUGP("read cb %lu\n", dwErrorCode);
}
if (dwNumberOfBytesTransfered == 0)
{
DEBUGP("read cb len %lu\n", dwNumberOfBytesTransfered);
}
reset_overlap(&ReadOverlap);
ReadBufferReadBytes = dwNumberOfBytesTransfered;
OverlapReadStarted = FALSE;
}
INT
read_async(
HANDLE Handle,
LPVOID Data,
UINT DataLen
)
{
INT retval = 0;
DWORD status = WaitForSingleObjectEx(Handle, 0, TRUE);
if ((status != WAIT_IO_COMPLETION) && (status != WAIT_TIMEOUT))
{
DEBUGP("Async read wait status %lu %lu %u %u %llu %llu\n", status, GetLastError(), ReadBufferReadBytes, OverlapReadStarted,
ReadOverlap.Internal,
ReadOverlap.InternalHigh);
}
if (ReadBufferReadBytes > 0)
{
memcpy(Data, ReadBuffer, ReadBufferReadBytes);
retval = ReadBufferReadBytes;
ReadBufferReadBytes = 0;
}
if (!OverlapReadStarted)
{
// DEBUGP("Async read starting %lu\n", status);
if (!ReadFileEx(Handle, ReadBuffer, MAX_PACKET_LEN, &ReadOverlap, read_callback))
{
DEBUGP("ReadFileEx error %lu\n", GetLastError());
}
else
{
DWORD error = GetLastError();
if (error != ERROR_SUCCESS)
{
DEBUGP("ReadFileEx ok %lu\n", error);
}
OverlapReadStarted = TRUE;
}
}
return retval;
}
This works for some frames but eventually I get stuck with an incoming frame that is not read and the completion routine isn’t called. I also get lots of these debug messages
LIB DEBUG: Async read wait status 0 0 0 1 0 0
Handle signaled state is something that changes from when it’s working but I can’t figure out why and how to get out of it.
ReadFileEx() call does not generate any debug-prints.
Adding more debug-prints seem to help in it working for longer.
So any problems or hints on how this should be done would be greatly appreciated.