Windows虚拟鼠标驱动程序



我正在开发一个kmdf虚拟鼠标驱动程序。

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

我的驱动程序已经在工作并将请求发送给其他驱动程序堆栈,但没有结果。

报告类型和数据包格式在Microsoft Resources上都没有证明。没有有关哪些数据以及我需要发送的设备以移动鼠标指针,模拟点击(使用鼠标或键盘)。

只有有关HID客户端,驱动程序等的一般信息。他们的文档通常是指Windows驱动程序样本GIT存储库,但是存储库不包含接近我任务的任何来源。很少有人正在开发驾驶员,因此也没有教程。

我很喜欢给我一个提示,我可以在哪里找到有关我的任务的更多信息。

JKS刘的答案已经指向正确的方向。如今,模仿鼠标的最佳方法是模仿USB HID HID WARDWARE。

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

如果我们谈论的是纯软件仿真,我认为您最好的选择是效仿将自己标识为HID设备的USB设备。有一篇关于创建自己的USB设备仿真的精彩文章。好事是他们以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规格,但更容易查看现有的MicroController实现。许多微控制器品牌都有有关如何使用USB堆栈模拟USB HID鼠标的示例。一些例子:

  • attel- AT91 USB HID HID驱动程序实现
  • Microchip- USB HID类在嵌入式设备上
  • Arduino- USB HID键盘,鼠标,触摸屏仿真器

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

HID描述符在设备类别定义中定义了HID和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

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

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. 键盘输出(我用来将键盘输入发送到驱动程序的设备)

最新更新