KiSignalThread
VOID __fastcall KiSignalThread(_KPRCB *Prcb, _ETHREAD *Thread, INT64 WaitStatus, _KWAIT_BLOCK *WaitBlock){
_KWAIT_STATUS_REGISTER v6;
int v8;
_DISPATCHER_HEADER *volatile Queue;
void *SystemArgument1;
struct _KPRCB *CurrentPrcb;
__int64 v12;
_ETHREAD **v13;
volatile unsigned __int8 State;
__int64 v15;
_DWORD *SchedulerAssist;
UINT64 SpinCount;
v6.Flags = (unsigned __int8)Thread->Tcb.WaitRegister;
v8 = v6.Flags & 7;
if( v8 == 1 || v8 == 4 )
{
Queue = Thread->Tcb.Queue;
if( Queue )
{
if( (*(_BYTE *)Queue & 0x7F) == 21 )
{
Thread->Tcb.QueuePriority = (unsigned __int8)Thread->Tcb.QueuePriority;
_InterlockedIncrement((volatile signed __int32 *)Queue + (unsigned int)Thread->Tcb.QueuePriority + 134);
}
else
{
_InterlockedIncrement((volatile signed __int32 *)Queue + 10);
}
}
SystemArgument1 = Thread->Tcb.SchedulerApc.SystemArgument1;
if( SystemArgument1 )
{
CurrentPrcb = KeGetCurrentPrcb();
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)SystemArgument1 + 7940, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *((_QWORD *)SystemArgument1 + 3970) );
SchedulerAssist = CurrentPrcb->SchedulerAssist;
if( SchedulerAssist && CurrentPrcb->NestingLevel <= 1u )
++SchedulerAssist[6];
}
if( Thread->Tcb.SchedulerApc.SystemArgument1 )
{
v12 = *(_QWORD *)Thread->Tcb.gapD8;
v13 = *(_ETHREAD ***)&Thread->Tcb.gapD8[8];
if( *(_ETHREAD **)(v12 + 8) != (_ETHREAD *)Thread->Tcb.gapD8 || *v13 != (_ETHREAD *)Thread->Tcb.gapD8 )
__fastfail(3u);
*v13 = (_ETHREAD *)v12;
*(_QWORD *)(v12 + 8) = v13;
Thread->Tcb.SchedulerApc.SystemArgument1 = 0i64;
}
_InterlockedAnd64((volatile signed __int64 *)SystemArgument1 + 3970, 0i64);
}
State = Thread->Tcb.State;
if( State == 1 )
{
Thread->Tcb._bf_0 |= 2u;
}
else if( State == 5 )
{
v15 = KUSER_SHARED_DATA.TickCount.LowPart - Thread->Tcb.WaitBlock[2].SpareLong;
if( Thread->Tcb.WaitMode )
Thread->Tcb.UserWaitTime += v15;
else
Thread->Tcb.KernelWaitTime += v15;
}
Thread->Tcb.WaitBlockFill6[68] = 7;
*(_QWORD *)Thread->Tcb.gapD8 = Prcb->DeferredReadyListHead.Next;
Prcb->DeferredReadyListHead.Next = (_SINGLE_LIST_ENTRY *)Thread->Tcb.gapD8;
Thread->Tcb.WaitStatus = WaitStatus;
Thread->Tcb.AbWaitObject = 0i64;
}
else if( WaitBlock )
{
if( (v6.Flags & 7) != 0 )
{
if( v8 == 5 )
{
Thread->Tcb.WaitRegister.Flags = v6.Flags & 0xF8 | 6;
}
else if( v8 == 3 )
{
WaitBlock->BlockState = 2;
}
}
else
{
Thread->Tcb.WaitRegister.Flags = v6.Flags & 0xF8 | 2;
Thread->Tcb.WaitStatus = WaitStatus;
Thread->Tcb.AbWaitObject = 0i64;
WaitBlock->BlockState = 0;
}
}
}Referenced by:
KeAlertThread
KeAlertThreadByThreadId
KiResumeThread
KiSignalThreadForApc
KiSuspendThread
KiTryUnwaitThreadWithPriority
KiWakeOtherQueueWaiters
KiWakeQueueWaiter