ClientEventReceiveDatagram routine
The ClientEventReceiveDatagram routine is an event handler that the underlying TDI transport calls in response to an incoming receive from a remote node that was directed to a local-node transport address that the client has opened.
Syntax
NTSTATUS ClientEventReceiveDatagram(
_In_ PVOID TdiEventContext,
_In_ LONG SourceAddressLength,
_In_ PVOID SourceAddress,
_In_ LONG OptionsLength,
_In_ PVOID Options,
_In_ ULONG ReceiveDatagramFlags,
_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 ClientEventReceiveDatagram was registered with the underlying transport.SourceAddressLength [in]
Specifies the size in bytes of the buffer at SourceAddress.SourceAddress [in]
Pointer to a buffer specifying the remote-node transport address from which the datagram was sent.OptionsLength [in]
Specifies the size in bytes of the buffer at Options. Zero implies no option string is available. Options is NULL if this parameter is zero.Options [in]
Pointer to a buffer specifying a string of transport-specific options sent with the datagram. This pointer is NULL if OptionsLength is zero.ReceiveDatagramFlags [in]
Specifies the nature of the receive-datagram indication as a combination (ORed) of the following flags:TDI_RECEIVE_ENTIRE_MESSAGE
The buffer at Tsdu contains a full TSDU. The client 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 if TDI_RECEIVE_PARTIAL is set by a legacy transport), ClientEventReceiveDatagram must check the BytesAvailable and BytesIndicated 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 ClientEventReceiveDatagram should copy the number of bytes available into an internal buffer, set the variable at BytesTaken, and return control. The client will subsequently submit one or more TDI_RECEIVE_DATAGRAM requests to get the remainder of the TSDU.TDI_RECEIVE_BROADCAST
The receive was broadcast.TDI_RECEIVE_MULTICAST
The receive was multicast.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_DATAGRAM request for the TSDU.
BytesIndicated [in]
Specifies the number of bytes of 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 datagram is less than 128 bytes in length. If BytesAvailable is greater than BytesIndicated, the transport has received data that it does not present when it calls ClientEventReceiveDatagram.BytesAvailable [in]
Specifies the total number of bytes in the received TSDU.BytesTaken [out]
Pointer to a caller-supplied variable in which ClientEventReceiveDatagram returns the number of bytes of data it copied from the datagram.Tsdu [in]
Pointer to a buffer containing the received TSDU data.IoRequestPacket [out]
Pointer to a caller-supplied variable in which ClientEventReceiveDatagram returns a pointer to an IRP that it set up with TdiBuildReceiveDatagram. If this parameter is NULL, the client will not be making a receive request for the remainder of the TSDU.
Return value
ClientEventReceiveDatagram can return one of the following:
Return code | Description |
---|---|
STATUS_SUCCESS | Indicates the client copied all the data in the given TSDU and set the variable at BytesTaken to the value at BytesIndicated. |
STATUS_MORE_PROCESSING_REQUIRED | Indicates the client has supplied an IRP requesting the remainder of the TSDU, usually after copying BytesIndicated into an internal buffer. |
STATUS_DATA_NOT_ACCEPTED | Indicates this client is not interested in the TSDU. |
Remarks
When a datagram arrives from a remote node, the transport calls the registered ClientEvent(Chained)ReceiveDatagram handlers for each client with an open file object representing an address that matches the destination address of the datagram. Because a datagram is not associated with an established connection, the TDI driver passes the transport address of the remote-node sender at SourceAddress to the receiving client along with the datagram.
ClientEventReceiveDatagram accepts or rejects a TSDU that the TDI driver has received on a particular transport address that the client opened with a preceding call to ZwCreateFile. A datagram TSDU is discrete. Unlike a normal or expedited TSDU, it cannot be transmitted as a sequence of records. In other words, a full datagram is available to the TDI transport, although the driver might not pass all of it in a single call to ClientEventReceiveDatagram.
The transport has removed the transport-layer header from the TSDU before it calls ClientEventReceiveDatagram.
The driver does not call ClientEventReceiveDatagram if the client has an outstanding receive or receive-datagram request on the local transport address that is the target of an incoming datagram.
When ClientEventReceiveDatagram 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
When it has finished copying receive data, ClientEventReceiveDatagram sets the variable at BytesTaken to the number of bytes of data accepted before it returns control.
If TDI_RECEIVE_ENTIRE_MESSAGE is clear (or TDI_RECEIVE_PARTIAL is set), copy all of the indicated data, set up an IRP for a TDI_RECEIVE_DATAGRAM request, and return STATUS_MORE_PROCESSING_REQUIRED
If the ClientEventReceiveDatagram issues a receive-datagram request, the transport retrieves any data that ClientEventReceiveDatagram did not receive, along with any new data the TDI transport has available. If the client does not make such a receive-datagram request, it loses this data.
Any TDI transport driver that supports internal buffering should retain a datagram during its clients' receive-datagram operations to satisfy any subsequent receive-datagram requests. The client of such a TDI driver can determine the total amount of buffer space it allocates for received datagrams by submitting a request, set up with TdiBuildQueryInformation for the QType TDI_QUERY_DATAGRAM_INFO or TDI_QUERY_MAX_DATAGRAM_INFO. Usually, such a transport's buffer space for datagrams is around four kilobytes.
To receive indications for broadcast datagrams that the TDI driver receives on the network, the client must open the local-node broadcast address of its underlying transport and register a ClientEvent(Chained)ReceiveDatagram handler on the address.
ClientEventReceiveDatagram 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
ClientEventChainedReceiveDatagram
TdiBuildInternalDeviceControlIrp