I made a protocol driver based on the 6.0 Connectionless example. It works perfectly as a demand start service, however, when I set it to autostart I do not receive any packets.
The pnp events are still happening, the binding, the querying, but i do not receive any net buffer lists. I did check that the OID_SET_PACKET_FILTER returned successfully.
Any help would be appreciated!!
You’re lacking a lot of details that would make helping easier but let’s start simple. After the reboot, are all of your other components in place and running (i.e. usermode service, actual network connection, etc)?
So what happens if you restart your driver service?
Does it start working again?
During startup, the stack pauses and restarts frequently as other elements
like filters are inserted. Since starting your driver when the system has
stabilized probably avoids your protocol edge from seeing pause/restart, I
would look at that first. You may well not be handling the restart
correctly and so whatever you thought you did (eons ago when you got bound
the first time) might no longer be relevant by the time the last resume
occurs and the binding path is *actually* completed.
Good Luck,
Dave Cattley
Thanks for the replies gentlemen!
I took a deeper look at what happens on the booting with the driver configured as autostart.
There are two situations:
-
The driver was started and is found at paused state. In this case if I restart the service it works correctly. In this case I do receive packets and driver works as it should, only issue is it is found at paused state and I have to restart the service to get it to running state.
-
The driver was started and is not found at paused state. In this case restarting the service does not resolve the problem. In this case I do not receive any packets. The packet filter is set, I can query the bindings, do IOCTLs and all, but no packets are received.
Most of the times after boot I get the second situation.
A question though… I might be wrong, but I feel that the stack pauses on startup and does not get to restart until I stop my service in situation one. Is this correct? Can I force the stack restart via an IOCTL or something like that without restarting the service?
I am working with NDIS 6.0 and above, and I only found the NdisRestart() function to do this, but it is deprecated after NDIS 5.X.
Yes, my components seem to be in place and running after reboot. Used the sc qc and sc query to check and the driver is already running once system is booted.
The code which threats the NDIS restart is the same as the sample from Microsoft “Connection-less NDIS 6.0 Sample Protocol Driver”. It just takes the new attributes such as MacOptions and MaxFrameSize.
What do I need to take care of here? Do I need to shutdown the bindings and restart them?
VOID
ndisprotRestart(
IN PNDISPROT_OPEN_CONTEXT pOpenContext,
IN PNDIS_PROTOCOL_RESTART_PARAMETERS RestartParameters
)
/*++
Routine Description:
Handle restart attributes changes.
Arguments:
pOpenContext - pointer to open context
RestartParameters - pointer to ndis restart parameters
Return Value:
None
NOTE: Protocols should query any attribute:
- the attribute is not included in the RestartAttributes
and 2. The protocol cares about whether the attributes is changed by underlying driver.
–*/
{
ULONG Length;
ULONG TotalLength = 0;
PUCHAR Buffer;
ULONG BufferLength;
#define NPROT_MAX_FILTER_NAME_LENGTH 128
WCHAR FilterNameBuffer[NPROT_MAX_FILTER_NAME_LENGTH];
PNDIS_RESTART_ATTRIBUTES NdisRestartAttributes;
PNDIS_RESTART_GENERAL_ATTRIBUTES NdisGeneralAttributes;
DEBUGP(DL_DRIVER_LOAD, (“---->NDIS Protocol: Restart\r\n”));
DEBUGP(DL_DRIVER_LOAD, (" Restart: Open %p\n", pOpenContext));
#ifdef THREAD_PRIORITY
DEBUGP(DL_THREAD_PRIORITY, (" Restart: "));
GetThreadPriority();
#endif
//
// Check the filter stack changes
//
if (RestartParameters->FilterModuleNameBuffer != NULL)
{
Buffer = RestartParameters->FilterModuleNameBuffer;
while (RestartParameters->FilterModuleNameBufferLength > TotalLength)
{
BufferLength = *(PUSHORT)Buffer;
Length = BufferLength + sizeof(USHORT);
TotalLength += Length;
if (BufferLength >= (NPROT_MAX_FILTER_NAME_LENGTH * sizeof(WCHAR)))
{
BufferLength = (NPROT_MAX_FILTER_NAME_LENGTH - 1) * sizeof(WCHAR);
}
NdisMoveMemory(FilterNameBuffer, Buffer + sizeof(USHORT), BufferLength);
BufferLength /= sizeof(WCHAR);
//
// BufferLength is bounded by the check above. Check again to suppress
// prefast warning
//
if (BufferLength < NPROT_MAX_FILTER_NAME_LENGTH)
{
FilterNameBuffer[BufferLength] = 0;
}
DEBUGP(DL_DRIVER_LOAD, (" Restart: Filter: %ws\n", FilterNameBuffer));
Buffer += Length;
}
}
//
// Checked for updated attributes
//
NdisRestartAttributes = RestartParameters->RestartAttributes;
//
// NdisProt is only interested in the generic attributes.
//
while (NdisRestartAttributes != NULL)
{
if (NdisRestartAttributes->Oid == OID_GEN_MINIPORT_RESTART_ATTRIBUTES)
{
break;
}
NdisRestartAttributes = NdisRestartAttributes->Next;
}
//
// Pick up the new attributes of interest
//
if (NdisRestartAttributes != NULL)
{
NdisGeneralAttributes = (PNDIS_RESTART_GENERAL_ATTRIBUTES)NdisRestartAttributes->Data;
pOpenContext->MacOptions = NdisGeneralAttributes->MacOptions;
pOpenContext->MaxFrameSize = NdisGeneralAttributes->MtuSize;
}
DEBUGP(DL_DRIVER_LOAD, (" Restart: Open %p\n", pOpenContext));
DEBUGP(DL_DRIVER_LOAD, (“<----NDIS Protocol: Restart\r\n”));
}