KeQueryValuesThread
VOID __stdcall KeQueryValuesThread(_ETHREAD *Thread, _KTHREAD_VALUES *Values){
unsigned __int8 WaitReason;
unsigned __int8 CurrentIrql;
struct _KPRCB *CurrentPrcb;
_KPRCB **v7;
int v8;
_KPRCB *v9;
volatile signed __int32 *SharedReadyQueue;
char v11;
volatile unsigned __int8 State;
unsigned int ReadyTime;
unsigned __int64 KernelWaitTime;
unsigned __int64 UserWaitTime;
char v16;
__int64 v17;
__int64 v18;
struct _KPRCB *v19;
unsigned __int64 NextProcessor;
struct _KPRCB *v21;
struct _KPRCB *v22;
__int64 v23;
struct _KPRCB *v24;
__int64 v25;
struct _KPRCB *v26;
_DWORD *SchedulerAssist;
_DWORD *v28;
_DWORD *v29;
_DWORD *v30;
_DWORD *v31;
__int64 v32[3];
UINT64 SpinCount;
UINT64 v34;
UINT64 v35;
UINT64 v36;
Values->WaitTime = 0;
WaitReason = 0;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&Thread->Tcb.ThreadLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( Thread->Tcb.ThreadLock );
SchedulerAssist = CurrentPrcb->SchedulerAssist;
if( SchedulerAssist && CurrentPrcb->NestingLevel <= 1u )
++SchedulerAssist[6];
}
if( Thread->Tcb.Process == (_EPROCESS *)&KiInitialProcess )
{
LOBYTE(v8) = Thread->Tcb.State;
BYTE2(Values[1].WaitTime) = 1;
goto LABEL_20;
}
LABEL_4:
v7 = &KiProcessorBlock;
while( 1 )
{
while( 1 )
{
v8 = Thread->Tcb.WaitBlockFill6[68];
v9 = 0i64;
SharedReadyQueue = 0i64;
if( v8 == 5 )
{
v11 = Thread->Tcb.WaitRegister.Flags & 7;
if( v11 == 1 || (unsigned __int8)(v11 - 3) <= 3u )
goto LABEL_7;
LOBYTE(v8) = 2;
goto LABEL_35;
}
if( Thread->Tcb.WaitBlockFill6[68] == 1 )
break;
if( Thread->Tcb.WaitBlockFill6[68] == 2 )
{
LABEL_35:
NextProcessor = Thread->Tcb.NextProcessor;
if( (NextProcessor & 0x80000000) == 0i64 )
{
v22 = KeGetCurrentPrcb();
v9 = v7[NextProcessor];
LODWORD(v32[0]) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v9->PrcbLock, 0i64) )
{
do
{
KeYieldProcessorEx((UINT64 *)v32);
NextProcessor = v9->PrcbLock;
}
while( NextProcessor );
v28 = v22->SchedulerAssist;
if( v28 && v22->NestingLevel <= 1u )
{
LODWORD(NextProcessor) = v28[6] + 1;
v28[6] = NextProcessor;
}
}
if( Thread == v9->CurrentThread )
goto LABEL_7;
LABEL_30:
_InterlockedAnd64((volatile signed __int64 *)&v9->PrcbLock, 0i64);
goto LABEL_31;
}
}
else
{
if( Thread->Tcb.WaitBlockFill6[68] != 3 )
goto LABEL_7;
v18 = Thread->Tcb.NextProcessor;
if( (int)v18 >= 0 )
{
v19 = KeGetCurrentPrcb();
v9 = v7[v18];
LODWORD(v34) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v9->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&v34);
while( v9->PrcbLock );
v31 = v19->SchedulerAssist;
if( v31 && v19->NestingLevel <= 1u )
++v31[6];
}
if( Thread == v9->NextThread )
goto LABEL_7;
LODWORD(NextProcessor) = Thread->Tcb.WaitBlockFill6[68];
if( (_BYTE)NextProcessor == 3 )
{
LODWORD(NextProcessor) = Thread->Tcb.NextProcessor;
if( (_DWORD)NextProcessor == (_DWORD)v18 )
__fastfail(0x1Eu);
}
goto LABEL_30;
}
}
}
v23 = Thread->Tcb.NextProcessor;
if( (int)v23 >= 0 )
{
v26 = KeGetCurrentPrcb();
v9 = v7[v23];
LODWORD(v36) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v9->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&v36);
while( v9->PrcbLock );
v29 = v26->SchedulerAssist;
if( v29 && v26->NestingLevel <= 1u )
++v29[6];
}
LODWORD(NextProcessor) = Thread->Tcb.WaitBlockFill6[68];
if( (_BYTE)NextProcessor == 1 )
{
LODWORD(NextProcessor) = Thread->Tcb.NextProcessor;
if( (_DWORD)NextProcessor == (_DWORD)v23 )
goto LABEL_7;
}
goto LABEL_30;
}
v24 = KeGetCurrentPrcb();
v25 = (unsigned int)v23;
LODWORD(v25) = v23 & 0x7FFFFFFF;
LODWORD(v35) = 0;
SharedReadyQueue = (volatile signed __int32 *)v7[v25]->SharedReadyQueue;
while( _interlockedbittestandset64(SharedReadyQueue, 0i64) )
{
do
KeYieldProcessorEx(&v35);
while( *(_QWORD *)SharedReadyQueue );
v30 = v24->SchedulerAssist;
if( v30 && v24->NestingLevel <= 1u )
++v30[6];
}
LODWORD(NextProcessor) = Thread->Tcb.WaitBlockFill6[68];
if( (_BYTE)NextProcessor == 1 )
{
LODWORD(NextProcessor) = Thread->Tcb.NextProcessor;
if( (_DWORD)NextProcessor == (_DWORD)v23 )
break;
}
_InterlockedAnd64((volatile signed __int64 *)SharedReadyQueue, 0i64);
LABEL_31:
v21 = KeGetCurrentPrcb();
v7 = (_KPRCB **)v21->SchedulerAssist;
if( !v7 || v21->NestingLevel > 1u || !(_DWORD)NextProcessor )
goto LABEL_4;
}
v9 = 0i64;
LABEL_7:
Values->WaitTime = Thread->Tcb.WaitTime;
State = Thread->Tcb.State;
ReadyTime = Thread->Tcb.ReadyTime;
if( State == 1 || State == 7 && (Thread->Tcb._bf_0 & 2) != 0 )
ReadyTime += KUSER_SHARED_DATA.TickCount.LowPart - Thread->Tcb.WaitBlock[2].SpareLong;
*(_DWORD *)&Values->State = ReadyTime;
KernelWaitTime = Thread->Tcb.KernelWaitTime;
UserWaitTime = Thread->Tcb.UserWaitTime;
if( Thread->Tcb.WaitBlockFill6[68] == 5 )
{
v16 = Thread->Tcb.WaitRegister.Flags & 7;
if( v16 == 1 || (unsigned __int8)(v16 - 3) <= 3u )
{
v17 = KUSER_SHARED_DATA.TickCount.LowPart - Thread->Tcb.WaitBlock[2].SpareLong;
if( Thread->Tcb.WaitMode )
UserWaitTime += v17;
else
KernelWaitTime += v17;
}
}
Values[2] = (_KTHREAD_VALUES)KernelWaitTime;
Values[3] = (_KTHREAD_VALUES)UserWaitTime;
if( v9 )
_InterlockedAnd64((volatile signed __int64 *)&v9->PrcbLock, 0i64);
if( SharedReadyQueue )
_InterlockedAnd64((volatile signed __int64 *)SharedReadyQueue, 0i64);
WaitReason = Thread->Tcb.WaitReason;
BYTE2(Values[1].WaitTime) = Thread->Tcb.Priority;
if( (_BYTE)v8 == 5 && (Thread->Tcb.WaitRegister.Flags & 7) == 4 )
WaitReason = 5;
LABEL_20:
HIBYTE(Values[1].WaitTime) = Thread->Tcb.BasePriority;
Thread->Tcb.ThreadLock = 0i64;
__writecr8(CurrentIrql);
BYTE1(Values[1].WaitTime) = WaitReason;
LOBYTE(Values[1].WaitTime) = v8;
}Referenced by:
ExpGetProcessInformation
NtQueryInformationThread
PsQueryStatisticsProcess