windowsdrivermousehidwdk

Windows virtual mouse driver


I am developing a KMDF virtual mouse driver.

The general idea is a KMDF root enumerated non-filter driver which will be able to send output reports to the mouse and keyboard driver stacks.

My driver is already working and sending requests to other driver stacks, but with no result.

Report types and packet formats are pretty undocumented on Microsoft resources. There are no information about which data and to which device I need to send in order to move the mouse pointer, simulate clicks (with either mouse or keyboard).

There is only general information about HID clients, drivers etc. Their documentation often refers to the Windows Driver Samples git repository, but the repository does not contain any sources close to my task. Few people are in driver development, so there are no tutorials either.

I would appreciate giving me a hint where can I find more about my task.


Solution

  • Here is the report descriptor set of my working driver.

    HID_REPORT_DESCRIPTOR g_reportDescriptor[] = {
        0x05, 0x01,     // USAGE_PAGE (Generic Desktop)
        0x09, 0x02,     // USAGE (Mouse)
        0xA1, 0x01,     // COLLECTION (Application)
        0x85,               REPORT_ID_MOUSE_INPUT,
        0x09, 0x01,         // USAGE_PAGE (Pointer)
        0xA1, 0x00,         // COLLECTION (Physical)
        0x05, 0x09,             // USAGE_PAGE (Buttons)
        0x19, 0x01,             // USAGE_MINIMUM (1)
        0x29, 0x03,             // USAGE_MAXIMUM (3)
        0x15, 0x00,             // LOGICAL_MINIMUM (0)
        0x25, 0x01,             // LOGICAL_MAXIMUM (1)
        0x95, 0x03,             // REPORT_COUNT (3)
        0x75, 0x01,             // REPORT_SIZE (1)
        0x81, 0x02,             // INPUT (Data, Variable, Absolute)
        0x95, 0x01,             // REPORT_COUNT (1)
        0x75, 0x05,             // REPORT_SIZE (5)
        0x81, 0x01,             // INPUT (Constant)
        0x05, 0x01,             // USAGE_PAGE (Generic Desktop)
        0x09, 0x30,             // USAGE (X)
        0x09, 0x31,             // USAGE (Y)
        0x15, 0x81,             // LOGICAL_MINIMUM (-127)
        0x25, 0x7F,             // LOGICAL_MAXIMUM (127)
        0x75, 0x08,             // REPORT_SIZE (8)
        0x95, 0x02,             // REPORT_COUNT (2)
        0x81, 0x06,             // Input (Data, Variable, Relative)
        0xC0,               // END_COLLECTION
        0xC0,           // END_COLLECTION
    
        0x05, 0x01,     // USAGE_PAGE (Generic Desktop)
        0x09, 0x00,     // USAGE (Undefined)
        0xa1, 0x01,     // COLLECTION (Application)
        0x85,               REPORT_ID_MOUSE_OUTPUT,
        0x09, 0x00,         // USAGE (Undefined)
        0x15, 0x00,         // LOGICAL_MINIMUM (0)
        0x26, 0xff, 0x00,   // LOGICAL_MAXIMUM (255)
        0x95, 0x03,         // REPORT_COUNT (3)
        0x75, 0x08,         // REPORT_SIZE (8)
        0x91, 0x02,         // OUTPUT (Data, Variable, Absolute)
        0xc0,           // END_COLLECTION
    
        0x05, 0x01,     // USAGE_PAGE (Generic Desktop)
        0x09, 0x06,     // USAGE (Keyboard)
        0xA1, 0x01,     // COLLECTION (Application)
        0x85,               REPORT_ID_KEYBOARD_INPUT,
        0x05, 0x07,         // USAGE_PAGE (Keyboard Key Codes)
        0x19, 0xE0,         // USAGE_MINIMUM (224)
        0x29, 0xE7,         // USAGE_MAXIMUM (231)
        0x15, 0x00,         // LOGICAL_MINIMUM (0)
        0x25, 0x01,         // LOGICAL_MAXIMUM (1)
        0x75, 0x01,         // REPORT_SIZE (1)
        0x95, 0x08,         // REPORT_COUNT (8)
        0x81, 0x02,         // INPUT (Data, Variable, Absolute)
        0x95, 0x01,         // REPORT_COUNT (1)
        0x75, 0x08,         // REPORT_SIZE (8)
        0x81, 0x01,         // INPUT (Constant)
        0x19, 0x00,         // USAGE_MINIMUM (0)
        0x29, 0x65,         // USAGE_MAXIMUM (101)
        0x15, 0x00,         // LOGICAL_MINIMUM (0)
        0x25, 0x65,         // LOGICAL_MAXIMUM (101)
        0x95, 0x06,         // REPORT_COUNT (6)
        0x75, 0x08,         // REPORT_SIZE (8)
        0x81, 0x00,         // INPUT (Data, Array, Absolute)
        0x05, 0x08,         // USAGE_PAGE (LEDs)
        0x19, 0x01,         // USAGE_MINIMUM (Num Lock)
        0x29, 0x05,         // USAGE_MAXIMUM (Kana)
        0x95, 0x05,         // REPORT_COUNT (5)
        0x75, 0x01,         // REPORT_SIZE (1)
        0x91, 0x02,         // OUTPUT (Data, Variable, Absolute)
        0x95, 0x01,         // REPORT_COUNT (1)
        0x75, 0x03,         // REPORT_SIZE (3)
        0x91, 0x01,         // OUTPUT (Constant)
        0xC0,           // END_COLLECTION
    
        0x05, 0x01,     // USAGE_PAGE (Generic Desktop)
        0x09, 0x00,     // USAGE (Undefined)
        0xa1, 0x01,     // COLLECTION (Application)
        0x85,               REPORT_ID_KEYBOARD_OUTPUT,
        0x09, 0x00,         // USAGE (Undefined)
        0x15, 0x00,         // LOGICAL_MINIMUM (0)
        0x26, 0xff, 0x00,   // LOGICAL_MAXIMUM (255)
        0x95, 0x08,         // REPORT_COUNT (8)
        0x75, 0x08,         // REPORT_SIZE (8)
        0x91, 0x02,         // OUTPUT (Data, Variable, Absolute)
        0xc0            // END_COLLECTION
    };
    

    It consists of:

    1. Mouse input (the device sending data to the Windows mouse stack)
    2. Mouse output (the device I use to send mouse input to my driver)
    3. Keyboard input (the device sending data to the Windows keyboard stack)
    4. Keyboard output (the device I use to send keyboard input to my driver)