Commit 5a2284cf authored by reillyg@chromium.org's avatar reillyg@chromium.org

Find HID report IDs in output and feature reports on Windows.

A device may only have HID output or feature reports. In this case we
missed report IDs associated with this reports. This patch uses Window's
HID descriptor parser to scan though all report types looking for HID
collection information.

BUG=

Review URL: https://codereview.chromium.org/502573002

Cr-Commit-Position: refs/heads/master@{#291553}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@291553 0039d316-1c4b-4281-b951-d872f2087c98
parent 5af6526e
...@@ -17,16 +17,6 @@ ...@@ -17,16 +17,6 @@
#define INITGUID #define INITGUID
#include <windows.h>
#include <hidclass.h>
extern "C" {
#include <hidsdi.h>
#include <hidpi.h>
}
#include <setupapi.h> #include <setupapi.h>
#include <winioctl.h> #include <winioctl.h>
#include "base/win/scoped_handle.h" #include "base/win/scoped_handle.h"
...@@ -159,6 +149,49 @@ void HidServiceWin::Enumerate() { ...@@ -159,6 +149,49 @@ void HidServiceWin::Enumerate() {
} }
} }
void HidServiceWin::CollectInfoFromButtonCaps(
PHIDP_PREPARSED_DATA preparsed_data,
HIDP_REPORT_TYPE report_type,
USHORT button_caps_length,
HidCollectionInfo* collection_info) {
if (button_caps_length > 0) {
scoped_ptr<HIDP_BUTTON_CAPS[]> button_caps(
new HIDP_BUTTON_CAPS[button_caps_length]);
if (HidP_GetButtonCaps(report_type,
&button_caps[0],
&button_caps_length,
preparsed_data) == HIDP_STATUS_SUCCESS) {
for (size_t i = 0; i < button_caps_length; i++) {
int report_id = button_caps[i].ReportID;
if (report_id != 0) {
collection_info->report_ids.insert(report_id);
}
}
}
}
}
void HidServiceWin::CollectInfoFromValueCaps(
PHIDP_PREPARSED_DATA preparsed_data,
HIDP_REPORT_TYPE report_type,
USHORT value_caps_length,
HidCollectionInfo* collection_info) {
if (value_caps_length > 0) {
scoped_ptr<HIDP_VALUE_CAPS[]> value_caps(
new HIDP_VALUE_CAPS[value_caps_length]);
if (HidP_GetValueCaps(
report_type, &value_caps[0], &value_caps_length, preparsed_data) ==
HIDP_STATUS_SUCCESS) {
for (size_t i = 0; i < value_caps_length; i++) {
int report_id = value_caps[i].ReportID;
if (report_id != 0) {
collection_info->report_ids.insert(report_id);
}
}
}
}
}
void HidServiceWin::PlatformAddDevice(const std::string& device_path) { void HidServiceWin::PlatformAddDevice(const std::string& device_path) {
HidDeviceInfo device_info; HidDeviceInfo device_info;
device_info.device_id = device_path; device_info.device_id = device_path;
...@@ -215,39 +248,32 @@ void HidServiceWin::PlatformAddDevice(const std::string& device_path) { ...@@ -215,39 +248,32 @@ void HidServiceWin::PlatformAddDevice(const std::string& device_path) {
collection_info.usage = HidUsageAndPage( collection_info.usage = HidUsageAndPage(
capabilities.Usage, capabilities.Usage,
static_cast<HidUsageAndPage::Page>(capabilities.UsagePage)); static_cast<HidUsageAndPage::Page>(capabilities.UsagePage));
USHORT button_caps_length = capabilities.NumberInputButtonCaps; CollectInfoFromButtonCaps(preparsed_data,
if (button_caps_length > 0) { HidP_Input,
scoped_ptr<HIDP_BUTTON_CAPS[]> button_caps( capabilities.NumberInputButtonCaps,
new HIDP_BUTTON_CAPS[button_caps_length]); &collection_info);
if (HidP_GetButtonCaps(HidP_Input, CollectInfoFromButtonCaps(preparsed_data,
&button_caps[0], HidP_Output,
&button_caps_length, capabilities.NumberOutputButtonCaps,
preparsed_data) == HIDP_STATUS_SUCCESS) { &collection_info);
for (int i = 0; i < button_caps_length; i++) { CollectInfoFromButtonCaps(preparsed_data,
int report_id = button_caps[i].ReportID; HidP_Feature,
if (report_id != 0) { capabilities.NumberFeatureButtonCaps,
collection_info.report_ids.insert(report_id); &collection_info);
device_info.has_report_id = true; CollectInfoFromValueCaps(preparsed_data,
} HidP_Input,
} capabilities.NumberInputValueCaps,
} &collection_info);
} CollectInfoFromValueCaps(preparsed_data,
USHORT value_caps_length = capabilities.NumberInputValueCaps; HidP_Output,
if (value_caps_length > 0) { capabilities.NumberOutputValueCaps,
scoped_ptr<HIDP_VALUE_CAPS[]> value_caps( &collection_info);
new HIDP_VALUE_CAPS[value_caps_length]); CollectInfoFromValueCaps(preparsed_data,
if (HidP_GetValueCaps(HidP_Input, HidP_Feature,
&value_caps[0], capabilities.NumberFeatureValueCaps,
&value_caps_length, &collection_info);
preparsed_data) == HIDP_STATUS_SUCCESS) { if (!collection_info.report_ids.empty()) {
for (int i = 0; i < value_caps_length; i++) { device_info.has_report_id = true;
int report_id = value_caps[i].ReportID;
if (report_id != 0) {
collection_info.report_ids.insert(report_id);
device_info.has_report_id = true;
}
}
}
} }
device_info.collections.push_back(collection_info); device_info.collections.push_back(collection_info);
} }
......
...@@ -10,6 +10,18 @@ ...@@ -10,6 +10,18 @@
#include "device/hid/hid_device_info.h" #include "device/hid/hid_device_info.h"
#include "device/hid/hid_service.h" #include "device/hid/hid_service.h"
#if defined(OS_WIN)
#include <windows.h>
#include <hidclass.h>
extern "C" {
#include <hidsdi.h>
#include <hidpi.h>
}
#endif // defined(OS_WIN)
namespace device { namespace device {
class HidConnection; class HidConnection;
...@@ -27,6 +39,14 @@ class HidServiceWin : public HidService { ...@@ -27,6 +39,14 @@ class HidServiceWin : public HidService {
virtual ~HidServiceWin(); virtual ~HidServiceWin();
void Enumerate(); void Enumerate();
static void CollectInfoFromButtonCaps(PHIDP_PREPARSED_DATA preparsed_data,
HIDP_REPORT_TYPE report_type,
USHORT button_caps_length,
HidCollectionInfo* collection_info);
static void CollectInfoFromValueCaps(PHIDP_PREPARSED_DATA preparsed_data,
HIDP_REPORT_TYPE report_type,
USHORT value_caps_length,
HidCollectionInfo* collection_info);
void PlatformAddDevice(const std::string& device_path); void PlatformAddDevice(const std::string& device_path);
void PlatformRemoveDevice(const std::string& device_path); void PlatformRemoveDevice(const std::string& device_path);
......
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