次の方法で共有


IRP を処理するドライバー ルーチン内でのキャンセルの同期

取り消し可能な状態で保持されている IRP でデキューまたは呼び出されるドライバー ルーチン (ドライバーの StartIo ルーチンを含む) は、次の操作を行う必要があります。

  1. IoAcquireCancelSpinLock を呼び出します。

  2. IrpDeviceObject->CurrentIrp と等しいことを確認します。 そうでない場合は、IoReleaseCancelSpinLock を呼び出して制御を返します。

    2 つが同じでない場合、IoStartPacket がキャンセル スピン ロックを解放してから、このルーチンがこれを取得するまでの間に、CurrentIrp が取り消された可能性があります。

  3. 取り消し可能な状態から IRP を削除するには、NULL CancelRoutine ポインターIoSetCancelRoutine を呼び出します。

  4. IRP を取り消すか、I/O 要求の処理を開始するかどうかを決定する Irp->Cancel フィールドを確認します。

    Irp->CancelTRUE に設定されている場合は、次の操作を行います。

    • IoReleaseCancelSpinLockを呼び出します。

    • Irp->IoStatus.Status を STATUS_CANCELLED に設定します。

    • Irp->IoStatus.Information を 0 に設定します。

    • IoStartNextPacket (StartIo ルーチン内) を呼び出して、次のパケットを開始します。

    • IRP を完了するには、IO_NO_INCREMENT の priority boost を使用して IoCompleteRequest を呼び出します。

    Irp->CancelFALSE に設定されている場合は、IoReleaseCancelSpinLock を呼び出し、I/O 要求の処理を開始するか、必要に応じて次の下位ドライバーに IRP を渡します。

I/O マネージャーによるデバイス キューを使用せず、専用の IRP キューを管理するドライバーは、IoSetCancelRoutine を呼び出すときにキャンセル スピン ロックを取得する必要はありません。 ただし、これらのドライバーは、Cancel ルーチンが既に開始されているかどうかを判断するために IoSetCancelRoutine が返す Cancel ルーチン ポインターを確認する必要があります。

取り消し可能な IRP を処理するドライバーでは、要求された I/O 操作の基になるデバイスがプログラムされる前に IRP を処理するすべてのドライバー ルーチンは、すべての受信 IRP のキャンセル可能な状態を確認する必要があります。 具体的には、StartIo ルーチンと ControllerControl ルーチンの両方を備えた最上位のデバイス ドライバーは、既に説明したように、これらのドライバー ルーチンの両方で受信 IRP を処理する必要があります。