

/*
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);
 
}
