| 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 #define INITGUID | 7 #define INITGUID |
| 8 | 8 |
| 9 #include <dbt.h> | 9 #include <dbt.h> |
| 10 #include <setupapi.h> | 10 #include <setupapi.h> |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 } | 40 } |
| 41 | 41 |
| 42 void HidServiceWin::Connect(const HidDeviceId& device_id, | 42 void HidServiceWin::Connect(const HidDeviceId& device_id, |
| 43 const ConnectCallback& callback) { | 43 const ConnectCallback& callback) { |
| 44 DCHECK(thread_checker_.CalledOnValidThread()); | 44 DCHECK(thread_checker_.CalledOnValidThread()); |
| 45 const auto& map_entry = devices().find(device_id); | 45 const auto& map_entry = devices().find(device_id); |
| 46 if (map_entry == devices().end()) { | 46 if (map_entry == devices().end()) { |
| 47 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); | 47 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); |
| 48 return; | 48 return; |
| 49 } | 49 } |
| 50 const HidDeviceInfo& device_info = map_entry->second; | 50 scoped_refptr<HidDeviceInfo> device_info = map_entry->second; |
| 51 | 51 |
| 52 base::win::ScopedHandle file(OpenDevice(device_info.device_id)); | 52 base::win::ScopedHandle file(OpenDevice(device_info->device_id())); |
| 53 if (!file.IsValid()) { | 53 if (!file.IsValid()) { |
| 54 PLOG(ERROR) << "Failed to open device"; | 54 PLOG(ERROR) << "Failed to open device"; |
| 55 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); | 55 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); |
| 56 return; | 56 return; |
| 57 } | 57 } |
| 58 | 58 |
| 59 task_runner_->PostTask( | 59 task_runner_->PostTask( |
| 60 FROM_HERE, | 60 FROM_HERE, |
| 61 base::Bind(callback, new HidConnectionWin(device_info, file.Pass()))); | 61 base::Bind(callback, new HidConnectionWin(device_info, file.Pass()))); |
| 62 } | 62 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 int report_id = value_caps[i].ReportID; | 149 int report_id = value_caps[i].ReportID; |
| 150 if (report_id != 0) { | 150 if (report_id != 0) { |
| 151 collection_info->report_ids.insert(report_id); | 151 collection_info->report_ids.insert(report_id); |
| 152 } | 152 } |
| 153 } | 153 } |
| 154 } | 154 } |
| 155 } | 155 } |
| 156 } | 156 } |
| 157 | 157 |
| 158 void HidServiceWin::OnDeviceAdded(const std::string& device_path) { | 158 void HidServiceWin::OnDeviceAdded(const std::string& device_path) { |
| 159 HidDeviceInfo device_info; | |
| 160 device_info.device_id = device_path; | |
| 161 | |
| 162 // Try to open the device. | 159 // Try to open the device. |
| 163 base::win::ScopedHandle device_handle(OpenDevice(device_path)); | 160 base::win::ScopedHandle device_handle(OpenDevice(device_path)); |
| 164 if (!device_handle.IsValid()) { | 161 if (!device_handle.IsValid()) { |
| 165 return; | 162 return; |
| 166 } | 163 } |
| 167 | 164 |
| 168 // Get VID/PID pair. | 165 // Get VID/PID pair. |
| 169 HIDD_ATTRIBUTES attrib = {0}; | 166 HIDD_ATTRIBUTES attrib = {0}; |
| 170 attrib.Size = sizeof(HIDD_ATTRIBUTES); | 167 attrib.Size = sizeof(HIDD_ATTRIBUTES); |
| 171 if (!HidD_GetAttributes(device_handle.Get(), &attrib)) { | 168 if (!HidD_GetAttributes(device_handle.Get(), &attrib)) { |
| 172 return; | 169 return; |
| 173 } | 170 } |
| 174 | 171 |
| 175 device_info.vendor_id = attrib.VendorID; | 172 scoped_refptr<HidDeviceInfo> device_info(new HidDeviceInfo()); |
| 176 device_info.product_id = attrib.ProductID; | 173 device_info->device_id_ = device_path; |
| 174 device_info->vendor_id_ = attrib.VendorID; |
| 175 device_info->product_id_ = attrib.ProductID; |
| 177 | 176 |
| 178 // Get usage and usage page (optional). | 177 // Get usage and usage page (optional). |
| 179 PHIDP_PREPARSED_DATA preparsed_data; | 178 PHIDP_PREPARSED_DATA preparsed_data; |
| 180 if (HidD_GetPreparsedData(device_handle.Get(), &preparsed_data) && | 179 if (HidD_GetPreparsedData(device_handle.Get(), &preparsed_data) && |
| 181 preparsed_data) { | 180 preparsed_data) { |
| 182 HIDP_CAPS capabilities = {0}; | 181 HIDP_CAPS capabilities = {0}; |
| 183 if (HidP_GetCaps(preparsed_data, &capabilities) == HIDP_STATUS_SUCCESS) { | 182 if (HidP_GetCaps(preparsed_data, &capabilities) == HIDP_STATUS_SUCCESS) { |
| 184 device_info.max_input_report_size = capabilities.InputReportByteLength; | 183 device_info->max_input_report_size_ = capabilities.InputReportByteLength; |
| 185 device_info.max_output_report_size = capabilities.OutputReportByteLength; | 184 device_info->max_output_report_size_ = |
| 186 device_info.max_feature_report_size = | 185 capabilities.OutputReportByteLength; |
| 186 device_info->max_feature_report_size_ = |
| 187 capabilities.FeatureReportByteLength; | 187 capabilities.FeatureReportByteLength; |
| 188 HidCollectionInfo collection_info; | 188 HidCollectionInfo collection_info; |
| 189 collection_info.usage = HidUsageAndPage( | 189 collection_info.usage = HidUsageAndPage( |
| 190 capabilities.Usage, | 190 capabilities.Usage, |
| 191 static_cast<HidUsageAndPage::Page>(capabilities.UsagePage)); | 191 static_cast<HidUsageAndPage::Page>(capabilities.UsagePage)); |
| 192 CollectInfoFromButtonCaps(preparsed_data, | 192 CollectInfoFromButtonCaps(preparsed_data, |
| 193 HidP_Input, | 193 HidP_Input, |
| 194 capabilities.NumberInputButtonCaps, | 194 capabilities.NumberInputButtonCaps, |
| 195 &collection_info); | 195 &collection_info); |
| 196 CollectInfoFromButtonCaps(preparsed_data, | 196 CollectInfoFromButtonCaps(preparsed_data, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 207 &collection_info); | 207 &collection_info); |
| 208 CollectInfoFromValueCaps(preparsed_data, | 208 CollectInfoFromValueCaps(preparsed_data, |
| 209 HidP_Output, | 209 HidP_Output, |
| 210 capabilities.NumberOutputValueCaps, | 210 capabilities.NumberOutputValueCaps, |
| 211 &collection_info); | 211 &collection_info); |
| 212 CollectInfoFromValueCaps(preparsed_data, | 212 CollectInfoFromValueCaps(preparsed_data, |
| 213 HidP_Feature, | 213 HidP_Feature, |
| 214 capabilities.NumberFeatureValueCaps, | 214 capabilities.NumberFeatureValueCaps, |
| 215 &collection_info); | 215 &collection_info); |
| 216 if (!collection_info.report_ids.empty()) { | 216 if (!collection_info.report_ids.empty()) { |
| 217 device_info.has_report_id = true; | 217 device_info->has_report_id_ = true; |
| 218 } | 218 } |
| 219 device_info.collections.push_back(collection_info); | 219 device_info->collections_.push_back(collection_info); |
| 220 } | 220 } |
| 221 // Whether or not the device includes report IDs in its reports the size | 221 // Whether or not the device includes report IDs in its reports the size |
| 222 // of the report ID is included in the value provided by Windows. This | 222 // of the report ID is included in the value provided by Windows. This |
| 223 // appears contrary to the MSDN documentation. | 223 // appears contrary to the MSDN documentation. |
| 224 if (device_info.max_input_report_size > 0) { | 224 if (device_info->max_input_report_size() > 0) { |
| 225 device_info.max_input_report_size--; | 225 device_info->max_input_report_size_--; |
| 226 } | 226 } |
| 227 if (device_info.max_output_report_size > 0) { | 227 if (device_info->max_output_report_size() > 0) { |
| 228 device_info.max_output_report_size--; | 228 device_info->max_output_report_size_--; |
| 229 } | 229 } |
| 230 if (device_info.max_feature_report_size > 0) { | 230 if (device_info->max_feature_report_size() > 0) { |
| 231 device_info.max_feature_report_size--; | 231 device_info->max_feature_report_size_--; |
| 232 } | 232 } |
| 233 HidD_FreePreparsedData(preparsed_data); | 233 HidD_FreePreparsedData(preparsed_data); |
| 234 } | 234 } |
| 235 | 235 |
| 236 AddDevice(device_info); | 236 AddDevice(device_info); |
| 237 } | 237 } |
| 238 | 238 |
| 239 void HidServiceWin::OnDeviceRemoved(const std::string& device_path) { | 239 void HidServiceWin::OnDeviceRemoved(const std::string& device_path) { |
| 240 RemoveDevice(device_path); | 240 RemoveDevice(device_path); |
| 241 } | 241 } |
| 242 | 242 |
| 243 base::win::ScopedHandle HidServiceWin::OpenDevice( | 243 base::win::ScopedHandle HidServiceWin::OpenDevice( |
| 244 const std::string& device_path) { | 244 const std::string& device_path) { |
| 245 base::win::ScopedHandle file( | 245 base::win::ScopedHandle file( |
| 246 CreateFileA(device_path.c_str(), GENERIC_WRITE | GENERIC_READ, | 246 CreateFileA(device_path.c_str(), GENERIC_WRITE | GENERIC_READ, |
| 247 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, | 247 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, |
| 248 FILE_FLAG_OVERLAPPED, NULL)); | 248 FILE_FLAG_OVERLAPPED, NULL)); |
| 249 if (!file.IsValid() && | 249 if (!file.IsValid() && |
| 250 GetLastError() == base::File::FILE_ERROR_ACCESS_DENIED) { | 250 GetLastError() == base::File::FILE_ERROR_ACCESS_DENIED) { |
| 251 file.Set(CreateFileA(device_path.c_str(), GENERIC_READ, FILE_SHARE_READ, | 251 file.Set(CreateFileA(device_path.c_str(), GENERIC_READ, FILE_SHARE_READ, |
| 252 NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)); | 252 NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)); |
| 253 } | 253 } |
| 254 return file.Pass(); | 254 return file.Pass(); |
| 255 } | 255 } |
| 256 | 256 |
| 257 } // namespace device | 257 } // namespace device |
| OLD | NEW |