次の方法で共有


MmLockPagableCodeSection マクロ (wdm.h)

MmLockPagableCodeSection ルーチンは、特別なコンパイラ ディレクティブでマークされたドライバー ルーチンのセットを含むドライバー コードのセクションをシステム空間にロックします。

構文

void MmLockPagableCodeSection(
  [in]  Address
);

パラメーター

[in] Address

シンボリック アドレスを指定します。 このアドレスは、通常、#pragma alloc_text (PAGExxxx、driverfunction)などのマークが付けられたドライバー コードのセクション内のドライバー関数の名前です。 その後、PAGExxxx セクションのすべての関数は、この関数が戻ったときにロックダウンされます。

戻り値

何一つ

備考

MmLockPagableCodeSection は、オペレーティング システムがドライバー コードのこのセクションを識別するために使用する不透明な値を返します。 この不透明な値は、後で mmLockPagableSectionByHandle(ドライバーがロックを解除してからセクションを再ロックする場合) に渡すか、mmUnlockPagableImageSectionできます。

MmLockPagableCodeSection ルーチンと MmUnlockPagableImageSection (反対のアクションを実行するルーチン) は、次の操作を実行できるドライバーをサポートします。

  • ドライバーのデバイスに対する受信 I/O 要求によって、これらのルーチンが IRP を処理する必要が生じるまで、ドライバー ルーチンのサブセットを常駐メモリに読み込むのを延期します。

  • I/O 要求の処理が完了し、ドライバーのデバイスに対する追加の要求が現在想定されていない場合は、同じドライバー ルーチンのサブセットをページングに使用できるようにします。

MmLockPagableCodeSectionMmLockPagableSectionByHandle、および MmUnlockPagableImageSection は、次の特性を持つデバイスおよび中間ドライバーで使用することを目的としています。

  • ドライバーには、システムの実行中に不要なコード パスがありますが、必要な場合は、任意のスレッド コンテキストまたは IRQL >= DISPATCH_LEVELで実行されるため、ドライバーのコードが常駐している必要があります。

  • ドライバーは、ページング可能なルーチンを読み込む必要がある正確なタイミングと、再びページングできるタイミングを決定できます。

たとえば、システム提供のフォールト トレラント ディスク ドライバーは、ミラー セット、ストライプ セット、ボリューム セットの作成をサポートします。 ただし、特定のマシンはミラー セットでのみ構成でき、ストライプ セットのみ、ボリューム セットのみ、またはこれら 3 つの可能なオプションの任意の組み合わせで構成できます。 このような状況では、システム ftdisk ドライバーは、ミラー、ストライプ、ボリューム セットを明示的にサポートするルーチンをページング可能なコード セクションに属しているとマークすることで、読み込まれたイメージのサイズを小さくします。 ドライバーの初期化中、ページング可能なコード セクションは、ユーザーがミラー、ストライプ、またはボリューム セットを持つディスクを構成した場合にのみ常駐します。 ユーザーがディスクを動的に再パーティション分割すると、ftdisk ドライバーは、ユーザーが要求するミラー、ストライプ、またはボリューム セットをサポートするために必要なページング可能な追加コード セクションをロックダウンします。

他の例と同様に、システム提供のシリアル ドライバーと並列ドライバーには、DispatchCreate DispatchClose ルーチンが されています。このルーチンは、特定のポートが排他的 I/O 用に開かれている場合と、開いているポートのハンドルが解放されたときに呼び出されます。 ただし、シリアル I/O 要求と並列 I/O 要求は散発的であり、エンド ユーザーが現在実行しているアプリケーションと、エンド ユーザーが現在実行しているアプリケーション オプションによって決まります。 このような状況では、システムのシリアルドライバーと並列ドライバーは、I/O の最初のポートが開かれている場合にのみ、DispatchCreate ルーチンが常駐するページング可能なコード セクションに属している多くのルーチンをマークすることによって、読み込まれたイメージのサイズを小さくします。

上記の各システム ドライバーは、ページング可能なセクションを持つという両方の条件を満たしていることに注意してください。ドライバーには、システムの実行中に不要なコード パスがあり、ドライバーはページング可能なセクションを読み込むタイミングを正確に判断でき、再びページングできます。

