NTSTATUS
TdiDispatchCleanup (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
TdiDispatchCleanup completes any outstanding IRPs for an address, connection endpoint, or control channel that is about to be closed.
A transport calls IoGetCurrentIrpStackLocation with the given Irp to get a pointer to its own stack location in the IRP, shown in the following list as IrpSp. TdiDispatchCleanup can use the information set in the following members of the IRP in processing a cleanup request:
TdiDispatchCleanup returns STATUS_SUCCESS when its cleanup operation is done and the transport has completed any pending IRPs it was holding queued for the address, connection endpoint, or control channel.
TdiDispatchCleanup runs when the I/O Manager is closing the last handle to an open file object representing an address, connection endpoint, or control channel. TdiDispatchCleanup is responsible for completing any IRPs currently held in the transport that reference the open file object.
When the I/O Manager is removing its last reference to such a file object handle, it calls TdiDispatchClose. In other words, the I/O Manager always submits an IRP_MJ_CLEANUP request to a transport before it submits an IRP_MJ_CLOSE request for a particular file object.
Cleaning up for an address, connection endpoint, or control channel is an inherently synchronous operation. TdiDispatchCleanup can block waiting for internal driver functions to handle particular cleanup subtasks, but TdiDispatchCleanup must complete the input cleanup IRP itself.
Closing the handle to a file object that represents an address cancels the use of a transport address previously opened by a client. On receipt of a cleanup request for which the FileObject represents an address, the transport does the following:
On return from TdiDispatchCleanup, the transport holds no outstanding IRPs queued for the address, but the driver can have outstanding references of its own to the file object representing that address, particularly if TdiDispatchCleanup did not release the driver-allocated context at FsContext and FsContext2 in the file object.
TdiDispatchCleanup can be called to close a connection endpoint even if the client has not made a request to disassociate the connection from the previously associated address. On receipt of a cleanup request for which the FileObject represents a connection endpoint, the transport does the following:
On return from TdiDispatchCleanup, the transport holds no outstanding sends or receives queued for the connection endpoint, but the driver can have outstanding references of its own to the file object representing that connection, particularly if TdiDispatchCleanup did not release the driver-allocated context at FsContext and FsContext2 in the file object.
On receipt of a cleanup request for which the FileObject represents a control channel, the transport completes any outstanding requests on the control channel. Such a request has no effect on addresses and connection endpoints open in the TDI driver.
How a transport handles pending IRPs when it receives a cleanup request is driver-determined. Usually, a transport sets STATUS_CANCELLED in the I/O status block and, then, calls IoCompleteRequest with each pending IRP. As an alternative, a transport might complete pending operations and complete each IRP when the requested operation was done; that is, return any resources allocated by the next lower driver for pending receives and transmit all pending sends for an address or connection endpoint, and collect a set of current statistics for a control channel before completing the corresponding IRPs.
In whatever manner a given transport handles pending IRPs for an address, connection endpoint, or control channel that is being closed, TdiDispatchCleanup cannot complete the cleanup IRP and return control until there are no outstanding IRPs that reference the FileObject in the given cleanup IRP.
By default, TdiDispatchCleanup runs at IRQL PASSIVE_LEVEL.