Skip to content

ドライバ開発情報

開発21 ディスパッチルーチンの概要

デバイスドライバをはじめ、デバイスにかかわるお困りごとの際はお気軽にお問い合わせください。


ディスパッチルーチンはアプリケーションからのデバイスに対する要求を処理します。階層ドライバの場合、最上位のドライバのディスパッチルーチンはユーザーモードのアプリケーションのI/O要求を直接処理します。その下の中間ドライバや物理ドライバのディスパッチルーチンは一つ上のドライバからのI/O要求を処理します。I/O処理要求があった際、ディスパッチルーチンはI/Oマネージャによって呼び出されます。どのディスパッチルーチンを呼ぶかは、I/Oメジャー機能コードによって管理されています。また、ディスパッチルーチンはドライバエントリ処理が終了してから呼び出されます。

ディスパッチルーチンは次のようなエントリポイントの形式になっています。

NTSTATUS Dispatchxxxx(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
);
DeviceObject:
ドライバエントリ処理で作成されたデバイスオブジェクト(FDO)のポインタです。
Irp:
実行されるI/Oリクエストが記述されているI/Oリクエストパケット(IRP)へのポインタです。

DeviceObjectとIrp引数は、ディスパッチルーチンがI/Oマネージャによって呼ばれる際に渡されます。IRPについては開発22で詳細を説明します。

 

1.オープンとクローズディスパッチルーチン

CreateFileとCloseHandle関数を実行する際、I/OマネージャはIRPを作成し、このディスパッチルーチンを呼び出します。このルーチンは直接アプリケーションからアクセスが許されているドライバにのみ存在します。階層ドライバの場合、中間ドライバと物理ドライバにこのルーチンは必要ありません。通常このルーチンは直接ハードウェアにアクセスする必要はありません。

このルーチンはオープンディスパッチルーチンとクローズディスパッチルーチンに分けられることもあります。このルーチンは次のようなエントリポイントの形式になっています。

NTSTATUS Bus_CreateClose(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
);

 

2.デバイス操作ディスパッチルーチン

ReadFile, WriteFile, DeviceIoControl関数を実行する際、I/OマネージャはIRPを作成し、このディスパッチルーチンを呼び出します。このルーチンは直接アプリケーションからアクセスが許されているドライバにのみ存在します。階層ドライバの場合、中間ドライバと物理ドライバにこのルーチンは必要ありません。通常このルーチンはHALを通じてハードウェアにアクセスします。

このルーチンはリードディスパッチルーチン、ライトディスパッチルーチン、DeviceIoControlディスパッチルーチンに分けられることもあります。ドライバの設定によって、上記すべてのルーチンが揃わない場合もあります。このルーチンは次のようなエントリポイントの形式になっています。

NTSTATUS Bus_IoCtl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
);

 

3.シャットダウンディスパッチルーチン

ユーザーがシャットダウンを行う際、ハードウェアを元の状態に戻すためにこのルーチンが呼び出されます。通常このルーチンを設ける必要はありません。このルーチンは次のようなエントリポイントの形式になっています。

NTSTATUS Bus_Shutdown(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
);

 

4.PnPディスパッチルーチン

PnP機能に対応するためのディスパッチルーチンです。PnPマネージャが新しいデバイスを検出した際、I/Oマネージャによってこのルーチンが呼び出されます。このディスパッチルーチンにはPnPに対応するために、数多くのマイナー機能を揃えています。このルーチンは次のようなエントリポイントの形式になっています。

NTSTATUS Bus_PnP(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
);

 

5. Powerディスパッチルーチン

Windowsの電源管理機能に対応するためのディスパッチルーチンです。WDMドライバには必ずこのルーチンが必要となります。このルーチンは次のようなエントリポイントの形式になっています。

NTSTATUS Bus_Power(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
);

 

6.メジャー機能コード

メジャー機能コードとは、ユーザーからI/O要求があった際、I/Oマネージャがそれぞれの要求に応じて生成した機能コードです。ドライバエントリでは各メジャー関数に対応するディスパッチルーチンの設定を行うことが可能です。メジャー機能コードは全部で30個近くあります。その中でも、次の7つがよく使われます。

IRP_MJ_CREATE

IRP_MJ_CLOSE

IRP_MJ_READ

IRP_MJ_WRITE

IRP_MJ_DEVICE_CONTROL

IRP_MJ_PNP

IRP_MJ_POWER

 

7.マイナー機能コード

I/Oマネージャがメジャー機能コードを生成する際、各メジャー機能に属するマイナー機能コードも同時に生成されます。しかし、すべてのメジャー機能にマイナー機能コードが存在するわけではありません。
例えば、IRP_MJ_READ、IRP_MJ_WRITE、IRP_MJ_DEVICE_CONTROLにはマイナー機能コードは存在しません。よく使われるマイナー機能コードはIRP_MJ_PNPとIRP_MJ_POWERに属したものです。

 

参考資料

「NTドライバプログラミング」
Peter G. Viscarola、W. Anthony Mason著 久保雅俊、三浦秀朗訳 サイエンスパーク株式会社 監修
「WDMデバイスドライバプログラミング完全ガイド」上、下
Edward N. Dekker, Joseph M. Newcomer著 株式会社クイック訳