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 | 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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |