DCH 準拠のドライバー パッケージの例

この記事では、 DCHU ドライバー サンプルDCH 設計原則を適用する方法について説明します。 これをモデルとして使用し、ご自分のドライバー パッケージに DCH 設計原則を適用できます。

サンプル リポジトリのローカル コピーが必要な場合は、Windows-driver-samples から複製できます。

このサンプルの一部では、特定のバージョンの Windows 10 以降でのみ使用できるディレクティブと API を使用する場合があります。 特定のディレクティブがサポートされている OS バージョンについては、「 デバイスとドライバーのインストール 」を参照してください。

前提条件

このセクションを読む前に、DCH 設計原則を理解しておく必要があります。

概要

サンプルで提供されているシナリオ例では、2 つのハードウェア パートナー Contoso (システム ビルダーまたは OEM) と Fabrikam (デバイスの製造元または IHV) が共同で、Contoso の次期システムのデバイス向け DCH 準拠ドライバーを作成しています。 対象のデバイスは OSR USB FX2 学習キットです。 これまで、Fabrikam は、特定の Contoso 製品ライン用にカスタマイズされたレガシ ドライバー パッケージを作成し、サービスを処理するために OEM に渡していました。 その結果、大きなメンテナンス オーバーヘッドが発生していたため、Fabrikam は、コードをリファクタリングして、代わりに DCH 準拠ドライバー パッケージを作成することを決定しました。

宣言型セクションおよびディレクティブを使用して INF を適切に分離する

最初に、Fabrikam は DCH 準拠ドライバー パッケージで無効な INF のセクションとディレクティブの一覧を確認します。 その間に、Fabrikam は無効なセクションとディレクティブの多くをドライバー パッケージで使っていることに気付きます。

Fabrikam のドライバーの INF は、プラットフォームに依存する設定とファイルを適用する共同インストーラーを登録します。 つまり、ドライバー パッケージは必要以上に大きく、バグがドライバーを出荷する OEM システムのサブセットにのみ影響を与えると、ドライバーのサービスを提供するのが困難になります。 また、OEM 固有の変更のほとんどはブランドに関連するため、OEM が追加されたり、軽微な問題が OEM システムのサブセットに影響を与えたりするたびに、Fabrikam はドライバー パッケージを更新する必要があります。

Fabrikam は、非宣言型セクションとディレクティブを削除し、InfVerif ツールを使って新しいドライバー パッケージの INF ファイルが宣言型 INF の要件に従っていることを確認します。

拡張 INF を使ってドライバー パッケージをコンポーネント化する

次に、Fabrikam は、OEM パートナー (Contoso など) に固有のカスタマイズを基本ドライバー パッケージから分離して、拡張 INF にまとめます。

[osrfx2_DCHU_extension.inx] から更新された次のスニペットは、 クラスを Extension 指定し、拡張機能ドライバー パッケージを所有するため、Contoso をプロバイダーとして識別します。

[Version]
...
Class       = Extension
ClassGuid   = {e2f84ce7-8efa-411c-aa69-97454ca4cb57}
Provider    = Contoso
ExtensionId = {zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz} ; replace with your own GUID
...

[osrfx2_DCHU_base.inx] では、Fabrikam によって次のエントリが指定されています。

[OsrFx2_AddReg]
HKR, OSR, "OperatingMode",, "Default" ; FLG_ADDREG_TYPE_SZ
HKR, OSR, "OperatingParams",, "None" ; FLG_ADDREG_TYPE_SZ

[osrfx2_DCHU_extension.inx] で、Contoso により基本パッケージで設定された OperatingParams レジストリ値がオーバーライドされ、OperatingExceptions が追加されます。

[OsrFx2Extension_AddReg]
HKR, OSR, "OperatingParams",, "-Extended"
HKR, OSR, "OperatingExceptions",, "x86"

拡張機能は常に基本 INF の後に処理されますが、明確な順序ではありません。 基本 INF が新しいバージョンに更新された場合、拡張 INF は新しい基本 INF がインストールされた後で再適用されます。

