硬件支持应用 (HSA):适用于驱动程序开发人员的步骤

硬件支持应用 (HSA) 是特定于设备的应用,与特定驱动程序或 RPC (远程过程调用) 终结点配对。

若要将应用商店应用与驱动程序关联,请首先保留一个名为自定义功能的特殊值。 然后,允许访问播发该功能的应用,并为应用开发人员提供该功能。 本页介绍驱动程序开发人员的这些步骤。

硬件支持应用 (HSA) :面向应用开发人员的步骤中介绍了应用开发人员的步骤

HSA 是 Windows 驱动程序的三 (“DCH”) 设计原则之一。

保留自定义功能

首先,保留自定义功能:

  1. Email Microsoft 硬件支持应用查看 (HSAReview@microsoft.com) ,其中包含以下信息:

    • 联系信息

    • 公司名称

    • 功能 (的名称必须是唯一的,并引用所有者)

    • 功能需要访问哪些资源?

    • 任何安全或隐私问题

    • 将向合作伙伴处理哪些数据事件?

      • 事件是否包括个人标识符,例如精确用户位置、密码、IP 地址、PUID、设备 ID、CID、用户名和联系人数据) ?

      • 数据事件是保留在用户设备上,还是发送给合作伙伴?

    • 你的功能提供对哪些数据的访问权限?

    • 此功能对最终用户有什么好处?

    • 包括 Microsoft Store 应用发布者 ID。 若要获取一个,请在 Microsoft Store 页面上创建主干应用条目。 有关预留应用 PFN 的详细信息,请参阅 通过保留名称创建应用

  2. 如果请求获得批准,Microsoft 通过电子邮件以 CompanyName.capabilityName_PublisherID格式回复唯一的自定义功能字符串名称。

现在可以使用自定义功能来允许访问 RPC 终结点或驱动程序。

允许使用自定义功能访问 UWP 应用的 RPC 终结点

若要允许访问具有自定义功能的 UWP 应用的 RPC 终结点,请执行以下步骤:

  1. 调用 DeriveCapabilitySidsFromName 将自定义功能名称转换为 SID) (安全 ID。

  2. 将 SID 以及 RPC 终结点的安全描述符所需的任何其他 SID 添加到允许的访问 ACE。

  3. 使用安全描述符中的信息创建 RPC 终结点。

可以在自定义功能示例中RPC 服务器代码中看到上述 的实现。

允许使用自定义功能访问 UWP 应用的驱动程序

若要允许使用自定义功能的 UWP 应用访问驱动程序,请向 INF 文件或驱动程序源添加几行。

在 INF 文件中,按如下所示指定自定义功能:

[WDMPNPB003_Device.NT.Interfaces]
AddInterface= {zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz},,AddInterfaceSection

[AddInterfaceSection]
AddProperty= AddInterfaceSection.AddProps

[AddInterfaceSection.AddProps]
; DEVPKEY_DeviceInterface_UnrestrictedAppCapabilities
{026e516e-b814-414b-83cd-856d6fef4822}, 8, 0x2012,, "CompanyName.myCustomCapabilityName_MyStorePubId"

或者,在驱动程序中执行以下操作:

WDF_DEVICE_INTERFACE_PROPERTY_DATA PropertyData = {};
WCHAR customCapabilities[] = L"CompanyName.myCustomCapabilityName_MyStorePubId\0";

WDF_DEVICE_INTERFACE_PROPERTY_DATA_INIT(
   &PropertyData,
   &m_VendorDefinedSubType,
   &DEVPKEY_DeviceInterface_UnrestrictedAppCapabilities);

Status = WdfDeviceAssignInterfaceProperty(
    m_FxDevice,
    &PropertyData,
    DEVPROP_TYPE_STRING_LIST,
    ARRAYSIZE(customCapabilities),
    reinterpret_cast<PVOID>(customCapabilities));

将 替换为 zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz 要公开的接口的 GUID。 将 CompanyName 替换为公司名称,将 myCustomCapabilityName 替换为公司中唯一的名称,将 MyStorePubId 替换为发布者应用商店 ID。

有关上面所示的驱动程序代码示例,请参阅 通用驱动程序的驱动程序包安装工具包

若要在内核模式下设置 属性,请使用如下所示的代码:

#if defined(NTDDI_WIN10_RS2) && (NTDDI_VERSION >= NTDDI_WIN10_RS2)

//
// Adding Custom Capability:
//
// Adds a custom capability to device interface instance that allows a Windows
// Store device app to access this interface using Windows.Devices.Custom namespace.
// This capability can be defined either in INF or here as shown below. In order
// to define it from the INF, uncomment the section "OsrUsb Interface installation"
// from the INF and remove the block of code below.
//

static const wchar_t customCapabilities[] = L"microsoft.hsaTestCustomCapability_q536wpkpf5cy2\0";

status = g_pIoSetDeviceInterfacePropertyData(&symbolicLinkName,
                                              &DEVPKEY_DeviceInterface_UnrestrictedAppCapabilities,
                                              0,
                                              0,
                                              DEVPROP_TYPE_STRING_LIST,
                                              sizeof(customCapabilities),
                                              (PVOID)&customCapabilities);

if (!NT_SUCCESS(status)) {
    TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                "IoSetDeviceInterfacePropertyData failed to set custom capability property  %!STATUS!\n", status);
    goto Error;
}

