Chromium Code Reviews| 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 |