2.1 Keyboard I/O Requests

IRP_MJ_CREATE (class)

Operation

The keyboard class driver sends an IRP_MJ_INTERNAL_DEVICE_CONTROL request with the I/O control code IOCTL_INTERNAL_KEYBOARD_ENABLE to the port driver.

When Called

This request is sent to the class driver when the Win32 subsystem, or possibly a vendor-supplied device driver applet, requests a handle for the file object that represents the keyboard device object. A keyboard is a nonexclusive device. However, only the Win32 subsystem has sufficient privilege to read incoming keyboard data.

I/O Status Block

The Information field is set to zero. The class driver sets the Status field to STATUS_SUCCESS or to the error status returned by the port driver for the IOCTL_INTERNAL_KEYBOARD_ENABLE request.

IRP_MJ_CREATE (port)

Operation

Returns STATUS_SUCCESS, indicating that the port exists.

When Called

This request is sent to the port driver when the class driver’s DriverEntry routine calls IoGetDeviceObjectPointer as part of its attempt to layer itself above the port driver.

I/O Status Block

The port driver sets the Status field to STATUS_SUCCESS.

IRP_MJ_CLEANUP (class)

Operation

Cancels each IRP currently queued on behalf of the caller in the device queue of the class driver’s device object by setting STATUS_CANCELLED in the IRP’s I/O status block and completing the IRP. The next request on behalf of this caller will be an IRP_MJ_CLOSE.

When Called

Either the system is being shut down because the Win32 subsystem is releasing its file object handles, or the Win32 subsystem is releasing the handle of the class driver’s device on behalf of an application.

I/O Status Block

Always sets the Status field to STATUS_SUCCESS and the Information field to zero for the cleanup IRP.

IRP_MJ_CLOSE (class)

Operation

The keyboard class driver sends an IRP_MJ_INTERNAL_DEVICE_CONTROL request with the I/O control code IOCTL_INTERNAL_KEYBOARD_DISABLE to the port driver.

When Called

This request is sent to the class driver following its completion of an IRP_MJ_CLEANUP request or when the system is being shut down.

I/O Status Block

Information is set to zero. The class driver sets Status to STATUS_SUCCESS or to the error status returned by the port driver for the IOCTL_INTERNAL_KEYBOARD_DISABLE request.

IRP_MJ_CLOSE (port)

Operation

Returns STATUS_SUCCESS.

When Called

The port is being closed, normally only when the system is being shut down.

I/O Status Block

The port driver sets the Status field to STATUS_SUCCESS.

IRP_MJ_READ

Operation

Transfers data from the device to the buffer at Irp->AssociatedIrp.SystemBuffer. The device data is packaged into one or more keyboard data packets defined as follows:

typedef struct KEYBOARD_INPUT_DATA {
    USHORT UnitId;   // zero-based unit number of the keyboard port
    USHORT MakeCode; // the make scan code (key depression)
    USHORT Flags;    // indicates a break (key release) and
                     // other miscellaneous scan-code info
    USHORT Reserved;
    ULONG ExtraInformation; // device-specific additional
                            // information for the event
} KEYBOARD_INPUT_DATA, *PKEYBOARD_INPUT_DATA

When Called

Any time after the IRP_MJ_CREATE request has been completed with STATUS_SUCCESS. A read request can be completed successfully only if it was made by a trusted subsystem, that is, by the Win32 subsystem. The class driver performs a privilege check to enforce this restriction.

I/O Status Block

The Information field always contains the number of bytes read into the system buffer. This is at most the requested length and at least one keyboard data packet when the Status field is set to STATUS_SUCCESS. Otherwise, the Status field can be set to STATUS_BUFFER_TOO_SMALL, STATUS_PRIVILEGE_NOT_HELD, or STATUS_CANCELLED, and no data is returned.

IRP_MJ_FLUSH_BUFFERS (class)

Operation

Clears the keyboard class driver’s internal data queue and flushes the keyboard device buffer, if applicable.

When Called

Not currently. Reserved for future use.

I/O Status Block

The Status field is set to STATUS_SUCCESS and the Information field is zero.

IRP_MJ_DEVICE_CONTROL

Operation

Determined by the I/O control code set at Parameters.DeviceIoControlCode.IoControlCode in the driver’s I/O stack location of the IRP. The system-supplied keyboard class driver usually performs sanity checks on the validity of the parameters for the I/O control code, determines the target UnitId (port) for the request, and then passes the request on to the port driver.

Drivers should validate the input UnitId, which is a zero-based value identifying the target keyboard port, for all I/O control codes for which the corresponding structures have this member. A driver should fail the request when an input UnitId value is out of range for the number of keyboards it supports.

When Called

The Win32 subsystem, or possibly a vendor-supplied device driver applet, has called DeviceIoControl to communicate a request to the keyboard driver.

I/O Status Block

The Status field value depends on the operation, either STATUS_SUCCESS or an appropriate STATUS_XXX value. For most operations, the set of possible STATUS_XXX values includes those propagated from a call to a support routine or the port driver and /or those chosen by the driver designer. In general, the Information field of the I/O status block is set to the number of bytes of returned data when the device driver completes the IRP.

The following section Keyboard I/O Control Codes summarizes the I/O control codes handled by keyboard drivers.