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 Irpto get a pointer to its own I/O stack location in the IRP, shown in the following list as IrpSp. The pointer to the IRP is shown in the following list as Irp. IRP members relevant to this request include the following:
Irp->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
Irp->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
Pointer 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
Pointer to a TDI_REQUEST_KERNEL_RECEIVEDG structure, defined as follows:
struct _TDI_REQUEST_KERNEL_RECEIVEDG {
ULONG ReceiveLength;
PTDI_CONNECTION_INFORMATION ReceiveDatagramInformation;
PTDI_CONNECTION_INFORMATION ReturnDatagramInformation;
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
Pointer 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.ReturnDatagramInformation
Pointer 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
Irp->MdlAddress
Pointer 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:
The just received datagram has a destination address that matches the local-node address represented by the file object at IrpSp->FileObject.
The just received datagram has a source address that either matches the value specified in RemoteAddress at IrpSp->Parameters or RemoteAddressLength is zero and RemoteAddress is NULL.
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 requests to register its ClientEventReceiveDatagram and/or ClientEventChainedReceiveDatagram handlers for a particular address. The transport supplies this information to its client by setting the ReceiveDatagramFlagsparameter 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 ReceiveDatagramFlagscan be set with either of the following:
TDI_RECEIVE_BROADCAST
The received TSDU was broadcast.TDI_RECEIVE_MULTICAST
The received TSDU was multicast.
A 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 a broadcast address, and the transport fails any client-issued TDI_ASSOCIATE_ADDRESS requests that specify its broadcast address.
TdiBuildReceiveDatagramis the macro a client uses to fill in the IRP.
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).
See Also
ClientEventChainedReceiveDatagram, ClientEventReceiveDatagram, TdiBuildReceiveDatagram, TDI_CONNECTION_INFORMATION, TdiDispatchInternalDeviceControl, TDI_QUERY_INFORMATION, TDI_SET_EVENT_HANDLER
Requirements
Header |
TdiKrnl.h (include TdiKrnl.h) |