Поделиться через


Приложение поддержки оборудования (HSA): шаги для разработчиков драйверов

Important

Метаданные устройства являются устаревшими и будут удалены в будущем выпуске Windows. Сведения о замене этой функции см. в разделе Метаданные контейнера пакетов драйверов.

Приложение поддержки оборудования (HSA) — это приложение для конкретного устройства, которое связано с определенной конечной точкой драйвера или RPC (удаленный вызов процедуры).

Чтобы связать приложение Store с драйвером, сначала зарезервировать специальное значение, называемое пользовательской возможностью. Затем разрешите доступ к приложениям, которые объявляют возможность и предоставляют возможности разработчику приложений. На этой странице описаны эти действия для разработчика драйвера.

Действия разработчика приложений описаны в разделе "Приложение поддержки оборудования" (HSA): шаги для разработчиков приложений.

HSA является одним из трех принципов проектирования DCH.

Резервирование пользовательской возможности

Сначала зарезервировать пользовательскую возможность:

  1. Электронная почта приложений службы поддержки оборудования Майкрософт ([email protected]) со следующими сведениями:

    • Contact information

    • Company name

    • Имя возможности (должно быть уникальным и ссылаться на владельца)

    • Какие ресурсы необходимы для доступа?

    • Любые проблемы безопасности или конфиденциальности

    • Какие события данных обрабатываются партнером?

      • Будут ли события включать личные идентификаторы, такие как точные расположения пользователей, пароли, IP-адрес, PUID, идентификатор устройства, CID, имя пользователя и контактные данные?

      • Остаются ли события данных на устройстве пользователя или отправляются партнеру?

    • К каким данным предоставляется доступ?

    • Что такое преимущество для конечного пользователя этой возможности?

    • Включите идентификатор издателя приложений Microsoft Store. Чтобы получить его, создайте запись скелетного приложения на странице Microsoft Store. Дополнительные сведения о резервирования PFN приложения см. в статье "Создание приложения" путем резервирования имени.

  2. If the request is approved, Microsoft emails back a unique custom capability string name in the format CompanyName.capabilityName_PublisherID.

Теперь можно использовать пользовательскую возможность, чтобы разрешить доступ к конечной точке RPC или драйверу.

Разрешение доступа к конечной точке RPC в приложение UWP с помощью пользовательской возможности

Чтобы разрешить доступ к конечной точке RPC к приложению UWP с пользовательскими возможностями, выполните следующие действия.

  1. Call DeriveCapabilitySidsFromName to convert the custom capability name to a security ID (SID).

  2. Добавьте идентификатор безопасности в доступ, разрешенный ACE, а также любые другие идентификаторы SID, необходимые для дескриптора безопасности конечной точки RPC.

  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 для предоставления интерфейса. Replace CompanyName with your company name, myCustomCapabilityName with a name that is unique within your company, and MyStorePubId with your publisher store 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.

Note

Приложение не должно быть подписано непосредственно с помощью сертификата, но указанный сертификат должен быть частью цепочки сертификатов, которая подписывает приложение.

После завершения SCCD владелец возможности отправляет его в корпорацию Майкрософт для подписания. Корпорация Майкрософт возвращает подписанный SCCD владельцу возможности.

Затем владелец возможности отправляет SCCD разработчику приложения. Разработчик приложения включает подписанный SCCD в манифест приложения. Сведения о том, что нужно сделать разработчику приложений, см. в разделе "Приложение поддержки оборудования" (HSA): действия для разработчиков приложений.

Ограничение области SCCD

В целях тестирования пользователь может ограничить установку приложения поддержки оборудования компьютерам в режиме разработчика.

To do so, before getting the SCCD signed by Microsoft, add 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>

The resulting signed SCCD works only on devices in Developer Mode.

Разрешение любому приложению использовать пользовательскую возможность

Рекомендуется указать авторизованные сущности (приложения), которые могут использовать пользовательскую возможность. Однако в некоторых случаях может потребоваться разрешить любому приложению включить SCCD. Starting in Windows 10 version 1809, you can do this by adding AllowAny to the AuthorizedEntities element. Because the best practice is to declare authorized entities in the SCCD file, please provide a justification for using AllowAny when submitting your SCCD to be signed by Microsoft.

<?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 проверяется в любом пакете приложения.

Multiple SCCDs

Начиная с Windows 10 версии 1803 приложения могут объявлять пользовательские возможности из одного или нескольких SCCD-файлов. Поместите файлы SCCD в корневой каталог пакета приложения.

Схема SCCD XML

Ниже приведена официальная схема XSD XML для SCCD-файла. Используйте эту схему для проверки SCCD перед отправкой ее для проверки. See Schema Cache and XML Document validation for info on importing a schema and validating with IntelliSense.

<?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>