-->

UWP USB (Hid) Device Won't Connect

2019-06-07 20:43发布

问题:

This is my Hid library. It supports UWP, and Android. https://bitbucket.org/MelbourneDeveloper/hid.net/src/master/

This is an example of the library being used with the Trezor hardware wallet: https://github.com/MelbourneDeveloper/Trezor.Net

I can connect to the Trezor with no problem on UWP, but I cannot connect to the KeepKey or Ledger which are other hardware wallets. This is the code I use to connect to both devices in my library. It looks through a list of devices, tries to connect and returns the first one that connects OK:

public async Task InitializeAsync()
{
    Logger.Log("Initializing Hid device", null, nameof(UWPHidDevice));

    foreach (var deviceInformation in _WindowsDeviceInformationList)
    {
        var hidDeviceOperation = HidDevice.FromIdAsync(deviceInformation.Id, Windows.Storage.FileAccessMode.ReadWrite);
        var task = hidDeviceOperation.AsTask();
        _HidDevice = await task;
        if (_HidDevice != null)
        {
            break;
        }
    }

    if (_HidDevice == null)
    {
        throw new Exception($"Could not obtain a connection to the device.");
    }

    _HidDevice.InputReportReceived += _HidDevice_InputReportReceived;

    if (_HidDevice == null)
    {
        throw new Exception("Could not connect to the device");
    }

    Connected?.Invoke(this, new EventArgs());
}

The Trezor connection returns fine, but the Ledger just loops through the existing drivers which are valid without returning anything. I strongly suspect that it is a permissions problem. In order to connect to a USB device in UWP, I can need to specify a device capability:

This is the section for Trezor:

  <Capabilities>
    <Capability Name="internetClient" />
    <uap:Capability Name="removableStorage" />
    <DeviceCapability Name="humaninterfacedevice">
      <Device Id="vidpid:534C 0001">
        <Function Type="usage:0005 *" />
        <Function Type="usage:FF00 0001" />
        <Function Type="usage:ff00 *" />
      </Device>
    </DeviceCapability>
  </Capabilities>

I have exactly the same thing for KeepKey except for the vendor:

<DeviceCapability Name="humaninterfacedevice">
  <Device Id="vidpid:‭‭2B24‬‬ 0001">
    <Function Type="usage:0005 *" />
    <Function Type="usage:FF00 0001" />
    <Function Type="usage:ff00 *" />
  </Device>
</DeviceCapability>

and Ledger:

  <Capabilities>
    <Capability Name="internetClient" />
    <uap:Capability Name="removableStorage" />   
    <DeviceCapability Name="humaninterfacedevice">
      <Device Id="vidpid:‭2C97‬ 0001">
        <Function Type="usage:0005 *" />
        <Function Type="usage:FF00 0001" />
        <Function Type="usage:ff00 *" />
      </Device>
    </DeviceCapability>
  </Capabilities>

But, Visual Studio complains about this with this error:

The ID attribute is invalid - the value 'vidpid:‭2B24 0001' is invalid according to its data type http://schemas.microsoft.com/appx/manifest/types:ST_DeviceId

But, that is the hex value of the Vendor ID. I can't change that because it needs to match the vendor IDs which are 2B24 and ‭2C97‬ or 11044 and 11415 as integers.

I tracked down this schema to here: https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/winrt/AppxManifestTypes.xsd

This seems to be the rules:

 <xs:simpleType name="ST_DeviceId">
    <xs:restriction base="ST_NonEmptyString">
      <xs:pattern value="any"/>
      <xs:pattern value="vidpid:[0-9a-fA-F]{4} [0-9a-fA-F]{4}( (usb|bluetooth))?"/>
      <xs:pattern value="model:[^;]{1,512};.{1,512}"/>
    </xs:restriction>
</xs:simpleType>

I'm actually now getting this useful error:

Severity Code Description Project File Line Suppression State Error Validation error. error C00CE169: App manifest validation error: The app manifest must be valid as per schema: Line 36, Column 15, Reason: 'vidpid:‭2C97‬ 0001' violates pattern constraint of 'any|vidpid:[0-9a-fA-F]{4} [0-9a-fA-F]{4}( (usb|bluetooth))?|model:[^;]{1,512};.{1,512}'. The attribute 'Id' with value 'vidpid:‭2C97‬ 0001' failed to parse. LedgerWalletUWPSample C:\GitRepos\ledger-dotnet-api\LedgerWalletUWPSample\bin\x86\Debug\AppxManifest.xml