Поделиться через


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)

 

 

Send comments about this topic to Microsoft