Commit da371737 authored by reillyg@chromium.org's avatar reillyg@chromium.org

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
parent afe7d90d
...@@ -90,6 +90,10 @@ void HidService::RemoveDevice(const HidDeviceId& device_id) { ...@@ -90,6 +90,10 @@ void HidService::RemoveDevice(const HidDeviceId& device_id) {
devices_.erase(it); devices_.erase(it);
} }
const HidService::DeviceMap& HidService::GetDevicesNoEnumerate() const {
return devices_;
}
HidService* HidService::GetInstance() { HidService* HidService::GetInstance() {
if (!g_hid_service_ptr.Get().get()) if (!g_hid_service_ptr.Get().get())
g_hid_service_ptr.Get().reset(CreateInstance()); g_hid_service_ptr.Get().reset(CreateInstance());
......
...@@ -50,6 +50,7 @@ class HidService : public base::MessageLoop::DestructionObserver { ...@@ -50,6 +50,7 @@ class HidService : public base::MessageLoop::DestructionObserver {
void AddDevice(const HidDeviceInfo& info); void AddDevice(const HidDeviceInfo& info);
void RemoveDevice(const HidDeviceId& device_id); void RemoveDevice(const HidDeviceId& device_id);
const DeviceMap& GetDevicesNoEnumerate() const;
base::ThreadChecker thread_checker_; base::ThreadChecker thread_checker_;
......
...@@ -66,78 +66,96 @@ void HidServiceWin::Enumerate() { ...@@ -66,78 +66,96 @@ void HidServiceWin::Enumerate() {
NULL, NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (device_info_set == INVALID_HANDLE_VALUE) std::set<std::string> connected_devices;
return;
for (int device_index = 0; if (device_info_set != INVALID_HANDLE_VALUE) {
SetupDiEnumDeviceInterfaces(device_info_set, for (int device_index = 0;
NULL, SetupDiEnumDeviceInterfaces(device_info_set,
&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, NULL,
0, &GUID_DEVINTERFACE_HID,
&required_size, device_index,
NULL); &device_interface_data);
++device_index) {
scoped_ptr<SP_DEVICE_INTERFACE_DETAIL_DATA_A, base::FreeDeleter> DWORD required_size = 0;
device_interface_detail_data(
static_cast<SP_DEVICE_INTERFACE_DETAIL_DATA_A*>( // Determime the required size of detail struct.
malloc(required_size))); SetupDiGetDeviceInterfaceDetailA(device_info_set,
device_interface_detail_data->cbSize = &device_interface_data,
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); NULL,
0,
// Get the detailed data for this device. &required_size,
res = SetupDiGetDeviceInterfaceDetailA(device_info_set, NULL);
&device_interface_data,
device_interface_detail_data.get(), scoped_ptr<SP_DEVICE_INTERFACE_DETAIL_DATA_A, base::FreeDeleter>
required_size, device_interface_detail_data(
NULL, static_cast<SP_DEVICE_INTERFACE_DETAIL_DATA_A*>(
NULL); malloc(required_size)));
if (!res) device_interface_detail_data->cbSize =
continue; sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
// Enumerate device info. Looking for Setup Class "HIDClass". // Get the detailed data for this device.
for (DWORD i = 0; res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data); &device_interface_data,
i++) { device_interface_detail_data.get(),
char class_name[256] = {0}; required_size,
res = SetupDiGetDeviceRegistryPropertyA(device_info_set, NULL,
&devinfo_data, NULL);
SPDRP_CLASS,
NULL,
(PBYTE) class_name,
sizeof(class_name) - 1,
NULL);
if (!res) if (!res)
break; continue;
if (memcmp(class_name, kHIDClass, sizeof(kHIDClass)) == 0) {
char driver_name[256] = {0}; // Enumerate device info. Looking for Setup Class "HIDClass".
// Get bounded driver. for (DWORD i = 0;
SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data);
i++) {
char class_name[256] = {0};
res = SetupDiGetDeviceRegistryPropertyA(device_info_set, res = SetupDiGetDeviceRegistryPropertyA(device_info_set,
&devinfo_data, &devinfo_data,
SPDRP_DRIVER, SPDRP_CLASS,
NULL, NULL,
(PBYTE) driver_name, (PBYTE) class_name,
sizeof(driver_name) - 1, sizeof(class_name) - 1,
NULL); NULL);
if (res) { if (!res)
// Found the driver.
break; 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) // Find disconnected devices.
continue; 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]);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment