Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(710)

Side by Side Diff: device/hid/hid_service_win.cc

Issue 502573002: Find HID report IDs in output and feature reports on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use unsigned types and move INITGUID to back to .cc. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/hid/hid_service_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "device/hid/hid_service_win.h" 5 #include "device/hid/hid_service_win.h"
6 6
7 #include <cstdlib> 7 #include <cstdlib>
8 8
9 #include "base/files/file.h" 9 #include "base/files/file.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "base/strings/sys_string_conversions.h" 11 #include "base/strings/sys_string_conversions.h"
12 #include "device/hid/hid_connection_win.h" 12 #include "device/hid/hid_connection_win.h"
13 #include "device/hid/hid_device_info.h" 13 #include "device/hid/hid_device_info.h"
14 #include "net/base/io_buffer.h" 14 #include "net/base/io_buffer.h"
15 15
16 #if defined(OS_WIN) 16 #if defined(OS_WIN)
17 17
18 #define INITGUID 18 #define INITGUID
19 19
20 #include <windows.h>
21 #include <hidclass.h>
22
23 extern "C" {
24
25 #include <hidsdi.h>
26 #include <hidpi.h>
27
28 }
29
30 #include <setupapi.h> 20 #include <setupapi.h>
31 #include <winioctl.h> 21 #include <winioctl.h>
32 #include "base/win/scoped_handle.h" 22 #include "base/win/scoped_handle.h"
33 23
34 #endif // defined(OS_WIN) 24 #endif // defined(OS_WIN)
35 25
36 // Setup API is required to enumerate HID devices. 26 // Setup API is required to enumerate HID devices.
37 #pragma comment(lib, "setupapi.lib") 27 #pragma comment(lib, "setupapi.lib")
38 #pragma comment(lib, "hid.lib") 28 #pragma comment(lib, "hid.lib")
39 29
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 disconnected_devices.push_back(it->first); 142 disconnected_devices.push_back(it->first);
153 } 143 }
154 } 144 }
155 145
156 // Remove disconnected devices. 146 // Remove disconnected devices.
157 for (size_t i = 0; i < disconnected_devices.size(); ++i) { 147 for (size_t i = 0; i < disconnected_devices.size(); ++i) {
158 PlatformRemoveDevice(disconnected_devices[i]); 148 PlatformRemoveDevice(disconnected_devices[i]);
159 } 149 }
160 } 150 }
161 151
152 void HidServiceWin::CollectInfoFromButtonCaps(
153 PHIDP_PREPARSED_DATA preparsed_data,
154 HIDP_REPORT_TYPE report_type,
155 USHORT button_caps_length,
156 HidCollectionInfo* collection_info) {
157 if (button_caps_length > 0) {
158 scoped_ptr<HIDP_BUTTON_CAPS[]> button_caps(
159 new HIDP_BUTTON_CAPS[button_caps_length]);
160 if (HidP_GetButtonCaps(report_type,
161 &button_caps[0],
162 &button_caps_length,
163 preparsed_data) == HIDP_STATUS_SUCCESS) {
164 for (size_t i = 0; i < button_caps_length; i++) {
165 int report_id = button_caps[i].ReportID;
166 if (report_id != 0) {
167 collection_info->report_ids.insert(report_id);
168 }
169 }
170 }
171 }
172 }
173
174 void HidServiceWin::CollectInfoFromValueCaps(
175 PHIDP_PREPARSED_DATA preparsed_data,
176 HIDP_REPORT_TYPE report_type,
177 USHORT value_caps_length,
178 HidCollectionInfo* collection_info) {
179 if (value_caps_length > 0) {
180 scoped_ptr<HIDP_VALUE_CAPS[]> value_caps(
181 new HIDP_VALUE_CAPS[value_caps_length]);
182 if (HidP_GetValueCaps(
183 report_type, &value_caps[0], &value_caps_length, preparsed_data) ==
184 HIDP_STATUS_SUCCESS) {
185 for (size_t i = 0; i < value_caps_length; i++) {
186 int report_id = value_caps[i].ReportID;
187 if (report_id != 0) {
188 collection_info->report_ids.insert(report_id);
189 }
190 }
191 }
192 }
193 }
194
162 void HidServiceWin::PlatformAddDevice(const std::string& device_path) { 195 void HidServiceWin::PlatformAddDevice(const std::string& device_path) {
163 HidDeviceInfo device_info; 196 HidDeviceInfo device_info;
164 device_info.device_id = device_path; 197 device_info.device_id = device_path;
165 198
166 // Try to open the device. 199 // Try to open the device.
167 base::win::ScopedHandle device_handle( 200 base::win::ScopedHandle device_handle(
168 CreateFileA(device_path.c_str(), 201 CreateFileA(device_path.c_str(),
169 GENERIC_WRITE | GENERIC_READ, 202 GENERIC_WRITE | GENERIC_READ,
170 FILE_SHARE_READ | FILE_SHARE_WRITE, 203 FILE_SHARE_READ | FILE_SHARE_WRITE,
171 NULL, 204 NULL,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 HIDP_CAPS capabilities = {0}; 241 HIDP_CAPS capabilities = {0};
209 if (HidP_GetCaps(preparsed_data, &capabilities) == HIDP_STATUS_SUCCESS) { 242 if (HidP_GetCaps(preparsed_data, &capabilities) == HIDP_STATUS_SUCCESS) {
210 device_info.max_input_report_size = capabilities.InputReportByteLength; 243 device_info.max_input_report_size = capabilities.InputReportByteLength;
211 device_info.max_output_report_size = capabilities.OutputReportByteLength; 244 device_info.max_output_report_size = capabilities.OutputReportByteLength;
212 device_info.max_feature_report_size = 245 device_info.max_feature_report_size =
213 capabilities.FeatureReportByteLength; 246 capabilities.FeatureReportByteLength;
214 HidCollectionInfo collection_info; 247 HidCollectionInfo collection_info;
215 collection_info.usage = HidUsageAndPage( 248 collection_info.usage = HidUsageAndPage(
216 capabilities.Usage, 249 capabilities.Usage,
217 static_cast<HidUsageAndPage::Page>(capabilities.UsagePage)); 250 static_cast<HidUsageAndPage::Page>(capabilities.UsagePage));
218 USHORT button_caps_length = capabilities.NumberInputButtonCaps; 251 CollectInfoFromButtonCaps(preparsed_data,
219 if (button_caps_length > 0) { 252 HidP_Input,
220 scoped_ptr<HIDP_BUTTON_CAPS[]> button_caps( 253 capabilities.NumberInputButtonCaps,
221 new HIDP_BUTTON_CAPS[button_caps_length]); 254 &collection_info);
222 if (HidP_GetButtonCaps(HidP_Input, 255 CollectInfoFromButtonCaps(preparsed_data,
223 &button_caps[0], 256 HidP_Output,
224 &button_caps_length, 257 capabilities.NumberOutputButtonCaps,
225 preparsed_data) == HIDP_STATUS_SUCCESS) { 258 &collection_info);
226 for (int i = 0; i < button_caps_length; i++) { 259 CollectInfoFromButtonCaps(preparsed_data,
227 int report_id = button_caps[i].ReportID; 260 HidP_Feature,
228 if (report_id != 0) { 261 capabilities.NumberFeatureButtonCaps,
229 collection_info.report_ids.insert(report_id); 262 &collection_info);
230 device_info.has_report_id = true; 263 CollectInfoFromValueCaps(preparsed_data,
231 } 264 HidP_Input,
232 } 265 capabilities.NumberInputValueCaps,
233 } 266 &collection_info);
234 } 267 CollectInfoFromValueCaps(preparsed_data,
235 USHORT value_caps_length = capabilities.NumberInputValueCaps; 268 HidP_Output,
236 if (value_caps_length > 0) { 269 capabilities.NumberOutputValueCaps,
237 scoped_ptr<HIDP_VALUE_CAPS[]> value_caps( 270 &collection_info);
238 new HIDP_VALUE_CAPS[value_caps_length]); 271 CollectInfoFromValueCaps(preparsed_data,
239 if (HidP_GetValueCaps(HidP_Input, 272 HidP_Feature,
240 &value_caps[0], 273 capabilities.NumberFeatureValueCaps,
241 &value_caps_length, 274 &collection_info);
242 preparsed_data) == HIDP_STATUS_SUCCESS) { 275 if (!collection_info.report_ids.empty()) {
243 for (int i = 0; i < value_caps_length; i++) { 276 device_info.has_report_id = true;
244 int report_id = value_caps[i].ReportID;
245 if (report_id != 0) {
246 collection_info.report_ids.insert(report_id);
247 device_info.has_report_id = true;
248 }
249 }
250 }
251 } 277 }
252 device_info.collections.push_back(collection_info); 278 device_info.collections.push_back(collection_info);
253 } 279 }
254 // Whether or not the device includes report IDs in its reports the size 280 // Whether or not the device includes report IDs in its reports the size
255 // of the report ID is included in the value provided by Windows. This 281 // of the report ID is included in the value provided by Windows. This
256 // appears contrary to the MSDN documentation. 282 // appears contrary to the MSDN documentation.
257 if (device_info.max_input_report_size > 0) { 283 if (device_info.max_input_report_size > 0) {
258 device_info.max_input_report_size--; 284 device_info.max_input_report_size--;
259 } 285 }
260 if (device_info.max_output_report_size > 0) { 286 if (device_info.max_output_report_size > 0) {
(...skipping 24 matching lines...) Expand all
285 return NULL; 311 return NULL;
286 scoped_refptr<HidConnectionWin> connection(new HidConnectionWin(device_info)); 312 scoped_refptr<HidConnectionWin> connection(new HidConnectionWin(device_info));
287 if (!connection->available()) { 313 if (!connection->available()) {
288 PLOG(ERROR) << "Failed to open device."; 314 PLOG(ERROR) << "Failed to open device.";
289 return NULL; 315 return NULL;
290 } 316 }
291 return connection; 317 return connection;
292 } 318 }
293 319
294 } // namespace device 320 } // namespace device
OLDNEW
« no previous file with comments | « device/hid/hid_service_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698