| OLD | NEW |
| 1 // Copyright (c) 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 #include <string> | |
| 9 | 8 |
| 10 #include "base/callback_helpers.h" | |
| 11 #include "base/lazy_instance.h" | |
| 12 #include "base/memory/scoped_ptr.h" | |
| 13 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 14 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
| 15 #include "device/hid/hid_connection.h" | |
| 16 #include "device/hid/hid_connection_win.h" | 11 #include "device/hid/hid_connection_win.h" |
| 17 #include "device/hid/hid_service.h" | 12 #include "device/hid/hid_device_info.h" |
| 18 #include "net/base/io_buffer.h" | 13 #include "net/base/io_buffer.h" |
| 19 | 14 |
| 20 #if defined(OS_WIN) | 15 #if defined(OS_WIN) |
| 21 | 16 |
| 22 #define INITGUID | 17 #define INITGUID |
| 23 | 18 |
| 24 #include <windows.h> | 19 #include <windows.h> |
| 25 #include <hidclass.h> | 20 #include <hidclass.h> |
| 26 | 21 |
| 27 extern "C" { | 22 extern "C" { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 42 #pragma comment(lib, "hid.lib") | 37 #pragma comment(lib, "hid.lib") |
| 43 | 38 |
| 44 namespace device { | 39 namespace device { |
| 45 namespace { | 40 namespace { |
| 46 | 41 |
| 47 const char kHIDClass[] = "HIDClass"; | 42 const char kHIDClass[] = "HIDClass"; |
| 48 | 43 |
| 49 } // namespace | 44 } // namespace |
| 50 | 45 |
| 51 HidServiceWin::HidServiceWin() { | 46 HidServiceWin::HidServiceWin() { |
| 52 initialized_ = Enumerate(); | 47 Enumerate(); |
| 53 } | 48 } |
| 49 |
| 54 HidServiceWin::~HidServiceWin() {} | 50 HidServiceWin::~HidServiceWin() {} |
| 55 | 51 |
| 56 bool HidServiceWin::Enumerate() { | 52 void HidServiceWin::Enumerate() { |
| 57 BOOL res; | 53 BOOL res; |
| 58 HDEVINFO device_info_set; | 54 HDEVINFO device_info_set; |
| 59 SP_DEVINFO_DATA devinfo_data; | 55 SP_DEVINFO_DATA devinfo_data; |
| 60 SP_DEVICE_INTERFACE_DATA device_interface_data; | 56 SP_DEVICE_INTERFACE_DATA device_interface_data; |
| 61 | 57 |
| 62 memset(&devinfo_data, 0, sizeof(SP_DEVINFO_DATA)); | 58 memset(&devinfo_data, 0, sizeof(SP_DEVINFO_DATA)); |
| 63 devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA); | 59 devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA); |
| 64 device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); | 60 device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); |
| 65 | 61 |
| 66 device_info_set = SetupDiGetClassDevs( | 62 device_info_set = SetupDiGetClassDevs( |
| 67 &GUID_DEVINTERFACE_HID, | 63 &GUID_DEVINTERFACE_HID, |
| 68 NULL, | 64 NULL, |
| 69 NULL, | 65 NULL, |
| 70 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); | 66 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); |
| 71 | 67 |
| 72 if (device_info_set == INVALID_HANDLE_VALUE) | 68 if (device_info_set == INVALID_HANDLE_VALUE) |
| 73 return false; | 69 return; |
| 74 | 70 |
| 75 for (int device_index = 0; | 71 for (int device_index = 0; |
| 76 SetupDiEnumDeviceInterfaces(device_info_set, | 72 SetupDiEnumDeviceInterfaces(device_info_set, |
| 77 NULL, | 73 NULL, |
| 78 &GUID_DEVINTERFACE_HID, | 74 &GUID_DEVINTERFACE_HID, |
| 79 device_index, | 75 device_index, |
| 80 &device_interface_data); | 76 &device_interface_data); |
| 81 device_index++) { | 77 ++device_index) { |
| 82 DWORD required_size = 0; | 78 DWORD required_size = 0; |
| 83 | 79 |
| 84 // Determime the required size of detail struct. | 80 // Determime the required size of detail struct. |
| 85 SetupDiGetDeviceInterfaceDetailA(device_info_set, | 81 SetupDiGetDeviceInterfaceDetailA(device_info_set, |
| 86 &device_interface_data, | 82 &device_interface_data, |
| 87 NULL, | 83 NULL, |
| 88 0, | 84 0, |
| 89 &required_size, | 85 &required_size, |
| 90 NULL); | 86 NULL); |
| 91 | 87 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 char driver_name[256] = {0}; | 120 char driver_name[256] = {0}; |
| 125 // Get bounded driver. | 121 // Get bounded driver. |
| 126 res = SetupDiGetDeviceRegistryPropertyA(device_info_set, | 122 res = SetupDiGetDeviceRegistryPropertyA(device_info_set, |
| 127 &devinfo_data, | 123 &devinfo_data, |
| 128 SPDRP_DRIVER, | 124 SPDRP_DRIVER, |
| 129 NULL, | 125 NULL, |
| 130 (PBYTE) driver_name, | 126 (PBYTE) driver_name, |
| 131 sizeof(driver_name) - 1, | 127 sizeof(driver_name) - 1, |
| 132 NULL); | 128 NULL); |
| 133 if (res) { | 129 if (res) { |
| 134 // Found the drive. | 130 // Found the driver. |
| 135 break; | 131 break; |
| 136 } | 132 } |
| 137 } | 133 } |
| 138 } | 134 } |
| 139 | 135 |
| 140 if (!res) | 136 if (!res) |
| 141 continue; | 137 continue; |
| 142 | 138 |
| 143 PlatformAddDevice(device_interface_detail_data->DevicePath); | 139 PlatformAddDevice(device_interface_detail_data->DevicePath); |
| 144 } | 140 } |
| 145 | |
| 146 return true; | |
| 147 } | 141 } |
| 148 | 142 |
| 149 void HidServiceWin::PlatformAddDevice(std::string device_path) { | 143 void HidServiceWin::PlatformAddDevice(const std::string& device_path) { |
| 150 HidDeviceInfo device_info; | 144 HidDeviceInfo device_info; |
| 151 device_info.device_id = device_path; | 145 device_info.device_id = device_path; |
| 152 | 146 |
| 153 // Try to open the device. | 147 // Try to open the device. |
| 154 base::win::ScopedHandle device_handle( | 148 base::win::ScopedHandle device_handle( |
| 155 CreateFileA(device_path.c_str(), | 149 CreateFileA(device_path.c_str(), |
| 156 0, | 150 0, |
| 157 FILE_SHARE_READ | FILE_SHARE_WRITE, | 151 FILE_SHARE_READ | FILE_SHARE_WRITE, |
| 158 NULL, | 152 NULL, |
| 159 OPEN_EXISTING, | 153 OPEN_EXISTING, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 188 device_info.feature_report_size = capabilities.FeatureReportByteLength; | 182 device_info.feature_report_size = capabilities.FeatureReportByteLength; |
| 189 } | 183 } |
| 190 // Detect if the device supports report ids. | 184 // Detect if the device supports report ids. |
| 191 if (capabilities.NumberInputValueCaps > 0) { | 185 if (capabilities.NumberInputValueCaps > 0) { |
| 192 scoped_ptr<HIDP_VALUE_CAPS[]> value_caps( | 186 scoped_ptr<HIDP_VALUE_CAPS[]> value_caps( |
| 193 new HIDP_VALUE_CAPS[capabilities.NumberInputValueCaps]); | 187 new HIDP_VALUE_CAPS[capabilities.NumberInputValueCaps]); |
| 194 USHORT value_caps_length = capabilities.NumberInputValueCaps; | 188 USHORT value_caps_length = capabilities.NumberInputValueCaps; |
| 195 if (HidP_GetValueCaps(HidP_Input, &value_caps[0], &value_caps_length, | 189 if (HidP_GetValueCaps(HidP_Input, &value_caps[0], &value_caps_length, |
| 196 preparsed_data) == HIDP_STATUS_SUCCESS) { | 190 preparsed_data) == HIDP_STATUS_SUCCESS) { |
| 197 device_info.has_report_id = (value_caps[0].ReportID != 0); | 191 device_info.has_report_id = (value_caps[0].ReportID != 0); |
| 192 // If report IDs are supported, adjust all the expected report sizes |
| 193 // down by one byte. This is because Windows will always provide sizes |
| 194 // which assume the presence of a report ID. |
| 195 if (device_info.has_report_id) { |
| 196 if (device_info.input_report_size > 0) |
| 197 device_info.input_report_size -= 1; |
| 198 if (device_info.output_report_size > 0) |
| 199 device_info.output_report_size -= 1; |
| 200 if (device_info.feature_report_size > 0) |
| 201 device_info.feature_report_size -= 1; |
| 202 } |
| 198 } | 203 } |
| 199 } | 204 } |
| 200 HidD_FreePreparsedData(preparsed_data); | 205 HidD_FreePreparsedData(preparsed_data); |
| 201 } | 206 } |
| 202 | 207 |
| 203 // Get the serial number | 208 // Get the serial number |
| 204 wchar_t str_property[512] = { 0 }; | 209 wchar_t str_property[512] = { 0 }; |
| 205 if (HidD_GetSerialNumberString(device_handle.Get(), | 210 if (HidD_GetSerialNumberString(device_handle.Get(), |
| 206 str_property, | 211 str_property, |
| 207 sizeof(str_property))) { | 212 sizeof(str_property))) { |
| 208 device_info.serial_number = base::SysWideToUTF8(str_property); | 213 device_info.serial_number = base::SysWideToUTF8(str_property); |
| 209 } | 214 } |
| 210 | 215 |
| 211 if (HidD_GetProductString(device_handle.Get(), | 216 if (HidD_GetProductString(device_handle.Get(), |
| 212 str_property, | 217 str_property, |
| 213 sizeof(str_property))) { | 218 sizeof(str_property))) { |
| 214 device_info.product_name = base::SysWideToUTF8(str_property); | 219 device_info.product_name = base::SysWideToUTF8(str_property); |
| 215 } | 220 } |
| 216 | 221 |
| 217 HidService::AddDevice(device_info); | 222 AddDevice(device_info); |
| 218 } | 223 } |
| 219 | 224 |
| 220 void HidServiceWin::PlatformRemoveDevice(std::string device_path) { | 225 void HidServiceWin::PlatformRemoveDevice(const std::string& device_path) { |
| 221 HidService::RemoveDevice(device_path); | 226 RemoveDevice(device_path); |
| 222 } | 227 } |
| 223 | 228 |
| 224 void HidServiceWin::GetDevices(std::vector<HidDeviceInfo>* devices) { | 229 void HidServiceWin::GetDevices(std::vector<HidDeviceInfo>* devices) { |
| 225 Enumerate(); | 230 Enumerate(); |
| 226 HidService::GetDevices(devices); | 231 HidService::GetDevices(devices); |
| 227 } | 232 } |
| 228 | 233 |
| 229 scoped_refptr<HidConnection> HidServiceWin::Connect(std::string device_id) { | 234 scoped_refptr<HidConnection> HidServiceWin::Connect( |
| 230 if (!ContainsKey(devices_, device_id)) return NULL; | 235 const HidDeviceId& device_id) { |
| 231 scoped_refptr<HidConnectionWin> connection( | 236 HidDeviceInfo device_info; |
| 232 new HidConnectionWin(devices_[device_id])); | 237 if (!GetDeviceInfo(device_id, &device_info)) |
| 238 return NULL; |
| 239 scoped_refptr<HidConnectionWin> connection(new HidConnectionWin(device_info)); |
| 233 if (!connection->available()) { | 240 if (!connection->available()) { |
| 234 LOG_GETLASTERROR(ERROR) << "Failed to open device."; | 241 LOG_GETLASTERROR(ERROR) << "Failed to open device."; |
| 235 return NULL; | 242 return NULL; |
| 236 } | 243 } |
| 237 return connection; | 244 return connection; |
| 238 } | 245 } |
| 239 | 246 |
| 240 } // namespace device | 247 } // namespace device |
| OLD | NEW |