irp cancelation boiler plate, for irp queues you manage yourself
Added: trunk/reactos/doc/irp cancel boilerplate.c

Added: trunk/reactos/doc/irp cancel boilerplate.c
--- trunk/reactos/doc/irp cancel boilerplate.c	2005-03-06 12:37:31 UTC (rev 13851)
+++ trunk/reactos/doc/irp cancel boilerplate.c	2005-03-06 13:41:18 UTC (rev 13852)
@@ -0,0 +1,102 @@
+
+
+/*
+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),
+      // but we got to remove the cancel routine before the canceler could, 
+      // so complete 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);
+   } 
+ 
+ 
+   /*
+   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);
+ 
+}
+
+
+
+
+ 
\ No newline at end of file