TdiDispatchCleanup

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.

Parameters

DeviceObject
Points to the device object created by the TDI transport.
Irp
Points to an IRP with IRP_MJ_CLEANUP set as the MajorFunctionCode in the I/O stack location of the transport driver.

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:

IoStatus.Status
Specifies the final status of the cleanup operation. The transport sets this member to the same value that will be returned by TdiDispatchCleanup. (IoStatus.Information is set to zero.)
IrpSp->MajorFunction
Specifies IRP_MJ_CLEANUP. The transport can ignore this member if it exports a TdiDispatchCleanup routine that handles only cleanup requests.
IrpSp->FileObject
Points to the open file object representing an address, connection endpoint, or control channel. The transport driver uses the value(s) of the FsContext and possibly FsContext2 field(s) in this file object to access the state that TdiDispatchCreate originally set up for the address, connection endpoint, or control channel when the file object was opened by the client.

Return Value

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.

Comments

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.

See Also

TdiDispatchClose, TdiDispatchCreate