KeSetLegacyAffinityThread

VOID __stdcall KeSetLegacyAffinityThread(PVOID MemoryToFree, PVOID DoNotUse){
  __int64 v2; 
  unsigned __int8 CurrentIrql; 
  struct _KPRCB *CurrentPrcb; 
  unsigned __int64 v7; 
  ULONG_PTR v8; 
  __int64 v9; 
  __int64 v10; 
  UINT64 SpinCount; 
  _SINGLE_LIST_ENTRY ReadyList; 
  _GROUP_AFFINITY Affinity; 
  v2 = *((_QWORD *)MemoryToFree + 68);
  if( DoNotUse )
  {
    ReadyList.Next = 0i64;
    Affinity = 0i64;
    CurrentIrql = KeGetCurrentIrql();
    __writecr8(2ui64);
    CurrentPrcb = KeGetCurrentPrcb();
    ExAcquireSpinLockSharedAtDpcLevel((PEX_SPIN_LOCK)(v2 + 64));
    Affinity.Group = *((_WORD *)MemoryToFree + 280);
    v7 = KeActiveProcessors.Bitmap[Affinity.Group] & (unsigned __int64)DoNotUse;
    if( v7 && (v7 & *(_QWORD *)(v2 + 8i64 * Affinity.Group + 88)) == v7 )
    {
      Affinity.Mask = v7;
      KiSetAffinityThread((_ETHREAD *)MemoryToFree, &ReadyList, &Affinity);
    }
    ExReleaseSpinLockSharedFromDpcLevel((PEX_SPIN_LOCK)(v2 + 64));
    KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
    if( CurrentIrql < 2u )
    {
      v8 = *((_QWORD *)CurrentPrcb + 1);
      if( *((_QWORD *)CurrentPrcb + 2) )
      {
        KiAbProcessContextSwitch(*((_KTHREAD **)CurrentPrcb + 1), 0i64);
        LODWORD(SpinCount) = 0;
        while( _interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
        {
          do
            KeYieldProcessorEx(&SpinCount);
          while( *((_QWORD *)CurrentPrcb + 6) );
        }
        v9 = *((_QWORD *)CurrentPrcb + 2);
        *((_QWORD *)CurrentPrcb + 2) = 0i64;
        _disable();
        KiEndThreadCycleAccumulation(CurrentPrcb, (_KTHREAD *)v8, 0i64);
        _enable();
        *((_QWORD *)CurrentPrcb + 1) = v9;
        if( *(_BYTE *)(v9 + 388) == 1 )
        {
          v10 = (unsigned int)(*(_DWORD *)(v9 + 132) - *(_DWORD *)(v9 + 436));
          *(_DWORD *)(v9 + 132) = v10 + KUSER_SHARED_DATA.TickCount.LowPart;
        }
        *(_BYTE *)(v9 + 388) = 2;
        *(_BYTE *)(v8 + 643) = 32;
        *(_BYTE *)(v8 + 390) = CurrentIrql;
        KiQueueReadyThread((__int64)CurrentPrcb, v8, v10);
        if( !KiSwapContext((PKTHREAD)v8, (PKTHREAD)v9) )
          goto LABEL_8;
      }
      else if( (*(_DWORD *)(v8 + 116) & 0x40) == 0 )
      {
LABEL_8:
        __writecr8(CurrentIrql);
        return;
      }
      __writecr8(1ui64);
      *(_DWORD *)(v8 + 116) &= ~0x40u;
      KiDeliverApc(0, 0i64, 0i64);
      goto LABEL_8;
    }
    if( *((_QWORD *)CurrentPrcb + 2) && !*((_BYTE *)CurrentPrcb + 12586) )
      KiRequestSoftwareInterrupt(CurrentPrcb, 2);
  }
}

Referenced by:

NtSetInformationThread