ClientEventReceiveExpedited routine

The ClientEventReceiveExpedited routine 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.

Syntax

NTSTATUS 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
);

Parameters

  • TdiEventContext [in]
    Pointer to the client-supplied context provided in the IRP that was set up with TdiBuildSetEventHandler when ClientEventReceiveExpedited was registered with the underlying transport.

  • ConnectionContext [in]
    Pointer 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 [in]
    Specifies the nature of the receive indication as a combination (ORed) of the following flags:

    • TDI_RECEIVE_EXPEDITED
      The buffer 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 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 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 at Tsdu to decide whether to submit a TDI_RECEIVE request for the TSDU.

  • BytesIndicated [in]
    Specifies the number of bytes of expedited data in the buffer 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 [in]
    Specifies the total number of bytes in the received TSDU.

  • BytesTaken [out]
    Pointer to a caller-supplied variable in which ClientEventReceiveExpedited returns the number of bytes of data it copies from the TSDU.

  • Tsdu [in]
    Pointer to a buffer containing the received TSDU data.

  • IoRequestPacket [out]
    Pointer 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:

Return code Description
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.

 

Remarks

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.

ClientEventReceiveExpedited must be capable of carrying out its operations at IRQL = DISPATCH_LEVEL.

Note   The TDI feature is deprecated and will be removed in future versions of Microsoft Windows. Depending on how you use TDI, use either the Winsock Kernel (WSK) or Windows Filtering Platform (WFP). For more information about WFP and WSK, see Windows Filtering Platform and Winsock Kernel. For a Windows Core Networking blog entry about WSK and TDI, see Introduction to Winsock Kernel (WSK).

 

Requirements

Target platform

Desktop

Header

Tdikrnl.h (include TdiKrnl.h)

IRQL

DISPATCH_LEVEL (see Remarks section)

See also

ClientEventChainedReceiveExpedited

ClientEventReceive

TdiBuildInternalDeviceControlIrp

TdiBuildReceive

TdiBuildSetEventHandler

 

 

Send comments about this topic to Microsoft