IoCancelIrp源码简析

来源:互联网 发布:.net 免费商城源码 编辑:程序博客网 时间:2024/05/19 12:41

Windows Driver中的IoCancelIrp源码如下:

相关宏定义如下:

//

// MessageId: CANCEL_STATE_IN_COMPLETED_IRP       //IRP Cancel错误标识

//

// MessageText:

//

//  CANCEL_STATE_IN_COMPLETED_IRP

//

#define CANCEL_STATE_IN_COMPLETED_IRP    ((ULONG)0x00000048L)

 

#define IOV_CANCEL_IRP(Irp, ReturnValue) \

        IovCancelIrp((Irp), (ReturnValue))

 

#define InterlockedExchangePointer(Target, Value) \

   (PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value))

 

IoCancelIrp接口代码如下:

IoCancelIrp(

    IN PIRP Irp

    ) 

/*++

 

Routine Description:

 

    This routine is invoked to cancel an individual I/O Request Packet.

    It acquires the cancel spin lock, sets the cancel flag in the IRP, and

    then invokes the cancel routine specified by the appropriate field in

    the IRP, if a routine was specified.  It is expected that the cancel

    routine will release the cancel spinlock.  If there is no cancel routine,

    then the cancel spin lock is released.

 

Arguments:

 

    Irp - Supplies a pointer to the IRP to be cancelled.

 

Return Value:

 

    The function value is TRUE if the IRP was in a cancelable state (it

    had a cancel routine), else FALSE is returned.

 

Notes:

 

    It is assumed that the caller has taken the necessary action to ensure

    that the packet cannot be fully completed before invoking this routine.

 

--*/

 

{

    PDRIVER_CANCEL cancelRoutine;

    KIRQL irql;

    BOOLEAN returnValue;

 

    ASSERT( Irp->Type == IO_TYPE_IRP );         //确保IRP是IO类型

 

    if (IopVerifierOn) {

        if (IOV_CANCEL_IRP(Irp, &returnValue)) {

            return returnValue;

        }

    }

 

    //

    // Acquire the cancel spin lock. 

    // 

    IoAcquireCancelSpinLock( &irql );

 

    //

    // Set the cancel flag in the IRP. 设置Cancel标志

    //

    Irp->Cancel = TRUE;

 

    //

    // Obtain the address of the cancel routine, and if one was specified,

    // invoke it.

    // 

    cancelRoutine = (PDRIVER_CANCEL) (ULONG_PTR) InterlockedExchangePointer( (PVOID *) &Irp->CancelRoutine, NULL ); 

    if (cancelRoutine) {

        if (Irp->CurrentLocation > (CCHAR) (Irp->StackCount + 1)) {

            KeBugCheckEx( CANCEL_STATE_IN_COMPLETED_IRP, (ULONG_PTR) Irp, (ULONG_PTR) cancelRoutine, 0, 0 );     //蓝屏提示0x00000048L

        }

        Irp->CancelIrql = irql;

 

        // cancelRoutine回调,内部释放自旋锁

        cancelRoutine( Irp->Tail.Overlay.CurrentStackLocation->DeviceObject, Irp );       // CancelIRP的具体操作接口


        //

        // The cancel spinlock should have been released by the cancel routine.

        //

        return(TRUE);

 

    } 

    else 

   {

        //

        // There was no cancel routine, so release the cancel spinlock and

        // return indicating the Irp was not currently cancelable.

        //

         IoReleaseCancelSpinLock( irql );

 

        return(FALSE);

    }

}

 

交换指针的操作:

LONG

FASTCALL

InterlockedExchange(

    IN OUT LONG volatile *Target,

    IN LONG Value

    )

{

    __asm {

        mov     eax, Value    

        mov     ecx, Target

        xchg    [ecx], eax

    }

}

0 0
原创粉丝点击