各ドライバー オブジェクトは、読み込まれたカーネル モード ドライバーのイメージを表します。 I/O マネージャーは 、DRIVER_OBJECT 構造体を割り当て、ドライバーの DriverEntry、 AddDevice、および省略可能な 再初期化 ルーチンとその Unload ルーチン (存在する場合) に入力パラメーターとして渡します。
ドライバー オブジェクトは部分的に不透明です。 ドライバーライターは、ドライバーを初期化し、ドライバーがアンロード可能な場合にアンロードするドライバー オブジェクトの特定のメンバーについて知っている必要があります。 ドライバー オブジェクトの次のメンバーは、ドライバーからアクセスできます。
構文
typedef struct _DRIVER_OBJECT {
CSHORT Type;
CSHORT Size;
PDEVICE_OBJECT DeviceObject;
ULONG Flags;
PVOID DriverStart;
ULONG DriverSize;
PVOID DriverSection;
PDRIVER_EXTENSION DriverExtension;
UNICODE_STRING DriverName;
PUNICODE_STRING HardwareDatabase;
PFAST_IO_DISPATCH FastIoDispatch;
PDRIVER_INITIALIZE DriverInit;
PDRIVER_STARTIO DriverStartIo;
PDRIVER_UNLOAD DriverUnload;
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
} DRIVER_OBJECT, *PDRIVER_OBJECT;
メンバーズ
Type
ドライバー オブジェクトのオブジェクト型識別子を指定します。 I/O マネージャーは、ドライバー オブジェクトを割り当てるときにこのフィールドを設定します。 ドライバーは、このフィールドを使用または変更しないでください。
Size
ドライバー オブジェクト構造のサイズをバイト単位で指定します。 I/O マネージャーは、ドライバー オブジェクトを割り当てるときにこのフィールドを設定します。 ドライバーは、このフィールドを使用または変更しないでください。
DeviceObject
ドライバーによって作成されたデバイス オブジェクトのリンクされたリスト内の最初のデバイス オブジェクトへのポインター。 このフィールドは、1 つのドライバーによって作成されたすべてのデバイスを一覧にリンクします。 ドライバーが IoCreateDevice を正常に呼び出すと、このメンバーは I/O マネージャーによって自動的に更新されます。 ドライバーは、このメンバーとDEVICE_OBJECTの NextDevice メンバーを使用して、ドライバーが作成したすべてのデバイス オブジェクトの完全な一覧を走査できます。 これは、ドライバーのアンロード中に、すべてのデバイス オブジェクトが適切にクリーンアップされるようにするために特に便利です。
Flags
ドライバーのさまざまな属性と状態を記述するシステム定義フラグが含まれています。 このフィールドは、ドライバー オブジェクトの拡張可能なフラグの場所を提供します。 これらのフラグは、I/O マネージャーおよびその他のシステム コンポーネントによって設定および管理されます。 ドライバーは、このフィールドを直接変更しないでください。
DriverStart
ドライバー イメージがシステム メモリに読み込まれるベース仮想アドレスを指します。 このアドレスは、カーネル アドレス空間内のドライバーのコード セクションの先頭を表します。 I/O マネージャーは、ドライバーが読み込まれるときにこの値を設定します。
DriverSize
メモリ内のドライバー イメージのサイズをバイト単位で指定します。 この値は、コード、データ、その他のセクションを含む、読み込まれたドライバーのメモリ占有領域の合計を表します。 I/O マネージャーは、ドライバーが読み込まれるときにこの値を設定します。
DriverSection
メモリ マネージャーのドライバー イメージを表すドライバーのセクション オブジェクトをポイントします。 これは、メモリ マネージャーとローダーによって内部的に使用される不透明なシステム構造です。 ドライバーは、このメンバーにアクセスしたり変更したりしないでください。
DriverExtension
ドライバー拡張機能へのポインター。 ドライバー拡張機能の唯一のアクセス可能なメンバーは 、DriverExtension->AddDeviceです。ドライバーの DriverEntry ルーチンには、ドライバーの AddDevice ルーチンが格納されます。
DriverName
ドライバーの Unicode 文字列名を格納します。 このフィールドは、エラー ログ スレッドによって、I/O 要求がバインドされているドライバーの名前を決定するために使用されます。 これは通常、 \Driver\DriverName という形式で、 DriverName はレジストリ内のドライバーのサービス名に対応します。 I/O マネージャーは、ドライバーのレジストリ構成に基づいてこの値を設定します。
HardwareDatabase
レジストリ内のハードウェア構成情報への \Registry\Machine\Hardware パスへのポインター。
FastIoDispatch
ドライバーの高速 I/O エントリ ポイントを定義する FAST_IO_DISPATCH 構造体へのポインター。 この省略可能なポインターは、"高速 I/O" サポート用のドライバーへの代替エントリ ポイントの配列を指します。 高速 I/O は、標準の IRP 呼び出しメカニズムを使用するのではなく、個別のパラメーターを使用してドライバー ルーチンを直接呼び出すことによって実行されます。 これらの関数は、同期 I/O およびファイルがキャッシュされる場合にのみ使用できます。 このメンバーは、ファイル システム ドライバー (FSD) とネットワーク トランスポート ドライバーでのみ使用されます。
DriverInit
ドライバーの DriverEntry ルーチンのエントリ ポイント アドレス。 I/O マネージャーは、ドライバーが読み込まれるときに、ドライバーの初期化関数を指すこのフィールドを設定します。 これは、メモリに読み込まれるときにドライバーで呼び出される最初の関数であり、ドライバー オブジェクトの初期化とディスパッチ ルーチンの設定を担当します。
DriverStartIo
ドライバーの StartIo ルーチンのエントリ ポイント (ある場合)、ドライバーの初期化時に DriverEntry ルーチンによって設定されます。 ドライバーに StartIo ルーチンがない場合、このメンバーは NULL 。
DriverUnload
ドライバーの アンロード ルーチンのエントリ ポイント (存在する場合)、ドライバーの初期化時に DriverEntry ルーチンによって設定されます。 ドライバーに Unload ルーチンがない場合、このメンバーは NULL 。
MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]
ドライバーの DispatchXxx ルーチンのエントリ ポイントの配列で構成されるディスパッチ テーブル。 配列のインデックス値は、各 IRP メジャー関数コードを表す IRP_MJ_XXX 値です。 このメジャー関数ディスパッチ テーブルは、拡張可能なままになるように、オブジェクトの最後のフィールドである必要があります。 各ドライバーは、ドライバーが処理する IRP_MJ_XXX 要求のエントリ ポイントをこの配列に設定する必要があります。 詳細については、「ディスパッチ ルーチン の作成」を参照してください。
ドライバー 、静的ドライバー検証ツール (SDV)、およびその他の検証ツールのコード分析をするために、次のコード例に示すように、各 DispatchXxx ルーチンはDRIVER_DISPATCH型を使用して宣言されます。
DRIVER_DISPATCH DispatchXxx;
その後、コールバック ルーチンは次のように実装されます。
_Use_decl_annotations_
NTSTATUS
DispatchXxx(
struct _DEVICE_OBJECT *DeviceObject,
struct _IRP *Irp
)
{
// Function body
}
DRIVER_DISPATCH関数の種類は、Wdm.h ヘッダー ファイルで定義されています。 コード分析ツールの実行時にエラーをより正確に識別するには、_Use_decl_annotations
_ 注釈を関数定義に追加してください。
_Use_decl_annotations_
注釈により、ヘッダー ファイル内のDRIVER_DISPATCH関数型に適用される注釈が確実に使用されます。 関数宣言の要件の詳細については、「WDM ドライバーの の関数の役割の種類を使用して関数を宣言するを参照してください。
_Use_decl_annotations_
の詳細については、「関数の動作 に注釈を付けるを参照してください。
備考
システムがドライバーを自動的に読み込むには、各カーネル モード ドライバーの初期化ルーチンに DriverEntry という名前を付ける必要があります。 このルーチンの名前が別の場合、ドライバー ライターはリンカーの初期化ルーチンの名前を定義する必要があります。それ以外の場合、システム ローダーまたは I/O マネージャーは、ドライバーの転送アドレスを見つけることができません。 他の標準ドライバー ルーチンの名前は、ドライバー ライターの裁量で選択できます。
ドライバーは、ドライバーが読み込まれるときに、DriverEntry ルーチンに渡されるドライバー オブジェクトの DispatchXxx エントリ ポイントを設定する必要があります。 デバイス ドライバーは、同じ種類のデバイスのドライバーが処理する必要がある IRP_MJ_XXX のエントリ ポイント 1 つ以上の DispatchXxx を設定する必要があります。 上位レベルのドライバーは、基になるデバイス ドライバーに渡す必要があるすべての IRP_MJ_XXX の 1 つ以上の DispatchXxx エントリ ポイントを設定する必要があります。 それ以外の場合、ドライバーは、ドライバー オブジェクトに DispatchXxx ルーチンを設定しない IRP_MJ_XXX の IRP を送信されません。 さまざまな種類の基になるデバイスのドライバーを処理する必要がある IRP_MJ_XXX のセットの詳細については、「IRP の主要な機能コードを参照してください。
DriverEntry ルーチンは、ドライバー オブジェクトにドライバーの AddDevice、StartIo、または Unload エントリ ポイント (存在する場合) を設定します。
HardwareDatabase 文字列は、ドライバーの読み込み時にデバイス ドライバーがレジストリからハードウェア構成情報を取得するために使用できます。 ドライバーには、この文字列への読み取り専用アクセス権が付与されます。
RegistryPathDriverEntry ルーチンへの入力は、driverName の値エントリがドライバーを識別する、\Registry\Machine\System\CurrentControlSet\Services\DriverName キー 指します。 このレジストリ キーには、次のような値を含むドライバーのサービス構成が含まれています。
- スタート: ドライバーを読み込む必要がある場合 (ブート、システム、自動、需要、または無効)
- 型: サービスの種類 (カーネル ドライバー、ファイル システム ドライバーなど)
- ErrorControl: ドライバーの読み込みに失敗した場合のシステムの応答方法
- ImagePath: ドライバー バイナリ ファイルへのパス
ドライバーは、サービス キーの Parameters サブキーの下に追加の構成データを格納できます。 入力ドライバー オブジェクトの HardwareDatabase に関しては、ドライバーには、この文字列への読み取り専用アクセス権が与えられています。
ドライバー オブジェクト内の文書化されていないメンバーは、アクセス不可と見なす必要があります。 オブジェクト メンバーの場所または文書化されていないメンバーへのアクセスに依存するドライバーは、移植性が維持されず、時間の経過と共に他のドライバーと相互運用できない可能性があります。
必要条件
要件 | 価値 |
---|---|
ヘッダー | wdm.h (Wdm.h、Ntddk.h、Ntifs.h を含む) |
関連項目
IoCreateDevice の
IoDeleteDevice の
StartIo の