ClientEventReceiveExpedited
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