PsGetNextProcessThread

_LIST_ENTRY **__fastcall PsGetNextProcessThread(_EPROCESS *Process, _ETHREAD *Thread){
  _ETHREAD *CurrentThread; 
  _LIST_ENTRY *p_ThreadListHead; 
  _LIST_ENTRY **v4; 
  _LIST_ENTRY **p_Blink; 
  int v7; 
  _EX_PUSH_LOCK *p_ProcessLock; 
  _LIST_ENTRY *Flink; 

  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  p_ThreadListHead = &Process->ThreadListHead;
  v4 = 0i64;
  p_Blink = 0i64;
  v7 = 0;
  --CurrentThread->Tcb.KernelApcDisable;
  p_ProcessLock = &Process->ProcessLock;
  ExAcquirePushLockSharedEx(&Process->ProcessLock, 0i64);
  if( Thread )
    Flink = Thread->ThreadListEntry.Flink;
  else
    Flink = p_ThreadListHead->Flink;
  if( Flink != p_ThreadListHead )
  {
    while( 1 )
    {
      p_Blink = &Flink[-79].Blink;
      if( ObReferenceObjectSafeWithTag((INT64)&Flink[-79].Blink, 1850045264i64) )
        break;
      Flink = Flink->Flink;
      if( Flink == p_ThreadListHead )
        goto LABEL_6;
    }
    v7 = 1;
  }
LABEL_6:
  if( _InterlockedCompareExchange64(&p_ProcessLock->_bf_0, 0i64, 17i64) != 17 )
    ExfReleasePushLockShared(p_ProcessLock);
  KeAbPostRelease(p_ProcessLock);
  KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
  if( Thread )
    ObfDereferenceObjectWithTag(Thread, 0x6E457350ui64);
  if( v7 )
    return p_Blink;
  return v4;
}

Referenced by:

DbgkpPostFakeThreadMessages
DbgkpSetProcessDebugObject
ExSwapinWorkerThreads
IopCancelIrpsInThreadListForCurrentProcess
NtGetNextThread
NtSetInformationProcess
NtSetInformationThread
PsEnumProcessThreads
PsResumeProcess
PsSuspendProcess
PspBoostJobIoPriorityCallback
PspTerminateAllThreads
PspWaitForUsermodeExit