KeRemoveQueueEx

NTSTATUS __fastcall KeRemoveQueueEx(UINT64 a1, INT8 a2, INT8 a3, INT64 a4, INT64 *EntryArray, UINT64 Count){
  _ETHREAD *CurrentThread; 
  UINT64 v7; 
  __int64 v9; 
  unsigned __int8 CurrentIrql; 
  NTSTATUS v12; 
  _DISPATCHER_HEADER *volatile Queue; 
  char v14; 
  struct _KPRCB *v15; 
  $BA6907B96C27CBFB414D9A454222AF19 *v16; 
  INT64 v17; 
  _DISPATCHER_HEADER *v18; 
  int v19; 
  unsigned __int64 v20; 
  _LIST_ENTRY *v21; 
  _LIST_ENTRY *v22; 
  INT64 v23; 
  unsigned int v25; 
  __int64 *v26; 
  __int64 **v27; 
  __int64 v28; 
  __int64 v29; 
  __int64 **v30; 
  struct _KPRCB *CurrentPrcb; 
  unsigned __int64 WaitIrql; 
  _ETHREAD *v33; 
  NTSTATUS v34; 
  INT64 v35; 
  struct _KPRCB *v36; 
  unsigned __int64 v37; 
  _ETHREAD *v38; 
  __int64 ThreadTimerDelay; 
  unsigned __int64 v40; 
  struct _KPRCB *v41; 
  unsigned __int8 v42; 
  INT64 v43; 
  struct _KPRCB *v44; 
  _ETHREAD *NextThread; 
  char v46; 
  _DWORD *v47; 
  INT64 v48; 
  struct _KPRCB *v49; 
  _ETHREAD *v50; 
  char v51; 
  _DWORD *SchedulerAssist; 
  struct _KPRCB *v53; 
  _DWORD *v55; 
  int v56; 
  _DWORD *v57; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *Blink; 
  PVOID BugCheckParameter4; 
  INT64 v61; 
  INT64 v62; 
  UINT64 SpinCount; 
  UINT64 v64; 
  __int64 i; 
  __int64 v66; 
  _KDUE_TIME_TYPE TimeoutType; 

  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v7 = 0i64;
  v9 = a2;
  v66 = 0i64;
  if( !_bittestandreset((signed __int32 *)&CurrentThread->Tcb.116, 2u) )
  {
    CurrentIrql = KeGetCurrentIrql();
    __writecr8(2ui64);
    CurrentThread->Tcb.WaitIrql = CurrentIrql;
  }
  v12 = 1;
  if( a4 )
  {
    if( *(int *)(a4 + 4) < 0 )
    {
      TimeoutType = DueTimeRelative;
      v7 = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart
         - KUSER_SHARED_DATA.InterruptTimeBias
         - (*(_QWORD *)a4
          + CurrentThread->Tcb.RelativeTimerBias);
    }
    else
    {
      v7 = *(_QWORD *)a4;
      TimeoutType = DueTimeAbsolute;
    }
  }
  else
  {
    TimeoutType = DueTimeNone;
  }
  Queue = CurrentThread->Tcb.Queue;
  if( Queue == (_DISPATCHER_HEADER *volatile)a1 )
  {
    if( *(_DWORD *)(a1 + 4) )
    {
      v25 = *(_DWORD *)(a1 + 40);
      if( v25 <= *(_DWORD *)(a1 + 44) )
      {
        LODWORD(v62) = 0;
        while( _interlockedbittestandset((volatile signed __int32 *)a1, 7u) )
        {
          do
            KeYieldProcessorEx((UINT64 *)&v62);
          while( (*(_DWORD *)a1 & 0x80u) != 0 );
        }
        if( *(_DWORD *)(a1 + 4) && *(_DWORD *)(a1 + 40) <= *(_DWORD *)(a1 + 44) )
        {
          v26 = *(__int64 **)(a1 + 24);
          v27 = (__int64 **)(a1 + 24);
          v28 = 0i64;
          do
          {
            --*(_DWORD *)(a1 + 4);
            v29 = *v26;
            if( !*v26 )
              KeBugCheckEx(0x96u, v26, (PVOID)a1, *(&WheapDeferredInternalLogsEventLock + 337), (PVOID)v26[2]);
            v30 = (__int64 **)v26[1];
            if( *(__int64 **)(v29 + 8) != v26 || *v30 != v26 )
              goto LABEL_160;
            *v30 = (__int64 *)v29;
            *(_QWORD *)(v29 + 8) = v30;
            *v26 = 0i64;
            EntryArray[v28] = (INT64)v26;
            v28 = (unsigned int)(v28 + 1);
            v26 = *v27;
          }
          while( *v27 != (__int64 *)v27 && (unsigned int)v28 < (unsigned int)Count );
          if( (_DWORD)v28 )
          {
            _InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
            CurrentPrcb = KeGetCurrentPrcb();
            WaitIrql = CurrentThread->Tcb.WaitIrql;
            if( (unsigned __int8)WaitIrql >= 2u )
            {
              if( CurrentPrcb->NextThread && !CurrentPrcb->DpcRoutineActive )
                KiRequestSoftwareInterrupt(CurrentPrcb, 2);
              return v28;
            }
            v33 = CurrentPrcb->CurrentThread;
            if( CurrentPrcb->NextThread )
            {
              KiAbProcessContextSwitch(&CurrentPrcb->CurrentThread->Tcb, 0i64);
              v44 = KeGetCurrentPrcb();
              HIDWORD(v62) = 0;
              while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
              {
                do
                  KeYieldProcessorEx((UINT64 *)((char *)&v62 + 4));
                while( CurrentPrcb->PrcbLock );
                SchedulerAssist = v44->SchedulerAssist;
                if( SchedulerAssist && v44->NestingLevel <= 1u )
                  ++SchedulerAssist[6];
              }
              NextThread = CurrentPrcb->NextThread;
              CurrentPrcb->NextThread = 0i64;
              _disable();
              KiEndThreadCycleAccumulation(
                (INT64)CurrentPrcb,
                (INT64)v33,
                0i64,
                v43,
                (INT64)BugCheckParameter4,
                v61,
                v62);
              _enable();
              CurrentPrcb->CurrentThread = NextThread;
              if( NextThread->Tcb.WaitBlockFill6[68] == 1 )
                NextThread->Tcb.ReadyTime = NextThread->Tcb.ReadyTime
                                          - NextThread->Tcb.WaitBlock[2].SpareLong
                                          + KUSER_SHARED_DATA.TickCount.LowPart;
              NextThread->Tcb.WaitBlockFill6[68] = 2;
              v33->Tcb.WaitReason = 32;
              v33->Tcb.WaitIrql = WaitIrql;
              KiQueueReadyThread(CurrentPrcb, &v33->Tcb);
              KiSwapContext();
              if( !v46 )
                goto LABEL_51;
            }
            else if( (v33->Tcb._bf_0 & 0x40) == 0 )
            {
LABEL_51:
              __writecr8(WaitIrql);
              return v28;
            }
            __writecr8(1ui64);
            v33->Tcb._bf_0 &= ~0x40u;
            KiDeliverApc(0, 0i64, 0i64);
            goto LABEL_51;
          }
        }
        _InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
        goto LABEL_9;
      }
    }
    if( a4 && !*(_QWORD *)a4 )
    {
      if( (*(_BYTE *)(a1 + 1) & 1) != 0 )
      {
        *EntryArray = 128i64;
      }
      else
      {
        if( a3 )
        {
          v53 = KeGetCurrentPrcb();
          LODWORD(SpinCount) = 0;
          while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentThread->Tcb.ThreadLock, 0i64) )
          {
            do
              KeYieldProcessorEx(&SpinCount);
            while( CurrentThread->Tcb.ThreadLock );
            v55 = v53->SchedulerAssist;
            if( v55 && v53->NestingLevel <= 1u )
            {
              v56 = v55[6] + 1;
              v55[6] = v56;
            }
          }
        }
        v34 = KiTestForAlertPending(&CurrentThread->Tcb, a3, v9, 1ui64);
        v35 = v34;
        if( !v34 )
          v35 = 258i64;
        *EntryArray = v35;
        if( a3 )
          KiReleaseThreadLockSafe((INT64)CurrentThread);
      }
      v36 = KeGetCurrentPrcb();
      v37 = CurrentThread->Tcb.WaitIrql;
      if( (unsigned __int8)v37 >= 2u )
      {
        if( v36->NextThread && !v36->DpcRoutineActive )
          KiRequestSoftwareInterrupt(v36, 2);
        return v12;
      }
      v38 = v36->CurrentThread;
      if( v36->NextThread )
      {
        KiAbProcessContextSwitch(&v36->CurrentThread->Tcb, 0i64);
        v49 = KeGetCurrentPrcb();
        HIDWORD(SpinCount) = 0;
        while( _interlockedbittestandset64((volatile signed __int32 *)&v36->PrcbLock, 0i64) )
        {
          do
            KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
          while( v36->PrcbLock );
          v57 = v49->SchedulerAssist;
          if( v57 && v49->NestingLevel <= 1u )
            ++v57[6];
        }
        v50 = v36->NextThread;
        v36->NextThread = 0i64;
        _disable();
        KiEndThreadCycleAccumulation((INT64)v36, (INT64)v38, 0i64, v48, (INT64)BugCheckParameter4, v61, v62);
        _enable();
        v36->CurrentThread = v50;
        if( v50->Tcb.WaitBlockFill6[68] == 1 )
          v50->Tcb.ReadyTime = v50->Tcb.ReadyTime
                             - v50->Tcb.WaitBlock[2].SpareLong
                             + KUSER_SHARED_DATA.TickCount.LowPart;
        v50->Tcb.WaitBlockFill6[68] = 2;
        v38->Tcb.WaitReason = 32;
        v38->Tcb.WaitIrql = v37;
        KiQueueReadyThread(v36, &v38->Tcb);
        KiSwapContext();
        if( !v51 )
          goto LABEL_64;
      }
      else if( (v38->Tcb._bf_0 & 0x40) == 0 )
      {
LABEL_64:
        __writecr8(v37);
        return v12;
      }
      __writecr8(1ui64);
      v38->Tcb._bf_0 &= ~0x40u;
      KiDeliverApc(0, 0i64, 0i64);
      goto LABEL_64;
    }
  }
