Commit 82c4e858 authored by jameshollyer's avatar jameshollyer Committed by Commit Bot

Check for valid file handle on gamepads

Windows sometimes keeps a cache of gamepads that are not plugged into
the machine.  To distinguish between gamepads we can talk to and
gamepads we cannot this CL adds a check for a valid file handle.  If
Windows does not return a valid file handle we do not take up a slot
for that gamepad.

Bug: 985446
Change-Id: I2bf917bd8989e9238128426af9b804627446c2eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1768878
Commit-Queue: James Hollyer <jameshollyer@chromium.org>
Reviewed-by: default avatarMatt Reynolds <mattreynolds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#691285}
parent 3d3eb430
......@@ -263,8 +263,15 @@ bool RawInputGamepadDeviceWin::QueryDeviceInfo() {
if (name_ == L"\\\\?\\VIRTUAL_DIGITIZER")
return false;
// We can now use the name to query the OS for a file handle that is used to
// read the product string from the device. If the OS does not return a valid
// handle this gamepad is invalid.
auto hid_handle = OpenHidHandle();
if (!hid_handle.IsValid())
return false;
// Fetch the human-friendly |product_string_|, if available.
if (!QueryProductString())
if (!QueryProductString(hid_handle))
product_string_ = L"Unknown Gamepad";
// Fetch information about the buttons and axes on this device. This sets
......@@ -336,19 +343,21 @@ bool RawInputGamepadDeviceWin::QueryDeviceName() {
return true;
}
bool RawInputGamepadDeviceWin::QueryProductString() {
DCHECK(hid_functions_);
DCHECK(hid_functions_->IsValid());
base::win::ScopedHandle hid_handle(::CreateFile(
name_.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL));
if (!hid_handle.IsValid())
return false;
bool RawInputGamepadDeviceWin::QueryProductString(
base::win::ScopedHandle& hid_handle) {
DCHECK(hid_handle.IsValid());
product_string_.resize(Gamepad::kIdLengthCap);
return hid_functions_->HidDGetProductString()(
hid_handle.Get(), &product_string_.front(), Gamepad::kIdLengthCap);
}
base::win::ScopedHandle RawInputGamepadDeviceWin::OpenHidHandle() {
return base::win::ScopedHandle(::CreateFile(
name_.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, /*lpSecurityAttributes=*/nullptr,
OPEN_EXISTING, /*dwFlagsAndAttributes=*/0, /*hTemplateFile=*/nullptr));
}
bool RawInputGamepadDeviceWin::QueryDeviceCapabilities() {
DCHECK(hid_functions_);
DCHECK(hid_functions_->IsValid());
......
......@@ -75,6 +75,10 @@ class RawInputGamepadDeviceWin final : public AbstractHapticGamepad {
// AbstractHapticGamepad implementation.
void DoShutdown() override;
// "Returns an open handle for the HID device, or an invalid handle if the
// device could not be opened."
base::win::ScopedHandle OpenHidHandle();
// Fetch information about this device. Returns true if the device appears to
// be a valid gamepad.
bool QueryDeviceInfo();
......@@ -86,7 +90,7 @@ class RawInputGamepadDeviceWin final : public AbstractHapticGamepad {
bool QueryDeviceName();
// Fetch the product string. Returns false if none is available.
bool QueryProductString();
bool QueryProductString(base::win::ScopedHandle& hid_handle);
// These methods fetch information about the capabilities of buttons and axes
// on the device.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment