TdiBuildSetEventHandler

VOID
TdiBuildSetEventHandler (
IN PIRP Irp,
IN PDEVICE_OBJECT DevObj,
IN PFILE_OBJECT FileObj,
IN PVOID CompRoutine,
IN PVOID Contxt,
IN INT InEventType,
IN PVOID InEventHandler,
IN PVOID InEventContext
);

TdiBuildSetEventHandler sets up an internal device control IRP for a TDI_SET_EVENT_HANDLER request to the underlying transport in which the local-node client has already opened a file object representing an address.

Parameters

Irp

Points to a client-supplied IRP, either originating in a higher level network component or, usually, allocated with TdiBuildInternalDeviceControlIrp.

DevObj

Points to the device object created by the next lower TDI transport driver.

FileObj

Points to a file object representing an address.

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.

InEventType

Specifies the type of event handler being registered as one of the following:

TDI_EVENT_CONNECT

Register the given ClientEventConnect handler to be called when an endpoint-to-endpoint connection is offered by a remote-node peer.

TDI_EVENT_DISCONNECT

Register the given ClientEventDisconnect handler to be called when an established endpoint-to-endpoint connection is being closed by the remote-node peer.

TDI_EVENT_RECEIVE

Register the given ClientEventReceive handler to be called when a normal receive comes in on an endpoint-to-endpoint connection from the remote node and the client will be given the opportunity to copy all or part of the buffered TSDU.

TDI_EVENT_CHAINED_RECEIVE

Register the given ClientEventChainedReceive handler to be called when a normal receive comes in on an endpoint-to-endpoint connection from the remote node and the client will be given read-only access to the buffered full TSDU until it calls TdiReturnChainedReceives.

TDI_EVENT_RECEIVE_EXPEDITED

Register the given ClientEventReceiveExpedited handler to be called when an expedited receive comes in on an endpoint-to-endpoint connection from the remote node and the client will be given the opportunity to copy all or part of the buffered TSDU.

TDI_EVENT_CHAINED_RECEIVE_EXPEDITED

Register the given ClientEventChainedReceiveExpedited handler to be called when an expedited receive comes in on an endpoint-to-endpoint connection from the remote node and the client will be given read-only access to the buffered full TSDU until it calls TdiReturnChainedReceives.

TDI_EVENT_RECEIVE_DATAGRAM

Register the given ClientEventReceiveDatagram handler to be called when a datagram comes in from a remote node and the client will be given the opportunity to copy all or part of the buffered TSDU.

TDI_EVENT_CHAINED_RECEIVE_DATAGRAM

Register the given ClientEventChainedReceiveDatagram handler to be called when a datagram comes in from a remote node and the client will be given read-only access to the buffered full TSDU until it calls TdiReturnChainedReceives.

TDI_EVENT_ERROR

Register the given ClientEventError handler to be called if an error occurs in an underlying driver such that network I/O on this local-node address has become unreliable or impossible.

TDI_EVENT_SEND_POSSIBLE

Register the given ClientEventSendPossible handler to be called when the underlying transport, which previously returned a submitted send request with STATUS_DEVICE_NOT_READY, again has internal buffer space available into which it can copy the resubmitted client-supplied data to be sent.

In addition to the preceding system-defined events, a transport can extend this interface to support transport-specific notifications of events to its clients. Such a transport must define TDI_EVENT_XXX codes in which the most significant bit is set.

InEventHandler

Specifies the entry point of the ClientEventXxx handler being registered. The client can set this parameter to NULL to cancel notifications to a previously registered event handler.

InEventContext

Points to caller-determined context to be passed in to the ClientEventXxx routine when it is called by the transport. This parameter must be NULL if InEventHandler is NULL.

Comments

When its client first opens a file object that represents an address, the underlying transport initializes all event handlers to NULL.

TdiBuildSetEventHandler sets IRP_MJ_INTERNAL_DEVICE_CONTROL as the MajorFunction and TDI_SET_EVENT_HANDLER as the MinorFunction codes in the transport's I/O stack location of the given IRP.

With each IRP set up by TdiBuildSetEventHandler and submitted to the underlying transport with IoCallDriver, the client registers one event handler for a given event type that can occur on a particular transport address. Indications from lower level NDIS drivers that are forwarded by the transport to ClientEventXxx routines usually occur at IRQL DISPATCH_LEVEL. For these client-supplied event handlers, the caller should allocate the area at InEventContext from nonpaged pool.

A client can register its ClientEvent(Chained)ReceiveDatagram and ClientEventError handlers as soon as it has opened a file object representing an address with a successful call to ZwCreateFile. It can register its ClientEventConnect handler as soon as it has opened file objects representing an address and a connection endpoint and made a successful associate-address request to the underlying transport.

For some InEventType values, the address represented by the given file object should be associated with a connection endpoint by the client before it registers certain ClientEventXxx handlers. In particular, a client should associate a connection endpoint with a local-node address before it registers its ClientEvent(Chained)Receive(Expedited), ClientEventDisconnect, and/or ClientEventSendPossible handlers for network transfers that are made on a connection-specific basis. Unless its transport supports delayed-connection acceptances, the client should assume that an endpoint-to-endpoint connection, already associated with the open file object representing the address, is active when it makes the set-event-handler request to register any of these event handlers.

Only clients of transports that buffer send data internally can register a ClientEventSendPossible handler.

In general, a TDI transport can indicate an event to a client while an event of the same kind is in progress. In other words, ClientEventXxx handlers are re-entrant. The transport also can call ClientEvent(Chained)Receive(Expedited) or ClientEvent(Chained)Receive(Datagram) before the client's set-event-handler IRP to register one of these routines is fully completed. Consequently, the client must be prepared to handle receives as soon as it requests the registration of a ClientEvent(Chained)Receive(Xxx) handler.

Calls to registered ClientEvent(Chained)Receive(Xxx) handlers are disabled whenever the client submits a receive or receive-datagram IRP set up with TdiBuildReceive or TdiBuildReceiveDatagram to the underlying transport. After it is called with such an IRP, the underlying transport carries out all operations necessary to complete that IRP before it resumes calling registered ClientEvent(Chained)Receive(Xxx) routine(s) with incoming receive indications.

A client can disable any registered event handler by making another set-event-handler request with the same InEventType but specifying NULL as the InEventHandler and InEventContext parameters to TdiBuildSetEventHandler.

See Also

TdiBuildAccept, TdiBuildAssociateAddress, TdiBuildConnect, TdiBuildDisconnect, TdiBuildListen, TdiBuildInternalDeviceControlIrp, TdiBuildReceive, TdiBuildReceiveDatagram, TDI_SET_EVENT_HANDLER, TdiReturnChainedReceives