PIRP
      
      
       KeyboardClassDequeueRead(
      
      
           
       _In_ PCHAR DeviceExtension
      
      
       )
      
      
       /
       *
       +
       +
      
      
        
      
      
       Routine Description:
      
      
           
       Dequeues the 
       next 
       available read irp regardless of FileObject
      
      
        
      
      
       Assumptions:
      
      
           
       DeviceExtension
       -
       >SpinLock 
       is 
       already held (so no further sync 
       is 
       required).
      
      
        
      
      
         
       -
       -
       *
       /
      
      
       {
      
      
           
       ASSERT(NULL !
       = 
       DeviceExtension);
      
      
        
      
      
           
       PIRP nextIrp 
       = 
       NULL;
      
      
        
      
      
           
       LIST_ENTRY
       * 
       ReadQueue 
       = 
       (LIST_ENTRY
       *
       )(DeviceExtension 
       + 
       READ_QUEUE_OFFSET_DE);
      
      
        
      
      
           
       while 
       (!nextIrp && !IsListEmpty(ReadQueue)) {
      
      
               
       PDRIVER_CANCEL oldCancelRoutine;
      
      
               
       PLIST_ENTRY listEntry 
       = 
       RemoveHeadList(ReadQueue);
      
      
        
      
      
               
       /
       /
      
      
               
       /
       / 
       Get the 
       next 
       IRP off the queue 
       and 
       clear the cancel routine
      
      
               
       /
       /
      
      
               
       nextIrp 
       = 
       CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry);
      
      
               
       oldCancelRoutine 
       = 
       IoSetCancelRoutine(nextIrp, NULL);
      
      
        
      
      
               
       /
       /
      
      
               
       /
       / 
       IoCancelIrp() could have just been called on this IRP.
      
      
               
       /
       / 
       What we're interested 
       in 
       is 
       not 
       whether IoCancelIrp() was called
      
      
               
       /
       / 
       (ie, nextIrp
       -
       >Cancel 
       is 
       set
       ), but whether IoCancelIrp() called (
       or
      
      
               
       /
       / 
       is 
       about to call) our cancel routine. To check that, check the result
      
      
               
       /
       / 
       of the test
       -
       and
       -
       set 
       macro IoSetCancelRoutine.
      
      
               
       /
       /
      
      
               
       if 
       (oldCancelRoutine) {
      
      
                   
       /
       /
      
      
                       
       /
       /  
       Cancel routine 
       not 
       called 
       for 
       this IRP.  Return this IRP.
      
      
                   
       /
       /
      
      
                   
       /
       *
       ASSERT(oldCancelRoutine 
       =
       = 
       KeyboardClassCancel);
       *
       /
      
      
               
       }
      
      
               
       else 
       {
      
      
                   
       /
       /
      
      
                       
       /
       / 
       This IRP was just cancelled 
       and 
       the cancel routine was (
       or 
       will
      
      
                   
       /
       / 
       be) called. The cancel routine will complete this IRP as soon as
      
      
                   
       /
       / 
       we drop the spinlock. So don't do anything with the IRP.
      
      
                   
       /
       /
      
      
                       
       /
       / 
       Also, the cancel routine will 
       try 
       to dequeue the IRP, so make the
      
      
                   
       /
       / 
       IRP's listEntry point to itself.
      
      
                   
       /
       /
      
      
                   
       /
       /
       ASSERT(nextIrp
       -
       >Cancel);
      
      
                   
       InitializeListHead(&nextIrp
       -
       >Tail.Overlay.ListEntry);
      
      
                   
       nextIrp 
       = 
       NULL;
      
      
               
       }
      
      
           
       }
      
      
        
      
      
           
       return 
       nextIrp;
      
      
       }