SDL: rawinput: Fix double detection of gamepads on some 3rd party X360 wireless receivers

From 677dc1015c76b9185d3f16edd26e30abecc2bdc8 Mon Sep 17 00:00:00 2001
From: Cameron Gutman <[EMAIL REDACTED]>
Date: Wed, 9 Mar 2022 19:43:29 -0600
Subject: [PATCH] rawinput: Fix double detection of gamepads on some 3rd party
 X360 wireless receivers

The name that the Raw Input joystick driver pulls from the HID stack comes
from USB string descriptors contained on the device. For official wireless
receivers, this always contains "Xbox 360 Wireless Receiver for Windows"
which matches the friendly name that WGI provides.

3rd party Xbox 360 wireless receivers may have different strings in their
USB string descriptors (one uses "XBOX 360 For Windows" instead). This
fails to match WGI's name and causes Raw Input and WGI to both report the
same gamepad.

Since wireless Xbox 360 controllers seem to have a consistent VID/PID
regardless of the adapter enumerating them, we can also match on that to
catch these.

The duplicate case reported to me was:
Controller (XBOX 360 For Windows) - 030000005e040000a102000000007200
Xbox 360 Wireless Receiver for Windows - 030000005e0400000000000000007701
---
 src/joystick/windows/SDL_rawinputjoystick.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c
index c4de681ad53..e0fcc28a916 100644
--- a/src/joystick/windows/SDL_rawinputjoystick.c
+++ b/src/joystick/windows/SDL_rawinputjoystick.c
@@ -922,9 +922,12 @@ RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, co
             return SDL_TRUE;
         }
 
-        /* The Xbox 360 wireless controller shows up as product 0 in WGI */
+        /* The Xbox 360 wireless controller shows up as product 0 in WGI.
+           Try to match it to a Raw Input device via name or known product ID. */
         if (vendor_id == device->vendor_id && product_id == 0 &&
-            name && SDL_strstr(device->name, name) != NULL) {
+            ((name && SDL_strstr(device->name, name) != NULL) ||
+             (device->vendor_id == USB_VENDOR_MICROSOFT &&
+              device->product_id == USB_PRODUCT_XBOX360_XUSB_CONTROLLER))) {
             return SDL_TRUE;
         }