LABEL_9:
  for( i = CurrentThread->Tcb.WaitIrql; ; CurrentThread->Tcb.WaitIrql = i )
  {
    v14 = i;
    while( 1 )
    {
      CurrentThread->Tcb._bf_0 &= ~0x10u;
      CurrentThread->Tcb.WaitRegister.Flags = 0;
      CurrentThread->Tcb.WaitMode = v9;
      if( a3 )
        CurrentThread->Tcb._bf_0 |= 0x10u;
      v15 = KeGetCurrentPrcb();
      LODWORD(v64) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentThread->Tcb.ThreadLock, 0i64) )
      {
        do
          KeYieldProcessorEx(&v64);
        while( CurrentThread->Tcb.ThreadLock );
        v47 = v15->SchedulerAssist;
        if( v47 && v15->NestingLevel <= 1u )
          ++v47[6];
      }
      if( !CurrentThread->Tcb.ApcState.KernelApcPending || CurrentThread->Tcb.SpecialApcDisable || v14 )
        break;
      KiReleaseThreadLockSafe((INT64)CurrentThread);
      __writecr8(1ui64);
      KiDeliverApc(0, 0i64, 0i64);
      KeGetCurrentIrql();
      __writecr8(2ui64);
      CurrentThread->Tcb.WaitIrql = 0;
    }
    v16 = &CurrentThread->Tcb.320;
    if( !a3 )
    {
      if( (CurrentThread->Tcb.ApcState.UserApcPendingAll & 2) == 0 || !(_BYTE)v9 )
      {
LABEL_21:
        CurrentThread->Tcb.WaitBlockFill6[68] = 5;
        CurrentThread->Tcb.WaitReason = 15;
        CurrentThread->Tcb.WaitBlock[2].SpareLong = KUSER_SHARED_DATA.TickCount.LowPart;
        CurrentThread->Tcb.ThreadLock = 0i64;
        v17 = 0i64;
        goto LABEL_22;
      }
      goto LABEL_91;
    }
    if( CurrentThread->Tcb.Alerted[v9] )
    {
      CurrentThread->Tcb.Alerted[v9] = 0;
      v17 = 257i64;
      goto LABEL_92;
    }
    if( (_BYTE)v9
      && (unsigned __int8 *)CurrentThread->Tcb.ApcState.ApcListHead[1].Flink != &CurrentThread->Tcb.ApcStateFill[16] )
    {
      CurrentThread->Tcb.ApcState.UserApcPendingAll |= 2u;
LABEL_91:
      v17 = 192i64;
      goto LABEL_92;
    }
    if( !CurrentThread->Tcb.Alerted[0] )
      goto LABEL_21;
    CurrentThread->Tcb.Alerted[0] = 0;
    v17 = 257i64;
