INT
ProtocolReceivePacket(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet
);
ProtocolReceivePacket is an optional driver function that processes receive indications made by underlying driver(s) that call NdisMIndicateReceivePacket either with packet arrays because the underlying driver supports multipacket receive indications or with individual packets that have associated out-of-band information.
Any protocol driver that might bind itself to an underlying NIC driver that supports multipacket receive indications should have a ProtocolReceivePacket function. Such an underlying driver always indicates full-packet receives.
A protocol can achieve better performance if it has a ProtocolReceivePacket function. Such a protocol (or the TDI clients of a highest level protocol) can hold on to all received data, to which it is given read-only access, specified at Packet if ProtocolReceivePacket returns a nonzero value. For a highest level protocol driver, the return value for such an input Packet descriptor pointer can be a reference count of clients the protocol has notified about the received net packet by forwarding the input Packet descriptor. For an intermediate NDIS driver, the return value can be a count of higher level protocols to which it has made a corresponding indication or one if the driver tracks the number of higher level protocols to which it forwards the processed indication. For a highest level protocol that forwards the input Packet descriptor pointer to some number of interested clients, each client retains read-only access to the indicated data until the client calls TdiReturnChainedReceives. An intermediate NDIS driver retains ownership of the indicated packet until it calls NdisReturnPackets with Packet as many times as the reference count returned by ProtocolReceivePacket.
ProtocolReceivePacket cannot call NdisReturnPackets. The protocol must pass the input Packet pointer to NdisReturnPackets after ProtocolReceivePacket returns control. Consequently, ProtocolReceivePacket should save the input Packet pointer in the ProtocolBindingContext area when it will return a nonzero value. The NDIS library maintains the reference count for such an indicated packet, and the protocol retains ownership of the packet until it has called NdisReturnPackets with that packet as many times as the value returned by its ProtocolReceivePacket function.
ProtocolReceivePacket returns zero to relinquish ownership of the given Packet if the protocol has no current clients or bound higher level protocols interested in the indicated network packet or if the ProtocolReceivePacket function copies the data from the given packet and associated out-of-band block, if any, to protocol-allocated storage itself. When ProtocolReceivePacket returns zero, NDIS either calls another bound protocol with the receive indication or returns the given packet descriptor at Packet to the miniport that made the indication.
Any protocol that binds itself to an underlying driver that supplies out-of-band information for receives must have a ProtocolReceivePacket function to interpret the miniport-supplied out-of-band information when processing receive indications. Such a protocol can retrieve the associated out-of-band information for the given Packet with the appropriate NDIS_GET_PACKET_XXX macro(s).
The ProtocolReceivePacket function of an NDIS intermediate driver cannot simply forward received indications to still higher-level protocols. Such an attempt can cause a deadlock. Instead, such a driver must repackage the indication in a fresh packet descriptor and call NdisIMSwitchToMiniport to forward the indication from the appropriate context. If NdisIMSwitchToMiniport returns FALSE, the driver must call NdisIMQueueMiniportCallback and forward the indication from a protocol-supplied MiniportCallback function.
By default, ProtocolReceivePacket runs at IRQL DISPATCH_LEVEL in an arbitrary thread context.
NdisAllocatePacket, NDIS_GET_PACKET_HEADER_SIZE, NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO, NDIS_GET_PACKET_TIME_RECEIVED, NDIS_GET_PACKET_TIME_SENT, NdisIMQueueMiniportCallback, NdisIMSwitchToMiniport, NdisMIndicateReceivePacket, NDIS_PACKET, NDIS_PACKET_OOB_DATA, NdisReturnPackets, ProtocolReceive, TdiReturnChainedReceives