And match it in winehid.sys instead of individual bus ids.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
This series should apply smoothly with the previous winebus.sys. I'm also sending it now because it may need a bit more consideration. The rationale of the design is described below:
The idea here is to create a new xinput.sys driver, which will match xinput-compatible winebus.sys devices, and create two device nodes on top of the underlying device.
The first one will be the public "&IG_00" XInput bogus HID gamepad, as native has, and as Win32 SDL expects to see.
The other will be a pass-through to the underlying device, but although it's going to be an HID compatible device too, it will need to be exposed on a different interface class GUID in order to be used only by Wine XInput.
The second node will filter its read requests, and then translate them into the corresponding bogus XInput HID report, passing them to the first one for its read request completion.
This design removes the need to really care about XInput gamepad compat in winebus.sys, making it possible to extend the HID reports there to include the full capabilities of the unix devices:
* It will allow the user-space XInput implementation to have access to the full capabilities of the underlying device, and not be limited by the bogus HID compatibility anymore.
* It also removes an eventual need to duplicate the winebus devices, as the two nodes will only need one underlying device (the bogus XInput node will never actually request reads to its underlying PDO).
* And finally it makes it possible to have XInput compatibility with any underlying device, not just with SDL or evdev where we handle the report creation. Even hidraw or iohid device reports can be translated to the XInput HID reports.
dlls/winebus.sys/main.c | 22 ++++++++++++++++++++-- dlls/winehid.sys/winehid.inf | 7 +------ 2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index e372ec6db3f..e360416b5dd 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -225,7 +225,7 @@ static WCHAR *get_device_id(DEVICE_OBJECT *device) return dst; }
-static WCHAR *get_compatible_ids(DEVICE_OBJECT *device) +static WCHAR *get_hardware_ids(DEVICE_OBJECT *device) { struct device_extension *ext = (struct device_extension *)device->DeviceExtension; WCHAR *dst; @@ -239,6 +239,24 @@ static WCHAR *get_compatible_ids(DEVICE_OBJECT *device) return dst; }
+static WCHAR *get_compatible_ids(DEVICE_OBJECT *device) +{ + static const WCHAR hid_compat[] = + { + 'W','I','N','E','B','U','S','\','W','I','N','E','_','C','O','M','P','_','H','I','D',0 + }; + DWORD len = strlenW(hid_compat); + WCHAR *dst; + + if ((dst = ExAllocatePool(PagedPool, (len + 2) * sizeof(WCHAR)))) + { + strcpyW(dst, hid_compat); + dst[len + 1] = 0; + } + + return dst; +} + static void remove_pending_irps(DEVICE_OBJECT *device) { struct device_extension *ext = device->DeviceExtension; @@ -441,7 +459,7 @@ static NTSTATUS handle_IRP_MN_QUERY_ID(DEVICE_OBJECT *device, IRP *irp) { case BusQueryHardwareIDs: TRACE("BusQueryHardwareIDs\n"); - irp->IoStatus.Information = (ULONG_PTR)get_compatible_ids(device); + irp->IoStatus.Information = (ULONG_PTR)get_hardware_ids(device); break; case BusQueryCompatibleIDs: TRACE("BusQueryCompatibleIDs\n"); diff --git a/dlls/winehid.sys/winehid.inf b/dlls/winehid.sys/winehid.inf index f9ed4091217..c1d8a1cf999 100644 --- a/dlls/winehid.sys/winehid.inf +++ b/dlls/winehid.sys/winehid.inf @@ -7,12 +7,7 @@ Class=HIDClass Wine=mfg_section
[mfg_section] -Wine hidraw device=device_section,HIDRAW -Wine IOHID device=device_section,IOHID -Wine libevent device=device_section,LNXEV -Wine SDL HID device=device_section,SDLJOY -Wine mouse device=device_section,WINEMOUSE -Wine keyboard device=device_section,WINEKEYBOARD +Wine HID compatible device=device_section,WINEBUS\WINE_COMP_HID
[device_section.Services] AddService = winehid,0x2,svc_section