Ivo Ivanov (@logos128) commented about dlls/winebus.sys/bus_udev.c:
if (*bus || desc->vid || desc->pid) continue; sscanf(ptr, "HID_ID=%x:%x:%x\n", bus, &desc->vid, &desc->pid); }
if (!strncmp(ptr, "PRODUCT=", 8) && *bus != BUS_BLUETOOTH)
if (!strcmp(subsystem, "input")) {
if (desc->version) continue;
if (!strcmp(subsystem, "usb"))
sscanf(ptr, "PRODUCT=%x/%x/%x\n", &desc->vid, &desc->pid, &desc->version);
else
if (!strncmp(ptr, "PRODUCT=", 8))
{
if (desc->version) continue; sscanf(ptr, "PRODUCT=%x/%x/%x/%x\n", bus, &desc->vid, &desc->pid, &desc->version);
I've found that the 'input' subsystem returns bcdHID here instead of bcdDevice for device revision. Since we parse the 'input' subsystem first, it extracts this value for desc->version, so when the 'usb' subsystem gets parsed it skips the extraction of the correct value.
For this reason I've added the check for *bus == BUS_BLUETOOTH here, so it won't extract it from here, and allows it to be extracted from the 'usb' subsystem in the next turn.
Maybe an elegant solution here is to just parse the 'usb' subsystem before the 'input' in udev_add_device().