Index: device/usb/usb_service_impl.cc |
diff --git a/device/usb/usb_service_impl.cc b/device/usb/usb_service_impl.cc |
index 97700078d0d6e5aa113a7b36031924f719777818..dd5cc9054d1adbd5977b0049efec672239a004c7 100644 |
--- a/device/usb/usb_service_impl.cc |
+++ b/device/usb/usb_service_impl.cc |
@@ -27,7 +27,6 @@ |
#include <usbiodef.h> |
#include "base/strings/string_util.h" |
-#include "device/core/device_info_query_win.h" |
#endif // OS_WIN |
#if defined(USE_UDEV) |
@@ -54,33 +53,96 @@ |
#if defined(OS_WIN) |
+// Wrapper around a HDEVINFO that automatically destroys it. |
+class ScopedDeviceInfoList { |
+ public: |
+ explicit ScopedDeviceInfoList(HDEVINFO handle) : handle_(handle) {} |
+ |
+ ~ScopedDeviceInfoList() { |
+ if (valid()) { |
+ SetupDiDestroyDeviceInfoList(handle_); |
+ } |
+ } |
+ |
+ bool valid() { return handle_ != INVALID_HANDLE_VALUE; } |
+ |
+ HDEVINFO get() { return handle_; } |
+ |
+ private: |
+ HDEVINFO handle_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ScopedDeviceInfoList); |
+}; |
+ |
+// Wrapper around an SP_DEVINFO_DATA that initializes it properly and |
+// automatically deletes it. |
+class ScopedDeviceInfo { |
+ public: |
+ ScopedDeviceInfo() { |
+ memset(&dev_info_data_, 0, sizeof(dev_info_data_)); |
+ dev_info_data_.cbSize = sizeof(dev_info_data_); |
+ } |
+ |
+ ~ScopedDeviceInfo() { |
+ if (dev_info_set_ != INVALID_HANDLE_VALUE) { |
+ SetupDiDeleteDeviceInfo(dev_info_set_, &dev_info_data_); |
+ } |
+ } |
+ |
+ // Once the SP_DEVINFO_DATA has been populated it must be freed using the |
+ // HDEVINFO it was created from. |
+ void set_valid(HDEVINFO dev_info_set) { |
+ DCHECK(dev_info_set_ == INVALID_HANDLE_VALUE); |
+ DCHECK(dev_info_set != INVALID_HANDLE_VALUE); |
+ dev_info_set_ = dev_info_set; |
+ } |
+ |
+ PSP_DEVINFO_DATA get() { return &dev_info_data_; } |
+ |
+ private: |
+ HDEVINFO dev_info_set_ = INVALID_HANDLE_VALUE; |
+ SP_DEVINFO_DATA dev_info_data_; |
+}; |
+ |
bool IsWinUsbInterface(const std::string& device_path) { |
- DeviceInfoQueryWin device_info_query; |
- if (!device_info_query.device_info_list_valid()) { |
+ ScopedDeviceInfoList dev_info_list(SetupDiCreateDeviceInfoList(NULL, NULL)); |
+ if (!dev_info_list.valid()) { |
USB_PLOG(ERROR) << "Failed to create a device information set"; |
return false; |
} |
- // This will add the device so we can query driver info. |
- if (!device_info_query.AddDevice(device_path.c_str())) { |
+ // This will add the device to |dev_info_list| so we can query driver info. |
+ if (!SetupDiOpenDeviceInterfaceA(dev_info_list.get(), device_path.c_str(), 0, |
+ NULL)) { |
USB_PLOG(ERROR) << "Failed to get device interface data for " |
<< device_path; |
return false; |
} |
- if (!device_info_query.GetDeviceInfo()) { |
+ ScopedDeviceInfo dev_info; |
+ if (!SetupDiEnumDeviceInfo(dev_info_list.get(), 0, dev_info.get())) { |
USB_PLOG(ERROR) << "Failed to get device info for " << device_path; |
return false; |
} |
- |
- std::string buffer; |
- if (!device_info_query.GetDeviceStringProperty(SPDRP_SERVICE, &buffer)) { |
+ dev_info.set_valid(dev_info_list.get()); |
+ |
+ DWORD reg_data_type; |
+ BYTE buffer[256]; |
+ if (!SetupDiGetDeviceRegistryPropertyA(dev_info_list.get(), dev_info.get(), |
+ SPDRP_SERVICE, ®_data_type, |
+ &buffer[0], sizeof buffer, NULL)) { |
USB_PLOG(ERROR) << "Failed to get device service property"; |
return false; |
} |
+ if (reg_data_type != REG_SZ) { |
+ USB_LOG(ERROR) << "Unexpected data type for driver service: " |
+ << reg_data_type; |
+ return false; |
+ } |
USB_LOG(DEBUG) << "Driver for " << device_path << " is " << buffer << "."; |
- if (base::StartsWith(buffer, "WinUSB", base::CompareCase::INSENSITIVE_ASCII)) |
+ if (base::StartsWith(reinterpret_cast<const char*>(buffer), "WinUSB", |
+ base::CompareCase::INSENSITIVE_ASCII)) |
return true; |
return false; |
} |