New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement: Find alternative names for a bluetooth joypad on Windows to work around forged PID/VID #8857
Comments
I just made a little Windows Console program that enumerates the DirectInput devices, then outputs their associated hardware device information. This is what it outputs when it sees the joypad:
So it's finding 4 different names for the joypad: Meanwhile, RetroArch just calls it "XInput Controller". |
RetroArch doesn't do anything BT, it just gets the device via HID. That Xinput Controller is probably because they used to use the same VID and PID as the original MS ones so it's just using the builtin autoconf (ie: the name is misleading and not obtained via any API) |
I thnk you can get the HID name from information/system information |
I checked that screen, it's still just the same name shown elsewhere. Only the VID/PID is useful information there, the rest is referring to what configuration file it loaded. |
I think the device name we use is the one that shows here:
[image: image.png]
If you can add more info such as the one that shows in the BT control panel
that would be great.
[image: image.png]
…On Fri, Jun 28, 2019 at 6:33 PM Dan Weiss ***@***.***> wrote:
I checked that screen, it's still just the same name shown elsewhere. Only
the VID/PID is useful information there, the rest is referring to what
configuration file it loaded.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#8857?email_source=notifications&email_token=AANEFUCKAIQIG6AMCW2A3CLP42NUFA5CNFSM4HPYWR2KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODY3MF6Q#issuecomment-506905338>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AANEFUHEZMWOSE6GDMOEWMDP42NUFANCNFSM4HPYWR2A>
.
|
Can't see the images here on github's issue tracker. If you're talking about the name shown in Device Manager vs the Bluetooth Settings app, then that's what I have taken. |
Yep, in my second message, it listed "Bluetooth Friendly Name: 8Bitdo SNES30 GamePad(x)" for my controller. That's what it shows in the Bluetooth Settings app. |
When you ask DirectInput for information about the controller, you get these:
When you ask Windows for device information using the CfgMgr32 API, you can get these:
Then you can also enumerate Bluetooth devices which match the Bluetooth Address, and get additional names from there. One problem with this approach is that you end up with a real XBOX 360 controller and the 8BitDo controller plugged in at the same time, it might not be possible to determine which DirectInput device corresponds to which Bluetooth device. |
The other thing I was looking into was detecting the drivers used by DS4Windows, so it can identify that the Joypad is a DualShock4. It fakes an XBOX 360 controller (VID 0x045E, PID 0x028E) connected by USB. But on a normal USB device, you can keep taking its parent, and eventually see a USB Root Hub. On the faked USB device, you will eventually see a parent of "ROOT\UNKNOWN\0000", and the location is listed as "Virtual Gamepad Emulation Bus". There is also another HID device (VID 0x054C, PID 0x05C4), and it is linked to the Bluetooth device. I think it's the actual PS4 controller. This is not the device that XInput sees. The only thing that clearly links it to the virtual XBOX 360 controller is that it was plugged in at the same date and time. |
IMHO adding other variables would be great as a tie breaker. Good thing that someone is looking into this again. |
Then there's the hard part... What would need to be done in RetroArch's input autoconfig system to allow it to use the four different names it can find for a Joypad? The four names are "Name", "Friendly Name", "Bus Reported Name", and "Bluetooth Name". |
I'd just add one.
…On Fri, Jun 28, 2019 at 11:29 PM Dan Weiss ***@***.***> wrote:
Then there's the hard part... What would need to be done in RetroArch's
input autoconfig system to allow it to use the four different names it can
find for a Joypad?
The four names are "Name", "Friendly Name", "Bus Reported Name", and
"Bluetooth Name".
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#8857?email_source=notifications&email_token=AANEFUHLEEP26WQSY4RBFWDP43QJNA5CNFSM4HPYWR2KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODY3RCYY#issuecomment-506925411>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AANEFUFTODBFOEFQOIR5TD3P43QJNANCNFSM4HPYWR2A>
.
|
Think I'll just simplify it, simply scan the BT devices for the same VID and PID as the joypad and take the first match. |
Has this problem got closer to a solution? Seems to be the issue that I’ve ran into in the past few days. |
Thank you for reminding me that this still exists, haven't looked at this at all in over a year. |
Been troubleshooting the past few days and finally found this issue. My friend has the 8bitdo SN30 and 6-button M30. When launching in RA, the notification says the right model has loaded but binding the controls and saving an autoconfig it creates the same “Bluetooth wireless controller”. Device manager shows the correct model names. |
One issue is that you can't reliably go from an XInput player number to a VID/PID or Device Node. So any time XInput is involved, it's only reliable when there's only one joypad. Otherwise, it's possible to misidentify the device given the XInput player number. If there's only one device, it's a lot easier. |
Just peeked inside of Xinput's code, Ultimately it is calling CreateFileW on a device (like this:)
After opening it, it communicates with that device. However, the device that is opened does not correspond with the user number. Asking for Player 2 still opens Player 1's joypad device. I haven't tested with multiple controllers yet, but if tries to open multiple devices, and the order of opening the device matches the player order, then that would help. |
Just tested and confirmed that multiple joypad devices will be read in player number order when you try to use XInput. |
The Xbox Series X|S controller does get the proper PID/VID information when connecting over Bluetooth in xinput mode. When connecting the X|S controller(Shock Blue) RetroArch sees it as "1118/2835" The Xbox One controller, is of course 1118/736. I can easily swap between the two without RetroArch confusing the two. Both of my Bluetooth Retro-BIt Sega Genesis / Saturn controllers and my 8BitDo SN30 however, also show up as 1118/736. Like it can't find the ID so falls back to a default. I read that xinput API isn't capable of reading the VIP/PID of devices so... are the Xbox controllers somehow built into Windows so RetroArch can identify them? Is this something that can be leveraged to allow RetorArch to ID these xinput controllers? I also found this post that seemed to fix the same problem for one developer; would that work here in this case? I hope I've been helpful and thanks for all the awesome work you guys do on RetroArch. |
In the meantime, I just wrote a program that will discover the actual device associated with an XInput controller. I'll post more about it soon. |
Okay, here is the test program. It is badly in need of testing to see if it works on anyone else's PC. Connect your controllers before running it. (Note: Updated since the last version, removes "Device Identification Service" matches among other things) https://www.dwedit.org/files/xinput-test-thingy-v2.7z Here is an example of what the program outputs:
|
Ok so that did not work for me. Instead, it just sent by Bluetooth driver into hiding. Basically, it vanished from Device Manager, but I got it back. Will try it on a different machine later tonight. |
I can't think of any step in my program that could cause a bluetooth driver to "go into hiding"... What the program does:
It doesn't try to install or uninstall devices, or anything like that, and doesn't enable or disable any devices. So seeing a problem like that is bizarre. |
It was bizarre. At any rate I just tried it on my laptop and looks like it worked there. Had both the SN30 and Retro-bit Genesis Bluetooth controllers connected in xinput mode. |
Interesting that it can't find a good name for the devices there... What are the devices named on the "Bluetooth & Other Devices" screen? Edit: looks like it's just pulling up the same device instead of finding an actual matching device, will try to fix. |
And now it just worked on the one that had the Bluetooth glitch, ran it a few times and nothing. Can't replicate the issue that caused the Bluetooth driver to shut itself off. |
On the 2nd test. Here is the results from your tool.
|
Try to use triple backquotes ``` at the beginning and end of your log so GitHub doesn't try to reformat it. Usually that key is to the left of the "1" key on the keyboard. |
Also... here's what the Xbox Series X|S and Xbox One controllers look like
|
Just updated the test tool, now it won't return "Device Identification Service" anymore. |
ok, re-downloaded thingy
|
Very happy you are working on something like this. Keep up the good work!!!! Here is the output from my izdtech zd-v108:
|
I'd be very interested in this being improved in RetroArch, here's the output from my 2 controllers.
|
Any change with this issue? I have a few 8bitdo controllers that always show up as xbox one controllers (I connect them to the pc using xinput mode, dinput mode used for android) and it would be cool if retroarch could distinguish them, even if just for the device index text. With the way things work currently, isn't most of the 8bitdo autoconfig files in the xinput folder pointless? |
We can use hidden func typedef struct _XINPUT_CAPABILITIES_EX
{
XINPUT_CAPABILITIES Capabilities;
WORD VendorId;
WORD ProductId;
WORD VersionNumber;
WORD unk1;
DWORD unk2;
} XINPUT_CAPABILITIES_EX, * PXINPUT_CAPABILITIES_EX;
// XInputGetCapabilitiesEx hidden function is available since Windows 8 version of XInput1_4.dll
DWORD XInputGetCapabilitiesEx(DWORD dwUserIndex, PXINPUT_CAPABILITIES_EX pCapabilitiesEx)
{
DWORD(WINAPI* XInputGetCapabilitiesExFunc)(DWORD unk1, DWORD dwUserIndex, DWORD dwFlags, PXINPUT_CAPABILITIES_EX pCapabilities);
XInputGetCapabilitiesExFunc = reinterpret_cast<decltype(XInputGetCapabilitiesExFunc)>(::GetProcAddress(::GetModuleHandleW(L"XInput1_4.dll"), (LPCSTR)108));
if (!XInputGetCapabilitiesExFunc)
return ERROR_INVALID_FUNCTION;
return XInputGetCapabilitiesExFunc(1, dwUserIndex, 0, pCapabilitiesEx);
}
....
XINPUT_CAPABILITIES_EX caps;
popMemZeroStruct(caps);
XInputGetCapabilitiesEx(m_UserIndex, &caps);
// Fixup for Wireless Xbox 360 Controller
if (caps.ProductId == 0 && caps.Capabilities.Flags & /*XINPUT_CAPS_WIRELESS*/0x0002)
{
caps.VendorId = 0x045E;
caps.ProductId = 0x02A1;
}
m_VendorId = caps.VendorId;
m_ProductId = caps.ProductId;
// Known controller VID/PID list: https://github.com/libsdl-org/SDL/blob/main/src/joystick/controller_type.h https://gist.github.com/DJm00n/0f0563702f6cf01e8812ebc760a78cf1#file-xinputgetcapabilitiesex-cpp |
Description
This is on my Windows 10 machine.
Some versions of the 8bitdo SN30 game pad are masquerading as an XBOX 360 controller, and are using a fake Vendor and Product ID to match that gamepad.
When I look around in Device Manager, I see two separate devices that refer to the same piece of hardware:
This one in Human Interface Devices:
And this one in Bluetooth Devices:
The instance paths are not identical, but they share these parts:
7&26E1B50A&0&
andE417D89795FA
, and the Bluetooth Device Addresses (which are supposed to be unique) are exact matches. Therefore, it is safe to consider those two to be the exact same piece of hardware.When RetroArch detects this controller, it will assume that it has the full set of XBOX 360 controls, and will assume the gamepad has a both a separate D-PAD and Left Analog stick. Meanwhile, the actual controller assigns the D-PAD to be the left analog stick, and has nothing mapped to the D-PAD controls. This causes cores which use D-PADs, but no analog controls to not accept input unless you do some remapping first.
While there is a system in place to set default options for controllers which do not conform properly, it was hampered by not being able to distinguish between two different controllers with identical VID/PID, and identical display names. Adding a second name (Bus-reported device description) and a third name (Matching Friendly Name from the Bluetooth device) could help distinguish them.
The text was updated successfully, but these errors were encountered: