Получить серийный номер USB аудиоустройства - PullRequest
0 голосов
/ 02 марта 2020

Мне нужно получить серийный номер, содержащийся в дескрипторе устройства микрофона USB на Windows (бонусный балл, если решение кроссплатформенное)

У меня есть кое-что, что почти работает с libusb (код ниже, без обработки ошибок), но так как мое устройство - mi c, оно управляется usbaudio2.sys, и я не могу прочитать дескриптор устройства. Может быть, libusb_detach_kernel_driver мог бы помочь мне, но он не поддерживается на Windows.

Итак, возможно ли получить серийный номер аудиоустройства USB на windows?

static int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{
    static libusb_device_handle *dev_handle{ nullptr };
    static libusb_device_descriptor desc;
    int rc;
    unsigned char string[256];

    libusb_get_device_descriptor(dev, &desc);

    switch(event){
    case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED:
        rc = libusb_open(dev, &dev_handle);

        if (desc.iSerialNumber) {
            // this call returns a LIBUSB_ERROR_BUSY (-6)
            // because (I think) it's a USB audio device and another driver
            // is handling the device
            rc = libusb_get_string_descriptor_ascii(dev_handle, desc.iSerialNumber, string, sizeof(string));
        }

        // omitting the other cases
    }
    return 0;
}

void DeviceWatcher::start()
{
    libusb_hotplug_callback_handle callback_handle;
    int rc = libusb_hotplug_register_callback(
                nullptr, static_cast<libusb_hotplug_event>(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
                LIBUSB_HOTPLUG_NO_FLAGS, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, (libusb_hotplug_callback_fn)&hotplug_callback, this, &callback_handle);

    if(rc != LIBUSB_SUCCESS) {
        libusb_exit(nullptr);
        throw "Cannot start libusb";
    }

    while(true) {
        libusb_handle_events_completed(nullptr, nullptr);
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}

...