ミニドライバーと HID クラス ドライバー

この記事では、ミニドライバーと HID クラス ドライバーについて説明します。

詳細については、「WDF HID ミニドライバーの作成」を参照してください。

HID クラス ドライバーの操作機能

HID クラス ドライバーは、次の操作を行います。

  • カーネル モード ドライバーとユーザー モード アプリケーションが、入力デバイスでサポートされている HID コレクションにアクセスするために使用する上位レベルのインターフェイスを提供および管理します。

    HID クラス ドライバーは、上位レベルのドライバーおよびアプリケーションと、HID コレクションをサポートする基になる入力デバイス間のすべての通信を透過的に管理およびルーティングします。 さまざまな入力デバイスおよび入力キューで使用される各種データ プロトコルを管理することで、同じ HID コレクションで開かれている複数のファイルをサポートします。

    HID コレクションの上位レベルのインターフェイスは、HID クラス ドライバー IOCTLHIDClass サポート ルーチン、および HIDClass 構造体で構成されます。

  • ミニドライバーの標準ドライバー ルーチンを呼び出すことによって HID ミニドライバーと通信します。

  • 下位レベルのバスまたはポート ドライバーによって列挙された HIDClass 入力デバイスの機能デバイス オブジェクト (FDO) を作成します。

    たとえば、HID クラス ドライバーは、システム提供の USB ドライバー スタックによって列挙された USB HID デバイスを表す FDO の操作を作成および管理します。

  • 基になる入力デバイスでサポートされている子デバイス (HID コレクション) のバス ドライバーの機能を提供します。

    HID クラス ドライバーは、入力デバイスでサポートされている HID コレクションごとに物理デバイス オブジェクト (PDO) を作成し、コレクションの操作を管理します。

ミニドライバーを HIDClass にバインドする

HID ミニドライバーは、HidRegisterMinidriver を呼び出して HID クラス ドライバーに自身を登録することで、その操作を HID クラス ドライバーにバインドします。 登録する操作は、次のとおりです。

  • HID クラス ドライバーのデバイス拡張機能で、HID ミニドライバーの標準ドライバー ルーチンへのエントリ ポイント (ポインター) のコピーを保存します。

    HID ミニドライバーが、ミニドライバーが DRIVER_INITIALIZE ルーチンへの入力として受け取るドライバー オブジェクトのエントリ ポイントを設定します。 HID ミニドライバーは、HID クラス ドライバーに登録する前に、これらのエントリ ポイントを設定します。

  • ミニドライバーのドライバー オブジェクトのエントリ ポイントを、HID クラス ドライバーによって提供される標準ドライバー ルーチンのエントリ ポイントにリセットします。

HID クラス ドライバーは、次の標準ドライバー ルーチンを提供します。

登録プロセスでは、HID ミニドライバーのデバイス拡張機能のメモリも割り当てられます。 メモリは HID クラス ドライバーによって割り当てられますが、このデバイス拡張機能を使用するのは HID ミニドライバーのみです。

HID ミニドライバーとの通信

HID クラス ドライバーは、HID ミニドライバーの DRIVER_ADD_DEVICEDRIVER_UNLOAD、およびディスパッチ ルーチンを次のように呼び出すことで HID ミニドライバーと通信します。

AddDevice ルーチンの呼び出し

機能デバイス オブジェクト (FDO) を作成するために HID クラス ドライバーの AddDevice ルーチンを呼び出すと、HID クラス ドライバーが FDO を作成してそれを初期化し、HID ミニドライバーの AddDevice ルーチンを呼び出します。 HID ミニドライバーの AddDevice ルーチンは、内部デバイスに固有の初期化を行い、成功した場合は STATUS_SUCCESS を返します。 HID ミニドライバーの AddDevice ルーチンが成功しなかった場合、HID クラス ドライバーは FDO を削除し、HID ミニドライバーの AddDevice ルーチンから返された状態を返します。

Unload ルーチンの呼び出し