INF ファイルからサービスをインストールする

Fabrikam では、OSR ボード上の LED 制御に Win32 サービスを使用しています。 同社にとってこのコンポーネントはデバイスのコア機能の一部であるため、基本 INF ([osrfx2_DCHU_base.inx]) の一部として組み込みます。 このユーザーモード サービス (usersvc) は、INF ファイルに AddService ディレクティブを指定して宣言することで、追加および開始できます。

[OsrFx2_Install.NT]
CopyFiles = OsrFx2_CopyFiles

[OsrFx2_Install.NT.Services]
AddService = WUDFRd, 0x000001fa, WUDFRD_ServiceInstall    ; Flag 0x2 sets this as the service for the device
AddService = osrfx2_DCHU_usersvc,, UserSvc_ServiceInstall

[UserSvc_ServiceInstall]
DisplayName = %UserSvcDisplayName%
ServiceType = 0x10                                ; SERVICE_WIN32_OWN_PROCESS
StartType = 0x3                                   ; SERVICE_DEMAND_START
ErrorControl = 0x1                                ; SERVICE_ERROR_NORMAL
ServiceBinary = %13%\osrfx2_DCHU_usersvc.exe
AddTrigger = UserSvc_AddTrigger                   ; AddTrigger syntax is only available in Windows 10 Version 2004 and above

[UserSvc_AddTrigger]
TriggerType = 1                                   ; SERVICE_TRIGGER_TYPE_DEVICE_INTERFACE_ARRIVAL
Action = 1                                        ; SERVICE_TRIGGER_ACTION_SERVICE_START
SubType = %GUID_DEVINTERFACE_OSRFX2%              ; Interface GUID
DataItem = 2, "USB\VID_0547&PID_1002"             ; SERVICE_TRIGGER_DATA_TYPE_STRING

[OsrFx2_CopyFiles]
osrfx2_DCHU_base.dll
osrfx2_DCHU_filter.dll
osrfx2_DCHU_usersvc.exe

このようなサービスは、シナリオに応じて、コンポーネントまたは拡張機能 INF にインストールすることもできます。

コンポーネントを使ってドライバー パッケージからレガシ ソフトウェアをインストールする

Fabrikam は、これまで共同インストーラーを使ってインストールしていた実行可能ファイル osrfx2_DCHU_componentsoftware.exe を持っています。 このレガシ ソフトウェアはボードによって設定されるレジストリ キーを表示し、OEM が必要とします。 これは、デスクトップ エディションの Windows でのみ実行される GUI ベースの実行可能ファイルです。 これをインストールするため、Fabrikam は別のコンポーネント ドライバー パッケージを作成し、それを拡張 INF に追加します。

[osrfx2_DCHU_extension.inx] の次のスニペットは、AddComponent ディレクティブを使って仮想子デバイスを作成します。

[OsrFx2Extension_Install.NT.Components]
AddComponent = osrfx2_DCHU_component,,OsrFx2Extension_ComponentInstall


[OsrFx2Extension_ComponentInstall]
ComponentIds=VID_045e&PID_94ab

その後、コンポーネントの INF [osrfx2_DCHU_component.inx] で指定されている AddSoftware ディレクティブによって、オプションの実行可能ファイルがインストールされます。

[OsrFx2Component_Install.NT.Software]
AddSoftware = osrfx2_DCHU_componentsoftware,, OsrFx2Component_SoftwareInstall

[OsrFx2Component_SoftwareInstall]
SoftwareType = 1
SoftwareBinary = osrfx2_DCHU_componentsoftware.exe
SoftwareArguments = <<DeviceInstanceId>>
SoftwareVersion = 1.0.0.0

[OsrFx2Component_CopyFiles]
osrfx2_DCHU_componentsoftware.exe

Win32 アプリのソース コードは、サンプルに含まれます。

コンポーネント ドライバー パッケージは、Windows ハードウェア デベロッパー センター ダッシュボードで設定されたターゲット設定のため、デスクトップ SKU でのみ配布されます。 詳しくは、「Windows Update にドライバーを公開する」をご覧ください。

