When a kernel-mode client makes a TDI_DISCONNECT request, it asks the underlying TDI transport driver to make a disconnect indication to the remote node, to acknowledge a disconnect indication from the remote node for an established endpoint-to-endpoint connection, or to reject an offered connection by a remote-node peer.
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:
STATUS_SUCCESS
STATUS_PENDING
STATUS_INVALID_CONNECTION
STATUS_REQUEST_TIMED_OUT
Some transport drivers simply terminate all activity on the given connection immediately. Others use the client-supplied value of the RequestFlags member to support controlled disconnects. For such a transport, RequestFlags can be set to either of the following:
When a preceding disconnect request made with TDI_DISCONNECT_RELEASE remains
pending on the connection, the client can issue another disconnect request
with TDI_DISCONNECT_ABORT, thereby forcing the underlying transport to close
the connection immediately.
The tranport can use client-supplied information in the buffer at RequestConnectionInformation to supply disconnection data, possibly supplemented with transport-provided status information, to the transport on the remote node. This buffer is formatted as a TDI_CONNECTION_INFORMATION structure.
The transport can return disconnect data and any status information supplied by the transport on the remote node in the client-supplied buffer at ReturnConnectionInformation. This buffer is formatted as a TDI_CONNECTION_INFORMATION structure. The contents of this buffer remain valid only until the client reuses the connection in a subsequent TDI_LISTEN or TDI_CONNECT request.
The TDI_DISCONNECT_WAIT flag is unused.
During a disconnect operation, the underlying transport driver usually refuses any incoming requests for an established connection and stops all activity at the specified connection endpoint, unless the transport supports controlled disconnects. That is, the completion of a client's disconnect request usually implies cessation of all activity, including receive indications, on the given connection.
By default, TDI_DISCONNECT requests the disconnection of an endpoint-to-endpoint connection that is not a controlled-disconnect operation: the transport need not complete outstanding I/O requests on the connection before it completes the disconnect request and returns control. For such a disconnect operation, the transport typically cancels all outstanding requests on the given connection, and the corresponding remote-node transport need not have its client confirm the disconnection before the local-node transport can complete its client's disconnect request and return control.
Clients on an endpoint-to-endpoint connection can request a controlled disconnect if their underlying TDI transports support this. If so, the client that initiates the disconnect operation with a TDI_DISCONNECT request causes both transports to coordinate their operations so the remote-node peer is informed that its endpoint-to-endpoint connection is closing. In these circumstances, the remote-node client must confirm the disconnect before the underlying transport can return from the initiating (local-node) client's disconnect request.
The following summarizes the sequence of operations for a controlled disconnect:
If the underlying transport supports delayed-connection acceptances, its clients also can submit TDI_DISCONNECT requests to reject incoming connection offers from remote nodes. Such a client is responding to a completed TDI_LISTEN request in which the client set the TDI_QUERY_ACCEPT flag or to a offer relayed by the transport to that client's registered ClientEventConnect handler.
TdiBuildDisconnect is the macro a client uses to fill in this IRP.
ClientEventConnect, TdiBuildDisconnect, TDI_CONNECTION_INFORMATION, TdiDispatchInternalDeviceControl, TDI_LISTEN, TDI_REQUEST_KERNEL