6.3.4.4 Points to Consider in Implementing Dispatch(Internal)DeviceControl

Keep the following points in mind when implementing a new DispatchDeviceControl or DispatchInternalDeviceControl routine:

·At a minimum, a higher-level driver must copy the parameters for an IRP_MJ_DEVICE_CONTROL or IRP_MJ_INTERNAL_DEVICE_CONTROL request from its own I/O stack location in the IRP to the next-lower-level driver's I/O stack location. Then, it must call IoCallDriver with a pointer to the next-lower driver's device object and the IRP.

Such a higher-level driver should propagate the status value returned by IoCallDriver or set in the returned IRP's I/O status block when it returns control for a request that lower drivers handle synchronously.

·The underlying device driver must process device control requests unless it has a closely coupled class driver that completes a subset of these requests on its behalf. A device driver's DispatchDeviceControl routine usually begins processing these requests by switching on the Parameters.DeviceIoControl.IoControlCode in its I/O stack location of each IRP.

·A device driver should check the parameters passed in with the request and fail the IRP with an appropriate error if any parameter is invalid. The most common check on the validity of parameters to these requests has the form:

if (Irp->Parameters.DeviceIoControl.InputBufferLength <
(sizeof(IOCTL_SPECIFIC_STRUCTURE))) {

status = STATUS_XXX;

or

if (Irp->Parameters.DeviceIoControl.OutputBufferLength <
(sizeof(IOCTL_SPECIFIC_STRUCTURE))) {

status = STATUS_XXX;

where the status value set is one of STATUS_BUFFER_TOO_SMALL or STATUS_INVALID_PARAMETER.

·Every device driver's DispatchDeviceControl or DispatchInternalDeviceControl routine must handle the receipt of an unrecognized I/O control code by setting the I/O status block with an appropriate NTSTATUS value, setting its Information field to zero, and completing the IRP with a PriorityBoost of IO_NO_INCREMENT.

·The particular I/O control codes a device driver handles must include any device-type-specific, system-defined I/O control codes for the same type of device. See the Kernel-mode Driver Reference for more information about the system requirements for each type of device and the corresponding (SDK) header files, each beginning with the prefix ntdd, for declarations of the system-defined structures for these I/O control codes.

·At the discretion of the driver designer, the class driver of a closely coupled class/port driver pair can process and complete a subset of device control requests without passing them on to the underlying port driver. However, such a class driver must pass on all valid device control requests that require a change of state for the device and those that require the return of volatile information about the device, such as its current baud rate, volume, or video mode.