HID クラス ドライバーの Unload ルーチンを呼び出すと、HID クラス ドライバーは、FDO に関連付けられているすべてのリソースを解放し、HID ミニドライバーの Unload ルーチンを呼び出します。

ディスパッチ ルーチンの呼び出し

HID クラス ドライバーは、デバイスを操作するために、主に内部デバイス制御要求に対して HID ミニドライバー ディスパッチ ルーチンを呼び出します。

I/O マネージャーが HID クラス ドライバーに要求を送信すると、HID クラス ドライバーは要求を処理し、HID ミニドライバーの対応するディスパッチ ルーチンを呼び出します。

HID クラス ドライバーは、HID ミニドライバーに対して、作成、クローズ、デバイス制御の要求を送信しません。

HID ミニドライバーの操作

HID トランスポート ミニドライバーは、入力デバイスが接続するハードウェア バスまたはポートの操作を抽象化します。

HID ミニドライバーは、次のいずれかのフレームワークを使用して構築できます。

  • UMDF – ユーザー モード ドライバー フレームワーク
  • KDMF – Kernel Mode Driver Framework
  • WDF - Windows Driver Framework
  • WDM – Windows Driver Model (レガシ)

Microsoft では、フレームワーク ベースのソリューション (KMDF または UMDF) の使用をお勧めします。 各ドライバー モデルの詳細については、次の各セクションを参照してください。

  • KMDF ベースの HID ミニドライバーについては、「フレームワーク ベースの HID ミニドライバーの作成」を参照してください。
  • UMDF ベースの HID ミニドライバーについては、「WDF HID ミニドライバーの作成」を参照してください。

次のセクションでは、WDM ベースの HID ミニドライバーの登録について説明しますが、その多くは KMDF ベースのフレームワーク ドライバーにも関連しています。 HID ミニドライバーはすべて HID クラス ドライバーに登録する必要があり、HID クラス ドライバーはミニドライバーの標準ドライバー ルーチンを呼び出すことによってミニドライバーと通信します。

HID ミニドライバーが標準ドライバー ルーチンでサポートする必要がある機能の詳細については、次の各セクションを参照してください。

HID クラス ドライバーの詳細については、「HID ミニドライバーの操作」を参照してください。

HID ミニドライバーの登録

HID ミニドライバーは、DRIVER_INITIALIZE ルーチンで他のすべてのドライバーの初期化を完了した後で、HidRegisterMinidriver を呼び出すことによって、その操作を HID クラス ドライバーにバインドします。

HID ミニドライバーは HID クラス ドライバーに登録するときに、HID_MINIDRIVER_REGISTRATION 構造体を使用します。 構造体は次のことを指定します。

  • HID のリビジョン
  • HID ミニドライバーのドライバー オブジェクト
  • HID ミニドライバー デバイス拡張機能のサイズ
  • デバイスがポーリングされるかどうか

HID ミニドライバー拡張機能

HID ミニドライバー デバイス拡張機能はデバイス固有であり、HID ミニドライバーでのみ使用されます。 HID クラス ドライバーは、クラス ドライバーが機能デバイス オブジェクト (FDO) のデバイス拡張機能を作成するときに、ミニドライバー デバイス拡張機能のメモリを割り当てます。 HID ミニドライバーは、HID クラス ドライバーにミニドライバーを登録するときに、そのデバイス拡張機能のサイズを指定します。 サイズは、HID_MINIDRIVER_REGISTRATION 構造体の DeviceExtensionSize メンバーによって指定されます。

HID_DEVICE_EXTENSION 構造体の使用

HID ミニドライバーは、機能デバイス オブジェクト (FDO) の HID クラス ドライバーによって作成されたデバイス拡張機能のレイアウトとして、HID_DEVICE_EXTENSION 構造体を使用する必要があります。 HID クラス ドライバーは、FDO を初期化するときに、この構造体のメンバーを設定します。 HID ミニドライバーは、この構造体の情報を変更することはできません。

