microsoft / WindowsAppSDK

The Windows App SDK empowers all Windows desktop apps with modern Windows UI, APIs, and platform features, including back-compat support, shipped via NuGet.
https://docs.microsoft.com/windows/apps/windows-app-sdk/
MIT License
3.8k stars 320 forks source link

DeviceInformation::FindAddAsync returns empty collection when specifying a usb device. #4457

Closed Tunghohin closed 4 months ago

Tunghohin commented 4 months ago

Describe the bug

DeviceInformation::FindAddAsync returns empty collection when specifying a usb device.

https://github.com/microsoft/cppwinrt/issues/1420

Steps to reproduce the bug

auto devices = DeviceInformation::FindAllAsync(
    DeviceClass::VideoCapture
).get();
for (auto&& dev : devices) {
    fmt::println(stderr, L"{}", dev.Properties()
                                          .TryLookup(L"System.Devices.DeviceInstanceId")
                                          .try_as<winrt::hstring>()
                                          .value_or(L"None")
                                          .c_str());
}
fmt::println(stderr, "{}", devices.Size());

output: e094238f350befad2228bb14d8975ed

auto devices = DeviceInformation::FindAllAsync(
    UsbDevice::GetDeviceSelector(0x0603, 0x8612)
).get();
for (auto&& dev : devices) {
    fmt::println(stderr, L"{}", dev.Properties()
                                          .TryLookup(L"System.Devices.DeviceInstanceId")
                                          .try_as<winrt::hstring>()
                                          .value_or(L"None")
                                          .c_str());
}
fmt::println(stderr, "{}", devices.Size());

gets a empty collection

DarranRowe commented 4 months ago

The problem here is that the Windows.Devices.Usb documentation states that it doesn't provide access to some USB devices. In particular, it states that this namespace is for WinUSB devices only. Have you verified that the device you are trying to access is WinUSB compatible?

To give an example, my system does have a WinUSB compatible device.

Screenshot 2024-05-30 213845

Screenshot 2024-05-30 213851

#include <Windows.h>

#include <string>
#include <format>

#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Devices.h>
#include <winrt/Windows.Devices.Enumeration.h>
#include <winrt/Windows.Devices.Usb.h>

int wmain()
{
    auto devices = winrt::Windows::Devices::Enumeration::DeviceInformation::FindAllAsync(
        winrt::Windows::Devices::Usb::UsbDevice::GetDeviceSelector(0x1e71, 0x300c)
    ).get();

    for (auto device : devices)
    {
        auto fmt_string = std::format(L"{}", std::wstring_view(device.Id()));
        _putws(fmt_string.c_str());
    }

    return 0;
}

This gave me the following output: \\?\USB#VID_1E71&PID_300C&MI_00#9&fbe3bfd&0&0000#{dee824ef-729b-4a0e-9c14-b7117d33a817}

So it works fine for me on my system when the device is properly declared as a WinUSB device.

DarranRowe commented 4 months ago

As a follow up to this, I did get an opportunity to try this out with a video capture USB device.

Screenshot 2024-06-01 151321

Screenshot 2024-06-01 151329

Screenshot 2024-06-01 151346

The code used was the same as above, except it had the VID changed to 0x07ca and PID changed to 0xd553 to reflect the device. As you can see, it successfully obtained an instance of the DeviceInformation. So again, can you confirm that the device is a WinUSB device?

Tunghohin commented 4 months ago

As a follow up to this, I did get an opportunity to try this out with a video capture USB device.

Screenshot 2024-06-01 151321

Screenshot 2024-06-01 151329

Screenshot 2024-06-01 151346

The code used was the same as above, except it had the VID changed to 0x07ca and PID changed to 0xd553 to reflect the device. As you can see, it successfully obtained an instance of the DeviceInformation. So again, can you confirm that the device is a WinUSB device?

I observed that my usb capture uses the usbccgp.sys driver instead of the winusb.sys driver, is this technically considered a winusb device? Very much appreciate it if you could provide me with more relevant information.

DarranRowe commented 4 months ago

I observed that my usb capture uses the usbccgp.sys driver instead of the winusb.sys driver, is this technically considered a winusb device?

No.

Screenshot 2024-06-01 165818

While usbccgp is in the driver stack for a WinUSB device, as clearly documented by the Windows.Devices.Usb Namespace documentation, a WinUSB device will have a very specific compatible ID. If the device does not have the USB\MS_COMP_WINUSB compatible ID then it is not a valid WinUSB device.

This information can be easily obtained from device manager.