3.5 TDI Requests versus Events

Many low-level network interfaces, such as NetBIOS and Windows Sockets, are primarily one-way. A client can call the underlying transport driver whenever it wants, but the transport driver cannot call the client. The only way such a transport driver can “say anything” to its client is by returning a specific error code on return from a client-initiated request. In the NetBIOS interface, for example, a transport informs its clients of a connection “hangup” by returning pending NCB_Receives (or an NCB_Receive_Any) with a specific error code (0x0A for a session being closed, for example).

TDI provides an event-notification mechanism that allows a TDI transport to call its affected kernel-mode clients whenever a specific network event occurs (receipt of a datagram, for example) if each such client has registered its ClientEventXxx handler with the transport for that type of event. The TDI client-supplied callback then takes appropriate action and returns control to the transport driver.

When a TDI transport driver calls a client's registered ClientEventXxx handler, it can pass a limited amount of data as a parameter of that call. This feature allows the client to receive messages from the transport without having to allocate a buffer.

For example, the Windows NT redirector takes advantage of this TDI feature. Many of the SMB requests that the redirector sends to the server (such as write SMBs) require little more than the standard SMB header to be present in the corresponding SMB response. The length of this header, which includes status indicators, multiplex ID, etc., is quite small, typically less than 100 bytes.

When the underlying TDI transport driver calls the redirector’s registered ClientEventReceive handler with such an SMB response message to a preceding send, the redirector need only view (not necessarily copy) the indicated message, note the SMB response status indicator, and return to the transport driver. In such a transaction, the redirector receives the SMB response message without having to allocate a buffer.