HID_DEVICE_EXTENSION 構造体には、次のメンバーが含まれています。

  • PhysicalDeviceObject: 基になる入力デバイスを表す物理デバイス オブジェクト (PDO) へのポインターです。

  • NextDeviceObject: FDO の下にあるデバイス スタックの先頭へのポインターです。

  • MiniDeviceExtension: HID ミニドライバー デバイス拡張機能へのポインターです。

入力デバイスの FDO へのポインターを指定すると、次の GET_MINIDRIVER_DEVICE_EXTENSION マクロから HID ミニドライバー拡張機能へのポインターが返されます。

#define GET_MINIDRIVER_DEVICE_EXTENSION(DO) ((PDEVICE_EXTENSION) (((PHID_DEVICE_EXTENSION)(DO)->DeviceExtension)->MiniDeviceExtension))

PDEVICE_EXTENSION は、HID ミニドライバーによって宣言されたデバイス固有のデバイス拡張機能へのポインターです。

同様に、HID ミニドライバーは、入力デバイスの PDO へのポインターと、入力デバイスの FDO の下にあるデバイス スタックの先頭へのポインターを取得できます。

HID ミニドライバーは、デバイス スタックに IRP を送信するとき、ターゲット デバイス オブジェクトとして NextDeviceObject を使用する必要があります。

標準ミニドライバー ルーチン

HID ミニドライバーは、次の標準ドライバーサポート ルーチンを提供する必要があります。

  • HID ミニドライバー DriverEntry ルーチン
  • HID ミニドライバー AddDevice ルーチン
  • HID ミニドライバー Unload ルーチン

HID ミニドライバーでは、「HID ミニドライバーによって提供されるディスパッチ ルーチン」で説明されているディスパッチ ルーチンもサポートする必要があります。

DriverEntry ルーチン

HID ミニドライバーの DRIVER_INITIALIZE ルーチンは、次の処理を行います。

  • リンクされたドライバーのペア (HID クラス ドライバーと HID ミニドライバー) のドライバー オブジェクトを作成します。

  • HID ミニドライバー ドライバー オブジェクトに必要なドライバー エントリ ポイントを設定します。

  • HidRegisterMinidriver を呼び出して、HID ミニドライバーを HID クラス ドライバーに登録します。

  • HID ミニドライバーによってのみ使用されるデバイス固有の構成を行います。

AddDevice ルーチン

HID クラス ドライバーは、基になる入力デバイスの機能デバイス オブジェクト (FDO) の作成と初期化を処理します。 HID クラス ドライバーは、基になるデバイスとその子デバイス (HID コレクション) への上位レベルのインターフェイスの観点から FDO も操作します。

HID クラス ドライバー DRIVER_ADD_DEVICE ルーチンは、HID ミニドライバー AddDevice ルーチンを呼び出して、ミニドライバーがデバイス固有の内部初期化を実行できるようにします。

HID ミニドライバー DRIVER_ADD_DEVICE ルーチンに渡されるパラメーターは、ミニドライバー ドライバー オブジェクトと FDO です。 HID クラス ドライバーは、基になる入力デバイスの物理デバイス オブジェクトではなく、ミニドライバーの AddDevice ルーチンに FDO を渡します。

HID ミニドライバー DRIVER_ADD_DEVICE ルーチンは、FDO からミニドライバー デバイス拡張機能へのポインターを取得します。

  • 通常、HID ミニドライバー DRIVER_ADD_DEVICE ルーチンは、次の処理を行います。

  • ミニドライバー デバイス拡張機能を初期化します。 デバイス拡張機能は、ミニドライバーでのみ使用されます。

  • STATUS_SUCCESS を返します。 ミニドライバーがエラー状態を返す場合、HID クラス ドライバーは FDO を削除し、プラグ アンド プレイ マネージャーにエラーの状態を返します。

Unload ルーチン

HID クラス ドライバーの Unload ルーチンは、HID ミニドライバー DRIVER_UNLOAD ルーチンを呼び出します。 HID ミニドライバーは、ミニドライバーによって割り当てられているすべての内部リソースを解放します。

ディスパッチ ルーチン