LABEL_92:
    KiReleaseThreadLockSafe((INT64)CurrentThread);
    KiCheckForThreadDispatch(KeGetCurrentPrcb(), i);
LABEL_22:
    if( v17 )
    {
      *EntryArray = v17;
      return v12;
    }
    v18 = CurrentThread->Tcb.Queue;
    if( (_DISPATCHER_HEADER *)a1 != v18 )
      KiSwitchQueue(&CurrentThread->Tcb, (_KQUEUE *)a1, v18);
    CurrentThread->Tcb.WaitBlock[0].WaitType = 3;
    CurrentThread->Tcb.WaitBlockFill4[17] = 4;
    v19 = 0;
    CurrentThread->Tcb.WaitBlock[0].WaitKey = 128;
    CurrentThread->Tcb.WaitBlock[0].Object = (void *)a1;
    while( _interlockedbittestandset((volatile signed __int32 *)a1, 7u) )
    {
      do
      {
        ++v19;
        _mm_pause();
      }
      while( (*(_DWORD *)a1 & 0x80u) != 0 );
    }
    if( *(_DWORD *)(a1 + 4) )
    {
      if( *(_DWORD *)(a1 + 40) <= *(_DWORD *)(a1 + 44) )
      {
        LODWORD(v28) = (unsigned int)KiAttemptFastRemoveQueue(
                                       (_KQUEUE *)a1,
                                       (_LIST_ENTRY **)EntryArray,
                                       (unsigned int)Count);
        if( (_DWORD)v28 )
        {
          _InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
          goto LABEL_85;
        }
      }
    }
    if( (*(_BYTE *)(a1 + 1) & 1) != 0 )
      break;
    v20 = v7;
    if( TimeoutType == DueTimeRelative )
    {
      ThreadTimerDelay = CurrentThread->Tcb.ThreadTimerDelay;
      v40 = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart
          - CurrentThread->Tcb.RelativeTimerBias
          - KUSER_SHARED_DATA.InterruptTimeBias;
      v20 = v7;
      if( CurrentThread->Tcb.WaitMode
        && !CurrentThread->Tcb.WaitBlock[3].SpareLong
        && !CurrentThread->Tcb.WaitIrql
        && !CurrentThread->Tcb.ApcState.InProgressFlags
        && (_DWORD)ThreadTimerDelay )
      {
        v20 = ThreadTimerDelay + v7;
      }
    }
    else
    {
      if( TimeoutType == DueTimeNone )
        goto LABEL_30;
      if( !v7 )
      {
LABEL_106:
        _InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
        *EntryArray = 258i64;
        goto LABEL_107;
      }
      v40 = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
    }
    if( v40 > v20 )
      goto LABEL_106;
