KeTerminateThread

VOID __stdcall KeTerminateThread(_ETHREAD *Thread){
  bool v1; 
  __int64 v3; 
  INT64 *v4; 
  WORK_QUEUE_TYPE v5; 
  void *v6; 
  char *v7; 
  __int64 v8; 
  char **v9; 
  _DISPATCHER_HEADER *v10; 
  struct _KPRCB *CurrentPrcb; 
  _KWAIT_BLOCK *v12; 
  _KWAIT_BLOCK *Flink; 
  signed __int64 *v14; 
  signed __int64 v15; 
  signed __int64 v16; 
  UINT64 v17; 
  _KWAIT_BLOCK *v18; 
  unsigned __int8 WaitType; 
  INT64 WaitKey; 
  INT64 v21; 
  INT64 **v22; 
  _KQUEUE *NotificationQueue; 
  _LIST_ENTRY *p_WaitListHead; 
  __int64 v25; 
  _KPRCB *v26; 
  int SignalState; 
  _LIST_ENTRY *Blink; 
  int v29[8]; 
  struct _IO_WORKITEM LockHandle; 
  UINT64 SpinCount; 
  _KPRCB *Prcb; 
  struct _KPRCB *v33; 
  v1 = (*((_DWORD *)Thread + 29) & 0x1000) == 0;
  memset(&LockHandle, 0, 24);
  if( !v1 )
    KeBugCheckEx(0x107u, (ULONG_PTR)Thread, 0i64, 0i64, 0i64);
  v3 = *((_QWORD *)Thread + 45);
  if( v3 )
    KeDisableProfiling((_KTHREAD *)Thread, *(_THREAD_PERFORMANCE_DATA **)(v3 + 8));
  v4 = (INT64 *)*((_QWORD *)Thread + 68);
  *((_BYTE *)Thread + 643) = 22;
  KeGetCurrentIrql();
  __writecr8(2ui64);
  ExAcquireSpinLockExclusiveAtDpcLevel(v4 + 8);
  v7 = (char *)Thread + 760;
  if( *((_QWORD *)Thread + 95) == *((_QWORD *)Thread + 96) )
  {
    LockHandle.WorkItem.List.Flink = 0i64;
    LockHandle.WorkItem.List.Blink = (_LIST_ENTRY *)KiProcessListLock;
    KxAcquireQueuedSpinLock(&LockHandle, KiProcessListLock, v5, v6);
    v21 = v4[106];
    v22 = (INT64 **)v4[107];
    if( *(INT64 **)(v21 + 8) != v4 + 106 || *v22 != v4 + 106 )
LABEL_39:
      __fastfail(3u);
    *v22 = (INT64 *)v21;
    *(_QWORD *)(v21 + 8) = v22;
    KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&LockHandle);
  }
  KiAcquireKobjectLockSafe(v4);
  v8 = *(_QWORD *)v7;
  v9 = (char **)*((_QWORD *)Thread + 96);
  if( *(char **)(*(_QWORD *)v7 + 8i64) != v7 || *v9 != v7 )
    goto LABEL_39;
  *v9 = (char *)v8;
  *(_QWORD *)(v8 + 8) = v9;
  _InterlockedAnd((volatile signed __int32 *)v4, 0xFFFFFF7F);
  if( *((_QWORD *)Thread + 13) )
    KiRemoveThreadFromSchedulingGroup((__int64)Thread);
  ExReleaseSpinLockExclusiveFromDpcLevel(v4 + 8);
  v10 = (_DISPATCHER_HEADER *)*((_QWORD *)Thread + 29);
  if( v10 )
    KiActivateWaiterQueueWithNoLocks(Thread, v10, (_LIST_ENTRY *)((char *)Thread + 520));
  CurrentPrcb = KeGetCurrentPrcb();
  v33 = CurrentPrcb;
  KiAcquireKobjectLockSafe(Thread);
  v12 = (_KWAIT_BLOCK *)((char *)Thread + 8);
  *((_DWORD *)Thread + 1) = 1;
  Flink = (_KWAIT_BLOCK *)*((_QWORD *)Thread + 1);
  while( Flink != v12 )
  {
    v18 = Flink;
    Flink = (_KWAIT_BLOCK *)Flink->WaitListEntry.Flink;
    WaitType = v18->WaitType;
    if( WaitType == 1 )
    {
      WaitKey = v18->WaitKey;
      goto LABEL_27;
    }
    if( WaitType == 2 )
    {
      v18->BlockState = 5;
      NotificationQueue = v18->NotificationQueue;
      v18->WaitListEntry.Flink = 0i64;
      p_WaitListHead = &NotificationQueue->Header.WaitListHead;
      KeGetCurrentIrql();
      __writecr8(2ui64);
      Prcb = KeGetCurrentPrcb();
      v25 = *((_QWORD *)Prcb + 1);
      KiAcquireKobjectLockSafe(NotificationQueue);
      if( p_WaitListHead->Flink == p_WaitListHead
        || NotificationQueue->CurrentCount >= NotificationQueue->MaximumCount
        || *(_KQUEUE **)(v25 + 232) == NotificationQueue && *(_BYTE *)(v25 + 643) == 15 )
      {
        v26 = Prcb;
      }
      else
      {
        v26 = Prcb;
        if( KiWakeQueueWaiter(Prcb, NotificationQueue, (INT64)v18) )
          goto LABEL_41;
      }
      SignalState = NotificationQueue->Header.SignalState;
      NotificationQueue->Header.SignalState = SignalState + 1;
      Blink = NotificationQueue->EntryListHead.Blink;
      if( Blink->Flink != &NotificationQueue->EntryListHead )
        goto LABEL_39;
      v18->WaitListEntry.Flink = &NotificationQueue->EntryListHead;
      v18->WaitListEntry.Blink = Blink;
      Blink->Flink = &v18->WaitListEntry;
      NotificationQueue->EntryListHead.Blink = &v18->WaitListEntry;
      if( !SignalState && p_WaitListHead->Flink != p_WaitListHead )
        KiWakeOtherQueueWaiters(v26, NotificationQueue);
LABEL_41:
      _InterlockedAnd(&NotificationQueue->Header.Lock, 0xFFFFFF7F);
      CurrentPrcb = v33;
    }
    else
    {
      WaitKey = 256i64;
LABEL_27:
      KiTryUnwaitThread(CurrentPrcb, v18, WaitKey, 0i64);
    }
  }
  *((_QWORD *)Thread + 2) = (char *)Thread + 8;
  v12->WaitListEntry.Flink = &v12->WaitListEntry;
  _InterlockedAnd((volatile signed __int32 *)Thread, 0xFFFFFF7F);
  *((_BYTE *)Thread + 388) = 4;
  if( *((_QWORD *)CurrentPrcb + 1441) )
    KiProcessThreadWaitList((struct KPRCB *)CurrentPrcb, 1, 0);
  v14 = (signed __int64 *)((char *)Thread + 1112);
  _m_prefetchw(&PsReaperListHead);
  v15 = PsReaperListHead;
  do
  {
    *v14 = v15;
    v16 = v15;
    v15 = _InterlockedCompareExchange64(&PsReaperListHead, (signed __int64)v14, v15);
  }
  while( v15 != v16 );
  if( v15 )
  {
    if( PsReaperWorkItem.Parameter
      && _interlockedbittestandreset((volatile signed __int32 *)&PsReaperWorkItem.Parameter, 0) )
    {
      v17 = 0xFFFFi64;
      goto LABEL_19;
    }
  }
  else
  {
    v17 = 0xFFFFFFFFi64;
LABEL_19:
    if( !ExQueueWorkItemEx(&PsReaperWorkItem, HyperCriticalWorkQueue, v17) )
      _interlockedbittestandset((volatile signed __int32 *)&PsReaperWorkItem.Parameter, 0);
  }
  _InterlockedOr(v29, 0);
  if( *((_QWORD *)Thread + 8) )
  {
    LODWORD(SpinCount) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)Thread + 16, 0i64) )
    {
      do
        KeYieldProcessorEx(&SpinCount);
      while( *((_QWORD *)Thread + 8) );
    }
    KiReleaseThreadLockSafe((INT64)Thread);
  }
  KiSwapThread(Thread, CurrentPrcb);
}

Referenced by:

PspExitThread