HID ミニドライバーは、作成、クローズ、内部デバイス制御、システム制御、プラグ アンド プレイ、電源管理の各ディスパッチ ルーチンを提供する必要があります。 内部デバイス制御要求を除き、これらのディスパッチ ルーチンのほとんどは最小限の機能を提供します。 HID クラス ドライバーは、これらのディスパッチ ルーチンを呼び出すと、ミニドライバー ドライバー オブジェクトと機能デバイス オブジェクト (FDO) を渡します。

IRP_MJ_CREATE

WDM の要件に準拠して、HID クラス ドライバーと HID ミニドライバーは、作成要求のためのディスパッチ ルーチンを提供します。 ただし、FDO を開くことはありません。 HID クラス ドライバーは、STATUS_UNSUCCESSFUL を返します。

HID ミニドライバーは、スタブのみを提供する必要があります。 作成のディスパッチ ルーチンは呼び出されません。

IRP_MJ_CLOSE

WDM の要件に準拠して、HID クラス ドライバーと HID ミニドライバーは、クローズ要求のためのディスパッチ ルーチンを提供する必要があります。 ただし、FDO を開くことはありません。 HID クラス ドライバーは、STATUS_INVALID_PARAMETER_1 を返します。

HID ミニドライバーは、スタブのみを提供する必要があります。 クローズのディスパッチ ルーチンは呼び出されません。

IRP_MJ_DEVICE_CONTROL

HID ミニドライバーは、デバイス制御要求のディスパッチ ルーチンを必要としません。 HID クラス ドライバーは、ミニドライバーにデバイス制御要求を渡しません。

IRP_MJ_INTERNAL_DEVICE_CONTROL

HID ミニドライバーは、HID ミニドライバー IOCTL で説明されている要求をサポートする内部デバイス制御要求に対応したディスパッチ ルーチンを提供する必要があります。

HID クラス ドライバーは、主に内部デバイス制御要求を使用して、基になる入力デバイスにアクセスします。

HID ミニドライバーは、デバイス固有の方法でこれらの要求を処理します。

IRP_MJ_SYSTEM_CONTROL

HID ミニドライバーは、システム制御要求のディスパッチ ルーチンを提供する必要があります。 ただし、HID ミニドライバーは、次のようにデバイス スタックにシステム制御要求を渡すためにのみ必要です。

  • 現在の IRP スタックの場所をスキップする

  • FDO のデバイス スタックに要求を送信する

IRP_MJ_PNP

HID ミニドライバーは、プラグ アンド プレイ要求のディスパッチ ルーチンを提供する必要があります。

HID クラス ドライバーは、FDO に関連付けられているすべてのプラグ アンド プレイ処理を実行します。 HID クラス ドライバーは、プラグ アンド プレイ要求を処理するときに、HID ミニドライバーのプラグ アンド プレイ ディスパッチ ルーチンを呼び出します。

HID ミニドライバーのプラグ アンド プレイ ディスパッチ ルーチンは、次の処理を行います。

  • 要求の種類に応じた適切な方法で、FDO のデバイス スタックに要求を送信し、デバイス スタックをバックアップする過程で要求の完了を処理します。

  • FDO の状態に関する情報を更新する特定の要求に関連付けられているデバイス固有の処理を行います。

    たとえば、ミニドライバーは、FDO のプラグ アンド プレイ状態を更新する場合があります (特に、FDO が開始済み、停止済み、または削除中かどうか)。

IRP_MJ_POWER

HID ミニドライバーは、電源要求のディスパッチ ルーチンを提供する必要があります。 ただし、FDO の電源処理は、HID クラス ドライバーが処理します。

WDM の要件に準拠して、HID ミニドライバーは次のように FDO のデバイス スタックに電源要求を送信します。

  • 現在の IRP スタックの場所をスキップする

  • 次の電源 IRP を開始する

  • FDO のデバイス スタックに電源 IRP を送信する

通常、HID ミニドライバーは、追加の処理を行うことなくデバイス スタックに電源要求を渡します。