summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2025-07-05 20:55:13 -0500
committerJordan Woyak <jordan.woyak@gmail.com>2025-07-06 19:41:14 -0500
commit13784f842ecabed003be30dc9d8fcabb07c2833e (patch)
tree9546a4683448b81d286071a2644237406d2f8bda /Source/Core
parenta5e85caf0af66fec07b476718a69519b06e6a69f (diff)
LibusbUtils: Add GetStringDescriptor function to return unicode strings and replace our libusb_get_string_descriptor_ascii calls.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/IOS/USB/Bluetooth/LibUSBBluetoothAdapter.cpp49
-rw-r--r--Source/Core/Core/IOS/USB/Host.cpp30
-rw-r--r--Source/Core/Core/LibusbUtils.cpp51
-rw-r--r--Source/Core/Core/LibusbUtils.h8
4 files changed, 79 insertions, 59 deletions
diff --git a/Source/Core/Core/IOS/USB/Bluetooth/LibUSBBluetoothAdapter.cpp b/Source/Core/Core/IOS/USB/Bluetooth/LibUSBBluetoothAdapter.cpp
index 2264d4d956..5fdf8fab06 100644
--- a/Source/Core/Core/IOS/USB/Bluetooth/LibUSBBluetoothAdapter.cpp
+++ b/Source/Core/Core/IOS/USB/Bluetooth/LibUSBBluetoothAdapter.cpp
@@ -107,50 +107,15 @@ LibUSBBluetoothAdapter::LibUSBBluetoothAdapter()
if (IsBluetoothDevice(device_descriptor) && OpenDevice(device_descriptor, device))
{
- unsigned char manufacturer[50] = {}, product[50] = {}, serial_number[50] = {};
- const int manufacturer_ret = libusb_get_string_descriptor_ascii(
- m_handle, device_descriptor.iManufacturer, manufacturer, sizeof(manufacturer));
- if (manufacturer_ret < LIBUSB_SUCCESS)
- {
- WARN_LOG_FMT(IOS_WIIMOTE,
- "Failed to get string for manufacturer descriptor {:02x} for device "
- "{:04x}:{:04x} (rev {:x}): {}",
- device_descriptor.iManufacturer, device_descriptor.idVendor,
- device_descriptor.idProduct, device_descriptor.bcdDevice,
- LibusbUtils::ErrorWrap(manufacturer_ret));
- manufacturer[0] = '?';
- manufacturer[1] = '\0';
- }
- const int product_ret = libusb_get_string_descriptor_ascii(
- m_handle, device_descriptor.iProduct, product, sizeof(product));
- if (product_ret < LIBUSB_SUCCESS)
- {
- WARN_LOG_FMT(IOS_WIIMOTE,
- "Failed to get string for product descriptor {:02x} for device "
- "{:04x}:{:04x} (rev {:x}): {}",
- device_descriptor.iProduct, device_descriptor.idVendor,
- device_descriptor.idProduct, device_descriptor.bcdDevice,
- LibusbUtils::ErrorWrap(product_ret));
- product[0] = '?';
- product[1] = '\0';
- }
- const int serial_ret = libusb_get_string_descriptor_ascii(
- m_handle, device_descriptor.iSerialNumber, serial_number, sizeof(serial_number));
- if (serial_ret < LIBUSB_SUCCESS)
- {
- WARN_LOG_FMT(IOS_WIIMOTE,
- "Failed to get string for serial number descriptor {:02x} for device "
- "{:04x}:{:04x} (rev {:x}): {}",
- device_descriptor.iSerialNumber, device_descriptor.idVendor,
- device_descriptor.idProduct, device_descriptor.bcdDevice,
- LibusbUtils::ErrorWrap(serial_ret));
- serial_number[0] = '?';
- serial_number[1] = '\0';
- }
+ const auto manufacturer =
+ LibusbUtils::GetStringDescriptor(m_handle, device_descriptor.iManufacturer).value_or("?");
+ const auto product =
+ LibusbUtils::GetStringDescriptor(m_handle, device_descriptor.iProduct).value_or("?");
+ const auto serial_number =
+ LibusbUtils::GetStringDescriptor(m_handle, device_descriptor.iSerialNumber).value_or("?");
NOTICE_LOG_FMT(IOS_WIIMOTE, "Using device {:04x}:{:04x} (rev {:x}) for Bluetooth: {} {} {}",
device_descriptor.idVendor, device_descriptor.idProduct,
- device_descriptor.bcdDevice, reinterpret_cast<char*>(manufacturer),
- reinterpret_cast<char*>(product), reinterpret_cast<char*>(serial_number));
+ device_descriptor.bcdDevice, manufacturer, product, serial_number);
m_is_wii_bt_module =
device_descriptor.idVendor == 0x57e && device_descriptor.idProduct == 0x305;
return false;
diff --git a/Source/Core/Core/IOS/USB/Host.cpp b/Source/Core/Core/IOS/USB/Host.cpp
index 5182b1642c..d14a76b0cc 100644
--- a/Source/Core/Core/IOS/USB/Host.cpp
+++ b/Source/Core/Core/IOS/USB/Host.cpp
@@ -114,27 +114,23 @@ std::string USBHost::GetDeviceNameFromVIDPID(u16 vid, u16 pid)
return device_name;
context.GetDeviceList([&device_name, vid, pid](libusb_device* device) {
- libusb_device_descriptor desc;
-
+ libusb_device_descriptor desc{};
if (libusb_get_device_descriptor(device, &desc) != LIBUSB_SUCCESS)
return true;
- if (desc.idVendor == vid && desc.idProduct == pid)
- {
- libusb_device_handle* handle;
- if (libusb_open(device, &handle) == LIBUSB_SUCCESS)
- {
- unsigned char buffer[256];
- if (desc.iProduct &&
- libusb_get_string_descriptor_ascii(handle, desc.iProduct, buffer, sizeof(buffer)) > 0)
- {
- device_name = reinterpret_cast<char*>(buffer);
- }
- libusb_close(handle);
- }
+ if (desc.idVendor != vid || desc.idProduct != pid)
+ return true;
+
+ if (desc.iProduct == 0)
return false;
- }
- return true;
+
+ libusb_device_handle* handle{};
+ if (libusb_open(device, &handle) != LIBUSB_SUCCESS)
+ return false;
+
+ device_name = LibusbUtils::GetStringDescriptor(handle, desc.iProduct).value_or("");
+ libusb_close(handle);
+ return false;
});
if (!device_name.empty())
diff --git a/Source/Core/Core/LibusbUtils.cpp b/Source/Core/Core/LibusbUtils.cpp
index 1b1852dddd..ba3d0fd8e6 100644
--- a/Source/Core/Core/LibusbUtils.cpp
+++ b/Source/Core/Core/LibusbUtils.cpp
@@ -12,6 +12,7 @@
#include "Common/Assert.h"
#include "Common/Flag.h"
+#include "Common/StringUtil.h"
#include "Common/Thread.h"
namespace LibusbUtils
@@ -145,4 +146,54 @@ const char* ErrorWrap::GetStrError() const
return "__LIBUSB__ not defined";
#endif
}
+
+std::optional<std::string> GetStringDescriptor(libusb_device_handle* dev_handle, uint8_t desc_index)
+{
+#if defined(__LIBUSB__)
+ struct StringDescriptor
+ {
+ u8 length;
+ u8 descriptor_type;
+ char16_t data[127];
+ };
+
+ StringDescriptor buffer{};
+
+ // Reading lang ID 0 returns a list of lang IDs.
+ const auto lang_id_result = libusb_get_string_descriptor(
+ dev_handle, desc_index, 0, reinterpret_cast<unsigned char*>(&buffer), 4);
+
+ if (lang_id_result != 4 || buffer.length < 4 || buffer.descriptor_type != LIBUSB_DT_STRING)
+ {
+ ERROR_LOG_FMT(IOS_USB, "libusb_get_string_descriptor(desc_index={}, lang_id=0) result:{}",
+ int(desc_index), lang_id_result);
+ return std::nullopt;
+ }
+
+ const u16 lang_id = buffer.data[0];
+
+ const auto str_result = libusb_get_string_descriptor(
+ dev_handle, desc_index, lang_id, reinterpret_cast<unsigned char*>(&buffer), 255);
+
+ if (str_result < 2 || buffer.length > str_result || buffer.descriptor_type != LIBUSB_DT_STRING)
+ {
+ ERROR_LOG_FMT(IOS_USB, "libusb_get_string_descriptor(desc_index={}, lang_id={}) result:{}",
+ int(desc_index), lang_id, str_result);
+ return std::nullopt;
+ }
+
+ // The UTF-16 data size should be even and equal to the return value.
+ if ((buffer.length & 1u) != 0 || buffer.length != str_result)
+ {
+ WARN_LOG_FMT(IOS_USB, "GetStringDescriptor: buffer.length:{} result:{}", buffer.length,
+ str_result);
+ }
+
+ const std::size_t str_length = std::max(0, buffer.length - 2) / 2;
+ return UTF16ToUTF8(std::u16string_view{buffer.data, str_length});
+#else
+ return "__LIBUSB__ not defined";
+#endif
+}
+
} // namespace LibusbUtils
diff --git a/Source/Core/Core/LibusbUtils.h b/Source/Core/Core/LibusbUtils.h
index 89fba398dd..6b73070409 100644
--- a/Source/Core/Core/LibusbUtils.h
+++ b/Source/Core/Core/LibusbUtils.h
@@ -4,8 +4,10 @@
#pragma once
#include <fmt/format.h>
+
#include <functional>
#include <memory>
+#include <optional>
#include <utility>
#include "Common/CommonTypes.h"
@@ -13,6 +15,7 @@
struct libusb_config_descriptor;
struct libusb_context;
struct libusb_device;
+struct libusb_device_handle;
namespace LibusbUtils
{
@@ -53,6 +56,11 @@ struct ErrorWrap
const char* GetStrError() const;
const char* GetName() const;
};
+
+// Returns the UTF-16 descriptor converted to UTF-8 or returns nullopt on error.
+std::optional<std::string> GetStringDescriptor(libusb_device_handle* dev_handle,
+ uint8_t desc_index);
+
} // namespace LibusbUtils
template <>