summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authorreillyg@chromium.org <reillyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-19 05:11:08 +0000
committerreillyg@chromium.org <reillyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-19 05:11:08 +0000
commitda371737a7c86c7ae60ad6be1d8342e25073e828 (patch)
treea7f50453b7ec86d29e5ddb31e736104ea1267c43 /device
parentafe7d90db148b91184bb43e21ff710664cf20afe (diff)
downloadchromium_src-da371737a7c86c7ae60ad6be1d8342e25073e828.zip
chromium_src-da371737a7c86c7ae60ad6be1d8342e25073e828.tar.gz
chromium_src-da371737a7c86c7ae60ad6be1d8342e25073e828.tar.bz2
Remove HID devices not found during enumeration on Windows.
Windows doesn't give us fine grained notifications for device add and remove so we must do a complete enumeration every time. This patch figures out which devices are no longer present in the enumeration and calls HidService::RemoveDevice. BUG=395272 R=rockot@chromium.org Review URL: https://codereview.chromium.org/399313008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284321 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'device')
-rw-r--r--device/hid/hid_service.cc4
-rw-r--r--device/hid/hid_service.h1
-rw-r--r--device/hid/hid_service_win.cc136
3 files changed, 82 insertions, 59 deletions
diff --git a/device/hid/hid_service.cc b/device/hid/hid_service.cc
index 4d24b00..8aa7cd4 100644
--- a/device/hid/hid_service.cc
+++ b/device/hid/hid_service.cc
@@ -90,6 +90,10 @@ void HidService::RemoveDevice(const HidDeviceId& device_id) {
devices_.erase(it);
}
+const HidService::DeviceMap& HidService::GetDevicesNoEnumerate() const {
+ return devices_;
+}
+
HidService* HidService::GetInstance() {
if (!g_hid_service_ptr.Get().get())
g_hid_service_ptr.Get().reset(CreateInstance());
diff --git a/device/hid/hid_service.h b/device/hid/hid_service.h
index ee0ebb7..ebde59a 100644
--- a/device/hid/hid_service.h
+++ b/device/hid/hid_service.h
@@ -50,6 +50,7 @@ class HidService : public base::MessageLoop::DestructionObserver {
void AddDevice(const HidDeviceInfo& info);
void RemoveDevice(const HidDeviceId& device_id);
+ const DeviceMap& GetDevicesNoEnumerate() const;
base::ThreadChecker thread_checker_;
diff --git a/device/hid/hid_service_win.cc b/device/hid/hid_service_win.cc
index 9f27cff..c3de09a 100644
--- a/device/hid/hid_service_win.cc
+++ b/device/hid/hid_service_win.cc
@@ -66,78 +66,96 @@ void HidServiceWin::Enumerate() {
NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
- if (device_info_set == INVALID_HANDLE_VALUE)
- return;
+ std::set<std::string> connected_devices;
- for (int device_index = 0;
- SetupDiEnumDeviceInterfaces(device_info_set,
- NULL,
- &GUID_DEVINTERFACE_HID,
- device_index,
- &device_interface_data);
- ++device_index) {
- DWORD required_size = 0;
-
- // Determime the required size of detail struct.
- SetupDiGetDeviceInterfaceDetailA(device_info_set,
- &device_interface_data,
+ if (device_info_set != INVALID_HANDLE_VALUE) {
+ for (int device_index = 0;
+ SetupDiEnumDeviceInterfaces(device_info_set,
NULL,
- 0,
- &required_size,
- NULL);
-
- scoped_ptr<SP_DEVICE_INTERFACE_DETAIL_DATA_A, base::FreeDeleter>
- device_interface_detail_data(
- static_cast<SP_DEVICE_INTERFACE_DETAIL_DATA_A*>(
- malloc(required_size)));
- device_interface_detail_data->cbSize =
- sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
-
- // Get the detailed data for this device.
- res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
- &device_interface_data,
- device_interface_detail_data.get(),
- required_size,
- NULL,
- NULL);
- if (!res)
- continue;
-
- // Enumerate device info. Looking for Setup Class "HIDClass".
- for (DWORD i = 0;
- SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data);
- i++) {
- char class_name[256] = {0};
- res = SetupDiGetDeviceRegistryPropertyA(device_info_set,
- &devinfo_data,
- SPDRP_CLASS,
- NULL,
- (PBYTE) class_name,
- sizeof(class_name) - 1,
- NULL);
+ &GUID_DEVINTERFACE_HID,
+ device_index,
+ &device_interface_data);
+ ++device_index) {
+ DWORD required_size = 0;
+
+ // Determime the required size of detail struct.
+ SetupDiGetDeviceInterfaceDetailA(device_info_set,
+ &device_interface_data,
+ NULL,
+ 0,
+ &required_size,
+ NULL);
+
+ scoped_ptr<SP_DEVICE_INTERFACE_DETAIL_DATA_A, base::FreeDeleter>
+ device_interface_detail_data(
+ static_cast<SP_DEVICE_INTERFACE_DETAIL_DATA_A*>(
+ malloc(required_size)));
+ device_interface_detail_data->cbSize =
+ sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
+
+ // Get the detailed data for this device.
+ res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
+ &device_interface_data,
+ device_interface_detail_data.get(),
+ required_size,
+ NULL,
+ NULL);
if (!res)
- break;
- if (memcmp(class_name, kHIDClass, sizeof(kHIDClass)) == 0) {
- char driver_name[256] = {0};
- // Get bounded driver.
+ continue;
+
+ // Enumerate device info. Looking for Setup Class "HIDClass".
+ for (DWORD i = 0;
+ SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data);
+ i++) {
+ char class_name[256] = {0};
res = SetupDiGetDeviceRegistryPropertyA(device_info_set,
&devinfo_data,
- SPDRP_DRIVER,
+ SPDRP_CLASS,
NULL,
- (PBYTE) driver_name,
- sizeof(driver_name) - 1,
+ (PBYTE) class_name,
+ sizeof(class_name) - 1,
NULL);
- if (res) {
- // Found the driver.
+ if (!res)
break;
+ if (memcmp(class_name, kHIDClass, sizeof(kHIDClass)) == 0) {
+ char driver_name[256] = {0};
+ // Get bounded driver.
+ res = SetupDiGetDeviceRegistryPropertyA(device_info_set,
+ &devinfo_data,
+ SPDRP_DRIVER,
+ NULL,
+ (PBYTE) driver_name,
+ sizeof(driver_name) - 1,
+ NULL);
+ if (res) {
+ // Found the driver.
+ break;
+ }
}
}
+
+ if (!res)
+ continue;
+
+ PlatformAddDevice(device_interface_detail_data->DevicePath);
+ connected_devices.insert(device_interface_detail_data->DevicePath);
}
+ }
- if (!res)
- continue;
+ // Find disconnected devices.
+ const DeviceMap& devices = GetDevicesNoEnumerate();
+ std::vector<std::string> disconnected_devices;
+ for (DeviceMap::const_iterator it = devices.begin();
+ it != devices.end();
+ ++it) {
+ if (!ContainsKey(connected_devices, it->first)) {
+ disconnected_devices.push_back(it->first);
+ }
+ }
- PlatformAddDevice(device_interface_detail_data->DevicePath);
+ // Remove disconnected devices.
+ for (size_t i = 0; i < disconnected_devices.size(); ++i) {
+ PlatformRemoveDevice(disconnected_devices[i]);
}
}