PspGetPreviousProcessThread

_LIST_ENTRY **__fastcall PspGetPreviousProcessThread(_EPROCESS *Process, _ETHREAD *Thread){
  _ETHREAD *CurrentThread; 
  _LIST_ENTRY *p_ThreadListHead; 
  _LIST_ENTRY **p_Blink; 
  int v6; 
  _EX_PUSH_LOCK *p_ProcessLock; 
  _LIST_ENTRY *Blink; 

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

Referenced by:

PspTerminateAllThreads