KeQueryValuesThread

VOID __stdcall KeQueryValuesThread(_ETHREAD *Thread, _KTHREAD_VALUES *Values){
  unsigned __int8 WaitReason; 
  unsigned __int8 CurrentIrql; 
  struct _KPRCB *CurrentPrcb; 
  _KPRCB **v7; 
  int v8; 
  _KPRCB *v9; 
  volatile signed __int32 *SharedReadyQueue; 
  char v11; 
  volatile unsigned __int8 State; 
  unsigned int ReadyTime; 
  unsigned __int64 KernelWaitTime; 
  unsigned __int64 UserWaitTime; 
  char v16; 
  __int64 v17; 
  __int64 v18; 
  struct _KPRCB *v19; 
  unsigned __int64 NextProcessor; 
  struct _KPRCB *v21; 
  struct _KPRCB *v22; 
  __int64 v23; 
  struct _KPRCB *v24; 
  __int64 v25; 
  struct _KPRCB *v26; 
  _DWORD *SchedulerAssist; 
  _DWORD *v28; 
  _DWORD *v29; 
  _DWORD *v30; 
  _DWORD *v31; 
  __int64 v32[3]; 
  UINT64 SpinCount; 
  UINT64 v34; 
  UINT64 v35; 
  UINT64 v36; 

  Values->WaitTime = 0;
  WaitReason = 0;
  CurrentIrql = KeGetCurrentIrql();
  __writecr8(2ui64);
  CurrentPrcb = KeGetCurrentPrcb();
  LODWORD(SpinCount) = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)&Thread->Tcb.ThreadLock, 0i64) )
  {
    do
      KeYieldProcessorEx(&SpinCount);
    while( Thread->Tcb.ThreadLock );
    SchedulerAssist = CurrentPrcb->SchedulerAssist;
    if( SchedulerAssist && CurrentPrcb->NestingLevel <= 1u )
      ++SchedulerAssist[6];
  }
  if( Thread->Tcb.Process == (_EPROCESS *)&KiInitialProcess )
  {
    LOBYTE(v8) = Thread->Tcb.State;
    BYTE2(Values[1].WaitTime) = 1;
    goto LABEL_20;
  }
LABEL_4:
  v7 = &KiProcessorBlock;
  while( 1 )
  {
    while( 1 )
    {
      v8 = Thread->Tcb.WaitBlockFill6[68];
      v9 = 0i64;
      SharedReadyQueue = 0i64;
      if( v8 == 5 )
      {
        v11 = Thread->Tcb.WaitRegister.Flags & 7;
        if( v11 == 1 || (unsigned __int8)(v11 - 3) <= 3u )
          goto LABEL_7;
        LOBYTE(v8) = 2;
        goto LABEL_35;
      }
      if( Thread->Tcb.WaitBlockFill6[68] == 1 )
        break;
      if( Thread->Tcb.WaitBlockFill6[68] == 2 )
      {
LABEL_35:
        NextProcessor = Thread->Tcb.NextProcessor;
        if( (NextProcessor & 0x80000000) == 0i64 )
        {
          v22 = KeGetCurrentPrcb();
          v9 = v7[NextProcessor];
          LODWORD(v32[0]) = 0;
          while( _interlockedbittestandset64((volatile signed __int32 *)&v9->PrcbLock, 0i64) )
          {
            do
            {
              KeYieldProcessorEx((UINT64 *)v32);
              NextProcessor = v9->PrcbLock;
            }
            while( NextProcessor );
            v28 = v22->SchedulerAssist;
            if( v28 && v22->NestingLevel <= 1u )
            {
              LODWORD(NextProcessor) = v28[6] + 1;
              v28[6] = NextProcessor;
            }
          }
          if( Thread == v9->CurrentThread )
            goto LABEL_7;
LABEL_30:
          _InterlockedAnd64((volatile signed __int64 *)&v9->PrcbLock, 0i64);
          goto LABEL_31;
        }
      }
      else
      {
        if( Thread->Tcb.WaitBlockFill6[68] != 3 )
          goto LABEL_7;
        v18 = Thread->Tcb.NextProcessor;
        if( (int)v18 >= 0 )
        {
          v19 = KeGetCurrentPrcb();
          v9 = v7[v18];
          LODWORD(v34) = 0;
          while( _interlockedbittestandset64((volatile signed __int32 *)&v9->PrcbLock, 0i64) )
          {
            do
              KeYieldProcessorEx(&v34);
            while( v9->PrcbLock );
            v31 = v19->SchedulerAssist;
            if( v31 && v19->NestingLevel <= 1u )
              ++v31[6];
          }
          if( Thread == v9->NextThread )
            goto LABEL_7;
          LODWORD(NextProcessor) = Thread->Tcb.WaitBlockFill6[68];
          if( (_BYTE)NextProcessor == 3 )
          {
            LODWORD(NextProcessor) = Thread->Tcb.NextProcessor;
            if( (_DWORD)NextProcessor == (_DWORD)v18 )
              __fastfail(0x1Eu);
          }
          goto LABEL_30;
        }
      }
    }
    v23 = Thread->Tcb.NextProcessor;
    if( (int)v23 >= 0 )
    {
      v26 = KeGetCurrentPrcb();
      v9 = v7[v23];
      LODWORD(v36) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)&v9->PrcbLock, 0i64) )
      {
        do
          KeYieldProcessorEx(&v36);
        while( v9->PrcbLock );
        v29 = v26->SchedulerAssist;
        if( v29 && v26->NestingLevel <= 1u )
          ++v29[6];
      }
      LODWORD(NextProcessor) = Thread->Tcb.WaitBlockFill6[68];
      if( (_BYTE)NextProcessor == 1 )
      {
        LODWORD(NextProcessor) = Thread->Tcb.NextProcessor;
        if( (_DWORD)NextProcessor == (_DWORD)v23 )
          goto LABEL_7;
      }
      goto LABEL_30;
    }
    v24 = KeGetCurrentPrcb();
    v25 = (unsigned int)v23;
    LODWORD(v25) = v23 & 0x7FFFFFFF;
    LODWORD(v35) = 0;
    SharedReadyQueue = (volatile signed __int32 *)v7[v25]->SharedReadyQueue;
    while( _interlockedbittestandset64(SharedReadyQueue, 0i64) )
    {
      do
        KeYieldProcessorEx(&v35);
      while( *(_QWORD *)SharedReadyQueue );
      v30 = v24->SchedulerAssist;
      if( v30 && v24->NestingLevel <= 1u )
        ++v30[6];
    }
    LODWORD(NextProcessor) = Thread->Tcb.WaitBlockFill6[68];
    if( (_BYTE)NextProcessor == 1 )
    {
      LODWORD(NextProcessor) = Thread->Tcb.NextProcessor;
      if( (_DWORD)NextProcessor == (_DWORD)v23 )
        break;
    }
    _InterlockedAnd64((volatile signed __int64 *)SharedReadyQueue, 0i64);
