| 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;
|
| }
|
|
|