TdiDispatchFastDeviceControl routine

The TdiDispatchFastDeviceControl routine is an optional TDI transport driver function that usually returns data already buffered internally by the transport.


BOOLEAN TdiDispatchFastDeviceControl(
  _In_    STRUCT FILE_OBJECT *FileObject,
  _In_    BOOLEAN            Wait,
  _In_    PVOID              InputBuffer,
  _In_    ULONG              InputBufferLength,
  _Inout_ PVOID              OutputBuffer,
  _In_    ULONG              OutputBufferLength,
  _In_    ULONG              IoControlCode,
  _Out_   PIO_STATUS_BLOCK   IoStatus


  • FileObject [in]
    Pointer to the file object representing the open address, connection endpoint, or control channel.

  • Wait [in]
    Specifies TRUE if the driver can wait in the context of the call to TdiDispatchFastDeviceControl.

  • InputBuffer [in]
    Optionally points to the input buffer, containing caller-supplied information required by the given IoControlCode.

  • InputBufferLength [in]
    Specifies the size in bytes of the input buffer.

  • OutputBuffer [in, out]
    Optionally points to the output buffer in which the transport returns any data requested.

  • OutputBufferLength [in]
    Specifies the size in bytes of the output buffer.

  • IoControlCode [in]
    Specifies the IOCTL_TDI_XXX code for the requested operation. This value must be one of the codes defined in ntddtdi.h.

    The set of valid IOCTL_TDI_XXX codes depends on the fast I/O support, if any, provided by an individual transport and on what that transport currently holds in its internal buffers. In general, transports are most likely to buffer read-ahead data to satisfy anticipated IOCTL_TDI_RECEIVE requests and, possibly, data used to satisfy IOCTL_TDI_QUERY_INFORMATION requests.

    The afd.sys driver, which provides support for Windows Sockets to communicate with underlying transports, also provides read-ahead fast I/O support for system transports that do not provide a fast I/O path for received data.

  • IoStatus [out]
    Pointer to a caller-supplied variable in which TdiDispatchFastDeviceControl returns the completion status, formatted as an IO_STATUS_BLOCK structure. TdiDispatchFastDeviceControl fills in the Status and Information members as appropriate for the given IoControlCode.

Return value

TdiDispatchFastDeviceControl returns TRUE only if it satisfies or completes the kernel-mode client's request before returning control.


When preparing a fast I/O request, a client neither allocates an IRP nor uses an IRP passed in from a higher network layer.

When the I/O manager calls TdiDispatchFastDeviceControl, a given OutputBuffer usually corresponds to the buffer at Irp-> MdlAddress in a client-supplied IRP. The InputBuffer contains any client-supplied information for the request, depending on the IoControlCode. This request is different from other kernel requests in that system-defined user-mode IOCTLs identify the requests, as opposed to the TDI_XXX minor function codes listed with TdiBuildInternalDeviceControlIrp.

For example, for IOCTL_TDI_SEND, InputBuffer contains a client-supplied TDI_REQUEST_SEND structure, and OutputBuffer contains the actual data to be sent over the network. For IOCTL_TDI_RECEIVE, InputBuffer contains a TDI_REQUEST_RECEIVE structure, and the transport driver copies the receive data to OutputBuffer.

The definition of each IOCTL_TDI_XXX code in ntddtdi.h determines how buffers should be set up. For an explanation of how to interpret IOCTL_XXX codes, see Defining I/O Control Codes.

When the buffer parameters have been set up for the transport, the client calls IoCallDriver to deliver the request to TdiDispatchFastDeviceControl if the transport exports this routine. If the transport cannot complete a fast I/O client request immediately, TdiDispatchFastDeviceControl returns FALSE and the I/O manager repackages the given request into an IRP_MJ_DEVICE_CONTROL IRP and submits the IRP to the transport driver's TdiDispatchDeviceControl routine. Otherwise, TdiDispatchFastDeviceControl satisfies the request itself, possibly by calling an internal driver function to process the request, or it fails the request. When TdiDispatchFastDeviceControl returns TRUE, the transport relinquishes ownership of the original buffers to the client.

At initialization, a TDI transport driver enables its fast I/O path by setting the FastIoDispatch field in the input driver object to the address of a driver-allocated FAST_IO_DISPATCH structure. The transport must fill in the SizeOfFastIoDispatch member and set FastIoDeviceControl to the entry point of the transport's TdiDispatchFastDeviceControl function; all other members of the FAST_IO_DISPATCH structure must be set to NULL. For more information about driver objects, see Introduction to Driver Objects.

TdiDispatchFastDeviceControl runs at IRQL PASSIVE_LEVEL or IRQL DISPATCH_LEVEL.

Note The TDI feature is deprecated and will be removed in future versions of Microsoft Windows. Depending on how you use TDI, use either the Winsock Kernel (WSK) or Windows Filtering Platform (WFP). For more information about WFP and WSK, see Windows Filtering Platform and Winsock Kernel. For a Windows Core Networking blog entry about WSK and TDI, see Introduction to Winsock Kernel (WSK).


Target platform



Wdm.h (include Ntddk.h, Wdm.h, or Ntddk.h)



See also






Send comments about this topic to Microsoft