ClientEventReceive

TDI_STATUS
ClientEventReceive (
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
);

ClientEventReceive is a routine the TDI driver calls in response to a TDI_EVENT_RECEIVE event. It copies normal data the TDI driver provides from the network. The driver does not call ClientEventReceive if the client has an outstanding receive request or has not accepted all previously indicated data.

ClientEventReceive uses a TSDU that the TDI driver has received on a connection. The TSDU consists of stream-mode or message-mode user data that represents a segment of a data stream, an entire message, or a piece of a message. The driver removes the transport layer header from the TSDU before it calls ClientEventReceive.

Note A driver operating in message mode delimits messages using end-of-record marks. It provides data that it receives after an end-of-record mark as a separate indication.

Because a TSDU can be any length (up to the limit the client sets using a TDI_QUERY_INFORMATION request message), ClientEventReceive may not receive an entire TSDU or even the available portion of the TSDU. The client can copy some or all of the data, issue a receive request to accept the data, or do both. It also has the option of receiving the rest of the data in subsequent TDI_EVENT_RECEIVE events.

When it has finished processing, ClientEventReceive writes the number of bytes of data accepted. If it wants to accept the data after issuing a receive request, it writes a pointer to an appropriate IRP and returns STATUS_MORE_PROCESSING_REQUIRED.

Parameters

TdiEventContext

Points to the context the client specifies in an IRP when it issues the TDI_SET_EVENT_HANDLER request message to register ClientEventReceive.

ConnectionContext

Specifies the context the client associates with the connection endpoint identifier.

ReceiveFlags

Specifies bit flags that provide additional information about the TSDU. The following bit flags are currently available:

Bit Flag Meaning
TDI_RECEIVE_PARTIAL Specifies that received data is not terminated with an end-of-record mark.
TDI_RECEIVE_COPY_LOOKAHEAD Specifies that the driver can copy lookahead data using fast copy functions.

BytesIndicated

Specifies the number of bytes of message-mode or stream-mode data. This value is always less than or equal to the value of BytesAvailable.

BytesAvailable

Specifies the total number of bytes currently available to the driver. The driver must provide a minimum of 128 bytes of data in its indication to the client, unless the received message or stream segment is less than 128 bytes in length. If BytesAvailable is greater than BytesIndicated, the driver has data that it does not present when it calls ClientEventReceive.

BytesTaken

Points to the caller–defined memory location to which ClientEventReceive writes the number of bytes of data it copies from the TSDU.

Tsdu

Points to the TSDU.

IoRequestPacket

Points to the caller–defined memory location to which ClientEventReceive writes a pointer to an IRP formatted for a receive request. If this parameter is NULL, the client will not be making such a request.

Return Value

ClientEventReceive can return the following status codes:

STATUS_DATA_NOT_ACCEPTED
STATUS_MORE_PROCESSING_REQUIRED
STATUS_SUCCESS

For more information about status codes, see Part II, Chapter 10.

Comments

If the client decides to receive further data by supplying an IRP for the driver, the associated internal driver receive routine retrieves the data that it has not delivered to the client, along with any new data that is available. The retrieval continues until the IRP is full or the driver encounters an end-of-record mark. The internal driver receive function must complete the IRP before the driver can issue another TDI_EVENT_RECEIVE indication to the client.

Note The limit set on TDI_EVENT_RECEIVE is stricter than for other events, but it allows the client to synchronize receive data correctly.

If the client decides not to receive further data, the TDI driver proceeds according to the amount of indicated data the client has accepted and the availability of additional data. If the driver has passed all indicated data and no more data was available at the time of the indication, the driver calls ClientEventReceive again when it receives more data from the network.

If the driver has not passed all indicated data to the client, or if it has additional data available but not presented at indication time, it assumes that the client has no room for the data and makes no further indications until the client issues a receive request. The driver can optionally initiate protocol flow control action to prevent retransmissions of data from the network until the client makes a receive request.

Windows NT does not require the TDI driver to correlate data reception from the network with TDI_EVENT_RECEIVE indications. If the driver provides internal buffering, it can acknowledge data at any time and make indications as necessary, for instance when it has received a certain amount of data or when its internal buffers are nearly full. A buffering driver should retain any data that the client does not receive until the client notifies it that the receive request is satisfied. If the driver does not perform internal data buffering, it can acknowledge data after the client has accepted it on a receive event, or place the data into an IRP.

See Also

TDI_QUERY_INFORMATION, TDI_SET_EVENT_HANDLER