/* * Get the VID, PID and current device speed */ static void GetUSBProperties(char* parent_path, char* device_id, usb_device_props* props) { HANDLE handle = INVALID_HANDLE_VALUE; DWORD size; DEVINST device_inst; USB_NODE_CONNECTION_INFORMATION_EX conn_info; USB_NODE_CONNECTION_INFORMATION_EX_V2 conn_info_v2; PF_INIT(CM_Get_DevNode_Registry_PropertyA, Cfgmgr32); if ((parent_path == NULL) || (device_id == NULL) || (props == NULL)) { return; } props->port = 0; size = sizeof(props->port); if ( (pfCM_Get_DevNode_Registry_PropertyA != NULL) && (CM_Locate_DevNodeA(&device_inst, device_id, 0) == CR_SUCCESS) ) { pfCM_Get_DevNode_Registry_PropertyA(device_inst, CM_DRP_ADDRESS, NULL, (PVOID)&props->port, &size, 0); } handle = CreateFileA(parent_path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (handle == INVALID_HANDLE_VALUE) { uprintf("Could not open hub %s: %s", parent_path, WindowsErrorString()); goto out; } memset(&conn_info, 0, sizeof(conn_info)); size = sizeof(conn_info); conn_info.ConnectionIndex = (ULONG)props->port; // coverity[tainted_data_argument] if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size, &conn_info, size, &size, NULL)) { uprintf("Could not get node connection information for '%s': %s", device_id, WindowsErrorString()); goto out; } props->vid = conn_info.DeviceDescriptor.idVendor; props->pid = conn_info.DeviceDescriptor.idProduct; props->speed = conn_info.Speed + 1; // In their great wisdom, Microsoft decided to BREAK the USB speed report between Windows 7 and Windows 8 if (nWindowsVersion >= WINDOWS_8) { memset(&conn_info_v2, 0, sizeof(conn_info_v2)); size = sizeof(conn_info_v2); conn_info_v2.ConnectionIndex = (ULONG)props->port; conn_info_v2.Length = size; conn_info_v2.SupportedUsbProtocols.Usb300 = 1; if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, &conn_info_v2, size, &conn_info_v2, size, &size, NULL)) { uprintf("Could not get node connection information (V2) for device '%s': %s", device_id, WindowsErrorString()); } else if (conn_info_v2.Flags.DeviceIsOperatingAtSuperSpeedOrHigher) { props->speed = USB_SPEED_SUPER_OR_LATER; } else if (conn_info_v2.Flags.DeviceIsSuperSpeedCapableOrHigher) { props->is_LowerSpeed = TRUE; } } out: safe_closehandle(handle); }
/* * Get the VID, PID and current device speed */ static BOOL GetUSBProperties(char* parent_path, char* device_id, usb_device_props* props) { BOOL r = FALSE; CONFIGRET cr; HANDLE handle = INVALID_HANDLE_VALUE; DWORD size; DEVINST device_inst; USB_NODE_CONNECTION_INFORMATION_EX conn_info; USB_NODE_CONNECTION_INFORMATION_EX_V2 conn_info_v2; PF_INIT(CM_Get_DevNode_Registry_PropertyA, Cfgmgr32); if ((parent_path == NULL) || (device_id == NULL) || (props == NULL) || (pfCM_Get_DevNode_Registry_PropertyA == NULL)) { goto out; } cr = CM_Locate_DevNodeA(&device_inst, device_id, 0); if (cr != CR_SUCCESS) { uprintf("Could not get device instance handle for '%s': CR error %d", device_id, cr); goto out; } props->port = 0; size = sizeof(props->port); cr = pfCM_Get_DevNode_Registry_PropertyA(device_inst, CM_DRP_ADDRESS, NULL, (PVOID)&props->port, &size, 0); if (cr != CR_SUCCESS) { uprintf("Could not get port for '%s': CR error %d", device_id, cr); goto out; } handle = CreateFileA(parent_path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (handle == INVALID_HANDLE_VALUE) { uprintf("Could not open hub %s: %s", parent_path, WindowsErrorString()); goto out; } size = sizeof(conn_info); memset(&conn_info, 0, size); conn_info.ConnectionIndex = (ULONG)props->port; // coverity[tainted_data_argument] if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, &conn_info, size, &conn_info, size, &size, NULL)) { uprintf("Could not get node connection information for '%s': %s", device_id, WindowsErrorString()); goto out; } // Some poorly written proprietary Windows 7 USB 3.0 controller drivers (<cough>ASMedia<cough>) // have a screwed up implementation of IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX that succeeds // but returns zeroed data => Add a workaround so that we don't lose our VID:PID... if ((conn_info.DeviceDescriptor.idVendor != 0) || (conn_info.DeviceDescriptor.idProduct != 0)) { props->vid = conn_info.DeviceDescriptor.idVendor; props->pid = conn_info.DeviceDescriptor.idProduct; props->speed = conn_info.Speed + 1; r = TRUE; } // In their great wisdom, Microsoft decided to BREAK the USB speed report between Windows 7 and Windows 8 if (nWindowsVersion >= WINDOWS_8) { size = sizeof(conn_info_v2); memset(&conn_info_v2, 0, size); conn_info_v2.ConnectionIndex = (ULONG)props->port; conn_info_v2.Length = size; conn_info_v2.SupportedUsbProtocols.Usb300 = 1; if (!DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, &conn_info_v2, size, &conn_info_v2, size, &size, NULL)) { uprintf("Could not get node connection information (V2) for device '%s': %s", device_id, WindowsErrorString()); } else if (conn_info_v2.Flags.DeviceIsOperatingAtSuperSpeedOrHigher) { props->speed = USB_SPEED_SUPER_OR_LATER; } else if (conn_info_v2.Flags.DeviceIsSuperSpeedCapableOrHigher) { props->is_LowerSpeed = TRUE; } } out: safe_closehandle(handle); return r; }