VOID
TdiBuildReceive (
IN PIRP Irp,
IN PDEVICE_OBJECT DevObj,
IN PFILE_OBJECT FileObj,
IN PVOID CompRoutine,
IN PVOID Contxt,
IN PMDL MdlAddr,
IN ULONG InFlags,
IN ULONG ReceiveLen
);
TdiBuildReceive sets up an internal device control IRP for a TDI_RECEIVE request to the underlying transport in which the local-node client has established an endpoint-to-endpoint connection with a remote-node peer.
Parameters
Irp
Points to a client-supplied IRP, either originating in a higher level network component or allocated with TdiBuildInternalDeviceControlIrp.
DevObj
Points to the device object created by the next lower TDI transport driver.
FileObj
Points to a file object representing a connection endpoint.
The caller previously made a successful request, set up with TdiBuildAssociateAddress, to the transport to set up an association between this connection endpoint and a local-node address. When the association was established, the caller also established an endpoint-to-endpoint connection with a remote-node peer, by issuing a successful request set up with TdiBuildConnect or TdiBuildListen, the latter possibly followed by a successful request set up with TdiBuildAccept.
CompRoutine
Specifies the entry point of a client-supplied IoCompletion routine or NULL. The I/O Manager calls this routine when the given IRP is completed, unless the client sets this parameter to NULL.
Contxt
Points to a client-determined context. This client-supplied pointer is passed in to the IoCompletion routine when it is called with the completed IRP. Contxt should be NULL if CompRoutine is NULL.
MdlAddr
Points to an MDL, possibly the initial MDL in a chain of MDLs, mapping a client-supplied buffer into which the transport is to transfer the received TSDU according to the given InFlags.
InFlags
Specifies the type of receive to be returned by the transport as one or more (Ored) or none (zero) of the following:
TDI_RECEIVE_NORMAL
Return a normal TSDU to the client-supplied buffer.
TDI_RECEIVE_EXPEDITED
Return an expedited TSDU to the client-supplied buffer.
If both TDI_RECEIVE_NORMAL and TDI_RECEIVE_EXPEDITED are set or if neither is set, the underlying transport will indicate either type of TSDU for this receive request.
TDI_RECEIVE_PEEK
Return indicated data as soon as a receive arrives from the remote node, even if it is a partial TSDU, and the client will request another receive for the remainder of the TSDU to be transferred into this buffer if the packet is of interest to this client. This flag is valid only if the underlying transport buffers received data internally.
ReceiveLen
Specifies the size in bytes of the client-supplied receive buffer.
Comments
TdiBuildReceive sets IRP_MJ_INTERNAL_DEVICE_CONTROL as the MajorFunction and TDI_RECEIVE as the MinorFunction codes in the transport's I/O stack location of the given IRP.
If the client has registered any of its ClientEvent(Chained)Receive(Expedited) handler(s) for the given connection endpoint, issuing a receive request suppresses calls to ClientEvent(Chained)Receive(Expedited) until the receive IRP is satisfied. Then, the transport resumes indicating receives to the appropriate ClientEvent(Chained)Receive(Expedited) handler(s).
Unless the TDI_RECEIVE_PEEK flag is set, the underlying transport fills the given buffer with received data until the client's buffer is full or the transport receives an end-of-record indication from the remote node. If this flag is set, the client must issue subsequent receive request(s) when this IRP is satisfied to obtain the full TSDU.
If the underlying transport is receiving normal data and expedited data arrives from the remote node, the transport pre-empts its normal receive operation and returns immediately to the client with any normal data it has already transferred into the client-supplied buffer. When this occurs, the client must make as many receive requests as necessary to receive the expedited TSDU. When the client has retrieved all the arriving expedited data, it issues another receive request to resume receiving normal data.
A client can also receive normal TSDUs on an endpoint-to-endpoint connection by calling ZwReadFile. However, the client cannot receive expedited data in this manner because the transport has no way to indicate receive flags. In addition, a call to ZwReadFile does not tell the client whether the underlying transport has received an end-of-record indication.
See Also
ClientEventChainedReceive, ClientEventChainedReceiveExpedited, ClientEventReceive, ClientEventReceiveExpedited, TdiBuildAccept, TdiBuildConnect, TdiBuildInternalDeviceControlIrp, TdiBuildListen, TdiBuildReceiveDatagram, TdiBuildSend, TdiBuildSetEventHandler, TDI_RECEIVE