LABEL_31:
    v21 = KeGetCurrentPrcb();
    v7 = (_KPRCB **)v21->SchedulerAssist;
    if( !v7 || v21->NestingLevel > 1u || !(_DWORD)NextProcessor )
      goto LABEL_4;
  }
  v9 = 0i64;
LABEL_7:
  Values->WaitTime = Thread->Tcb.WaitTime;
  State = Thread->Tcb.State;
  ReadyTime = Thread->Tcb.ReadyTime;
  if( State == 1 || State == 7 && (Thread->Tcb._bf_0 & 2) != 0 )
    ReadyTime += KUSER_SHARED_DATA.TickCount.LowPart - Thread->Tcb.WaitBlock[2].SpareLong;
  *(_DWORD *)&Values->State = ReadyTime;
  KernelWaitTime = Thread->Tcb.KernelWaitTime;
  UserWaitTime = Thread->Tcb.UserWaitTime;
  if( Thread->Tcb.WaitBlockFill6[68] == 5 )
  {
    v16 = Thread->Tcb.WaitRegister.Flags & 7;
    if( v16 == 1 || (unsigned __int8)(v16 - 3) <= 3u )
    {
      v17 = KUSER_SHARED_DATA.TickCount.LowPart - Thread->Tcb.WaitBlock[2].SpareLong;
      if( Thread->Tcb.WaitMode )
        UserWaitTime += v17;
      else
        KernelWaitTime += v17;
    }
  }
  Values[2] = (_KTHREAD_VALUES)KernelWaitTime;
  Values[3] = (_KTHREAD_VALUES)UserWaitTime;
  if( v9 )
    _InterlockedAnd64((volatile signed __int64 *)&v9->PrcbLock, 0i64);
  if( SharedReadyQueue )
    _InterlockedAnd64((volatile signed __int64 *)SharedReadyQueue, 0i64);
  WaitReason = Thread->Tcb.WaitReason;
  BYTE2(Values[1].WaitTime) = Thread->Tcb.Priority;
  if( (_BYTE)v8 == 5 && (Thread->Tcb.WaitRegister.Flags & 7) == 4 )
    WaitReason = 5;
LABEL_20:
  HIBYTE(Values[1].WaitTime) = Thread->Tcb.BasePriority;
  Thread->Tcb.ThreadLock = 0i64;
  __writecr8(CurrentIrql);
  BYTE1(Values[1].WaitTime) = WaitReason;
  LOBYTE(Values[1].WaitTime) = v8;
}

Referenced by:

ExpGetProcessInformation
NtQueryInformationThread
PsQueryStatisticsProcess