NTSTATUS
ClientEventChainedReceive(
IN PVOID TdiEventContext,
IN CONNECTION_CONTEXT ConnectionContext,
IN ULONG ReceiveFlags,
IN ULONG ReceiveLength,
IN ULONG StartingOffset,
IN PMDL Tsdu,
IN PVOID TsduDescriptor
);
ClientEventChainedReceive is an event handler that the underlying TDI transport calls in response to an incoming receive from a remote node with which the client has an established endpoint-to-endpoint connection.
The transport calls this handler, rather than ClientEventReceive, when it is indicating a full TSDU and the client can be given direct read-only access to the buffered TSDU until the client has consumed the data.
ClientEventChainedReceive can return one of the following:
If the underlying transport buffers receives internally, the client might retrieve the data with a TDI_RECEIVE request, unless the transport discards buffered data indicated to ClientEventChainedReceive(Xxx) handlers.
A call to ClientEventChainedReceive gives the client read-only access to the indicated TSDU for the range within the buffer specified by the input StartingOffset and ReceiveLength. If the indicated data is of interest to the client, ClientEventChainedReceive either copies the indicated range of TSDU data into a client-allocated internal buffer and returns STATUS_SUCCESS immediately or retains control of the buffer by returning STATUS_PENDING. If it returns STATUS_PENDING, the client must call TdiReturnChainedReceives subsequently with the input TsduDescriptor to relinquish control of the buffer after the client has consumed the data.
In general, such a call to TdiReturnChainedReceives should occur as quickly as possible. Holding on to a buffer passed to ClientEventChainedReceive for any extended period constrains I/O throughput in underlying driver(s), because the driver that allocated the buffer cannot reuse this resource for subsequent receive indications until TdiReturnChainedReceives is called.
Because calls to ClientEventChainedReceive always indicate the availability of a full TSDU, the client never has to set up TDI_RECEIVE requests for such an indication, as the corresponding ClientEventReceive handler sometimes must to obtain a full TSDU. Consequently, receive indications made to ClientEventChainedReceive increase network I/O throughput and performance by decreasing call overhead for the client, for its underlying transport, and for the system overall.
If the client has registered only ClientEventChainedReceive and ClientEventReceive handlers for the endpoint-to-endpoint connection, ClientEventChainedReceive can determine whether the TSDU is normal or expedited data by checking the ReceiveFlags, assuming both transports support expedited sends and receives. A transport never calls the corresponding ClientEventReceive handler with the same indication it makes to ClientEventChainedReceive.
The transport does not call ClientEvent(Chained)Receive while the client has an outstanding normal receive request or has rejected previously indicated data for a particular incoming normal receive until that receive is done. However, a transport that supports expedited data can call ClientEvent(Chained)Receive(Expedited) in the process of indicating a normal TSDU if an expedited TSDU comes in from the remote-node peer.
When ClientEventChainedReceive returns control with either STATUS_SUCCESS or STATUS_DATA_NOT_ACCEPTED, the underlying transport assumes the client is done with this receive indication.
By default, ClientEventChainedReceive runs at IRQL DISPATCH_LEVEL.
ClientEventChainedReceiveExpedited, ClientEventReceive, TdiBuildReceive, TdiBuildSetEventHandler, TdiReturnChainedReceives