mirror of
https://github.com/reactos/reactos.git
synced 2024-12-11 12:23:31 +08:00
104 lines
2.1 KiB
C
104 lines
2.1 KiB
C
|
|
|
|
/*
|
|
Boiler plate for irp cancelation, for irp queues you manage yourself
|
|
-Gunnar
|
|
*/
|
|
|
|
|
|
|
|
CancelRoutine(
|
|
DEV_OBJ Dev,
|
|
Irp
|
|
)
|
|
{
|
|
//don't need this since we have our own sync. protecting irp cancellation
|
|
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
|
|
|
theLock = Irp->Tail.Overlay.DriverContext[3];
|
|
|
|
Lock(theLock);
|
|
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
|
Unlock(theLock);
|
|
|
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
}
|
|
|
|
|
|
QUEUE_BOLIERPLATE
|
|
{
|
|
Lock(theLock);
|
|
|
|
Irp->Tail.Overlay.DriverContext[3] = &theLock;
|
|
|
|
IoSetCancelRoutine(Irp, CancelRoutine);
|
|
if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
|
{
|
|
/*
|
|
Irp has already been cancelled (before we got to queue it),
|
|
and we got to remove the cancel routine before the canceler could,
|
|
so we cancel/complete the irp ourself.
|
|
*/
|
|
|
|
Unlock(theLock);
|
|
|
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//else were ok
|
|
|
|
|
|
Irp->IoStatus.Status = STATUS_PENDING;
|
|
IoMarkIrpPending(Irp);
|
|
|
|
InsertTailList(Queue);
|
|
|
|
Unlock(theLock);
|
|
|
|
}
|
|
|
|
|
|
DEQUEUE_BOILERPLATE
|
|
{
|
|
Lock(theLock);
|
|
|
|
Irp = RemoveHeadList(Queue);
|
|
|
|
if (!IoSetCancelRoutine(Irp, NULL))
|
|
{
|
|
/*
|
|
Cancel routine WILL be called after we release the spinlock. It will try to remove
|
|
the irp from the list and cancel/complete this irp. Since we allready removed it,
|
|
make its ListEntry point to itself.
|
|
*/
|
|
|
|
InitializeListHead(&Irp->Tail.Overlay.ListEntry);
|
|
|
|
Unlock(theLock);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
Cancel routine will NOT be called, canceled or not.
|
|
The Irp might have been canceled (Irp->Cancel flag set) but we don't care,
|
|
since we are to complete this Irp now anyways.
|
|
*/
|
|
|
|
Unlock(theLock);
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
}
|