タイマー オブジェクトの使用
次の図は、通知タイマーを使用して操作のタイムアウト間隔を設定し、他のドライバー ルーチンが I/O 要求を処理するまで待機する方法を示しています。
前の図に示すように、ドライバーはタイマー オブジェクトの記憶域を提供する必要があります。これは、この記憶域へのポインターを持つ KeInitializeTimer の呼び出しによって初期化する必要があります。 ドライバーは通常、 AddDevice ルーチンからこの呼び出しを行います。
ドライバーが作成したスレッドや同期 I/O 操作を要求するスレッドなど、特定のスレッドのコンテキスト内で、ドライバーは前の図に示すようにタイマー オブジェクトを待機できます。
スレッドは KeSetTimer をタイマー オブジェクトへのポインターと、指定された DueTime 値を100 ナノ秒単位で表して呼び出します。 DueTime の正の値は、タイマー オブジェクトをカーネルのタイマー キューから削除し、Signaled 状態に設定する絶対時刻を指定します。 DueTime の負の値は、現在のシステム時刻を基準とした間隔を指定します。
スレッド (またはシステム・スレッドで実行されているドライバー・ルーチン) は、DPC オブジェクトに NULL ポインター を渡します ( 前述のとおり、 CustomTimerDpc ルーチンに タイマーオブジェクトと DPC オブジェクトを使用する方法を示す図)、 KeSetTimer を呼び出すときに、 CustomTimerDpc ルーチンをキューに入れる代わりにタイマー オブジェクトで待機することに注意してください。
スレッドは、タイマー オブジェクトへのポインターを使用して KeWaitForSingleObject を呼び出します。これにより、タイマー オブジェクトがカーネルのタイマー キューにある間、スレッドは待機状態になります。
指定された DueTime の有効期限が切れます。
カーネルはタイマー オブジェクトをデキューし、それを Signaled 状態に設定し、スレッドの状態を待機状態から準備完了に変更します。
カーネルは、優先順位の高いスレッドが待機状態になく、より高い IRQL で実行すべきカーネルモードルーチンが存在しない場合にのみ、プロセッサが使用可能になるとすぐに実行のためにスレッドをディスパッチします。
IRQL >= DISPATCH_LEVEL で実行されるドライバー ルーチンは、関連付けられた DPC オブジェクトを持つタイマー オブジェクトを使用して、ドライバー指定の CustomTimerDpc ルーチンをキューに登録することで、要求をタイムアウトできます。 前の図に示すように、タイマー オブジェクトで 0 以外の間隔を待機できるのは、非ビット スレッド コンテキスト内で実行されるドライバー ルーチンだけです。
他のすべてのスレッドと同様に、ドライバーによって作成されたスレッドは、ディスパッチャー オブジェクトでもあるカーネル スレッド オブジェクトによって表されます。 したがって、ドライバーは、ドライバーが作成したスレッドがタイマー オブジェクトを使用して、指定された間隔で自発的に待機状態に入る必要はありません。 代わりに、スレッドは呼び出し元が指定した間隔で KeDelayExecutionThread を呼び出すことができます。 この手法の詳細については、「 デバイスのポーリング」を参照してください。
DriverEntry, Reinitializeと Unload ルーチンもシステム スレッド コンテキストで実行されるため、ドライバーは初期化中またはアンロード中に、ドライバー初期化タイマー オブジェクトまたは KeWaitForSingleObject を使用して KeDelayExecutionThread を呼び出すことができます。 デバイス ドライバーは、初期化中にデバイスが状態を更新するまで待機する必要がある場合、非常に短い間隔 (できれば 50 マイクロ秒未満) の KeStallExecutionProcessor を呼び出すことができます。
ただし、上位レベルのドライバーは、通常、タイマー オブジェクトを使用する代わりに、 DriverEntry および 再初期化 ルーチンで別の同期メカニズムを使用します。 上位レベルのドライバーは、常に、特定の種類または種類のデバイスの下位レベルのドライバーの上にレイヤーを重ねるように設計されるべきです。 そのため、上位レベルのドライバーは、タイマー オブジェクトを待機するか、 KeDelayExecutionThread を呼び出す合、読み込みに時間がかかる傾向があります。このようなドライバーは、ドライバーをサポートする最も遅いデバイスに対応するのに十分な長い間隔を待機する必要があるためです。 また、このような待機の「安全な」最小間隔は判断が非常に困難であることにも注意してください。
同様に、PnP ドライバーは、他のアクションが発生するのを待つ必要はありませんが、代わりに PnP マネージャーの 通知 メカニズムを使用する必要があります。