OLD | NEW |
---|---|
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 | |
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> | 18 #include <setupapi.h> |
31 #include <winioctl.h> | 19 #include <winioctl.h> |
32 #include "base/win/scoped_handle.h" | 20 #include "base/win/scoped_handle.h" |
33 | 21 |
34 #endif // defined(OS_WIN) | 22 #endif // defined(OS_WIN) |
35 | 23 |
36 // Setup API is required to enumerate HID devices. | 24 // Setup API is required to enumerate HID devices. |
37 #pragma comment(lib, "setupapi.lib") | 25 #pragma comment(lib, "setupapi.lib") |
38 #pragma comment(lib, "hid.lib") | 26 #pragma comment(lib, "hid.lib") |
39 | 27 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
152 disconnected_devices.push_back(it->first); | 140 disconnected_devices.push_back(it->first); |
153 } | 141 } |
154 } | 142 } |
155 | 143 |
156 // Remove disconnected devices. | 144 // Remove disconnected devices. |
157 for (size_t i = 0; i < disconnected_devices.size(); ++i) { | 145 for (size_t i = 0; i < disconnected_devices.size(); ++i) { |
158 PlatformRemoveDevice(disconnected_devices[i]); | 146 PlatformRemoveDevice(disconnected_devices[i]); |
159 } | 147 } |
160 } | 148 } |
161 | 149 |
150 void HidServiceWin::CollectInfoFromButtonCaps( | |
151 PHIDP_PREPARSED_DATA preparsed_data, | |
152 HIDP_REPORT_TYPE report_type, | |
153 USHORT button_caps_length, | |
154 HidCollectionInfo* collection_info) { | |
155 if (button_caps_length > 0) { | |
156 scoped_ptr<HIDP_BUTTON_CAPS[]> button_caps( | |
157 new HIDP_BUTTON_CAPS[button_caps_length]); | |
158 if (HidP_GetButtonCaps(report_type, | |
159 &button_caps[0], | |
160 &button_caps_length, | |
161 preparsed_data) == HIDP_STATUS_SUCCESS) { | |
162 for (int i = 0; i < button_caps_length; i++) { | |
rpaquay
2014/08/22 21:36:30
Should "i" be unsigned (size_t)?
Reilly Grant (use Gerrit)
2014/08/22 21:54:54
Done.
| |
163 int report_id = button_caps[i].ReportID; | |
164 if (report_id != 0) { | |
165 collection_info->report_ids.insert(report_id); | |
166 } | |
167 } | |
168 } | |
169 } | |
170 } | |
171 | |
172 void HidServiceWin::CollectInfoFromValueCaps( | |
173 PHIDP_PREPARSED_DATA preparsed_data, | |
174 HIDP_REPORT_TYPE report_type, | |
175 USHORT value_caps_length, | |
176 HidCollectionInfo* collection_info) { | |
177 if (value_caps_length > 0) { | |
178 scoped_ptr<HIDP_VALUE_CAPS[]> value_caps( | |
179 new HIDP_VALUE_CAPS[value_caps_length]); | |
180 if (HidP_GetValueCaps( | |
181 report_type, &value_caps[0], &value_caps_length, preparsed_data) == | |
182 HIDP_STATUS_SUCCESS) { | |
183 for (int i = 0; i < value_caps_length; i++) { | |
rpaquay
2014/08/22 21:36:30
Should "i" be unsigned (size_t)?
Reilly Grant (use Gerrit)
2014/08/22 21:54:54
Done.
| |
184 int report_id = value_caps[i].ReportID; | |
185 if (report_id != 0) { | |
186 collection_info->report_ids.insert(report_id); | |
187 } | |
188 } | |
189 } | |
190 } | |
191 } | |
192 | |
162 void HidServiceWin::PlatformAddDevice(const std::string& device_path) { | 193 void HidServiceWin::PlatformAddDevice(const std::string& device_path) { |
163 HidDeviceInfo device_info; | 194 HidDeviceInfo device_info; |
164 device_info.device_id = device_path; | 195 device_info.device_id = device_path; |
165 | 196 |
166 // Try to open the device. | 197 // Try to open the device. |
167 base::win::ScopedHandle device_handle( | 198 base::win::ScopedHandle device_handle( |
168 CreateFileA(device_path.c_str(), | 199 CreateFileA(device_path.c_str(), |
169 GENERIC_WRITE | GENERIC_READ, | 200 GENERIC_WRITE | GENERIC_READ, |
170 FILE_SHARE_READ | FILE_SHARE_WRITE, | 201 FILE_SHARE_READ | FILE_SHARE_WRITE, |
171 NULL, | 202 NULL, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
208 HIDP_CAPS capabilities = {0}; | 239 HIDP_CAPS capabilities = {0}; |
209 if (HidP_GetCaps(preparsed_data, &capabilities) == HIDP_STATUS_SUCCESS) { | 240 if (HidP_GetCaps(preparsed_data, &capabilities) == HIDP_STATUS_SUCCESS) { |
210 device_info.max_input_report_size = capabilities.InputReportByteLength; | 241 device_info.max_input_report_size = capabilities.InputReportByteLength; |
211 device_info.max_output_report_size = capabilities.OutputReportByteLength; | 242 device_info.max_output_report_size = capabilities.OutputReportByteLength; |
212 device_info.max_feature_report_size = | 243 device_info.max_feature_report_size = |
213 capabilities.FeatureReportByteLength; | 244 capabilities.FeatureReportByteLength; |
214 HidCollectionInfo collection_info; | 245 HidCollectionInfo collection_info; |
215 collection_info.usage = HidUsageAndPage( | 246 collection_info.usage = HidUsageAndPage( |
216 capabilities.Usage, | 247 capabilities.Usage, |
217 static_cast<HidUsageAndPage::Page>(capabilities.UsagePage)); | 248 static_cast<HidUsageAndPage::Page>(capabilities.UsagePage)); |
218 USHORT button_caps_length = capabilities.NumberInputButtonCaps; | 249 CollectInfoFromButtonCaps(preparsed_data, |
219 if (button_caps_length > 0) { | 250 HidP_Input, |
220 scoped_ptr<HIDP_BUTTON_CAPS[]> button_caps( | 251 capabilities.NumberInputButtonCaps, |
221 new HIDP_BUTTON_CAPS[button_caps_length]); | 252 &collection_info); |
222 if (HidP_GetButtonCaps(HidP_Input, | 253 CollectInfoFromButtonCaps(preparsed_data, |
223 &button_caps[0], | 254 HidP_Output, |
224 &button_caps_length, | 255 capabilities.NumberOutputButtonCaps, |
225 preparsed_data) == HIDP_STATUS_SUCCESS) { | 256 &collection_info); |
226 for (int i = 0; i < button_caps_length; i++) { | 257 CollectInfoFromButtonCaps(preparsed_data, |
227 int report_id = button_caps[i].ReportID; | 258 HidP_Feature, |
228 if (report_id != 0) { | 259 capabilities.NumberFeatureButtonCaps, |
229 collection_info.report_ids.insert(report_id); | 260 &collection_info); |
230 device_info.has_report_id = true; | 261 CollectInfoFromValueCaps(preparsed_data, |
231 } | 262 HidP_Input, |
232 } | 263 capabilities.NumberInputValueCaps, |
233 } | 264 &collection_info); |
234 } | 265 CollectInfoFromValueCaps(preparsed_data, |
235 USHORT value_caps_length = capabilities.NumberInputValueCaps; | 266 HidP_Output, |
236 if (value_caps_length > 0) { | 267 capabilities.NumberOutputValueCaps, |
237 scoped_ptr<HIDP_VALUE_CAPS[]> value_caps( | 268 &collection_info); |
238 new HIDP_VALUE_CAPS[value_caps_length]); | 269 CollectInfoFromValueCaps(preparsed_data, |
239 if (HidP_GetValueCaps(HidP_Input, | 270 HidP_Feature, |
240 &value_caps[0], | 271 capabilities.NumberFeatureValueCaps, |
241 &value_caps_length, | 272 &collection_info); |
242 preparsed_data) == HIDP_STATUS_SUCCESS) { | 273 if (!collection_info.report_ids.empty()) { |
243 for (int i = 0; i < value_caps_length; i++) { | 274 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 } | 275 } |
252 device_info.collections.push_back(collection_info); | 276 device_info.collections.push_back(collection_info); |
253 } | 277 } |
254 // Whether or not the device includes report IDs in its reports the size | 278 // 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 | 279 // of the report ID is included in the value provided by Windows. This |
256 // appears contrary to the MSDN documentation. | 280 // appears contrary to the MSDN documentation. |
257 if (device_info.max_input_report_size > 0) { | 281 if (device_info.max_input_report_size > 0) { |
258 device_info.max_input_report_size--; | 282 device_info.max_input_report_size--; |
259 } | 283 } |
260 if (device_info.max_output_report_size > 0) { | 284 if (device_info.max_output_report_size > 0) { |
(...skipping 24 matching lines...) Expand all Loading... | |
285 return NULL; | 309 return NULL; |
286 scoped_refptr<HidConnectionWin> connection(new HidConnectionWin(device_info)); | 310 scoped_refptr<HidConnectionWin> connection(new HidConnectionWin(device_info)); |
287 if (!connection->available()) { | 311 if (!connection->available()) { |
288 PLOG(ERROR) << "Failed to open device."; | 312 PLOG(ERROR) << "Failed to open device."; |
289 return NULL; | 313 return NULL; |
290 } | 314 } |
291 return connection; | 315 return connection; |
292 } | 316 } |
293 | 317 |
294 } // namespace device | 318 } // namespace device |
OLD | NEW |