Пример #1
0
static
VOID
NTAPI
IopCsqCancelRoutine(
    _Inout_ PDEVICE_OBJECT DeviceObject,
    _Inout_ _IRQL_uses_cancel_ PIRP Irp)
{
    PIO_CSQ Csq;
    KIRQL Irql;

    /* First things first: */
    IoReleaseCancelSpinLock(Irp->CancelIrql);

    /* We could either get a context or just a csq */
    Csq = (PIO_CSQ)Irp->Tail.Overlay.DriverContext[3];

    if(Csq->Type == IO_TYPE_CSQ_IRP_CONTEXT)
    {
        PIO_CSQ_IRP_CONTEXT Context = (PIO_CSQ_IRP_CONTEXT)Csq;
        Csq = Context->Csq;

        /* clean up context while we're here */
        Context->Irp = NULL;
    }

    /* Now that we have our CSQ, complete the IRP */
    Csq->CsqAcquireLock(Csq, &Irql);
    Csq->CsqRemoveIrp(Csq, Irp);
    Csq->CsqReleaseLock(Csq, Irql);

    Csq->CsqCompleteCanceledIrp(Csq, Irp);
}
Пример #2
0
VOID
IopCsqCancelRoutine(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
/*++

Routine Description:

    This routine removes the IRP that's associated with a context from the queue.
    It's expected that this routine will be called from a timer or DPC or other threads which complete an
    IO. Note that the IRP associated with this context could already have been freed.

Arguments:

    Csq - Pointer to the cancel queue.
    Context - Context associated with Irp.


Return Value:

    Returns the IRP associated with the context. If the value is not NULL, the IRP was successfully
    retrieved and can be used safely. If the value is NULL, the IRP was already canceled.

--*/
{
    KIRQL   irql;
    PIO_CSQ_IRP_CONTEXT irpContext;
    PIO_CSQ cfq;

    UNREFERENCED_PARAMETER (DeviceObject);

    IoReleaseCancelSpinLock(Irp->CancelIrql);

    irpContext = Irp->Tail.Overlay.DriverContext[3];

    if (irpContext->Type == IO_TYPE_CSQ_IRP_CONTEXT) {
        cfq = irpContext->Csq;
    } else if ((irpContext->Type == IO_TYPE_CSQ) ||
                (irpContext->Type == IO_TYPE_CSQ_EX)) {
        cfq = (PIO_CSQ)irpContext;
    } else {

        //
        // Bad type
        //

        ASSERT(0);
        return;
    }

    ASSERT(cfq);

    cfq->ReservePointer = NULL; // Force drivers to be good citizens

    cfq->CsqAcquireLock(cfq, &irql);
    cfq->CsqRemoveIrp(cfq, Irp);


    //
    // Break the association if necessary.
    //

    if (irpContext != (PIO_CSQ_IRP_CONTEXT)cfq) {
        irpContext->Irp = NULL;

        Irp->Tail.Overlay.DriverContext[3] = NULL;
    }
    cfq->CsqReleaseLock(cfq, irql);

    cfq->CsqCompleteCanceledIrp(cfq, Irp);
}