问题
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.
回答1:
The answer from Jks Liu already points in the right direction. The best way to emulate a mouse these days is to emulate USB HID hardware.
If your virtual mouse data comes from hardware you have control over, you can as well skip the driver part and make your hardware HID compliant.
If we're talking about a pure software emulation, I think your best bet will be to emulate a USB device that identifies itself as a HID device. There's a great MSDN article on creating your own USB device emulation. The good thing is that they're using HID as an example USB descriptor:
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
};
To know which endpoints and HID data you need to send, you could read the HID specs, but easier would be to take a look into existing microcontroller implementations. A lot of microcontroller brands have examples on how to emulate a USB HID mouse with their USB stack. Some examples:
- Atmel - AT91 USB HID Driver implementation
- Microchip - USB HID Class on an Embedded Device
- Arduino - A USB HID Keyboard, Mouse, Touchscreen emulator
回答2:
HID is a standard defined by USB. So Microsoft does not define the format. In fact, HID is so versatile that the format should be defined by yourself in the HID report descriptor.
HID descriptor is defined in Device Class Definition HID and HID Usage Tables.
In page 61 of `Device Class Definition HID' there is an example of mouse which is exact what you want.
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
回答3:
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:
- Mouse input (the device sending data to the Windows mouse stack)
- Mouse output (the device I use to send mouse input to my driver)
- Keyboard input (the device sending data to the Windows keyboard stack)
- Keyboard output (the device I use to send keyboard input to my driver)
来源:https://stackoverflow.com/questions/47942366/windows-virtual-mouse-driver