KeSetAffinityThread
VOID __stdcall KeSetAffinityThread(_ETHREAD *Thread, _GROUP_AFFINITY *Affinity){
__int64 Group;
__int64 v4;
unsigned __int8 CurrentIrql;
struct _KPRCB *CurrentPrcb;
__int64 v8;
ULONG_PTR v9;
bool v10;
__int64 v11;
__int64 v12;
UINT64 SpinCount;
_SINGLE_LIST_ENTRY ReadyList;
Group = Affinity->Group;
v4 = *((_QWORD *)Thread + 68);
ReadyList.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)(v4 + 64));
v8 = *(_QWORD *)(v4 + 8 * Group + 88);
if( !v8 || (v8 & Affinity->Mask) != Affinity->Mask )
KiExtendProcessAffinity(v4, Group);
if( !Affinity->Mask )
Affinity->Mask = *(_QWORD *)(v4 + 8 * Group + 88);
KiSetAffinityThread(Thread, &ReadyList, Affinity);
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v4 + 64));
KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
if( CurrentIrql >= 2u )
{
if( *((_QWORD *)CurrentPrcb + 2) && !*((_BYTE *)CurrentPrcb + 12586) )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
}
else
{
v9 = *((_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) );
}
v11 = *((_QWORD *)CurrentPrcb + 2);
*((_QWORD *)CurrentPrcb + 2) = 0i64;
_disable();
KiEndThreadCycleAccumulation(CurrentPrcb, (_KTHREAD *)v9, 0i64);
_enable();
*((_QWORD *)CurrentPrcb + 1) = v11;
if( *(_BYTE *)(v11 + 388) == 1 )
{
v12 = (unsigned int)(*(_DWORD *)(v11 + 132) - *(_DWORD *)(v11 + 436));
*(_DWORD *)(v11 + 132) = v12 + KUSER_SHARED_DATA.TickCount.LowPart;
}
*(_BYTE *)(v11 + 388) = 2;
*(_BYTE *)(v9 + 643) = 32;
*(_BYTE *)(v9 + 390) = CurrentIrql;
KiQueueReadyThread((__int64)CurrentPrcb, v9, v12);
v10 = !KiSwapContext((PKTHREAD)v9, (PKTHREAD)v11);
}
else
{
v10 = (*(_DWORD *)(v9 + 116) & 0x40) == 0;
}
if( !v10 )
{
__writecr8(1ui64);
*(_DWORD *)(v9 + 116) &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
}
__writecr8(CurrentIrql);
}
}Referenced by:
ExpWorkQueueManagerThread
ExpWorkerThread
NtSetInformationThread