Перечисление USB-устройств

109
01 апреля 2022, 14:30

Понадобилось написать программу, выполняющую функцию подобно утилите Linux - lsusb. Вывод должен быть похож на:

Я решил использовать библиотеку libusb-1.0. У меня получился вот такой код:

#include <iostream>
#include <iomanip>
#include <cstring>
#include "libusb.h"
using namespace std;
void print_device(libusb_device *dev) {
  struct libusb_device_descriptor desc;
  libusb_device_handle *handle = NULL;
  unsigned char str[256] = {0};
  if (libusb_get_device_descriptor(dev, &desc) < 0) {
    cout << "failed to get device descriptor" << endl;
    return;
  }
  cout << "Bus " << std::setfill('0') << std::setw(3) << hex << +libusb_get_bus_number(dev) << " "
       << "Device " << std::setfill('0') << std::setw(3) << hex << +libusb_get_device_address(dev) << ": "
       << "ID " << std::setfill('0') << std::setw(4) << hex << desc.idVendor << ":"
       << std::setfill('0') << std::setw(4) << hex << desc.idProduct;
  if (libusb_open(dev, &handle) == LIBUSB_SUCCESS) {
    if (desc.iProduct) {
      if (libusb_get_string_descriptor_ascii(handle, desc.iProduct, str, sizeof(str)) > 0) {
        string s(reinterpret_cast<char*>(str));
        cout << " " << s.substr(s.find_first_not_of(" \t"));
      }
    }
  } else cout << " -";
  cout << endl;
  if (handle) libusb_close(handle);
}
int main() {
  libusb_device **devs;
  ssize_t cnt;
  if (libusb_init(NULL) < 0) return 1;
  cnt = libusb_get_device_list(NULL, &devs);
  if (cnt < 0) return 1;
  for (int i = 0; devs[i]; i++) print_device(devs[i]);
  libusb_free_device_list(devs, 1);
  libusb_exit(NULL);
  return 0;
}

Но сборка под Linux (Manjaro Linux) не выводит названия устройств. Получается просто вот так:

Если произвожу сборку под Windows x64, то названия выводятся частично:

Для уточнения, Linuх - под виртуальной машиной, Windows на реальной. Поэтому список устройств отличается.

Вопрос

Я не правильно использую библиотеку libusb для вывода названий USB-устройств? Если "да", то как правильно?

UPD

Запуск моей проги под Линуксом, но под рутом - несколько исправил положение:

Answer 1

Ошибка у вас вот тут:

if (libusb_get_string_descriptor_ascii(handle, desc.iProduct, str, sizeof(string)) > 0) {
        string s(reinterpret_cast<char*>(str));

sizeof(string) - это размер экземпляра класса string, ничего общего с размером буфера строки не имеет.

Как можно решить проблему (без костыля с буфером):

string str(2048); //сразу с хорошим запасом выделяем память
if(libusb_get_string_descriptor_ascii(handle, desc.iProduct, str.data(), str.size() > 0) 
{
    str.resize(strlen(str.c_str()); //обрезаем строку по '\0'
    str=str.substr(str.find_first_not_of(" \t")); 
}
READ ALSO
Выравнивание структуры

Выравнивание структуры

Есть структура _dem_ram_data_Она должна занимать в памяти 16 байт, но я получаю 21 байт

97
QML не реагирует на изменения члена-класса C++

QML не реагирует на изменения члена-класса C++

Есть приложение с областью, которая реагирует на клик мышки:

105
Почему ошибка index out of range?

Почему ошибка index out of range?

Числовая последовательность называется пилообразной если каждый ее член (кроме первого и последнего) либо больше обоих своих соседей, либо...

96