TDI_STATUS
ClientEventReceiveExpedited (
IN PVOID TdiEventContext,
IN CONNECTION_CONTEXT ConnectionContext,
IN ULONG ReceiveFlags,
IN ULONG BytesIndicated,
IN ULONG BytesAvailable,
OUT ULONG *BytesTaken,
IN PVOID Tsdu,
OUT PIRP *IoRequestPacket
);
ClientEventReceiveExpedited is an event handler that the underlying TDI transport calls in response to an incoming expedited receive from a remote node with which the client has an established endpoint-to-endpoint connection.
Parameters
TdiEventContext
Points to the client-supplied context provided in the IRP that was set up with TdiBuildSetEventHandler when ClientEventReceiveExpedited was registered with the underlying transport.
ConnectionContext
Points to the client's context area for this connection endpoint. The client previously supplied this value to its underlying transport when its ClientEventConnect handler accepted a connection offer from the remote-node peer and/or when it opened the connection endpoint with ZwCreateFile.
ReceiveFlags
Specifies the nature of the receive indication as a combination (ORed) of the following flags:
TDI_RECEIVE_EXPEDITED
The buffer mapped at Tsdu contains expedited data received from the client's remote-node peer. This flag is always set when ClientEventReceiveExpedited is called.
TDI_RECEIVE_ENTIRE_MESSAGE
The buffer mapped at Tsdu contains a full TSDU. ClientEventReceiveExpedited should return control as quickly as possible after copying the indicated data into an internal buffer if it accepts the TSDU.
If this flag is clear (or TDI_RECEIVE_PARTIAL is set by a legacy transport), ClientEventReceiveExpedited must check the BytesIndicated and BytesAvailable parameters to determine how much of the TSDU has been provided. Although legacy transports continue to set the TDI_RECEIVE_PARTIAL flag, newer transports leave clear the TDI_RECEIVE_ENTIRE_MESSAGE flag to indicate partial TSDUs to their clients.
TDI_RECEIVE_COPY_LOOKAHEAD
Unless TDI_RECEIVE_ENTIRE_MESSAGE is set, BytesIndicated is something less than BytesAvailable, and ClientEventReceiveExpedited should copy the number of indicated bytes into an internal buffer, set the variable at BytesTaken, and return control. The client will subsequently submit one or more TDI_RECEIVE requests to get the remainder of the TSDU or ClientEventReceiveExpedited will be called again to copy the remainder of the TSDU.
TDI_RECEIVE_FRAGMENT
The buffer mapped at Tsdu contains a fragmented TSDU.
TDI_RECEIVE_PEEK
The transport has buffered some receive data internally, but not yet the full TSDU. The client can examine the buffer mapped at Tsdu to decide whether to submit a TDI_RECEIVE request for the TSDU.
TDI_RECEIVE_AT_DISPATCH_LEVEL
The receive is being indicated at IRQL DISPATCH_LEVEL. This flag restricts the set of support routines that the client can call in processing this indication. Some transports never set this flag, whatever the current IRQL, when making receive-event notifications.
BytesIndicated
Specifies the number of bytes of expedited data in the buffer mapped at Tsdu. This parameter is always less than or equal to the value of BytesAvailable. A TDI transport provides at least 128 bytes of data in a receive indication to its client, unless the received message or stream segment is less than 128 bytes in length. If BytesAvailable is greater than BytesIndicated, the transport has received data that it does not make available when it calls ClientEventReceiveExpedited.
BytesAvailable
Specifies the total number of bytes in the received TSDU.
BytesTaken
Points to a caller-supplied variable in which ClientEventReceiveExpedited returns the number of bytes of data it copies from the TSDU.
Tsdu
Points to an MDL, possibly the initial MDL in a chain, mapping the buffer containing the received TSDU data.
IoRequestPacket
Points to a variable in which ClientEventReceiveExpedited returns a pointer to an IRP that was set up with TdiBuildReceive. If this parameter is NULL, the client will not be making a receive request for the remainder of the TSDU.
Return Value
ClientEventReceiveExpedited can return one of the following:
STATUS_SUCCESS
Indicates the client copied all the data in the given TSDU.
STATUS_MORE_PROCESSING_REQUIRED
Indicates the client has supplied an IRP requesting the remainder of the TSDU, after copying BytesIndicated into an internal buffer.
STATUS_DATA_NOT_ACCEPTED
Indicates this client is not interested in the TSDU.
Comments
ClientEventReceiveExpedited accepts or rejects an expedited TSDU that the TDI driver has received on an established endpoint-to-endpoint connection. This handler is almost identical to ClientEventReceive, except that expedited data flow supersedes normal data flow.
Consequently, the underlying transport can call ClientEventReceiveExpedited on a connection while a normal receive operation or an indication to ClientEventReceive (or ClientEventChainedReceive) is in progress. If this occurs, normal data flow does not resume until ClientEventReceiveExpedited has returned and the client has received all the expedited data for the TSDU. If ClientEventReceiveExpedited provides a TDI_RECEIVE request at IoRequestPacket, this request also has priority over any client-issued request for nonexpedited data.
When ClientEventReceiveExpedited is called, it can do one of the following:
·Reject the indicated TSDU if it has no use for the data by returning STATUS_DATA_NOT_ACCEPTED
·Copy all of the data into an internal buffer if TDI_RECEIVE_ENTIRE_MESSAGE is set in the ReceiveFlags and return STATUS_SUCCESS
·If TDI_RECEIVE_ENTIRE_MESSAGE is clear (or TDI_RECEIVE_PARTIAL is set), copy some or all of the indicated data and return either of the following, depending on which operation it carries out:
STATUS_MORE_PROCESSING_REQUIRED if the client is supplying a TDI_RECEIVE request at IoRequestPacket to obtain the remaining TSDU data
STATUS_SUCCESS if the transport is expected to call ClientEventReceiveExpedited again with the remaining TSDU data
When it has finished copying receive data, ClientEventReceiveExpedited sets the variable at BytesTaken to the number of bytes of data accepted before it returns control.
By default, ClientEventReceiveExpedited runs at IRQL DISPATCH_LEVEL.
See Also
ClientEventChainedReceiveExpedited, ClientEventReceive, TdiBuildInternalDeviceControlIrp, TdiBuildReceive, TdiBuildSetEventHandler