UMDF ドライバーでのデバイス インターフェイスの使用

警告

UMDF 2 は UMDF の最新バージョンであり、UMDF 1 よりも優先されます。 すべての新しい UMDF ドライバーは、UMDF 2 を使用して記述する必要があります。 UMDF 1 には新機能が追加されておらず、新しいバージョンのWindows 10では UMDF 1 のサポートが制限されています。 ユニバーサル Windows ドライバーでは、UMDF 2 を使用する必要があります。

アーカイブされた UMDF 1 サンプルは、Windows 11 バージョン 22H2 - 2022 年 5 月のドライバー サンプル更新プログラムで確認できます。

詳細については、「UMDF を使用したはじめに」を参照してください。

デバイス インターフェイスは、アプリケーションがデバイスへのアクセスに使用できるプラグ アンド プレイ (PnP) デバイスへのシンボリック リンクです。 ユーザー モード アプリケーションは、インターフェイスのシンボリック リンク名を、Microsoft Win32 CreateFile 関数などの API 要素に渡すことができます。 デバイス インターフェイスのシンボリック リンク名を取得するために、ユーザー モード アプリケーションは SetupDi 関数を 呼び出すことができます。 SetupDi 関数の詳細については、「SetupDi Device Interface Functions」を参照してください。

各デバイス インターフェイスは、 デバイス インターフェイス クラスに属します。 たとえば、CD-ROM デバイスのドライバー スタックには、GUID_DEVINTERFACE_CDROM クラスに属するインターフェイスが用意されている場合があります。 CD-ROM デバイスのドライバーの 1 つは、CD-ROM デバイスが使用可能であることをシステムとアプリケーションに通知するために、GUID_DEVINTERFACE_CDROM クラスのインスタンスを登録します。 デバイス インターフェイス クラスの詳細については、「デバイス インターフェイス の概要」を参照してください。

デバイス インターフェイスの登録

デバイス インターフェイス クラスのインスタンスを登録するために、UMDF ベースのドライバーは、IDriverEntry::OnDeviceAdd コールバック関数内から IWDFDevice::CreateDeviceInterface を呼び出すことができます。 ドライバーがインターフェイスの複数のインスタンスをサポートしている場合は、各インスタンスに一意の参照文字列を割り当てることができます。

デバイス インターフェイスの有効化と無効化

作成が成功した場合、フレームワークはデバイスの PnP 状態に基づいてインターフェイスを自動的に有効および無効にします。

さらに、ドライバーは、デバイス インターフェイスを無効にし、必要に応じて再度有効にすることができます。 たとえば、ドライバーがデバイスの応答を停止したと判断した場合、ドライバーは IWDFDevice::AssignDeviceInterfaceState を呼び出してデバイスのインターフェイスを無効にし、アプリケーションがインターフェイスへの新しいハンドルを取得できないようにすることができます。 (インターフェイスへの既存のハンドルは影響を受けません。デバイスが後で使用可能になった場合、ドライバーは IWDFDevice::AssignDeviceInterfaceState をもう一度呼び出してインターフェイスを再度有効にすることができます。

デバイス インターフェイスへのアクセス要求の受信

アプリケーションがドライバーのデバイス インターフェイスへのアクセスを要求すると、フレームワークはドライバーの IQueueCallbackCreate::OnCreateFile コールバック関数を呼び出します。 ドライバーは IWDFFile::RetrieveFileName を呼び出して、アプリケーションがアクセスしているデバイスまたはファイルの名前を取得できます。 ドライバーがデバイス インターフェイスの登録時に参照文字列を指定した場合、オペレーティング システムは 、IWDFFile::RetrieveFileName が返すファイル名またはデバイス名に参照文字列を含めます。

デバイス イベントの作成

UMDF ベースのドライバーは、IWDFDevice::P ostEvent を呼び出すことによって、デバイス固有のカスタム イベント (デバイス イベントと呼ばれます) を作成できます。 デバイスのインターフェイスのいずれかを使用するように登録されているドライバーは、デバイスのカスタム イベントの通知を受け取ることができます。 UMDF ベースのドライバーは、 IRemoteInterfaceCallbackEvent::OnRemoteInterfaceEvent コールバック関数を提供することで、このような通知を受け取ります。

カスタム イベントは、デバイスに固有です。 イベントを作成するドライバーの開発者と、イベントを受け取るドライバーの開発者の両方が、イベントの意味を理解する必要があります。

別のドライバーのデバイス インターフェイスへのアクセス

UMDF ベースのドライバーが、別のドライバーが提供するデバイス インターフェイスに I/O 要求を送信する場合は、デバイス インターフェイスを表す リモート I/O ターゲット を作成できます。

まず、デバイス インターフェイスが使用可能な場合に通知を受け取るために、ドライバーを登録する必要があります。 次の手順に従います。

  1. ドライバーが IWDFDriver::CreateDevice を呼び出すと、ドライバーは IPnpCallbackRemoteInterfaceNotification インターフェイスを提供できます。 このインターフェイスの IPnpCallbackRemoteInterfaceNotification::OnRemoteInterfaceArrival コールバック関数は、デバイス インターフェイスが使用可能であることをドライバーに通知します。

  2. ドライバーは 、IWDFDriver::CreateDevice を呼び出した後、ドライバーが使用する各デバイス インターフェイスに対して IWDFDevice2::RegisterRemoteInterfaceNotification を呼び出すことができます。

その後、フレームワークは、指定されたデバイス インターフェイスが使用可能になるたびに、ドライバーの IPnpCallbackRemoteInterfaceNotification::OnRemoteInterfaceArrival コールバック関数を呼び出します。 コールバック関数は 、IWDFRemoteInterfaceInitialize::GetInterfaceGuidIWDFRemoteInterfaceInitialize::RetrieveSymbolicLink を呼び出して、到着したデバイス インターフェイスを決定できます。

ドライバーの IPnpCallbackRemoteInterfaceNotification::OnRemoteInterfaceArrival コールバック関数は、通常、次のことを行う必要があります。

  1. IWDFDevice2::CreateRemoteInterface を呼び出してリモート インターフェイス オブジェクトを作成し、必要に応じて IRemoteInterfaceCallbackEvent インターフェイスと IRemoteInterfaceCallbackRemoval インターフェイスを提供します。

  2. IWDFDevice2::CreateRemoteTarget を呼び出してリモート ターゲット オブジェクトを作成し、必要に応じて IRemoteTargetCallbackRemoval インターフェイスを提供します。

  3. IWDFRemoteTarget::OpenRemoteInterface を呼び出して、デバイス インターフェイスをリモート ターゲットに接続します。

    デバイス インターフェイスが SWENUM ソフトウェア デバイス列挙子によって作成されるインターフェイスの場合、ドライバーは作業項目から OpenRemoteInterface を呼び出す必要があります。 (たとえば、Windows SDK の QueueUserWorkItem 関数を参照してください)。

これで、ドライバーは I/O 要求をフォーマットしてリモート I/O ターゲットに送信できるようになりました。

UMDF ベースのドライバーは、 IPnpCallbackRemoteInterfaceNotification::OnRemoteInterfaceArrival コールバック関数に加えて、デバイス インターフェイス イベントの通知を受け取る 2 つの追加のコールバック関数を提供できます。