From 42be3929971f7c99343260f4bc56a4fb2a66ea6e Mon Sep 17 00:00:00 2001 From: Alessandro Bellia Date: Sat, 28 Sep 2024 17:43:32 +0200 Subject: [PATCH] fixed usb devices gathering Signed-off-by: Alessandro Bellia --- Client/scan/mouse.cpp | 192 ++++++++++++++++++++++++------------------ 1 file changed, 110 insertions(+), 82 deletions(-) diff --git a/Client/scan/mouse.cpp b/Client/scan/mouse.cpp index 98b6da1..f1a82bd 100644 --- a/Client/scan/mouse.cpp +++ b/Client/scan/mouse.cpp @@ -319,7 +319,7 @@ QWORD SDL_GetTicksNS(void) #include #include #include -#include +#include #include #include #include @@ -339,96 +339,84 @@ DEFINE_GUID(GUID_DEVINTERFACE_USB_HOST_CONTROLLER, 0x3abf6f2d, 0x71c4, 0x462a, 0 0x68, 0x61, 0xe6, 0xaf, 0x27); -std::vector get_usb_ports(void) +std::vector get_usb_hubs(void) { - std::vector ports; + std::vector hubs; - HDEVINFO device_interface = SetupDiGetClassDevsA(&GUID_CLASS_USB_HOST_CONTROLLER, 0, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); - if (device_interface == 0) + HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_HUB, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + if (hDevInfo == INVALID_HANDLE_VALUE) { - return {}; + std::cerr << "Error: Unable to get device information set for USB hubs. " << GetLastError() << std::endl; + return hubs; } - SP_DEVINFO_DATA device_data{}; - device_data.cbSize = sizeof(SP_DEVINFO_DATA); - - for (int index = 0; SetupDiEnumDeviceInfo(device_interface, index, &device_data); index++) + SP_DEVICE_INTERFACE_DATA deviceInterfaceData; + deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + DWORD index = 0; + while (SetupDiEnumDeviceInterfaces( + hDevInfo, + NULL, + &GUID_DEVINTERFACE_USB_HUB, + index, + &deviceInterfaceData + )) { - SP_DEVICE_INTERFACE_DATA interface_data{}; - interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - if (!SetupDiEnumDeviceInterfaces(device_interface, - 0, - (LPGUID)&GUID_CLASS_USB_HOST_CONTROLLER, - index, - &interface_data)) - { - continue; - } + DWORD requiredSize = 0; + SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, NULL, 0, &requiredSize, NULL); - ULONG requested_size = 0; - if (!SetupDiGetDeviceInterfaceDetailA(device_interface, - &interface_data, - NULL, - 0, - &requested_size, - NULL) - && - GetLastError() != ERROR_INSUFFICIENT_BUFFER) + PSP_DEVICE_INTERFACE_DETAIL_DATA pDeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiredSize); + if (!pDeviceInterfaceDetailData) { - continue; + std::cerr << "Error: Unable to allocate memory. " << GetLastError() << std::endl; + break; } + pDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); - PSP_DEVICE_INTERFACE_DETAIL_DATA_A interface_detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)malloc(requested_size); + SP_DEVINFO_DATA devInfoData; + devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - interface_detail->cbSize = sizeof(PSP_DEVICE_INTERFACE_DETAIL_DATA_A); - - if (!SetupDiGetDeviceInterfaceDetailA(device_interface, - &interface_data, - interface_detail, - requested_size, - &requested_size, - NULL)) + if (!SetupDiGetDeviceInterfaceDetail( + hDevInfo, + &deviceInterfaceData, + pDeviceInterfaceDetailData, + requiredSize, + NULL, + &devInfoData + )) { - free(interface_detail); - continue; + std::cerr << "Error: Unable to get device interface detail data. " << GetLastError() << std::endl; + free(pDeviceInterfaceDetailData); + break; } - HANDLE root_hub = CreateFileA(interface_detail->DevicePath, - GENERIC_WRITE, - FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - 0, - NULL); - - if (root_hub == INVALID_HANDLE_VALUE) - continue; - - char buffer[2048]; - memset(buffer, 0, 2048); - DeviceIoControl(root_hub, IOCTL_USB_GET_ROOT_HUB_NAME, buffer, 2048, buffer, 2048, 0, 0); - CloseHandle(root_hub); - - wchar_t device_path[260]{}; - wcscat(device_path, L"\\\\.\\"); - wcscat(device_path, ((USB_ROOT_HUB_NAME*)buffer)->RootHubName); - - HANDLE hub = CreateFileW(device_path, + HANDLE hHubDevice = CreateFile( + pDeviceInterfaceDetailData->DevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, - NULL); + NULL + ); - if (hub == INVALID_HANDLE_VALUE) + if (hHubDevice == INVALID_HANDLE_VALUE) + { + std::cerr << "Error: Unable to open hub device. " << GetLastError() << std::endl; + free(pDeviceInterfaceDetailData); + index++; continue; + } - ports.push_back(hub); + hubs.push_back(hHubDevice); + free(pDeviceInterfaceDetailData); + index++; } - return ports; + SetupDiDestroyDeviceInfoList(hDevInfo); + + return hubs; } typedef struct _STRING_DESCRIPTOR_NODE @@ -472,7 +460,7 @@ BOOL get_device_descriptor(HANDLE hub, DWORD index, USB_DEVICE_DESCRIPTOR *devic auto entry = (PUSB_COMMON_DESCRIPTOR)usb_desc; BOOL status = 0; - while ((PUCHAR)entry + sizeof(USB_COMMON_DESCRIPTOR) < usb_desc_size && + while ((PUCHAR)entry + sizeof(USB_COMMON_DESCRIPTOR) <= usb_desc_size && (PUCHAR)entry + entry->bLength <= usb_desc_size) { if (entry->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) @@ -502,38 +490,78 @@ std::vector get_usb_devices() { std::vector devices; - for (auto &port : get_usb_ports()) + const auto hubs = get_usb_hubs(); + + for (const auto hHubDevice : hubs) { - USB_NODE_INFORMATION port_info{}; - port_info.NodeType = USB_HUB_NODE::UsbHub; - DeviceIoControl(port, IOCTL_USB_GET_NODE_INFORMATION, &port_info, sizeof(USB_NODE_INFORMATION), &port_info, sizeof(USB_NODE_INFORMATION), 0, 0); + // Get hub information + USB_NODE_INFORMATION hubInfo = { }; + DWORD bytesReturned = 0; + BOOL success = DeviceIoControl( + hHubDevice, + IOCTL_USB_GET_NODE_INFORMATION, + &hubInfo, + sizeof(hubInfo), + &hubInfo, + sizeof(hubInfo), + &bytesReturned, + NULL + ); + + if (!success) + { + std::cerr << "Error: Unable to get hub information. " << GetLastError() << std::endl; + CloseHandle(hHubDevice); + continue; + } - for (int i = 0; i < port_info.u.HubInformation.HubDescriptor.bNumberOfPorts; i++) + ULONG numPorts = hubInfo.u.HubInformation.HubDescriptor.bNumberOfPorts; + + // Enumerate ports on the hub + for (ULONG port = 1; port <= numPorts; port++) { - USB_NODE_CONNECTION_INFORMATION_EX connection { 0 }; - connection.ConnectionIndex = i; + USB_NODE_CONNECTION_INFORMATION_EX connectionInfoEx = { 0 }; + connectionInfoEx.ConnectionIndex = port; + + success = DeviceIoControl( + hHubDevice, + IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, + &connectionInfoEx, + sizeof(connectionInfoEx), + &connectionInfoEx, + sizeof(connectionInfoEx), + &bytesReturned, + NULL + ); + + if (!success) + { + std::cerr << "Error: Unable to get connection information. " << GetLastError() << std::endl; + continue; + } - DeviceIoControl(port, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &connection, sizeof(connection), &connection, sizeof(connection), 0, 0); - if (connection.ConnectionStatus != USB_CONNECTION_STATUS::DeviceConnected) + // Check if a device is connected + if (connectionInfoEx.ConnectionStatus != USB_CONNECTION_STATUS::DeviceConnected) { continue; } - if (!get_device_descriptor(port, i, &connection.DeviceDescriptor)) + // Use the DeviceDescriptor from connectionInfoEx + if (!get_device_descriptor(hHubDevice, port, &connectionInfoEx.DeviceDescriptor)) { continue; } devices.push_back( - {connection.DeviceDescriptor.idVendor, connection.DeviceDescriptor.idProduct, - connection.DeviceDescriptor.bDeviceClass, - connection.DeviceDescriptor.bDeviceSubClass, - connection.DeviceDescriptor.bDeviceProtocol + { connectionInfoEx.DeviceDescriptor.idVendor, connectionInfoEx.DeviceDescriptor.idProduct, + connectionInfoEx.DeviceDescriptor.bDeviceClass, + connectionInfoEx.DeviceDescriptor.bDeviceSubClass, + connectionInfoEx.DeviceDescriptor.bDeviceProtocol } ); } - CloseHandle(port); + CloseHandle(hHubDevice); } return devices;