Skip to content

Commit

Permalink
Save the driver name in the new Windows USB backend.
Browse files Browse the repository at this point in the history
Communication with a device depends on what driver Windows has loaded
for it. This patch looks up the loaded driver (service) name and saves
it in the UsbDeviceWin object for later use.

BUG=422562

Review-Url: https://codereview.chromium.org/2703373005
Cr-Commit-Position: refs/heads/master@{#452211}
  • Loading branch information
reillyeon authored and Commit bot committed Feb 22, 2017
1 parent c9b2117 commit afbe153
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 15 deletions.
2 changes: 2 additions & 0 deletions device/usb/usb_device_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ UsbDeviceWin::UsbDeviceWin(
const std::string& device_path,
const std::string& hub_path,
int port_number,
const std::string& driver_name,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
: device_path_(device_path),
hub_path_(hub_path),
port_number_(port_number),
driver_name_(driver_name),
task_runner_(base::ThreadTaskRunnerHandle::Get()),
blocking_task_runner_(std::move(blocking_task_runner)) {}

Expand Down
3 changes: 3 additions & 0 deletions device/usb/usb_device_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ class UsbDeviceWin : public UsbDevice {
UsbDeviceWin(const std::string& device_path,
const std::string& hub_path,
int port_number,
const std::string& driver_name,
scoped_refptr<base::SequencedTaskRunner> task_runner);

~UsbDeviceWin() override;

const std::string& device_path() const { return device_path_; }
int port_number() const { return port_number_; }
const std::string& driver_name() const { return driver_name_; }

// Opens the device's parent hub in order to read the device, configuration
// and string descriptors.
Expand All @@ -59,6 +61,7 @@ class UsbDeviceWin : public UsbDevice {
const std::string device_path_;
const std::string hub_path_;
const int port_number_;
const std::string driver_name_;

scoped_refptr<base::SequencedTaskRunner> task_runner_;
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
Expand Down
15 changes: 15 additions & 0 deletions device/usb/usb_service_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_io_thread.h"
#include "device/base/features.h"
#include "device/test/test_device_client.h"
#include "device/test/usb_test_gadget.h"
#include "device/usb/usb_device.h"
Expand Down Expand Up @@ -50,6 +52,19 @@ TEST_F(UsbServiceTest, GetDevices) {
}
}

#if defined(OS_WIN)
TEST_F(UsbServiceTest, GetDevicesNewBackend) {
base::test::ScopedFeatureList features;
features.InitAndEnableFeature(device::kNewUsbBackend);
UsbService* service = device_client_->GetUsbService();
if (service) {
base::RunLoop loop;
service->GetDevices(base::Bind(&OnGetDevices, loop.QuitClosure()));
loop.Run();
}
}
#endif // defined(OS_WIN)

TEST_F(UsbServiceTest, ClaimGadget) {
if (!UsbTestGadget::IsTestEnabled()) return;

Expand Down
49 changes: 35 additions & 14 deletions device/usb/usb_service_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ bool GetDeviceInterfaceDetails(HDEVINFO dev_info,
SP_DEVICE_INTERFACE_DATA* device_interface_data,
std::string* device_path,
uint32_t* port_number,
std::string* parent_instance_id) {
DWORD required_size;
std::string* parent_instance_id,
std::string* service_name) {
DWORD required_size = 0;
if (SetupDiGetDeviceInterfaceDetail(dev_info, device_interface_data, nullptr,
0, &required_size, nullptr) ||
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
Expand Down Expand Up @@ -127,6 +128,20 @@ bool GetDeviceInterfaceDetails(HDEVINFO dev_info,
}
}

if (service_name) {
if (!GetDeviceStringProperty(dev_info, &dev_info_data,
DEVPKEY_Device_Service, service_name)) {
USB_PLOG(ERROR) << "Failed to get device driver name";
return false;
}

// Windows pads this string with a variable number of NUL bytes for no
// discernible reason.
size_t end = service_name->find_last_not_of('\0');
if (end != std::string::npos)
service_name->erase(end + 1);
}

return true;
}

Expand All @@ -150,7 +165,7 @@ bool GetHubDevicePath(const std::string& instance_id,
}

return GetDeviceInterfaceDetails(dev_info.get(), &device_interface_data,
device_path, nullptr, nullptr);
device_path, nullptr, nullptr, nullptr);
}

} // namespace
Expand Down Expand Up @@ -182,9 +197,10 @@ class UsbServiceWin::BlockingThreadHelper {
std::string device_path;
uint32_t port_number;
std::string parent_instance_id;
std::string service_name;
if (!GetDeviceInterfaceDetails(dev_info.get(), &device_interface_data,
&device_path, &port_number,
&parent_instance_id)) {
&parent_instance_id, &service_name)) {
continue;
}

Expand All @@ -198,8 +214,9 @@ class UsbServiceWin::BlockingThreadHelper {
}

service_task_runner_->PostTask(
FROM_HERE, base::Bind(&UsbServiceWin::CreateDeviceObject, service_,
device_path, hub_path, port_number));
FROM_HERE,
base::Bind(&UsbServiceWin::CreateDeviceObject, service_, device_path,
hub_path, port_number, service_name));
}

