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.