IoSetCompletionRoutine 関数 (wdm.h)
IoSetCompletionRoutine ルーチンは IoCompletion ルーチンを登録します。これは、次の下位レベルのドライバーが特定の IRP に対して要求された操作を完了したときに呼び出されます。
構文
void IoSetCompletionRoutine(
[in] PIRP Irp,
[in, optional] PIO_COMPLETION_ROUTINE CompletionRoutine,
[in, optional] __drv_aliasesMem PVOID Context,
[in] BOOLEAN InvokeOnSuccess,
[in] BOOLEAN InvokeOnError,
[in] BOOLEAN InvokeOnCancel
);
パラメーター
[in] Irp
ドライバーが処理している IRP へのポインター。
[in, optional] CompletionRoutine
ドライバー提供の IoCompletion ルーチンのエントリ ポイントを指定します。これは、次の下位ドライバーがパケットを完了したときに呼び出されます。
[in, optional] Context
IoCompletion ルーチンに渡すドライバーによって決定されたコンテキストへのポインター。 IoCompletion ルーチンは IRQL <= DISPATCH_LEVEL で呼び出されるため、コンテキスト情報は非ページ メモリに格納する必要があります。
[in] InvokeOnSuccess
NT_SUCCESS マクロの結果に基づいて、IRP のIO_STATUS_BLOCK構造体の成功状態値で IRP が完了した場合に完了ルーチンを呼び出すかどうかを指定します (「NTSTATUS 値の使用」を参照)。
[in] InvokeOnError
IRP が IRP の IO_STATUS_BLOCK 構造体で非success 状態値で完了した場合に、完了ルーチンを呼び出すかどうかを指定します。
[in] InvokeOnCancel
ドライバーまたはカーネルが IoCancelIrp を呼び出して IRP を取り消した場合に、完了ルーチンを呼び出すかどうかを指定します。
戻り値
なし
解説
完了ルーチンが終了する前にアンロードされないことを保証できるドライバーのみが 、IoSetCompletionRoutine を使用できます。 それ以外の場合、ドライバーは IoSetCompletionRoutineEx を使用する必要があります。これにより、ドライバーは完了ルーチンが実行されるまでアンロードできなくなります。
このルーチンは、指定された IRP の IoCompletion ルーチンの転送アドレスを設定します。 階層化されたドライバーのチェーン内の最下位レベルのドライバーは、このルーチンを呼び出すことができません。
IoSetCompletionRoutine は、次の下位レベルのドライバーが次のいずれかの方法またはすべての方法で要求された操作を完了したときに呼び出される指定されたルーチンを登録します。
成功状態の値を使用する
nonsuccess 状態値を使用する
IRP を取り消す
通常、I/O 状態ブロックは、基になるデバイス ドライバーによって設定されます。 これは読み取られますが、上位レベルのドライバーの IoCompletion ルーチンでは変更されません。
IoAllocateIrp または IoBuildAsynchronousFsdRequest を使用して IRP を割り当てる上位レベルのドライバーは、ドライバー割り当て IRP を IoCallDriver に渡す前に、すべての InvokeOnXxx パラメーターを TRUE に設定してこのルーチンを呼び出す必要があります。 このような IRP を使用して IoCompletion ルーチンを呼び出す場合は、ドライバーによって割り当てられた IRP と、ドライバーが要求用に設定したその他のリソース ( IoBuildPartialMdl を使用した MDLs など) を解放する必要があります。 このようなドライバーは、 IoFreeIrp を呼び出して、ドライバー割り当て IRP の I/O マネージャーの完了処理をすべてフォレスト化するときに、STATUS_MORE_PROCESSING_REQUIREDを返す必要があります。
IoCompletion ルーチンを実行する前にアンロードされる可能性がある PnP 以外のドライバーでは、代わりに IoSetCompletionRoutineEx を使用する必要があります。