Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(398)

Side by Side Diff: device/usb/usb_service_impl.cc

Issue 1439443002: Reland: Add code to deal with serial device disconnection detection on Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address grt@'s comments Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/usb/usb_service_impl.h" 5 #include "device/usb/usb_service_impl.h"
6 6
7 #include <list> 7 #include <list>
8 #include <set> 8 #include <set>
9 9
10 #include "base/barrier_closure.h" 10 #include "base/barrier_closure.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/memory/weak_ptr.h" 13 #include "base/memory/weak_ptr.h"
14 #include "base/single_thread_task_runner.h" 14 #include "base/single_thread_task_runner.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
18 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
19 #include "components/device_event_log/device_event_log.h" 19 #include "components/device_event_log/device_event_log.h"
20 #include "device/usb/usb_device_handle.h" 20 #include "device/usb/usb_device_handle.h"
21 #include "device/usb/usb_error.h" 21 #include "device/usb/usb_error.h"
22 #include "device/usb/webusb_descriptors.h" 22 #include "device/usb/webusb_descriptors.h"
23 #include "third_party/libusb/src/libusb/libusb.h" 23 #include "third_party/libusb/src/libusb/libusb.h"
24 24
25 #if defined(OS_WIN) 25 #if defined(OS_WIN)
26 #include <setupapi.h> 26 #include <setupapi.h>
27 #include <usbiodef.h> 27 #include <usbiodef.h>
28 28
29 #include "base/strings/string_util.h" 29 #include "base/strings/string_util.h"
30 #include "device/core/device_info_query_win.h"
30 #endif // OS_WIN 31 #endif // OS_WIN
31 32
32 #if defined(USE_UDEV) 33 #if defined(USE_UDEV)
33 #include "device/udev_linux/scoped_udev.h" 34 #include "device/udev_linux/scoped_udev.h"
34 #endif // USE_UDEV 35 #endif // USE_UDEV
35 36
36 using net::IOBufferWithSize; 37 using net::IOBufferWithSize;
37 38
38 namespace device { 39 namespace device {
39 40
40 namespace { 41 namespace {
41 42
42 // Standard USB requests and descriptor types: 43 // Standard USB requests and descriptor types:
43 const uint16_t kUsbVersion2_1 = 0x0210; 44 const uint16_t kUsbVersion2_1 = 0x0210;
44 const uint8_t kGetDescriptorRequest = 0x06; 45 const uint8_t kGetDescriptorRequest = 0x06;
45 const uint8_t kStringDescriptorType = 0x03; 46 const uint8_t kStringDescriptorType = 0x03;
46 const uint8_t kBosDescriptorType = 0x0F; 47 const uint8_t kBosDescriptorType = 0x0F;
47 48
48 // WebUSB requests: 49 // WebUSB requests:
49 const uint8_t kGetAllowedOriginsRequest = 0x01; 50 const uint8_t kGetAllowedOriginsRequest = 0x01;
50 const uint8_t kGetLandingPageRequest = 0x02; 51 const uint8_t kGetLandingPageRequest = 0x02;
51 52
52 const int kControlTransferTimeout = 60000; // 1 minute 53 const int kControlTransferTimeout = 60000; // 1 minute
53 54
54 #if defined(OS_WIN) 55 #if defined(OS_WIN)
55 56
56 // Wrapper around a HDEVINFO that automatically destroys it.
57 class ScopedDeviceInfoList {
58 public:
59 explicit ScopedDeviceInfoList(HDEVINFO handle) : handle_(handle) {}
60
61 ~ScopedDeviceInfoList() {
62 if (valid()) {
63 SetupDiDestroyDeviceInfoList(handle_);
64 }
65 }
66
67 bool valid() { return handle_ != INVALID_HANDLE_VALUE; }
68
69 HDEVINFO get() { return handle_; }
70
71 private:
72 HDEVINFO handle_;
73
74 DISALLOW_COPY_AND_ASSIGN(ScopedDeviceInfoList);
75 };
76
77 // Wrapper around an SP_DEVINFO_DATA that initializes it properly and
78 // automatically deletes it.
79 class ScopedDeviceInfo {
80 public:
81 ScopedDeviceInfo() {
82 memset(&dev_info_data_, 0, sizeof(dev_info_data_));
83 dev_info_data_.cbSize = sizeof(dev_info_data_);
84 }
85
86 ~ScopedDeviceInfo() {
87 if (dev_info_set_ != INVALID_HANDLE_VALUE) {
88 SetupDiDeleteDeviceInfo(dev_info_set_, &dev_info_data_);
89 }
90 }
91
92 // Once the SP_DEVINFO_DATA has been populated it must be freed using the
93 // HDEVINFO it was created from.
94 void set_valid(HDEVINFO dev_info_set) {
95 DCHECK(dev_info_set_ == INVALID_HANDLE_VALUE);
96 DCHECK(dev_info_set != INVALID_HANDLE_VALUE);
97 dev_info_set_ = dev_info_set;
98 }
99
100 PSP_DEVINFO_DATA get() { return &dev_info_data_; }
101
102 private:
103 HDEVINFO dev_info_set_ = INVALID_HANDLE_VALUE;
104 SP_DEVINFO_DATA dev_info_data_;
105 };
106
107 bool IsWinUsbInterface(const std::string& device_path) { 57 bool IsWinUsbInterface(const std::string& device_path) {
108 ScopedDeviceInfoList dev_info_list(SetupDiCreateDeviceInfoList(NULL, NULL)); 58 device::DeviceInfoQueryWin device_info_query;
grt (UTC plus 2) 2015/11/17 16:06:56 omit device::
juncai 2015/11/17 19:14:07 Done.
109 if (!dev_info_list.valid()) { 59 if (!device_info_query.device_info_list_valid()) {
110 USB_PLOG(ERROR) << "Failed to create a device information set"; 60 USB_PLOG(ERROR) << "Failed to create a device information set";
111 return false; 61 return false;
112 } 62 }
113 63
114 // This will add the device to |dev_info_list| so we can query driver info. 64 // This will add the device so we can query driver info.
115 if (!SetupDiOpenDeviceInterfaceA(dev_info_list.get(), device_path.c_str(), 0, 65 if (!device_info_query.AddDevice(device_path.c_str())) {
116 NULL)) {
117 USB_PLOG(ERROR) << "Failed to get device interface data for " 66 USB_PLOG(ERROR) << "Failed to get device interface data for "
118 << device_path; 67 << device_path;
119 return false; 68 return false;
120 } 69 }
121 70
122 ScopedDeviceInfo dev_info; 71 if (!device_info_query.GetDeviceInfo()) {
123 if (!SetupDiEnumDeviceInfo(dev_info_list.get(), 0, dev_info.get())) {
124 USB_PLOG(ERROR) << "Failed to get device info for " << device_path; 72 USB_PLOG(ERROR) << "Failed to get device info for " << device_path;
125 return false; 73 return false;
126 } 74 }
127 dev_info.set_valid(dev_info_list.get());
128 75
129 DWORD reg_data_type; 76 std::string buffer;
130 BYTE buffer[256]; 77 if (!device_info_query.GetDeviceStringProperty(SPDRP_SERVICE, &buffer)) {
131 if (!SetupDiGetDeviceRegistryPropertyA(dev_info_list.get(), dev_info.get(),
132 SPDRP_SERVICE, &reg_data_type,
133 &buffer[0], sizeof buffer, NULL)) {
134 USB_PLOG(ERROR) << "Failed to get device service property"; 78 USB_PLOG(ERROR) << "Failed to get device service property";
135 return false; 79 return false;
136 } 80 }
137 if (reg_data_type != REG_SZ) {
138 USB_LOG(ERROR) << "Unexpected data type for driver service: "
139 << reg_data_type;
140 return false;
141 }
142 81
143 USB_LOG(DEBUG) << "Driver for " << device_path << " is " << buffer << "."; 82 USB_LOG(DEBUG) << "Driver for " << device_path << " is " << buffer << ".";
144 if (base::StartsWith(reinterpret_cast<const char*>(buffer), "WinUSB", 83 if (base::StartsWith(buffer, "WinUSB", base::CompareCase::INSENSITIVE_ASCII))
145 base::CompareCase::INSENSITIVE_ASCII))
146 return true; 84 return true;
147 return false; 85 return false;
148 } 86 }
149 87
150 #endif // OS_WIN 88 #endif // OS_WIN
151 89
152 void GetDeviceListOnBlockingThread( 90 void GetDeviceListOnBlockingThread(
153 const std::string& new_device_path, 91 const std::string& new_device_path,
154 scoped_refptr<UsbContext> usb_context, 92 scoped_refptr<UsbContext> usb_context,
155 scoped_refptr<base::SequencedTaskRunner> task_runner, 93 scoped_refptr<base::SequencedTaskRunner> task_runner,
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 PlatformDeviceMap::iterator it = platform_devices_.find(platform_device); 791 PlatformDeviceMap::iterator it = platform_devices_.find(platform_device);
854 if (it != platform_devices_.end()) { 792 if (it != platform_devices_.end()) {
855 RemoveDevice(it->second); 793 RemoveDevice(it->second);
856 } else { 794 } else {
857 devices_being_enumerated_.erase(platform_device); 795 devices_being_enumerated_.erase(platform_device);
858 } 796 }
859 libusb_unref_device(platform_device); 797 libusb_unref_device(platform_device);
860 } 798 }
861 799
862 } // namespace device 800 } // namespace device
OLDNEW
« device/serial/serial_io_handler_win.cc ('K') | « device/serial/serial_io_handler_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698