レガシ フィルター ドライバーの移植ガイドライン
開発者は、フィルター ドライバーの機能を向上させ、システムの信頼性を向上させるために、従来のフィルター ドライバーをフィルター マネージャー モデルに移植することをお勧めします。 経験豊富な開発者であれば、従来のフィルター ドライバーをミニフィルター ドライバーに移植するのは比較的簡単であることがわかります。 Microsoft のフィルター ドライバー開発者は、次のアプローチを推奨しています。
信頼性の高い回帰テスト スイートから始めて、従来のフィルター ドライバーと移植されたミニフィルター ドライバー間の動作を検証します。
ミニフィルター ドライバー シェルを作成し、従来のフィルター ドライバーからミニフィルター ドライバーに機能を体系的に移動します。 たとえば、アタッチメントを動作させてから、一度に 1 つの操作を移植し、各操作の後にテストします。
ユーザー モード/カーネル モード通信を最後に変更すると、既存のツールを使用してミニフィルター ドライバーをテストできます。
PREfast でコンパイルし、Driver Verifier の Filter Verifier I/O 検証オプションを有効にしてテストします。
移植プロセス中に、フィルター マネージャーの機能を最大限に活用するために、すべての従来のフィルター ドライバー コードを確認する必要があります。 特に、次の点に留意してください。
IRP ベースの I/O 操作と高速 I/O 操作は、必要に応じて同じ操作で実行できるため、コードの重複を減らすことができます。
操作を登録するときに、ミニフィルター ドライバーはすべてのページング I/O とキャッシュされた I/O を無視することを明示的に選択できるため、これらをチェックするコードの必要がなくなります。
インスタンス通知により、アタッチ/デタッチ ロジックが大幅に簡素化されます。
ミニフィルタードライバーが処理する必要がある操作にのみ登録します。他のすべてを無視できます。
フィルター マネージャーのコンテキストと名前管理のサポートを活用します。
非再帰 I/O を発行するためのフィルター マネージャー サポートを利用します。
従来のフィルター ドライバーとは異なり、ミニフィルター ドライバーは、操作前処理から操作後処理までのコンテキストを維持するためにローカル変数に依存することができません。 操作状態を保存するためにルックアサイド リストを割り当てることを検討してください。
名前またはコンテキストの設定が完了したら、必ず参照を解放してください。
ユーザー モードの完了ポートは、キューを構築するための強力な手法を追加します。 おそらく、単一の名前付きポートへの接続は 1 つだけ必要になります。
次の表は、従来のフィルター ドライバーでの一般的な操作と、それらがフィルター マネージャー モデルにどのようにマップされるかを示しています。
従来のフィルター ドライバー モデル | フィルターマネージャーモデル |
---|---|
完了ルーチンのないパススルー操作 |
ミニフィルター ドライバーがこのタイプの I/O 操作で動作しない場合は、この操作に対して操作前または操作後のコールバック ルーチンを登録しないでください。 それ以外の場合は、この操作用に登録された操作前コールバック ルーチンから FLT_PREOP_SUCCESS_NO_CALLBACK を返します。 Returning FLT_PREOP_SUCCESS_NO_CALLBACK を参照して下さい。 |
完了ルーチンによるパススルー操作 |
操作前コールバック ルーチンから FLT_PREOP_SUCCESS_WITH_CALLBACK を返します。 |
操作前コールバック ルーチンでの操作の保留 |
FltLockUserBuffer を必要に応じて呼び出し、ワーカースレッドでアクセスできるようにユーザバッファが適切にロックされるようにします。 FltAllocateDeferredIoWorkItem そして FltQueueDeferredIoWorkItem のようなサポート ルーチンを呼び出して、作業をワーカー スレッドのキューに入れます。. 操作前コールバック ルーチンから FLT_PREOP_PENDING を返します。 I/O 操作をフィルター マネージャーに返す準備ができたら、FltCompletePendedPreOperation の呼び出しを行います。 操作前コールバック ルーチンでの I/O 操作の保留中 を参照して下さい。 |
操作後のコールバック ルーチンでの操作の保留 |
操作前コールバック ルーチンで、FltLockUserBuffer の呼び出しを行い、ユーザー バッファがワーカー スレッドでアクセスできるように適切にロックされていることを確認します。 FltAllocateGenericWorkItem と FltQueueGenericWorkItem のようなサポート ルーチンを呼び出して、作業をワーカー スレッドのキューに入れます。 操作後のコールバック ルーチンから FLT_POSTOP_MORE_PROCESSING_REQUIRED を返します。 I/O 操作をフィルター マネージャーに返す準備ができたら、FltCompletePendedPostOperation の呼び出しを行います。 Pending an I/O Operation in a Postoperation Callback Routine を参照して下さい。 |
操作を同期する |
操作前コールバック ルーチンから FLT_PREOP_SYNCHRONIZE を返します。 FLT_PREOP_SYNCHRONIZE へ戻る を参照して下さい。 |
操作前コールバック ルーチンで操作を完了する |
FLT_CALLBACK_DATA 構造体の Ioステータス メンバーに、操作の最終ステータスと情報を設定します。 操作前コールバック ルーチンから FLT_PREOP_COMPLETE を返します。 事前操作コールバックルーチンでI/Oオペレーションを完了するを参照してください。 |
操作前コールバック ルーチンで保留された後、操作を完了します。 |
FLT_CALLBACK_DATA 構造体の Ioステータス メンバーに、操作の最終ステータスと情報を設定します。 I/Oオペレーションを処理するワーカースレッドから FltCompletePendedPreOperation を呼び出し、コールバックステータス パラメータとしてFLT_PREOP_COMPLETEを渡します。 事前操作コールバックルーチンでI/Oオペレーションを完了するを参照してください。 |
すべての完了作業を完了ルーチンで実行します。 |
操作後のコールバック ルーチンから FLT_POSTOP_FINISHED_PROCESSING を返します。 操作後のコールバック ルーチンの作成 を参照して下さい。 |
安全なIRQLで完了作業を行う |
操作後のコールバック ルーチンから FltDoCompletionProcessingWhenSafe を呼び出します。 |
完了ルーチンからイベントを通知する |
この操作の操作前コールバック ルーチンから FLT_PREOP_SYNCHRONIZE を返します。 フィルター マネージャーは、IRQL <=APC_LEVELで、操作前コールバック ルーチンと同じスレッド コンテキストで操作後コールバック ルーチンを呼び出します。 FLT_PREOP_SYNCHRONIZE へ戻る を参照して下さい。 |
作成操作が成功すると失敗する |
作成操作の操作後コールバック ルーチンから FltCancelFileOpen を呼び出す。 適切なエラーNTSTATUS値をIoステータス数FLT_CALLBACK_DATA操作のための構造。 FLT_POSTOP_FINISHED_PROCESSING を返します。 |
I/O 操作の高速 I/O パスを介した I/O を禁止する |
操作の操作前コールバック ルーチンから FLT_STATUS_DISALLOW_FAST_IO を返します。 操作前コールバックルーチンでの高速I/O操作の禁止 を参照して下さい。 |
I/O操作のパラメータを変更する |
変更したパラメータ値をIopb数 FLT_CALLBACK_DATA 操作のための構造。 FLT_CALLBACK_DATA構造体の Ioステータス メンバの内容を変更した場合を除き、FltSetCallbackDataDirty を呼び出して、FLT_CALLBACK_DATA構造体をダーティとしてマークします。 I/O 操作のパラメータの変更 を参照してください。 |
操作用のユーザー バッファをロックする |
I/O 操作のためのユーザー バッファへのアクセス で説明されているテクニックとガイドラインを使用してください。 |