if (GetLastError() != ERROR_NO_MORE_ITEMS)
Expand Down Expand Up @@ -228,9 +245,10 @@ class UsbServiceWin::BlockingThreadHelper {

uint32_t port_number;
std::string parent_instance_id;
std::string service_name;
if (!GetDeviceInterfaceDetails(dev_info.get(), &device_interface_data,
nullptr, &port_number,
&parent_instance_id)) {
nullptr, &port_number, &parent_instance_id,
&service_name)) {
return;
}

Expand All @@ -244,8 +262,9 @@ class UsbServiceWin::BlockingThreadHelper {
}

service_task_runner_->PostTask(
FROM_HERE, base::Bind(&UsbServiceWin::CreateDeviceObject, service_,
device_path, hub_path, port_number));
FROM_HERE,
base::Bind(&UsbServiceWin::CreateDeviceObject, service_, device_path,
hub_path, port_number, service_name));
}

private:
Expand Down Expand Up @@ -327,15 +346,16 @@ void UsbServiceWin::HelperStarted() {

void UsbServiceWin::CreateDeviceObject(const std::string& device_path,
const std::string& hub_path,
int port_number) {
int port_number,
const std::string& driver_name) {
// Devices that appear during initial enumeration are gathered into the first
// result returned by GetDevices() and prevent device add/remove notifications
// from being sent.
if (!enumeration_ready())
++first_enumeration_countdown_;

scoped_refptr<UsbDeviceWin> device(
new UsbDeviceWin(device_path, hub_path, port_number, task_runner()));
scoped_refptr<UsbDeviceWin> device(new UsbDeviceWin(
device_path, hub_path, port_number, driver_name, blocking_task_runner()));
devices_by_path_[device->device_path()] = device;
device->ReadDescriptors(base::Bind(&UsbServiceWin::DeviceReady,
weak_factory_.GetWeakPtr(), device));
Expand Down Expand Up @@ -367,7 +387,8 @@ void UsbServiceWin::DeviceReady(scoped_refptr<UsbDeviceWin> device,
<< device->manufacturer_string()
<< "\", product=" << device->product_id() << " \""
<< device->product_string() << "\", serial=\""
<< device->serial_number() << "\", guid=" << device->guid();
<< device->serial_number() << "\", driver=\""
<< device->driver_name() << "\", guid=" << device->guid();
} else {
devices_by_path_.erase(it);
}
Expand Down
3 changes: 2 additions & 1 deletion device/usb/usb_service_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ class UsbServiceWin : public DeviceMonitorWin::Observer, public UsbService {
void HelperStarted();
void CreateDeviceObject(const std::string& device_path,
const std::string& hub_path,
int port_number);
int port_number,
const std::string& driver_name);

void DeviceReady(scoped_refptr<UsbDeviceWin> device, bool success);

Expand Down

0 comments on commit afbe153

Please sign in to comment.