For after the code freeze
From: Etaash Mathamsetty etaash.mathamsetty@gmail.com
--- dlls/xinput1_3/main.c | 32 ++++++++++++++++++++++++++++++++ dlls/xinput1_4/xinput1_4.spec | 1 + include/xinput.h | 11 +++++++++++ 3 files changed, 44 insertions(+)
diff --git a/dlls/xinput1_3/main.c b/dlls/xinput1_3/main.c index e69553fba16..c4b2d5e871b 100644 --- a/dlls/xinput1_3/main.c +++ b/dlls/xinput1_3/main.c @@ -1129,3 +1129,35 @@ DWORD WINAPI DECLSPEC_HOTPATCH XInputGetBatteryInformation(DWORD index, BYTE typ
return ERROR_NOT_SUPPORTED; } + +DWORD WINAPI DECLSPEC_HOTPATCH XInputGetCapabilitiesEx(DWORD unk, DWORD index, DWORD flags, XINPUT_CAPABILITIES_EX *caps) +{ + HIDD_ATTRIBUTES attr; + TRACE("unk %lu, index %lu, flags %#lx, capabilities %p.\n", unk, index, flags, caps); + + start_update_thread(); + + if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS; + + if (!controller_lock(&controllers[index])) return ERROR_DEVICE_NOT_CONNECTED; + + if (flags & XINPUT_FLAG_GAMEPAD && controllers[index].caps.SubType != XINPUT_DEVSUBTYPE_GAMEPAD) + { + controller_unlock(&controllers[index]); + return ERROR_DEVICE_NOT_CONNECTED; + } + + memcpy(&caps->Capabilities, &controllers[index].caps, sizeof(caps->Capabilities)); + + if (!HidD_GetAttributes(controllers[index].device, &attr)) + { + controller_unlock(&controllers[index]); + return ERROR_DEVICE_NOT_CONNECTED; + } + + caps->VendorId = attr.VendorID; + caps->ProductId = attr.ProductID; + caps->VersionNumber = attr.VersionNumber; + + return ERROR_SUCCESS; +} diff --git a/dlls/xinput1_4/xinput1_4.spec b/dlls/xinput1_4/xinput1_4.spec index 8c3f4c0cd73..22c511237dd 100644 --- a/dlls/xinput1_4/xinput1_4.spec +++ b/dlls/xinput1_4/xinput1_4.spec @@ -7,3 +7,4 @@ 8 stdcall XInputGetKeystroke(long long ptr) 10 stub XInputGetAudioDeviceIds(long ptr ptr ptr ptr) 100 stdcall XInputGetStateEx(long ptr) +108 stdcall XInputGetCapabilitiesEx(long long long ptr) diff --git a/include/xinput.h b/include/xinput.h index f7c291630cb..4fca5a04480 100644 --- a/include/xinput.h +++ b/include/xinput.h @@ -210,6 +210,16 @@ typedef struct _XINPUT_CAPABILITIES { XINPUT_VIBRATION Vibration; } XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
+typedef struct _XINPUT_CAPABILITIES_EX +{ + XINPUT_CAPABILITIES Capabilities; + WORD VendorId; + WORD ProductId; + WORD VersionNumber; + WORD unk1; + DWORD unk2; +} XINPUT_CAPABILITIES_EX, *PXINPUT_CAPABILITIES_EX; + /* * Defines the structure for a joystick input event which is * retrieved using the function XInputGetKeystroke @@ -237,6 +247,7 @@ DWORD WINAPI XInputSetState(DWORD, XINPUT_VIBRATION*); DWORD WINAPI XInputGetState(DWORD, XINPUT_STATE*); DWORD WINAPI XInputGetKeystroke(DWORD, DWORD, PXINPUT_KEYSTROKE); DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*); +DWORD WINAPI XInputGetCapabilitiesEx(DWORD, DWORD, DWORD, XINPUT_CAPABILITIES_EX*); DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*); DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
From: Etaash Mathamsetty etaash.mathamsetty@gmail.com
--- dlls/xinput1_3/main.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-)
diff --git a/dlls/xinput1_3/main.c b/dlls/xinput1_3/main.c index c4b2d5e871b..beba90b4b45 100644 --- a/dlls/xinput1_3/main.c +++ b/dlls/xinput1_3/main.c @@ -1086,25 +1086,17 @@ DWORD WINAPI DECLSPEC_HOTPATCH XInputGetKeystroke(DWORD index, DWORD reserved, P
DWORD WINAPI DECLSPEC_HOTPATCH XInputGetCapabilities(DWORD index, DWORD flags, XINPUT_CAPABILITIES *capabilities) { - TRACE("index %lu, flags %#lx, capabilities %p.\n", index, flags, capabilities); - - start_update_thread(); - - if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS; + XINPUT_CAPABILITIES_EX caps_ex; + DWORD ret;
- if (!controller_lock(&controllers[index])) return ERROR_DEVICE_NOT_CONNECTED; + ret = XInputGetCapabilitiesEx(0, index, flags, &caps_ex);
- if (flags & XINPUT_FLAG_GAMEPAD && controllers[index].caps.SubType != XINPUT_DEVSUBTYPE_GAMEPAD) + if (!ret) { - controller_unlock(&controllers[index]); - return ERROR_DEVICE_NOT_CONNECTED; + memcpy(capabilities, &caps_ex.Capabilities, sizeof(*capabilities)); }
- memcpy(capabilities, &controllers[index].caps, sizeof(*capabilities)); - - controller_unlock(&controllers[index]); - - return ERROR_SUCCESS; + return ret; }
DWORD WINAPI DECLSPEC_HOTPATCH XInputGetDSoundAudioDeviceGuids(DWORD index, GUID *render_guid, GUID *capture_guid)
Rémi Bernon (@rbernon) commented about include/xinput.h:
XINPUT_VIBRATION Vibration;
} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
+typedef struct _XINPUT_CAPABILITIES_EX +{
- XINPUT_CAPABILITIES Capabilities;
- WORD VendorId;
- WORD ProductId;
- WORD VersionNumber;
- WORD unk1;
- DWORD unk2;
+} XINPUT_CAPABILITIES_EX, *PXINPUT_CAPABILITIES_EX;
Please use spaces.
Rémi Bernon (@rbernon) commented about dlls/xinput1_3/main.c:
- {
controller_unlock(&controllers[index]);
return ERROR_DEVICE_NOT_CONNECTED;
- }
- memcpy(&caps->Capabilities, &controllers[index].caps, sizeof(caps->Capabilities));
- if (!HidD_GetAttributes(controllers[index].device, &attr))
- {
controller_unlock(&controllers[index]);
return ERROR_DEVICE_NOT_CONNECTED;
- }
- caps->VendorId = attr.VendorID;
- caps->ProductId = attr.ProductID;
- caps->VersionNumber = attr.VersionNumber;
You're missing unlock here, something like that would be better:
```suggestion:-16+0 DWORD ret = ERROR_SUCCESS;
/* ... */
if (!controller_lock(&controllers[index])) return ERROR_DEVICE_NOT_CONNECTED;
if (flags & XINPUT_FLAG_GAMEPAD && controllers[index].caps.SubType != XINPUT_DEVSUBTYPE_GAMEPAD) ret = ERROR_DEVICE_NOT_CONNECTED; if (!HidD_GetAttributes(controllers[index].device, &attr)) ret = ERROR_DEVICE_NOT_CONNECTED; else { caps->Capabilities = controllers[index].caps; caps->VendorId = attr.VendorID; caps->ProductId = attr.ProductID; caps->VersionNumber = attr.VersionNumber; }
controller_unlock(&controllers[index]); ```
Rémi Bernon (@rbernon) commented about dlls/xinput1_3/main.c:
return ERROR_NOT_SUPPORTED;
}
+DWORD WINAPI DECLSPEC_HOTPATCH XInputGetCapabilitiesEx(DWORD unk, DWORD index, DWORD flags, XINPUT_CAPABILITIES_EX *caps) +{
- HIDD_ATTRIBUTES attr;
- TRACE("unk %lu, index %lu, flags %#lx, capabilities %p.\n", unk, index, flags, caps);
```suggestion:-2+0 HIDD_ATTRIBUTES attr;
TRACE("unk %lu, index %lu, flags %#lx, capabilities %p.\n", unk, index, flags, caps);
```
Rémi Bernon (@rbernon) commented about dlls/xinput1_3/main.c:
- start_update_thread();
- if (index >= XUSER_MAX_COUNT) return ERROR_BAD_ARGUMENTS;
- XINPUT_CAPABILITIES_EX caps_ex;
- DWORD ret;
- if (!controller_lock(&controllers[index])) return ERROR_DEVICE_NOT_CONNECTED;
- ret = XInputGetCapabilitiesEx(0, index, flags, &caps_ex);
- if (flags & XINPUT_FLAG_GAMEPAD && controllers[index].caps.SubType != XINPUT_DEVSUBTYPE_GAMEPAD)
- if (!ret) {
controller_unlock(&controllers[index]);
return ERROR_DEVICE_NOT_CONNECTED;
}memcpy(capabilities, &caps_ex.Capabilities, sizeof(*capabilities));
```suggestion:-6+0 TRACE("index %lu, flags %#lx, capabilities %p.\n", index, flags, capabilities);
ret = XInputGetCapabilitiesEx(0, index, flags, &caps_ex); if (!ret) capabilities = caps_ex.Capabilities; ```
Fwiw this is also used by SDL2 to find out the actual underlying device VID/PID.
Also, I wouldn't mind having a couple of tests to show that it's actually present (and maybe check that it's missing from other xinput versions).