#endif

准备签名的自定义功能描述符 (SCCD) 文件

签名的自定义功能描述符 (SCCD) 文件是授权使用一个或多个自定义功能的签名 XML 文件。 驱动程序或 RPC 终结点的所有者通过提供此文件向应用开发人员授予自定义功能。

若要准备 SCCD 文件,请先更新自定义功能字符串。 使用以下示例作为起点:

<?xml version="1.0" encoding="utf-8"?>
<CustomCapabilityDescriptor xmlns="http://schemas.microsoft.com/appx/2016/sccd" xmlns:s="http://schemas.microsoft.com/appx/2016/sccd">
<CustomCapabilities>
    <CustomCapability Name="microsoft.hsaTestCustomCapability_q536wpkpf5cy2"></CustomCapability>
</CustomCapabilities>
<AuthorizedEntities>
    <AuthorizedEntity AppPackageFamilyName="MicrosoftHSATest.Microsoft.SDKSamples.Hsa.CPP_q536wpkpf5cy2" CertificateSignatureHash="ca9fc964db7e0c2938778f4559946833e7a8cfde0f3eaa07650766d4764e86c4"></AuthorizedEntity>
</AuthorizedEntities>
<Catalog>0000</Catalog>
</CustomCapabilityDescriptor>

接下来,自定义功能所有者从应用开发人员获取包系列名称 (PFN) 和签名哈希,并在 SCCD 文件中更新这些字符串。

注意

应用不必直接使用证书进行签名,但指定的证书必须是对应用进行签名的证书链的一部分。

完成 SCCD 后,功能所有者会通过电子邮件将其发送到 Microsoft 进行签名。 Microsoft 将签名的 SCCD 返回到功能所有者。

然后,功能所有者将 SCCD 发送给应用开发人员。 应用开发人员在应用清单中包含签名的 SCCD。 若要了解应用开发人员需要执行的操作,请参阅 硬件支持应用 (HSA) :面向应用开发人员的步骤

限制 SCCD 的范围

出于测试目的,自定义功能所有者可以将硬件支持应用的安装限制为开发人员模式下的计算机。

为此,在获取 Microsoft 签名的 SCCD 之前,请添加 DeveloperModeOnly

<?xml version="1.0" encoding="utf-8"?>
<CustomCapabilityDescriptor xmlns="http://schemas.microsoft.com/appx/2016/sccd" xmlns:s="http://schemas.microsoft.com/appx/2016/sccd">
<CustomCapabilities>
    <CustomCapability Name="microsoft.hsaTestCustomCapability_q536wpkpf5cy2"></CustomCapability>
</CustomCapabilities>
<AuthorizedEntities>
    <AuthorizedEntity AppPackageFamilyName="MicrosoftHSATest.Microsoft.SDKSamples.Hsa.CPP_q536wpkpf5cy2" CertificateSignatureHash="ca9fc964db7e0c2938778f4559946833e7a8cfde0f3eaa07650766d4764e86c4"></AuthorizedEntity>
</AuthorizedEntities>
<Catalog>0000</Catalog>
<DeveloperModeOnly Value="true" />
</CustomCapabilityDescriptor>

生成的签名 SCCD 仅适用于 开发人员模式下的设备。

允许任何应用使用自定义功能

建议指定可以使用自定义功能的应用 (授权实体) 。 但在某些情况下,你可能希望允许任何应用包含 SCCD。 从 Windows 10 版本 1809 开始,可以通过将 AllowAny 添加到 AuthorizedEntities 元素来执行此操作。 由于最佳做法是在 SCCD 文件中声明授权的实体,因此请在提交要由 Microsoft 签名的 SCCD 时提供使用 AllowAny 的理由。

