信頼性の高いカーネルモード ドライバーの作成
ドライバーは、カーネル モードで実行されるコード全体のかなりの割合を占めます。 カーネルモード ドライバーは、実際にはオペレーティング システムのコンポーネントです。 したがって、信頼性が高く安全なドライバーは、オペレーティング システムの全体的な信頼性に大きく貢献します。 信頼性の高いカーネルモード ドライバーを作成するには、次のガイドラインに従ってください。
デバイス オブジェクトを適切にセキュリティで保護します。
システムのドライバーとデバイスへのユーザー アクセスは、システムがデバイス オブジェクトに割り当てるセキュリティ記述子によって制御されます。 ほとんどの場合、システムはデバイスのインストール時にデバイスのセキュリティ パラメーターを設定します。 詳細については、「セキュリティで保護されたデバイスのインストールの作成」を参照してください。 状況によっては、デバイスへのアクセス制御の一部をドライバーに任せることが適切な場合もあります。 詳細については、「デバイス オブジェクトの保全」を参照してください。
デバイス オブジェクトを正しく検証します。
ドライバーが複数の種類のデバイス オブジェクトを作成する場合は、各 IRP で受け取る型をチェックする必要があります。 詳細については、「デバイス オブジェクトの検証失敗」を参照してください。
"セーフ文字列" 関数を使用します。
文字列を操作する場合、ドライバーは、C/C++ 言語ランタイム ライブラリで提供される文字列関数ではなく、セーフ文字列関数を使用する必要があります。 詳細については、「セーフ文字列関数の使用」を参照してください。
オブジェクト ハンドルを検証します。
入力としてオブジェクト ハンドルを受け取るドライバーは、ハンドルが有効であること、アクセス可能であること、想定されている型であることを検証する必要があります。 オブジェクト ハンドルの使用方法の詳細については、次のトピックを参照してください
マルチプロセッサを適切にサポートします。
ドライバーが単一のプロセッサ システムでのみ実行されると決して想定しないでください。 ドライバーがマルチプロセッサ システムで正しく機能するために使用できるプログラミング手法については、次のトピックを参照してください。
ドライバーの状態を適切に処理します。
ドライバーが想定した状態であることを常に検証することが重要です。 たとえば、ドライバーが IRP を受け取った場合、同じ型の IRP が既に処理されていないかを確認してください。 ドライバーがこの状況を確認しなければ、最初の IRP が失われる可能性があります。 詳細については、「ドライバーの状態の検証失敗」を参照してください。
IRP 入力値を検証します。
信頼性とセキュリティの両方の観点から、バッファー アドレスや長さなど、IRP に関連付けられているすべての値を検証することが不可欠です。 次のトピックでは、IRP 入力値の検証に関する情報を提供しています。
バッファー付き I/O を使用した DispatchReadWrite
I/O スタックを適切に処理します。
ドライバー スタックに IRP を渡すときは、ドライバーが IoSkipCurrentIrpStackLocation または IoCopyCurrentIrpStackLocationToNext を呼び出して、次のドライバーの I/O スタック位置を設定することが重要です。 1 つの I/O スタック位置を次の I/O スタック位置に直接コピーするコードを記述しないでください。
IRP 完了操作を適切に処理します。
ドライバーは、IRP を実際にサポートし、処理しない限り、STATUS_SUCCESS の状態値を持つ IRP を絶対に完了してはなりません。 IRP 完了操作の正しい処理方法については、「IRP の完了」を参照してください。
IRP のキャンセル操作を適切に処理します。
キャンセル操作は、通常、非同期的に実行されるため、適切なコーディングが難しい場合があります。 多くの場合、このコードは実行中のシステムであまり実行されないため、キャンセル操作を処理するコードの問題は長期間気付かれないことがあります。
「IRP のキャンセル」に記載されているすべての情報を必ず読んで理解してください。 特に、「IRP キャンセルの同期」と「IRP をキャンセルするときに考慮すべき点」に注意してください。
キャンセル操作に関連する同期の問題を回避する 1 つの方法は、キャンセル セーフな IRP キューを 実装することです。 キャンセル セーフな IRP キューは、Windows XP 以降のオペレーティング システム バージョン用に導入されたドライバー管理キューですが、以前のバージョンと下位互換性もあります。
IRP のクリーンアップを処理し、操作を正常に終了します。
IRP_MJ_CLEANUP 要求と IRP_MJ_CLOSE 要求の違いを正確に理解してください。 クリーンアップ要求は、アプリケーションがファイル オブジェクトのすべてのハンドルを閉じた後に届きますが、届いた時点で I/O 要求がまだすべて完了していない場合があります。 閉じる要求は、ファイル オブジェクトのすべての I/O 要求が完了または取り消された後に届きます。 詳細については、次のトピックを参照してください。
IRP の正しい処理方法の詳細については、「IRP の処理におけるその他のエラー」を参照してください。
ドライバーの検証ツールの使用
ドライバー検証ツール は、ドライバーの信頼性を確保するために使用できる最も重要なツールです。 ドライバー検証ツールは、このセクションで説明する一部のドライバーを含め、一般的なさまざまなドライバーの問題をチェックできます。 ただし、ドライバー検証ツールを使用しても、慎重で熟考されたソフトウェア設計が不要になるわけではありません。