| 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 11 matching lines...) Expand all  Loading... | 
| 22 #include "device/hid/hid_connection_win.h" | 22 #include "device/hid/hid_connection_win.h" | 
| 23 #include "device/hid/hid_device_info.h" | 23 #include "device/hid/hid_device_info.h" | 
| 24 #include "net/base/io_buffer.h" | 24 #include "net/base/io_buffer.h" | 
| 25 | 25 | 
| 26 // Setup API is required to enumerate HID devices. | 26 // Setup API is required to enumerate HID devices. | 
| 27 #pragma comment(lib, "setupapi.lib") | 27 #pragma comment(lib, "setupapi.lib") | 
| 28 #pragma comment(lib, "hid.lib") | 28 #pragma comment(lib, "hid.lib") | 
| 29 | 29 | 
| 30 namespace device { | 30 namespace device { | 
| 31 | 31 | 
| 32 namespace { |  | 
| 33 |  | 
| 34 void Noop() { |  | 
| 35   // This function does nothing. |  | 
| 36 } |  | 
| 37 } |  | 
| 38 |  | 
| 39 HidServiceWin::HidServiceWin( | 32 HidServiceWin::HidServiceWin( | 
| 40     scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) | 33     scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) | 
| 41     : file_task_runner_(file_task_runner), | 34     : file_task_runner_(file_task_runner), | 
| 42       device_observer_(this), | 35       device_observer_(this), | 
| 43       weak_factory_(this) { | 36       weak_factory_(this) { | 
| 44   task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 37   task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 
| 45   DCHECK(task_runner_.get()); | 38   DCHECK(task_runner_.get()); | 
| 46   DeviceMonitorWin* device_monitor = | 39   DeviceMonitorWin* device_monitor = | 
| 47       DeviceMonitorWin::GetForDeviceInterface(GUID_DEVINTERFACE_HID); | 40       DeviceMonitorWin::GetForDeviceInterface(GUID_DEVINTERFACE_HID); | 
| 48   if (device_monitor) { | 41   if (device_monitor) { | 
| 49     device_observer_.Add(device_monitor); | 42     device_observer_.Add(device_monitor); | 
| 50   } | 43   } | 
| 51   file_task_runner_->PostTask( | 44   file_task_runner_->PostTask( | 
| 52       FROM_HERE, base::Bind(&HidServiceWin::EnumerateOnFileThread, | 45       FROM_HERE, base::Bind(&HidServiceWin::EnumerateOnFileThread, | 
| 53                             weak_factory_.GetWeakPtr(), task_runner_)); | 46                             weak_factory_.GetWeakPtr(), task_runner_)); | 
| 54 } | 47 } | 
| 55 | 48 | 
|  | 49 HidServiceWin::~HidServiceWin() {} | 
|  | 50 | 
| 56 void HidServiceWin::Connect(const HidDeviceId& device_id, | 51 void HidServiceWin::Connect(const HidDeviceId& device_id, | 
| 57                             const ConnectCallback& callback) { | 52                             const ConnectCallback& callback) { | 
| 58   DCHECK(thread_checker_.CalledOnValidThread()); | 53   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 59   const auto& map_entry = devices().find(device_id); | 54   const auto& map_entry = devices().find(device_id); | 
| 60   if (map_entry == devices().end()) { | 55   if (map_entry == devices().end()) { | 
| 61     task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); | 56     task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); | 
| 62     return; | 57     return; | 
| 63   } | 58   } | 
| 64   scoped_refptr<HidDeviceInfo> device_info = map_entry->second; | 59   scoped_refptr<HidDeviceInfo> device_info = map_entry->second; | 
| 65 | 60 | 
| 66   base::win::ScopedHandle file(OpenDevice(device_info->device_id())); | 61   base::win::ScopedHandle file(OpenDevice(device_info->device_id())); | 
| 67   if (!file.IsValid()) { | 62   if (!file.IsValid()) { | 
| 68     HID_PLOG(EVENT) << "Failed to open device"; | 63     HID_PLOG(EVENT) << "Failed to open device"; | 
| 69     task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); | 64     task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); | 
| 70     return; | 65     return; | 
| 71   } | 66   } | 
| 72 | 67 | 
| 73   task_runner_->PostTask( | 68   task_runner_->PostTask( | 
| 74       FROM_HERE, | 69       FROM_HERE, | 
| 75       base::Bind(callback, new HidConnectionWin(device_info, file.Pass()))); | 70       base::Bind(callback, new HidConnectionWin(device_info, file.Pass()))); | 
| 76 } | 71 } | 
| 77 | 72 | 
| 78 HidServiceWin::~HidServiceWin() { |  | 
| 79 } |  | 
| 80 |  | 
| 81 // static | 73 // static | 
| 82 void HidServiceWin::EnumerateOnFileThread( | 74 void HidServiceWin::EnumerateOnFileThread( | 
| 83     base::WeakPtr<HidServiceWin> service, | 75     base::WeakPtr<HidServiceWin> service, | 
| 84     scoped_refptr<base::SingleThreadTaskRunner> task_runner) { | 76     scoped_refptr<base::SingleThreadTaskRunner> task_runner) { | 
| 85   HDEVINFO device_info_set = | 77   HDEVINFO device_info_set = | 
| 86       SetupDiGetClassDevs(&GUID_DEVINTERFACE_HID, NULL, NULL, | 78       SetupDiGetClassDevs(&GUID_DEVINTERFACE_HID, NULL, NULL, | 
| 87                           DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); | 79                           DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); | 
| 88 | 80 | 
| 89   if (device_info_set != INVALID_HANDLE_VALUE) { | 81   if (device_info_set != INVALID_HANDLE_VALUE) { | 
| 90     SP_DEVICE_INTERFACE_DATA device_interface_data; | 82     SP_DEVICE_INTERFACE_DATA device_interface_data; | 
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 279       FROM_HERE, | 271       FROM_HERE, | 
| 280       base::Bind(&HidServiceWin::AddDeviceOnFileThread, | 272       base::Bind(&HidServiceWin::AddDeviceOnFileThread, | 
| 281                  weak_factory_.GetWeakPtr(), task_runner_, device_path)); | 273                  weak_factory_.GetWeakPtr(), task_runner_, device_path)); | 
| 282 } | 274 } | 
| 283 | 275 | 
| 284 void HidServiceWin::OnDeviceRemoved(const GUID& class_guid, | 276 void HidServiceWin::OnDeviceRemoved(const GUID& class_guid, | 
| 285                                     const std::string& device_path) { | 277                                     const std::string& device_path) { | 
| 286   // Execute a no-op closure on the file task runner to synchronize with any | 278   // Execute a no-op closure on the file task runner to synchronize with any | 
| 287   // devices that are still being enumerated. | 279   // devices that are still being enumerated. | 
| 288   file_task_runner_->PostTaskAndReply( | 280   file_task_runner_->PostTaskAndReply( | 
| 289       FROM_HERE, base::Bind(&Noop), | 281       FROM_HERE, base::Bind(&base::DoNothing), | 
| 290       base::Bind(&HidServiceWin::RemoveDevice, weak_factory_.GetWeakPtr(), | 282       base::Bind(&HidServiceWin::RemoveDevice, weak_factory_.GetWeakPtr(), | 
| 291                  device_path)); | 283                  device_path)); | 
| 292 } | 284 } | 
| 293 | 285 | 
| 294 // static | 286 // static | 
| 295 base::win::ScopedHandle HidServiceWin::OpenDevice( | 287 base::win::ScopedHandle HidServiceWin::OpenDevice( | 
| 296     const std::string& device_path) { | 288     const std::string& device_path) { | 
| 297   base::win::ScopedHandle file( | 289   base::win::ScopedHandle file( | 
| 298       CreateFileA(device_path.c_str(), GENERIC_WRITE | GENERIC_READ, | 290       CreateFileA(device_path.c_str(), GENERIC_WRITE | GENERIC_READ, | 
| 299                   FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, | 291                   FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, | 
| 300                   FILE_FLAG_OVERLAPPED, NULL)); | 292                   FILE_FLAG_OVERLAPPED, NULL)); | 
| 301   if (!file.IsValid() && | 293   if (!file.IsValid() && | 
| 302       GetLastError() == base::File::FILE_ERROR_ACCESS_DENIED) { | 294       GetLastError() == base::File::FILE_ERROR_ACCESS_DENIED) { | 
| 303     file.Set(CreateFileA(device_path.c_str(), GENERIC_READ, FILE_SHARE_READ, | 295     file.Set(CreateFileA(device_path.c_str(), GENERIC_READ, FILE_SHARE_READ, | 
| 304                          NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)); | 296                          NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)); | 
| 305   } | 297   } | 
| 306   return file.Pass(); | 298   return file.Pass(); | 
| 307 } | 299 } | 
| 308 | 300 | 
| 309 }  // namespace device | 301 }  // namespace device | 
| OLD | NEW | 
|---|