HID Device Shown as Unknown Devices in Win7, but Works in Win8 and onwards

Hello,

I’m working on a KMDF root-enumerated HID miniport driver. The driver
is installed as ROOT\RUBYINPUT. On IOCTL_HID_GET_REPORT_DESCRIPTOR,
the driver returns a descriptor with 3 devices: 2 mice and 1 keyboard.

The driver is installed by devcon.exe. On Win8 and onwards, the root
device, 1 HID keyboard and 2 HID mice all appear in Device Manager and
everything is working well.

However on Win7, only the root device is installed properly and the 3
HID devices are shown as unknown devices with the yellow question
marks on them. I can manually update the driver for those unknown
devices and choose HID keyboard / mouse. However we expect the driver
to be installed automatically by our MSI. From the kd, the last call
to the driver is EvtDeviceSelfManagedIoInit registered in PnP
callbacks.

I double checked the driver code and couldn’t find a clue. One thing I
notice is the HID keyboard and mice in Win7 don’t have a Hardware Id,
while in Win8 they do.

Is there any significant difference between Win7 and Win8 on HID handling?

The HID descriptor I’m using is:
HID_REPORT_DESCRIPTOR g_keyboardReportDescriptor =
{
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application)
0x85, g_keyboardReportId, // Report ID (1) <– used for keyboard reports
0x05, 0x07, // Usage Page (Key Codes)
0x19, 0xE0, // Usage Minimum (224 == Left Ctrl)
0x29, 0xE7, // Usage Maximum (231 == Right GUI)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1 bit)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data, Variable, Absolute) <– modifier keys
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8 bits)
0x81, 0x01, // Input (Constant) <– reserved byte
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1 bit)
0x05, 0x08, // Usage Page (LEDs)
0x19, 0x01, // Usage Minimum (1 == NumLock)
0x29, 0x05, // Usage Maximum (5 == Kana)
0x91, 0x02, // Output (Data, Variable, Absolute) <– LED report
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3 bits)
0x91, 0x01, // Output (Constant) <– LED report padding
0x95, 0x06, // Report Count (6)
0x75, 0x08, // Report Size (8 bits)
0x15, 0x00, // Logical Minimum (0 == Reserved)
0x25, g_keyboardKeyCount, // Logical Maximum (101 ==
Application [Windows MENU key])
0x05, 0x07, // Usage Page (Key Codes)
0x19, 0x00, // Usage Minimum (0 == Reserved)
0x29, g_keyboardKeyCount, // Usage Maximum (101 == Application)
0x81, 0x00, // Input (Data, Array) <– non-modifier keys
0xC0, // End Collection
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x02, // Usage (Mouse)
0xA1, 0x01, // Collection (Application)
0x85, g_mouseReportId, // Report ID (2) <– used for mouse reports
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x05, 0x09, // Usage Page (Buttons)
0x19, 0x01, // Usage Minimum (1)
0x29, g_mouseButtonCount, // Usage Maximum (5)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, g_mouseButtonCount, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data, Variable, Absolute) <– mouse buttons
0x95, 0x01, // Report Count (1)
0x75, static_cast(8 - g_mouseButtonCount), // Report Size (3)
0x81, 0x01, // Input (Constant) <– padding
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)
0xA1, 0x02, // Collection (Logical)
0x85, g_wheelScaleReportId, // Report ID (3)
0x09, 0x48, // Usage (Resolution Multiplier)
0x95, 0x01, // Report Count (1)
0x75, 0x04, // Report Size (4)
0x15, 0x00, // Logical Minimum (0)
0x25, g_wheelScaleMax, // Logical Maximum (1?)
0x35, 0x01, // Physical Minimum (1)
0x45, g_wheelScaleMax, // Physical Maximum (6)
0xB1, 0x02, // Feature (Data, Variable, Absolute)
0x85, g_mouseReportId, // Report ID (2)
0x09, 0x38, // Usage (Wheel)
0x35, 0x00, // Physical Minimum (0)
0x45, 0x00, // Physical Maximum (0)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (+127)
0x75, 0x08, // Report Size (8)
0x81, 0x06, // Input (Data, Variable, Relative)
0xC0, // End Collection
0xA1, 0x02, // Collection (Logical)
0x85, g_wheelScaleReportId, // Report ID (3)
0x09, 0x48, // Usage (Resolution Multiplier)
0x95, 0x01, // Report Count (1)
0x75, 0x04, // Report Size (4)
0x15, 0x00, // Logical Minimum (0)
0x25, g_wheelScaleMax, // Logical Maximum (1?)
0x35, 0x01, // Physical Minimum (1)
0x45, g_wheelScaleMax, // Physical Maximum (6)
0xB1, 0x02, // Feature (Data, Variable, Absolute)
0x85, g_mouseReportId, // Report ID (2)
0x05, 0x0C, // Usage Page (Consumer Devices)
0x0A, 0x38, 0x02, // Usage (AC Pan)
0x35, 0x00, // Physical Minimum (0)
0x45, 0x00, // Physical Maximum (0)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (+127)
0x75, 0x08, // Report Size (8)
0x81, 0x06, // Input (Data, Variable, Relative)
0xC0, // End Collection
0xC0, // End Collection
0xC0, // End Collection
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x02, // Usage (Mouse)
0xA1, 0x01, // Collection (Application)
0x85, g_absoluteMouseReportId, // Report ID (4)
0xA1, 0x00, // Collection (Physical)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x15, 0x00, // Logical Minimum (0)
0x27, 0xFF, 0xFF, 0x00, 0x00, // Logical Maximum (65535)
0x35, 0x00, // Physical Minimum (0)
0x47, 0xFF, 0xFF, 0x00, 0x00, // Physical Maximum (65535)
0x95, 0x02, // Report Count (2)
0x75, 0x10, // Report Size (16 bits)
0x81, 0x02, // Input (Data, Variable, Absolute)
0xC0, // End Collection
0xC0, // End Collection
};

Thanks
-Mike