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.
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.
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.
TdiBuildAccept, TdiBuildAssociateAddress, TdiBuildConnect, TdiBuildDisconnect, TdiBuildListen, TdiBuildInternalDeviceControlIrp, TdiBuildReceive, TdiBuildReceiveDatagram, TDI_SET_EVENT_HANDLER, TdiReturnChainedReceives