Windows虚拟鼠标驱动程序

时间:2017-12-22 13:28:59

标签: windows driver mouse hid wdk

我正在开发KMDF虚拟鼠标驱动程序。

一般的想法是KMDF根枚举的非过滤驱动程序,它能够将输出报告发送到鼠标和键盘驱动程序堆栈。

我的驱动程序已经在运行并向其他驱动程序堆栈发送请求,但没有结果。

报告类型和数据包格式在Microsoft资源上几乎没有记录。没有关于我需要发送哪些数据和设备以便移动鼠标指针,模拟点击(使用鼠标或键盘)的信息。

只有关于HID客户端,驱动程序等的一般信息。他们的文档通常是指Windows驱动程序示例git存储库,但存储库不包含任何接近我的任务的源。很少有人参与驱动程序开发,因此也没有教程。

我希望能给我一个提示,在哪里可以找到更多关于我的任务的信息。

3 个答案:

答案 0 :(得分:4)

来自Jks Liu的answer已指向正确的方向。这些天模拟鼠标的最佳方法是模拟USB HID硬件。

如果您的虚拟鼠标数据来自您可以控制的硬件,您也可以跳过驱动程序部分并使您的硬件HID兼容。

如果我们谈论纯软件模拟,我认为最好的办法是模拟一个将自己标识为HID设备的USB设备。创建自己的USB设备仿真有一个很棒的MSDN article。好消息是他们使用HID作为USB描述符的示例:

const UCHAR g_UsbDeviceDescriptor[] = {
    // Device Descriptor
    0x12, // Descriptor Size
    0x01, // Device Descriptor Type
    0x00, 0x03, // USB 3.0
    0x00, // Device class
    0x00, // Device sub-class
    0x00, // Device protocol
    0x09, // Maxpacket size for EP0 : 2^9
    0x5E, 0x04, // Vendor ID
    0x39, 0x00, // Product ID 
    0x00, // LSB of firmware version
    0x03, // MSB of firmware version
    0x01, // Manufacture string index
    0x03, // Product string index
    0x00, // Serial number string index
    0x01 // Number of configurations
};

要知道您需要发送哪些端点和HID数据,您可以阅读HID规范,但更容易看一下现有的微控制器实现。许多微控制器品牌都有关于如何使用USB堆栈模拟USB HID鼠标的示例。一些例子:

答案 1 :(得分:1)

HID是USB定义的标准。所以微软没有定义格式。实际上,HID是如此通用,以至于格式应该由您自己在HID报告描述符中定义。

HID描述符在Device Class Definition HIDHID Usage Tables中定义。

在“设备类定义HID”的第61页中,有一个鼠标的例子就是你想要的。 Usage Page (Generic Desktop), Usage (Mouse), Collection (Application), Usage (Pointer), Collection (Physical), Report Count (3), Report Size (1), Usage Page (Buttons), Usage Minimum (1), Usage Maximum (3), Logical Minimum (0), Logical Maximum (1), Input (Data, Variable, Absolute), Report Count (1), Report Size (5), Input (Constant), Report Size (8), Report Count (2), Usage Page (Generic Desktop), Usage (X), Usage (Y), Logical Minimum (-127), Logical Maximum (127), Input (Data, Variable, Relative), End Collection, End Collection

答案 2 :(得分:0)

这是我工作的驱动程序的报告描述符集。

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
};

它包括:

  1. 鼠标输入(将数据发送到Windows鼠标堆栈的设备)
  2. 鼠标输出(我用来将鼠标输入发送到驱动程序的设备)
  3. 键盘输入(将数据发送到Windows键盘堆栈的设备)
  4. 键盘输出(我用来将键盘输入发送给驱动程序的设备)