ハードウェア サポート アプリとの通信を許可する

Fabrikam は、Windows ドライバー パッケージの一部として GUI ベースのコンパニオン アプリを提供したいと考えています。 Win32 ベースのコンパニオン アプリケーションは Windows ドライバー パッケージの一部にできないため、Win32 アプリをユニバーサル Windows プラットフォーム (UWP) に移植し、アプリとデバイスをペアリングします

osrfx2_DCHU_base/device.c の次のスニペットでは、ベース ドライバー パッケージがデバイス インターフェイスのインスタンスにカスタム機能を追加する方法が示されています。

    WDF_DEVICE_INTERFACE_PROPERTY_DATA PropertyData = { 0 };
    static const wchar_t customCapabilities[] = L"CompanyName.yourCustomCapabilityName_YourStorePubId\0";

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

    Status = WdfDeviceAssignInterfaceProperty(Device,
                                              &PropertyData,
                                              DEVPROP_TYPE_STRING_LIST,
                                              sizeof(customCapabilities),
                                              (PVOID)customCapabilities);

(サンプルに含まれない) 新しいアプリは、セキュリティで保護され、Microsoft Store で簡単に更新することができます。 UWP アプリケーション対応になったことで、Contoso は DISM (展開イメージのサービスと管理) を使ってアプリケーションを Windows デスクトップ エディションのイメージに事前に読み込みます。

複数の INF ファイルを密結合する

基本パッケージ、拡張パッケージ、コンポーネント パッケージの間には、優れたバージョン管理コントラクトが存在するのが理想です。 これら 3 つのパッケージが個別にサービスを受けることには ("疎結合" のシナリオ) サービス上のメリットがありますが、シナリオによっては、バージョン管理コントラクトが不十分なために、単一のドライバー パッケージへのバンドル ("密結合") が必要な場合があります。 次のサンプルでは、両方のシナリオの例が示されています。

[OsrFx2Extension_Install.NT]
CopyInf=osrfx2_DCHU_component.inf

このディレクティブは、多機能デバイス内での INF ファイルのインストールを調整することもできます。 詳細については、「 INF ファイルのコピー」を参照してください。

注意

ベース ドライバーのペイロードに拡張機能を格納する (そして、配送先住所ラベルでベース ドライバーをターゲットにする) ことはできますが、別のドライバーとバンドルされている拡張機能を、拡張機能のハードウェア ID に公開することはできません。

ドライバー ストアから実行する

ドライバーを容易に更新できるように、Fabrikam は、可能であれば dirid 13 を使って、ドライバー ストアをドライバー ファイルのコピー先として指定します。 コピー先ディレクトリの値として 13 を使うと、ドライバー更新プロセスの間の安定性が向上します。 [osrfx2_DCHU_base.inx]: の例を次に示します。

[DestinationDirs]
OsrFx2_CopyFiles = 13 ; copy to Driver Store

ファイルを動的に見つけてドライバー ストアから読み込む方法の詳細については、「ドライバー ストアから実行する」ページを参照してください。

要約

次の図は、Fabrikam と Contoso が DCH 準拠ドライバー用に作成したドライバー パッケージを示したものです。 疎結合の例では、Windows ハードウェア デベロッパー センター ダッシュボードに対して 3 つの個別の送信を行います。1 つはベース用、もう 1 つは拡張機能用、もう 1 つはコンポーネント用です。 密結合された例では、base と extension/component の 2 つの送信を行います。

拡張、基本、コンポーネントの各ドライバー パッケージ。

コンポーネント INF はコンポーネントのハードウェア ID で一致しますが、ベースと拡張機能はボードのハードウェア ID で一致します。

関連項目

Windows ドライバーの概要

拡張 INF ファイルの使用

osrfx2_DCHU_base.inx

"疎結合" osrfx2_DCHU_component.inx

"疎結合" osrfx2_DCHU_extension.inx

"密結合" osrfx2_DCHU_component.inx

"密結合" osrfx2_DCHU_extension.inx