TDI_RECEIVE_DATAGRAM

When a kernel-mode client makes a TDI_RECEIVE_DATAGRAM request, it asks the underlying TDI transport driver to indicate a TSDU, as a datagram, on a specified address.

IRP

The transport calls IoGetCurrentIrpStackLocation with the given Irp to get a pointer to its own I/O stack location in the IRP, shown in the following list as IrpSp. IRP members relevant to this request include the following:

IoStatus.Status
Specifies the final status of the receive-datagram request. The transport sets this member before it completes the IRP, possibly to one of the following:

STATUS_PENDING
STATUS_INSUFFICIENT_RESOURCES
STATUS_INVALID_ADDRESS
STATUS_BUFFER_OVERFLOW
STATUS_BUFFER_TOO_SMALL

IoStatus.Information
Specifies the number of bytes of received data the transport is returning in the client-supplied buffer.
IrpSp->MajorFunction
Specifies IRP_MJ_INTERNAL_DEVICE_CONTROL. The transport can ignore this member if it exports a TdiDispatchInternalDeviceControl routine that handles only TDI_XXX requests.
IrpSp->MinorFunction
Specifies TDI_RECEIVE_DATAGRAM.
IrpSp->FileObject
Points to an open file object representing the local-node address. The transport uses the FsContext and, possibly, FsContext2 fields to access the state it maintains about this address.
IrpSp->Parameters
Points to a TDI_REQUEST_KERNEL_RECEIVEDG structure, defined as follows:
struct _TDI_REQUEST_KERNEL_RECEIVEDG { 
    ULONG ReceiveLength; 
    PTDI_CONNECTION_INFORMATION ReceiveDatagramInformation; 
    PTDI_CONNECTION_INFORMATION ReturnInformation; 
    ULONG ReceiveFlags; 
} TDI_REQUEST_KERNEL_RECEIVEDG, *PTDI_REQUEST_KERNEL_RECEIVEDG; 
 

The transport uses the members of this structure as follows:

ReceiveLength
Specifies the maximum size in bytes of the client-supplied receive buffer. If this member is zero, the transport can use the full buffer mapped at Irp->MdlAddress.
ReceiveDatagramInformation
Points to a TDI_CONNECTION_INFORMATION structure, specifying either the remote address from which the client expects to receive a datagram or zero in the RemoteAddressLength member if a datagram from any remote node is acceptable to this client.
ReturnInformation
Points to a caller-supplied buffer, formatted as a TDI_CONNECTION_INFORMATION structure, in which the transport returns the remote-node address from which the returned datagram was received.
ReceiveFlags
Specifies the type of datagram the client expects as none (zero), one, or a combination (ORed) of the following flags:

TDI_RECEIVE_NORMAL - return normal datagram

TDI_RECEIVE_PEEK - return any available portion of datagram

MdlAddress
Points to an MDL, possibly the initial MDL in a chain, mapping a client-supplied buffer in which the transport returns the received datagram.

Comments

Because a datagram is never associated with an endpoint-to-endpoint connection, the transport must return the address of the remote-node client to the receiving client along with each datagram.

TDI transports do not fragment datagrams. Consequently, a client makes a single receive-datagram request for a full datagram, unless it sets the TDI_RECEIVE_PEEK flag. When a TDI transport driver receives a datagram from a remote node, it completes a client's receive-datagram request if both of the following are true:

If the received datagram is too large for the client-supplied buffer mapped at Irp->MdlAddress, the transport fills this buffer with ReceiveLength bytes and completes the client's receive-datagram IRP. In effect, a client receives a truncated datagram if that client does not provide a large enough buffer with its receive-datagram request.

A local-node client can also receive datagrams by issuing TDI_SET_EVENT_HANDLER request(s) to register its ClientEventReceiveDatagram and/or ClientEventChainedReceiveDatagram handler(s) for a particular address. The transport supplies this information to its client by setting the ReceiveDatagramFlags parameter to ClientEvent(Chained)ReceiveDatagram with any of the flags listed in the reference for TDI_RECEIVE, except TDI_RECEIVE_EXPEDITED. In addition, for datagram indications, the ReceiveDatagramFlags can be set with either of the following:

TDI_RECEIVE_BROADCAST
The received TSDU was broadcast.
TDI_RECEIVE_MULTICAST
The received TSDU was multicast.

A NetBIOS TDI client can receive a broadcast datagram by opening a file object that represents the underlying transport's broadcast address. Any broadcast address has a driver-specific format, which the client can obtain by issuing a TDI_QUERY_INFORMATION request to the underlying transport. A transport does not allow its clients to send datagrams from such a broadcast address, and the transport fails any client-issued TDI_ASSOCIATE_ADDRESS requests that specify its broadcast address.

Windows NT currently specifies the reception of broadcast datagrams only for NetBIOS TDI clients. Other TDI transports can indicate received broadcast datagrams to their clients in the same manner as any other type of datagram.

TdiBuildReceiveDatagram is the macro a client uses to fill in the IRP.

See Also

ClientEventChainedReceiveDatagram, ClientEventReceiveDatagram, TdiBuildReceiveDatagram, TDI_CONNECTION_INFORMATION, TdiDispatchInternalDeviceControl, TDI_QUERY_INFORMATION, TDI_SET_EVENT_HANDLER