ProtocolTransferDataComplete

VOID
   ProtocolTransferDataComplete(

       IN NDIS_HANDLE ProtocolBindingContext,
       IN PNDIS_PACKET Packet,
       IN NDIS_STATUS Status,
       IN UINT BytesTransferred
       );

ProtocolTransferDataComplete is a required driver function if the protocol might bind itself to an underlying NIC driver that does not indicate full-packet receives with NdisMIndicateReceivePacket. ProtocolTransferDataComplete completes the processing of a protocol-initiated transfer-data request for which NdisTransferData returned NDIS_STATUS_PENDING.

Parameters

ProtocolBindingContext

Specifies the handle to a protocol-allocated context area in which the protocol driver maintains per-binding runtime state. The driver supplied this handle when it called NdisOpenAdapter

Packet

Points to the protocol-allocated packet descriptor the driver originally passed to NdisTransferData.

Status

Specifies the final status of the transfer-data operation.

BytesTransferred

Specifies the number of bytes of data that the NIC driver transferred into the buffers mapped by buffer descriptors chained to the packet descriptor at Packet. The protocol uses this value to determine whether the miniport supplied all the requested data for the originally indicated network packet.

Comments

ProtocolTransferDataComplete can be called before NdisTransferData returns control. If this occurs, the protocol driver has no opportunity to inspect the status code that NdisTransferData returns at Status. The protocol must assume that the given packet descriptor at Packet was pending until ProtocolTransferDataComplete was called.

When the underlying NIC driver calls NdisMTransferDataComplete, NDIS forwards the miniport-supplied Packet pointer and Status value to ProtocolTransferDataComplete. When this occurs, the protocol regains ownership of the resources it allocated for a preceding call to NdisTransferData. ProtocolTransferDataComplete can postprocess the miniport-supplied data in the buffers the protocol chained to the packet descriptor at Packet, along with the data ProtocolReceive copied in the corresponding indication. Then, ProtocolTransferDataComplete can notify interested clients of the received network data.

ProtocolTransferDataComplete also can either release the resources that the protocol allocated for its call to NdisTransferData or prepare the returned buffer and packet descriptors for reuse in a subsequent call to NdisTransferData. As a general rule, reusing such resources yields better performance than releasing them except, possibly, in periods of low network traffic if the protocol previously allocated a surplus of these resources to handle a period of heavy I/O demand.

To prepare the buffer and packet descriptors for reuse, ProtocolTransferDataComplete should follow these guidelines:

·Always call an NdisUnchainBufferAtXxx function as many times as necessary to save the buffer descriptor pointers before ProtocolTransferDataComplete calls NdisReinitializePacket with the descriptor at Packet.

Otherwise, NdisReinitializePacket sets the head of the buffer chain to NULL so the protocol cannot recover pointers to the buffer descriptors chained to the packet descriptor. In effect, the protocol loses a set of buffer descriptors that the protocol allocated with NdisAllocateBuffer, and possibly loses access to the protocol-allocated buffers mapped by these descriptors as well.

·Never call NdisZeroMemory with a pointer to a packet descriptor. Use NdisReinitializePacket instead.

Otherwise, NdisZeroMemory destroys the packet descriptor the protocol allocated with NdisAllocatePacket, rendering it unusable for specifying subsequent data transfers and sends.

The ProtocolTransferDataComplete function of an NDIS intermediate driver cannot simply forward completion indications to still higher-level protocols. Such an attempt can cause a deadlock. Instead, such a driver must call NdisIMSwitchToMiniport to forward the indication from the appropriate context. If NdisIMSwitchToMiniport returns FALSE, the driver must call NdisIMQueueMiniportCallback and forward the indication from the protocol-supplied MiniportCallback function.

By default, ProtocolTransferDataComplete runs at IRQL DISPATCH_LEVEL in an arbitrary thread context.

See Also

MiniportTransferData, NdisAllocateBuffer, NdisFreeBuffer, NdisFreeMemory, NdisFreePacket, NdisIMQueueMiniportCallback, NdisIMSwitchToMiniport, NdisMIndicateReceivePacket, NdisMTransferDataComplete, NdisReinitializePacket, NdisTransferData, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront, NdisZeroMemory, ProtocolReceive, ProtocolReceivePacket