セクションをロックダウンするのはコストのかかる操作であるため、ドライバーが複数の場所でページング可能なコード セクションをロックダウンする場合は、最初の要求に MmLockPagableCodeSection を使用します。 mmLockPagableSectionByHandle 呼び出して、MmLockPagableCodeSectionによって返されるハンドルを渡、後続のロック要求を行います。 メモリ マネージャーは不透明な戻り値を使用して、読み込まれたモジュールの一覧を検索するのではなく、関連するセクションをすばやく検索するため、ハンドルによるロックによってドライバーのパフォーマンスが大幅に向上します。 ロックダウン セクションは、mmUnlockPagableImageSection 呼び出すことによってロック解除されます。

ページング可能なコード セクション内の各ドライバー ルーチンは、次のコンパイラ ディレクティブでマークする必要があります。

#pragma alloc_text(PAGExxxx, DriverRoutine)

ここで、xxxx は、呼び出し元のページング可能なセクションの省略可能な 4 文字の一意識別子であり、DriverRoutine はページング可能なコード セクションに含めるエントリ ポイントです。 PAGE キーワードとドライバーによって決定されるサフィックス (最大 4 文字) は大文字と小文字が区別されます。つまり、PAGE は大文字にする必要があります。

たとえば、ドライバーの DispatchCreate ルーチン MmLockPagableCodeSection を 1 回呼び出すと、同じ PAGExxxx 識別子でマークされたすべてのドライバー ルーチンを含むセクション全体がシステム空間でロックされます。

特定の種類のドライバー ルーチンは、次のようなドライバーのページング可能なセクションの一部にすることはできません。

  • ISR をページング可能にしないでください。 特に割り込みベクトルを共有できる場合は、デバイス が使用されていない場合でも、デバイス ドライバーがスプリアス割り込みを受け取る可能性があります。 一般に、ドライバーがデバイスの割り込みを明示的に無効にできる場合でも、ISR をページングできないようにする必要があります。

  • DpcForIsr や、ISR からキューに入れられる可能性がある CustomDpc ルーチンなど、ドライバーが DPC がキューに入れられるタイミングを制御できない場合は、DPC ルーチンをページングできないようにします。 一般に、IRQL >= DISPATCH_LEVELで実行され、任意のスレッド コンテキストで呼び出したり、ランダムな外部イベントに応答して呼び出したりできるドライバー ルーチンはページングできません。

  • システムページング I/O パスの一部である可能性があるドライバーで、DispatchRead または DispatchWrite ルーチンをページング可能に しないでください。 システム ページ ファイルを含む可能性のあるディスクのドライバーには、DispatchRead と、システムの実行中に常駐する DispatchWrite ルーチン 必要があります。これは、このようなディスク ドライバーの上にすべてのドライバーを重ねて配置する必要があります。

コンパイラ ディレクティブ #pragma alloc_text(PAGExxxx, ...) でマークされたページング可能なセクションのルーチンは、コンパイラ ディレクティブ #pragma alloc_text(INIT, ...)でマークされたルーチンとは異なります。INIT セクションのルーチンはページング可能ではなく、ドライバーが DriverEntry または 再初期化 ルーチン (存在する場合) から戻るとすぐに破棄されます。

メモリ マネージャーは、ドライバーのページング可能なセクションの内部ロック数を保持します。 mmLockPagableCodeSection 呼び出 このカウントをインクリメントし、mmUnlockPagableImageSection 逆数 カウントをデクリメントします。 ドライバーのページング可能なセクションは、この数が 0 でない限り、ページアウトできません。

ページング可能なコード セクションの作成の詳細については、「ドライバーのページング可能なを作成する」を参照してください。

必要条件

要件 価値
ターゲット プラットフォーム デスクトップ
ヘッダー wdm.h (Wdm.h、Ntddk.h、Ntifs.h を含む)
ライブラリ NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <=APC_LEVEL

関連項目

mmLockPagableDataSection する

mmLockPagableSectionByHandle

mmPageEntireDriver する

mmResetDriverPaging

MmUnlockPagableImageSection