<?xml version="1.0" encoding="utf-8"?>
<CustomCapabilityDescriptor xmlns="http://schemas.microsoft.com/appx/2018/sccd" xmlns:s="http://schemas.microsoft.com/appx/2018/sccd">
<CustomCapabilities>
    <CustomCapability Name="microsoft.hsaTestCustomCapability_q536wpkpf5cy2"></CustomCapability>
</CustomCapabilities>
<AuthorizedEntities AllowAny="true"/>
<Catalog>0000</Catalog>
</CustomCapabilityDescriptor>

生成的签名 SCCD 将在任何应用包中验证。

多个 SCCD

从 Windows 10 版本 1803 开始,应用可以从一个或多个 SCCD 文件声明自定义功能。 将 SCCD 文件放在应用包的根目录中。

SCCD 签名序列摘要

下图总结了上述顺序:

获取 SCCD 签名。

SCCD XML 架构

下面是 SCCD 文件的正式 XML XSD 架构。 在提交 SCCD 以供审阅之前,使用此架构来验证 SCCD。 有关使用 IntelliSense 导入架构和验证的信息,请参阅架构 缓存XML 文档验证

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
  xmlns:xs="https://www.w3.org/2001/XMLSchema"
  targetNamespace="http://schemas.microsoft.com/appx/2016/sccd"
  xmlns:s="http://schemas.microsoft.com/appx/2016/sccd"
  xmlns="http://schemas.microsoft.com/appx/2016/sccd">

  <xs:element name="CustomCapabilityDescriptor" type="CT_CustomCapabilityDescriptor">
    <xs:unique name="Unique_CustomCapability_Name">
      <xs:selector xpath="s:CustomCapabilities/s:CustomCapability"/>
      <xs:field xpath="@Name"/>
    </xs:unique>
  </xs:element>

  <xs:complexType name="CT_CustomCapabilityDescriptor">
    <xs:sequence>
      <xs:element ref="CustomCapabilities" minOccurs="1" maxOccurs="1"/>
      <xs:element ref="AuthorizedEntities" minOccurs="1" maxOccurs="1"/>
      <xs:element ref="DeveloperModeOnly" minOccurs="0" maxOccurs="1"/>
      <xs:element ref="Catalog" minOccurs="1" maxOccurs="1"/>
      <xs:any minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="CustomCapabilities" type="CT_CustomCapabilities" />

  <xs:complexType name="CT_CustomCapabilities">
    <xs:sequence>
      <xs:element ref="CustomCapability" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="CustomCapability">
    <xs:complexType>
      <xs:attribute name="Name" type="ST_CustomCapability" use="required"/>
    </xs:complexType>
  </xs:element>

  <xs:simpleType name="ST_NonEmptyString">
    <xs:restriction base="xs:string">
      <xs:minLength value="1"/>
      <xs:maxLength value="32767"/>
      <xs:pattern value="[^\s]|([^\s].*[^\s])"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="ST_CustomCapability">
    <xs:annotation>
      <xs:documentation>Custom capabilities should be a string in the form of Company.capabilityName_PublisherId</xs:documentation>
    </xs:annotation>
    <xs:restriction base="ST_NonEmptyString">
      <xs:pattern value="[A-Za-z0-9][-_.A-Za-z0-9]*_[a-hjkmnp-z0-9]{13}"/>
      <xs:minLength value="15"/>
      <xs:maxLength value="255"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:element name="AuthorizedEntities" type="CT_AuthorizedEntities" />

  <xs:complexType name="CT_AuthorizedEntities">
    <xs:sequence>
      <xs:element ref="AuthorizedEntity" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="AuthorizedEntity" type="CT_AuthorizedEntity" />

  <xs:complexType name="CT_AuthorizedEntity">
    <xs:attribute name="CertificateSignatureHash" type="ST_CertificateSignatureHash" use="required"/>
    <xs:attribute name="AppPackageFamilyName" type="ST_NonEmptyString" use="required"/>
  </xs:complexType>

  <xs:simpleType name="ST_CertificateSignatureHash">
    <xs:restriction base="ST_NonEmptyString">
      <xs:pattern value="[A-Fa-f0-9]+"/>
      <xs:minLength value="64"/>
      <xs:maxLength value="64"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:element name="DeveloperModeOnly">
    <xs:complexType>
      <xs:attribute name="Value" type="xs:boolean" use="required"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="Catalog" type="ST_Catalog" />

  <xs:simpleType name="ST_Catalog">
    <xs:restriction base="xs:string">
      <xs:pattern value="[A-Za-z0-9\+\/\=]+"/>
      <xs:minLength value="4"/>
    </xs:restriction>
  </xs:simpleType>

