diff options
author | reillyg@chromium.org <reillyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-19 05:11:08 +0000 |
---|---|---|
committer | reillyg@chromium.org <reillyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-19 05:11:08 +0000 |
commit | da371737a7c86c7ae60ad6be1d8342e25073e828 (patch) | |
tree | a7f50453b7ec86d29e5ddb31e736104ea1267c43 /device/hid/hid_service_win.cc | |
parent | afe7d90db148b91184bb43e21ff710664cf20afe (diff) | |
download | chromium_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/hid/hid_service_win.cc')
-rw-r--r-- | device/hid/hid_service_win.cc | 136 |
1 files changed, 77 insertions, 59 deletions
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]); } } |