Implementing a ProtocolReceive Handler in a Protocol Driver (NDIS 5.1)
Note NDIS 5. x has been deprecated and is superseded by NDIS 6. x. For new NDIS driver development, see Network Drivers Starting with Windows Vista. For information about porting NDIS 5. x drivers to NDIS 6. x, see Porting NDIS 5.x Drivers to NDIS 6.0.
If the underlying connectionless miniport driver calls a filter-specific NdisMXxxIndicateReceive function, NDIS always calls the ProtocolReceive function of each bound protocol driver.
If one or more of such a protocol driver's clients are a target of the packet, and the lookahead buffer size is less than the total packet size, ProtocolReceive must do the following:
Copy the lookahead data into an internal buffer mapped by a protocol-allocated packet descriptor.
Chain buffer descriptors to a protocol-allocated packet descriptor. The driver should map a sufficient number of protocol-allocated buffers to contain the rest of the network packet data.
Call NdisTransferData with the packet descriptor, so the underlying driver copies the rest of the received data into the protocol driver's buffers.
When NdisTransferData returns STATUS_SUCCESS or NDIS calls the ProtocolTransferDataComplete function, the protocol driver can chain the lookahead buffer to the packet descriptor containing this transferred data and indicate it up to clients.
NdisTransferDatacan only be called once for each receive indication and it must be called within the context of the call to ProtocolReceive. The protocol driver must set up its packet descriptor with chained buffers of a sufficient size to contain the full network packet.
The size of the lookahead buffer passed to ProtocolReceive is greater than or equal to the lookahead size returned by an OID_GEN_CURRENT_LOOKAHEAD query plus the size of the MAC header. However, if the total size of the packet (including the MAC header size) is less than this value, the lookahead buffer size is the size of the packet. All data in the lookahead buffer is read-only to ProtocolReceive.
If the lookahead buffer size is less than or equal to the size of the total packet indicated by a filter-specific NdisMXxxIndicateReceive function, ProtocolReceive should call NdisTransferData to copy the lookahead data into an internal buffer.
If the call to ProtocolReceive occurred because the underlying miniport driver set the status for one or more packets in a packet array to NDIS_STATUS_RESOURCES before calling NdisMIndicateReceivePacket, the size of the lookahead buffer will always be equal to the size of the full network packet minus the MAC header size. In these circumstances, the protocol driver should never call NdisTransferDatabecause ProtocolReceivecan copy the full indication into an internal buffer immediately.
If the NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA bit is set in response to an OID_GEN_MAC_OPTIONS request, a protocol driver can use any means to copy lookahead data into an internal buffer, such as calling NdisMoveMemory. If this flag was not set, the protocol driver mustcall NdisCopyLookaheadData to copy the indicated data; otherwise, the results from a copy operation are indeterminate.
ProtocolReceivemust execute as quickly as possible. The protocol driver must ensure that it has protocol-allocated packet resources available before it receives incoming indications. After the protocol driver examines the packet and determines that it will not copy the packet, ProtocolReceiveshould simply return NDIS_STATUS_NOT_ACCEPTED.
ProtocolReceive must not process the received data as soon as it is copied since that would adversely impact system performance, as well as possibly causing dropped receives in the underlying miniport driver. Instead, the protocol driver processes the received data later in its ProtocolReceiveComplete function. NDIS calls ProtocolReceiveComplete after the underlying miniport driver calls NdisMXxxIndicateReceiveComplete. Typically, this occurs when the underlying miniport driver has received and indicated a miniport-determined number of packets. This can also occur before the underlying miniport driver exits its receive handler. The protocol driver must queue the received data in ProtocolReceiveso that it is available to ProtocolReceiveCompletefor postprocessing.