LABEL_30:
    _InterlockedDecrement((volatile signed __int32 *)(a1 + 40));
    v21 = (_LIST_ENTRY *)(a1 + 8);
    v22 = *(_LIST_ENTRY **)(a1 + 8);
    if( v22->Blink != (_LIST_ENTRY *)(a1 + 8) )
      goto LABEL_160;
    v16->WaitBlock[0].WaitListEntry.Flink = v22;
    CurrentThread->Tcb.WaitBlock[0].WaitListEntry.Blink = v21;
    v22->Blink = (_LIST_ENTRY *)v16;
    v21->Flink = (_LIST_ENTRY *)v16;
    _InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
    CurrentThread->Tcb.WaitBlockCount = 1;
    KiCommitThreadWait(CurrentThread, CurrentThread->Tcb.WaitBlock, TimeoutType, v7);
    CurrentThread->Tcb.WaitReason = 0;
    if( v23 != 256 )
    {
      *EntryArray = v23;
      if( (unsigned int)Count > 1
        && (unsigned __int64)(v23 - 257) > 1
        && v23 != 128
        && v23 != 192
        && *(_DWORD *)(a1 + 4) )
      {
        v42 = KeGetCurrentIrql();
        __writecr8(2ui64);
        KiAcquireKobjectLockSafe((VOID *)a1);
        if( *(_DWORD *)(a1 + 4) )
          v12 = (unsigned int)KiAttemptFastRemoveQueue(
                                (_KQUEUE *)a1,
                                (_LIST_ENTRY **)EntryArray + 1,
                                (unsigned int)(Count - 1))
              + 1;
        _InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
        __writecr8(v42);
      }
      return v12;
    }
    i = KeGetCurrentIrql();
    __writecr8(2ui64);
  }
  if( !CurrentThread->Tcb.Queue )
    goto LABEL_159;
  Flink = CurrentThread->Tcb.QueueListEntry.Flink;
  Blink = CurrentThread->Tcb.QueueListEntry.Blink;
  if( Flink->Blink != &CurrentThread->Tcb.QueueListEntry || Blink->Flink != &CurrentThread->Tcb.QueueListEntry )
LABEL_160:
    __fastfail(3u);
  Blink->Flink = Flink;
  Flink->Blink = Blink;
  CurrentThread->Tcb.Queue = 0i64;
LABEL_159:
  _InterlockedAnd((volatile signed __int32 *)a1, 0xFFFFFF7F);
  *EntryArray = 128i64;
LABEL_107:
  LODWORD(v28) = 1;
LABEL_85:
  CurrentThread->Tcb.WaitReason = 0;
  v41 = KeGetCurrentPrcb();
  if( v41->DeferredReadyListHead.Next )
    KiProcessThreadWaitList(v41, AdjustUnwait, 0i64, 2ui64);
  KiFastExitThreadWait(v41, &CurrentThread->Tcb, 1u);
  return v28;
}

Referenced by:

IoRemoveIoCompletion
KeRemoveQueue