KeSetLegacyAffinityThread
UINT64 __stdcall KeSetLegacyAffinityThread(_ETHREAD *Thread, UINT64 Affinity){
_EPROCESS *Process;
unsigned __int64 Mask;
unsigned __int8 CurrentIrql;
struct _KPRCB *CurrentPrcb;
unsigned __int64 v8;
_ETHREAD *CurrentThread;
INT64 v11;
_ETHREAD *NextThread;
char v13;
INT64 v14;
_SINGLE_LIST_ENTRY ReadyList;
_GROUP_AFFINITY Affinitya;
Process = Thread->Tcb.Process;
Mask = 0i64;
if( Affinity )
{
ReadyList.Next = 0i64;
Affinitya = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
ExAcquireSpinLockSharedAtDpcLevel((PEX_SPIN_LOCK)&Process->Pcb.ProcessLock);
Affinitya.Group = Thread->Tcb.UserAffinity.Group;
v8 = KeActiveProcessors.Bitmap[Affinitya.Group] & Affinity;
if( v8 && (v8 & Process->Pcb.Affinity.Bitmap[Affinitya.Group]) == v8 )
{
Mask = Thread->Tcb.UserAffinity.Mask;
Affinitya.Mask = v8;
KiSetAffinityThread(&Thread->Tcb, &ReadyList, &Affinitya);
}
ExReleaseSpinLockSharedFromDpcLevel((PEX_SPIN_LOCK)&Process->Pcb.ProcessLock);
KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
if( CurrentIrql < 2u )
{
CurrentThread = CurrentPrcb->CurrentThread;
if( CurrentPrcb->NextThread )
{
KiAbProcessContextSwitch(&CurrentPrcb->CurrentThread->Tcb, 0i64);
LODWORD(v14) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)&v14);
while( CurrentPrcb->PrcbLock );
}
NextThread = CurrentPrcb->NextThread;
CurrentPrcb->NextThread = 0i64;
_disable();
KiEndThreadCycleAccumulation(
(INT64)CurrentPrcb,
(INT64)CurrentThread,
0i64,
v11,
v14,
(INT64)ReadyList.Next,
Affinitya.Mask);
_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();
if( !v13 )
goto LABEL_8;
}
else if( (CurrentThread->Tcb._bf_0 & 0x40) == 0 )
{
LABEL_8:
__writecr8(CurrentIrql);
return Mask;
}
__writecr8(1ui64);
CurrentThread->Tcb._bf_0 &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
goto LABEL_8;
}
if( CurrentPrcb->NextThread && !CurrentPrcb->DpcRoutineActive )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
}
return Mask;
}Referenced by:
NtSetInformationThread