KeSetSelectedCpuSetsThread
NTSTATUS __fastcall KeSetSelectedCpuSetsThread(INT64 a1, UINT64 a2, INT8 *a3){
unsigned int v5;
NTSTATUS result;
INT64 *ThreadCpuSetMaskPointer;
unsigned __int8 CurrentIrql;
__int64 v9;
volatile int *v10;
int v11;
_KPRCB *updated;
int v13;
_KPRCB *v14;
UINT64 Number;
struct _KPRCB *CurrentPrcb;
_ETHREAD *CurrentThread;
INT64 v18;
_ETHREAD *NextThread;
char v20;
bool v21;
UINT64 SpinCount;
_SINGLE_LIST_ENTRY ReadyList;
INT64 v24;
UINT64 v25;
LODWORD(v25) = 0;
v5 = a2;
LOBYTE(result) = KiValidateCpuSetMasks((_GUID *)a3, (_IOBJECT_TYPE_LIST *)a2);
if( result >= 0 )
{
ReadyList.Next = 0i64;
ThreadCpuSetMaskPointer = (INT64 *)KiGetThreadCpuSetMaskPointer(a1, &v25);
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
v10 = (volatile int *)(v9 + 64);
ExAcquireSpinLockSharedAtDpcLevel((PEX_SPIN_LOCK)(v9 + 64));
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(a1 + 64), 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *(_QWORD *)(a1 + 64) );
}
v11 = *(_DWORD *)(a1 + 588);
KiWriteCpuSetMasks(ThreadCpuSetMaskPointer, (unsigned int)v25, (INT64)a3, v5);
updated = KiUpdateThreadCpuSets((_KTHREAD *)a1, &ReadyList);
v13 = *(_DWORD *)(a1 + 588);
v14 = updated;
KiReleaseThreadLockSafe(a1);
if( (xmmword_140CFB490 & 0x8000000) != 0 )
EtwTraceIdealProcessor(a1, 0x546u, v11, v13);
ExReleaseSpinLockSharedFromDpcLevel(v10);
if( v14 )
{
Number = v14->Number;
if( KeGetPcr()->Prcb.Number != (_DWORD)Number )
KiSendSoftwareInterrupt(Number, 2u);
}
CurrentPrcb = KeGetCurrentPrcb();
KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
if( CurrentIrql >= 2u )
{
if( CurrentPrcb->NextThread && !CurrentPrcb->DpcRoutineActive )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
}
else
{
CurrentThread = CurrentPrcb->CurrentThread;
if( CurrentPrcb->NextThread )
{
KiAbProcessContextSwitch(&CurrentPrcb->CurrentThread->Tcb, 0i64);
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( CurrentPrcb->PrcbLock );
}
NextThread = CurrentPrcb->NextThread;
CurrentPrcb->NextThread = 0i64;
_disable();
KiEndThreadCycleAccumulation(
(INT64)CurrentPrcb,
(INT64)CurrentThread,
0i64,
v18,
SpinCount,
(INT64)ReadyList.Next,
v24);
_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();
v21 = v20 == 0;
}
else
{
v21 = (CurrentThread->Tcb._bf_0 & 0x40) == 0;
}
if( !v21 )
{
__writecr8(1ui64);
CurrentThread->Tcb._bf_0 &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
}
__writecr8(CurrentIrql);
}
return 0;
}
return result;
}Referenced by:
NtSetInformationThread