KeSetAffinityThread
NTSTATUS __fastcall KeSetAffinityThread(INT64 a1, INT64 a2){
__int64 v2;
__int64 v4;
unsigned __int8 CurrentIrql;
struct _KPRCB *CurrentPrcb;
__int64 v8;
NTSTATUS result;
_ETHREAD *CurrentThread;
bool v11;
INT64 v12;
_ETHREAD *NextThread;
char v14;
INT64 v15;
INT64 v16;
INT64 v17;
UINT64 SpinCount;
_SINGLE_LIST_ENTRY ReadyList;
v2 = *(unsigned __int16 *)(a2 + 8);
v4 = *(_QWORD *)(a1 + 544);
ReadyList.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)(v4 + 64));
v8 = *(_QWORD *)(v4 + 8 * v2 + 88);
if( !v8 || (v8 & *(_QWORD *)a2) != *(_QWORD *)a2 )
KiExtendProcessAffinity((_KPROCESS *)v4, (unsigned __int16)v2);
if( !*(_QWORD *)a2 )
*(_QWORD *)a2 = *(_QWORD *)(v4 + 8 * v2 + 88);
KiSetAffinityThread((_KTHREAD *)a1, &ReadyList, (_GROUP_AFFINITY *)a2);
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v4 + 64));
KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
if( CurrentIrql >= 2u )
{
if( CurrentPrcb->NextThread )
{
LOBYTE(result) = CurrentPrcb->DpcRoutineActive;
if( !(_BYTE)result )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
}
}
else
{
CurrentThread = CurrentPrcb->CurrentThread;
if( CurrentPrcb->NextThread )
{
KiAbProcessContextSwitch(&CurrentPrcb->CurrentThread->Tcb, 0i64);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( CurrentPrcb->PrcbLock );
}
NextThread = CurrentPrcb->NextThread;
CurrentPrcb->NextThread = 0i64;
_disable();
KiEndThreadCycleAccumulation((INT64)CurrentPrcb, (INT64)CurrentThread, 0i64, v12, v15, v16, v17);
_enable();
CurrentPrcb->CurrentThread = NextThread;
if( NextThread->Tcb.WaitBlockFill6[68] == 1 )
NextThread->Tcb.ReadyTime = NextThread->Tcb.ReadyTime
- NextThread->Tcb.WaitBlock[2].SpareLong
+ KUSER_SHARED_DATA.TickCount.LowPart;
NextThread->Tcb.WaitBlockFill6[68] = 2;
CurrentThread->Tcb.WaitReason = 32;
CurrentThread->Tcb.WaitIrql = CurrentIrql;
KiQueueReadyThread(CurrentPrcb, &CurrentThread->Tcb);
KiSwapContext();
v11 = v14 == 0;
}
else
{
v11 = (CurrentThread->Tcb._bf_0 & 0x40) == 0;
}
if( !v11 )
{
__writecr8(1ui64);
CurrentThread->Tcb._bf_0 &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
}
result = CurrentIrql;
__writecr8(CurrentIrql);
}
return result;
}Referenced by:
ExpWorkQueueManagerThread
ExpWorkerThread
NtSetInformationThread