KeSetThreadSchedulerAssist
NTSTATUS __stdcall KeSetThreadSchedulerAssist(_ETHREAD *Thread){
__int64 v1;
int v2;
unsigned __int64 v3;
int v5;
int v6;
unsigned __int8 v7;
struct _KPRCB *v8;
ULONG_PTR v9;
__int64 v10;
__int64 v11;
bool v12;
__int64 v13;
unsigned __int8 v14;
__int16 v15;
INT64 v16;
bool v17;
INT64 v18;
INT64 v19;
unsigned __int8 CurrentIrql;
ULONG_PTR v21;
char v22;
char v23;
char v24;
unsigned int v25;
char v26;
char v27;
__int64 v28;
struct _KPRCB *CurrentPrcb;
ULONG_PTR v30;
__int64 v31;
__int64 v32;
UINT64 v34;
_SINGLE_LIST_ENTRY ReadyList;
_KSHARED_READY_QUEUE *ControlReadyQueue;
void *ControlPrcb[7];
int v38;
void *retaddr;
UINT64 SpinCount;
UINT64 v41;
v3 = (unsigned __int64)&retaddr;
ControlPrcb[0] = 0i64;
ReadyList.Next = 0i64;
ControlReadyQueue = 0i64;
if( !v2 )
{
if( v1 )
{
*((_QWORD *)Thread + 121) = v1;
_interlockedbittestandset((volatile signed __int32 *)Thread + 30, 0x16u);
if( (KiVelocityFlags & 0x400) != 0 )
_interlockedbittestandset((volatile signed __int32 *)Thread, 0x16u);
*((_DWORD *)Thread + 256) = 32;
return v3;
}
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LODWORD(v34) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)Thread + 16, 0i64) )
{
do
KeYieldProcessorEx(&v34);
while( *((_QWORD *)Thread + 8) );
}
if( *((_DWORD *)Thread + 256) != 32 )
{
v21 = *((char *)Thread + 1024);
v22 = *((_BYTE *)Thread + v21 + 824);
if( !v22 )
KeBugCheckEx(0x157u, (ULONG_PTR)Thread, v21, 2ui64, 0i64);
v23 = v22 - 1;
*((_BYTE *)Thread + v21 + 824) = v23;
if( !v23 )
{
v24 = v21;
v25 = *((_DWORD *)Thread + 214) ^ (1 << v21);
*((_DWORD *)Thread + 214) = v25;
if( v25 < 1 << v24 )
{
v26 = *((_BYTE *)Thread + 195);
if( v26 < 16 )
{
v27 = *((_BYTE *)Thread + 563) + (*((_BYTE *)Thread + 564) & 0xF) + (*((_BYTE *)Thread + 564) >> 4);
if( v27 < v26 )
KiSetPriorityThread((_KTHREAD *)Thread, &ReadyList, (unsigned int)v27);
}
}
}
*((_DWORD *)Thread + 256) = 32;
}
KiAcquireThreadStateLock(Thread, (_KPRCB **)ControlPrcb, &ControlReadyQueue);
_interlockedbittestandreset((volatile signed __int32 *)Thread + 30, 0x16u);
*((_QWORD *)Thread + 121) = 0i64;
if( (KiVelocityFlags & 0x400) != 0 )
_interlockedbittestandreset((volatile signed __int32 *)Thread, 0x16u);
KiReleaseThreadStateLock(v28, (__int64)ControlPrcb[0], (volatile signed __int64 *)ControlReadyQueue);
KiReleaseThreadLockSafe((INT64)Thread);
CurrentPrcb = KeGetCurrentPrcb();
KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
if( CurrentIrql >= 2u )
{
if( *((_QWORD *)CurrentPrcb + 2) && !*((_BYTE *)CurrentPrcb + 12586) )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
goto LABEL_69;
}
v30 = *((_QWORD *)CurrentPrcb + 1);
if( *((_QWORD *)CurrentPrcb + 2) )
{
KiAbProcessContextSwitch(*((_KTHREAD **)CurrentPrcb + 1), 0i64);
HIDWORD(v34) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&v34 + 4));
while( *((_QWORD *)CurrentPrcb + 6) );
}
v31 = *((_QWORD *)CurrentPrcb + 2);
*((_QWORD *)CurrentPrcb + 2) = 0i64;
_disable();
KiEndThreadCycleAccumulation(CurrentPrcb, (_KTHREAD *)v30, 0i64);
_enable();
*((_QWORD *)CurrentPrcb + 1) = v31;
if( *(_BYTE *)(v31 + 388) == 1 )
{
v32 = (unsigned int)(*(_DWORD *)(v31 + 132) - *(_DWORD *)(v31 + 436));
*(_DWORD *)(v31 + 132) = v32 + KUSER_SHARED_DATA.TickCount.LowPart;
}
*(_BYTE *)(v31 + 388) = 2;
*(_BYTE *)(v30 + 643) = 32;
*(_BYTE *)(v30 + 390) = CurrentIrql;
KiQueueReadyThread((__int64)CurrentPrcb, v30, v32);
if( !KiSwapContext((PKTHREAD)v30, (PKTHREAD)v31) )
goto LABEL_63;
}
else if( (*(_DWORD *)(v30 + 116) & 0x40) == 0 )
{
goto LABEL_63;
}
__writecr8(1ui64);
*(_DWORD *)(v30 + 116) &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
LABEL_63:
__writecr8(CurrentIrql);
LABEL_69:
LODWORD(v3) = KeSetPriorityThread((PKTHREAD)Thread, *((char *)Thread + 563));
return v3;
}
v5 = v2 - 1;
if( v5 )
{
v6 = v5 - 1;
if( !v6 || v6 == 1 )
{
v7 = KeGetCurrentIrql();
__writecr8(2ui64);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)Thread + 16, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *((_QWORD *)Thread + 8) );
}
KiUpdateVpBackingThreadPriorityFromTopLevel(Thread);
KiReleaseThreadLockSafe((INT64)Thread);
v8 = KeGetCurrentPrcb();
LODWORD(v3) = (unsigned int)KiReadyDeferredReadyList(v8, &ReadyList);
if( v7 < 2u )
{
v9 = *((_QWORD *)v8 + 1);
if( *((_QWORD *)v8 + 2) )
{
KiAbProcessContextSwitch(*((_KTHREAD **)v8 + 1), 0i64);
LODWORD(v41) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v8 + 12, 0i64) )
{
do
KeYieldProcessorEx(&v41);
while( *((_QWORD *)v8 + 6) );
}
v10 = *((_QWORD *)v8 + 2);
*((_QWORD *)v8 + 2) = 0i64;
_disable();
KiEndThreadCycleAccumulation(v8, (_KTHREAD *)v9, 0i64);
_enable();
*((_QWORD *)v8 + 1) = v10;
if( *(_BYTE *)(v10 + 388) == 1 )
{
v11 = (unsigned int)(*(_DWORD *)(v10 + 132) - *(_DWORD *)(v10 + 436));
*(_DWORD *)(v10 + 132) = v11 + KUSER_SHARED_DATA.TickCount.LowPart;
}
*(_BYTE *)(v10 + 388) = 2;
*(_BYTE *)(v9 + 643) = 32;
*(_BYTE *)(v9 + 390) = v7;
KiQueueReadyThread((__int64)v8, v9, v11);
v12 = !KiSwapContext((PKTHREAD)v9, (PKTHREAD)v10);
}
else
{
v12 = (*(_DWORD *)(v9 + 116) & 0x40) == 0;
}
if( !v12 )
{
__writecr8(1ui64);
*(_DWORD *)(v9 + 116) &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
}
v3 = v7;
LABEL_33:
__writecr8(v3);
return v3;
}
if( *((_QWORD *)v8 + 2) )
{
LOBYTE(v3) = *((_BYTE *)v8 + 12586);
if( !(_BYTE)v3 )
LODWORD(v3) = KiRequestSoftwareInterrupt(v8, 2);
}
}
}
else
{
LODWORD(v3) = KiVelocityFlags;
v13 = *((_QWORD *)Thread + 121);
if( (KiVelocityFlags & 0x10) != 0 && v13 )
{
v14 = KeGetCurrentIrql();
__writecr8(2ui64);
v15 = v38;
_disable();
v16 = *(unsigned int *)(v13 + 4);
v17 = (v15 & 0x200) != 0;
if( (_DWORD)v16 != (unsigned __int8)*((_DWORD *)Thread + 128) && (int)v16 < 5 )
{
KeSetThreadBamQosLevel((INT64)Thread, v16);
KeCheckAndApplyBamQos((INT64)KeGetCurrentPrcb(), (INT64)Thread, v18, v19);
}
if( v17 )
_enable();
v3 = v14;
goto LABEL_33;
}
}
return v3;
}Referenced by:
VmSetThreadSchedulerAssist