다음을 통해 공유


HSA(하드웨어 지원 앱): 드라이버 개발자를 위한 단계

HSA(하드웨어 지원 앱)는 특정 드라이버 또는 RPC(원격 프로시저 호출) 엔드포인트와 쌍을 이루는 디바이스별 앱입니다.

스토어 앱을 드라이버와 연결하려면 먼저 사용자 지정 기능이라는 특수 값을 예약합니다. 그런 다음, 기능을 보급하고 앱 개발자에게 기능을 제공하는 앱에 대한 액세스를 허용합니다. 이 페이지에서는 드라이버 개발자를 위한 이러한 단계를 설명합니다.

앱 개발자를 위한 단계는 HSA(하드웨어 지원 앱): 앱 개발자를 위한 단계에 설명되어 있습니다.

HSA는 Windows 드라이버의 세 가지("DCH") 디자인 원칙 중 하나입니다.

사용자 지정 기능 예약

먼저 사용자 지정 기능을 예약합니다.

  1. 다음 정보를 사용하여 Microsoft 하드웨어 지원 앱 검토()를HSAReview@microsoft.com Email.

    • 연락처 정보

    • 회사 이름

    • 기능의 이름(고유해야 하며 소유자를 참조해야 함)

    • 접근 권한 값에 액세스하는 데 필요한 리소스는 무엇인가요?

    • 모든 보안 또는 개인 정보 보호 문제

    • 파트너에게 처리할 데이터 이벤트는 무엇인가요?

      • 이벤트에는 정확한 사용자 위치, 암호, 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. 액세스 허용 ACE에 SID를 RPC 엔드포인트의 보안 설명자에 필요한 다른 SID와 함께 추가합니다.

  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));

을 노출할 인터페이스의 GUID로 바꿉 zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz 다. 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의 scope 제한

테스트 목적으로 사용자 지정 기능 소유자는 하드웨어 지원 앱의 설치를 개발자 모드의 컴퓨터로 제한할 수 있습니다.

이렇게 하려면 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의 유효성을 검사합니다. 스키마 가져오기 및 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 플랫폼 소개

UWP(유니버설 Windows 플랫폼)

앱 기능

Visual Studio를 사용하여 UWP 앱 개발

UWP(유니버설 Windows 플랫폼) 앱과 드라이버 페어링

UWP 앱 개발

Desktop App Converter를 사용하여 앱 패키징(데스크톱 브리지)

사용자 지정 기능 샘플 앱

사용자 지정 기능 드라이버 샘플

Windows 10 앱 테스트용 로드

사용자 지정 기능에 대한 FAQ