</xs:schema>

以下架构自 Windows 10 版本 1809 起也有效。 它使 SCCD 能够将任何应用包声明为授权实体。

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
  xmlns:xs="https://www.w3.org/2001/XMLSchema"
  targetNamespace="http://schemas.microsoft.com/appx/2018/sccd"
  xmlns:s="http://schemas.microsoft.com/appx/2018/sccd"
  xmlns="http://schemas.microsoft.com/appx/2018/sccd">

  <xs:element name="CustomCapabilityDescriptor" type="CT_CustomCapabilityDescriptor">
    <xs:unique name="Unique_CustomCapability_Name">
      <xs:selector xpath="s:CustomCapabilities/s:CustomCapability"/>
      <xs:field xpath="@Name"/>
    </xs:unique>
  </xs:element>

  <xs:complexType name="CT_CustomCapabilityDescriptor">
    <xs:sequence>
      <xs:element ref="CustomCapabilities" minOccurs="1" maxOccurs="1"/>
      <xs:element ref="AuthorizedEntities" minOccurs="1" maxOccurs="1"/>
      <xs:element ref="DeveloperModeOnly" minOccurs="0" maxOccurs="1"/>
      <xs:element ref="Catalog" minOccurs="1" maxOccurs="1"/>
      <xs:any minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  
  <xs:element name="CustomCapabilities" type="CT_CustomCapabilities" />

  <xs:complexType name="CT_CustomCapabilities">
    <xs:sequence>
      <xs:element ref="CustomCapability" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="CustomCapability">
    <xs:complexType>
      <xs:attribute name="Name" type="ST_CustomCapability" use="required"/>
    </xs:complexType>
  </xs:element>

  <xs:simpleType name="ST_NonEmptyString">
    <xs:restriction base="xs:string">
      <xs:minLength value="1"/>
      <xs:maxLength value="32767"/>
      <xs:pattern value="[^\s]|([^\s].*[^\s])"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="ST_CustomCapability">
    <xs:annotation>
      <xs:documentation>Custom capabilities should be a string in the form of Company.capabilityName_PublisherId</xs:documentation>
    </xs:annotation>
    <xs:restriction base="ST_NonEmptyString">
      <xs:pattern value="[A-Za-z0-9][-_.A-Za-z0-9]*_[a-hjkmnp-z0-9]{13}"/>
      <xs:minLength value="15"/>
      <xs:maxLength value="255"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:element name="AuthorizedEntities" type="CT_AuthorizedEntities" />

  <xs:complexType name="CT_AuthorizedEntities">
    <xs:sequence>
      <xs:element ref="AuthorizedEntity" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="AllowAny" type="xs:boolean" use="optional"/>
  </xs:complexType>
  
  <xs:element name="AuthorizedEntity" type="CT_AuthorizedEntity" />
  
  <xs:complexType name="CT_AuthorizedEntity">
    <xs:attribute name="CertificateSignatureHash" type="ST_CertificateSignatureHash" use="required"/>
    <xs:attribute name="AppPackageFamilyName" type="ST_NonEmptyString" use="required"/>
  </xs:complexType>

  <xs:simpleType name="ST_CertificateSignatureHash">
    <xs:restriction base="ST_NonEmptyString">
      <xs:pattern value="[A-Fa-f0-9]+"/>
      <xs:minLength value="64"/>
      <xs:maxLength value="64"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:element name="DeveloperModeOnly">
    <xs:complexType>
      <xs:attribute name="Value" type="xs:boolean" use="required"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="Catalog" type="ST_Catalog" />

  <xs:simpleType name="ST_Catalog">
    <xs:restriction base="xs:string">
      <xs:pattern value="[A-Za-z0-9\+\/\=]+"/>
      <xs:minLength value="4"/>
    </xs:restriction>
  </xs:simpleType>
  
</xs:schema>

另请参阅

Windows 驱动程序入门

通用 Windows 平台简介

通用 Windows 平台 (UWP)

应用功能

使用 Visual Studio 开发 UWP 应用

将驱动程序与通用 Windows 平台 (UWP) 应用配对

开发 UWP 应用

使用 Desktop App Converter 将应用打包(桌面桥)

自定义功能示例应用

自定义功能驱动程序示例

Windows 10 中的旁加载应用

有关自定义功能的常见问题解答