The TdiDispatchInternalDeviceControl routine handles TDI_XXX device-control requests from kernel-mode clients.
NTSTATUS TdiDispatchInternalDeviceControl( _In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp );
- DeviceObject [in]
Pointer to the device object created by the TDI driver.
- Irp [in]
Pointer to the IRP.
A transport calls IoGetCurrentIrpStackLocation with the given Irp to get a pointer to its own I/O stack location in the IRP, shown in the following list as IrpSp. The transport can use the information set in the following members of the IRP in processing an internal device-control request:
Specifies the final status of the operation. The transport sets this member to the same value that will be returned by TdiDispatchInternalDeviceControl.
Usually, this member is initialized to zero. Depending on the IrpSp-> MinorFunction value, the transport resets this member to the number of bytes of data it is returning to the client or to the number of bytes of data it transferred before the transport completes this IRP.
- IrpSp-> MajorFunction
Specifies IRP_MJ_INTERNAL_DEVICE_CONTROL. The transport can ignore this member if it exports a TdiDispatchInternalDeviceControl routine that handles only these requests.
- IrpSp > MinorFunction
Specifies the TDI_XXX code for the operation to be carried out.
- IrpSp-> FileObject
Pointer to the file object representing an address, connection endpoint, or control channel. The transport driver uses the values of the FsContext and possibly FsContext2 fields in this file object to access any driver-allocated state for operations on the address, connection endpoint, or control channel.
TdiDispatchInternalDeviceControl returns STATUS_SUCCESS if it completed the requested operation successfully. Otherwise, it returns a driver-determined error status, such as STATUS_INVALID_DEVICE_REQUEST or STATUS_INVALID_DEVICE_STATE.
When preparing a request, a kernel-mode client either allocates an IRP with TdiBuildInternalDeviceControlIrp or uses an IRP passed in from a higher network layer. The client calls a TdiBuildXxx macro to set up the IRP for the underlying transport with the corresponding TDI_XXX as the MinorFunction code and IRP_MJ_INTERNAL_DEVICE_CONTROL as the MajorFunction code in the IRP. When it has set up the IRP, the client calls IoCallDriver to submit the request to the underlying transport's TdiDispatchInternalDeviceControl routine.
Usually, a transport's TdiDispatchInternalDeviceControl routine determines whether the given file object at IrpSp-> FileObject represents an address, connection endpoint, or control channel, because certain TDI_XXX are relevant only to addresses, others are relevant only to connection endpoints, and a subset of TDI_XXX codes are relevant to both and to control channels. The following summarizes which TDI_XXX codes are likely to be processed for each:
- FileObject represents an address
- FileObject represents a connection endpoint
- FileObject represents an address, connection endpoint, or control channel
For each TDI_XXX the transport handles, its TdiDispatchInternalDeviceControl routine usually calls an internal driver function to carry out the requested operation. Possibly, the internal driver function also complete the IRP, particularly if that function transfers data because it then can set IoStatus.Information to the appropriate value, leaving TdiDispatchInternalDeviceControl to complete IRPs in which this member is set to zero. Each such internal function usually returns an NTSTATUS-type value, which TdiDispatchInternalDeviceControl propagates when it returns control.
For more information about each of the TDI_XXX mentioned here, see TDI IOCTLs for Transport Drivers, next.
|PASSIVE_LEVEL or DISPATCH_LEVEL|