KiSignalThreadForApc
VOID __stdcall KiSignalThreadForApc(_KPRCB *Prcb, _KAPC *Apc, UINT8 OldIrql){
_ETHREAD *Thread;
char ApcMode;
volatile unsigned __int8 State;
char v6;
int v7[10];
Thread = Apc->Thread;
ApcMode = Apc->ApcMode;
if( Apc->ApcStateIndex == Thread->Tcb.ApcStateIndex )
{
if( Thread == Prcb->CurrentThread )
{
if( !ApcMode && (!Thread->Tcb.WaitBlock[3].SpareLong || !Apc->NormalRoutine && !Thread->Tcb.SpecialApcDisable) )
{
Thread->Tcb.ApcState.KernelApcPending = 1;
if( OldIrql )
{
LABEL_24:
LOBYTE(Prcb) = 1;
HalRequestSoftwareInterrupt((UINT64)Prcb);
return;
}
Thread->Tcb._bf_0 |= 0x40u;
}
}
else if( ApcMode )
{
if( Thread->Tcb.WaitBlockFill6[68] == 5
&& Thread->Tcb.WaitMode == 1
&& (unsigned __int8)((Thread->Tcb.WaitRegister.Flags & 7) - 3) > 1u
&& ((Thread->Tcb._bf_0 & 0x10) != 0 || (Thread->Tcb.ApcState.UserApcPendingAll & 2) != 0) )
{
Thread->Tcb.WaitRegister.Flags |= 0x40u;
KiSignalThread(Prcb, Thread, 192i64, 0i64);
if( v6 )
Thread->Tcb.ApcState.UserApcPendingAll |= 2u;
}
}
else
{
Thread->Tcb.ApcState.KernelApcPending = 1;
_InterlockedOr(v7, 0);
State = Thread->Tcb.State;
if( State == 2 )
{
Prcb = (_KPRCB *)Thread->Tcb.NextProcessor;
LODWORD(Prcb) = (unsigned int)Prcb & 0x7FFFFFFF;
if( KeGetPcr()->Prcb.Number == (_DWORD)Prcb )
goto LABEL_24;
KiSendSoftwareInterrupt((UINT64)Prcb, 1u);
}
else if( State == 5
&& !Thread->Tcb.WaitIrql
&& !Thread->Tcb.SpecialApcDisable
&& (!Apc->NormalRoutine || !Thread->Tcb.KernelApcDisable && !Thread->Tcb.ApcState.InProgressFlags) )
{
KiSignalThread(Prcb, Thread, 256i64, 0i64);
Thread->Tcb.WaitRegister.Flags |= 0x20u;
}
}
}
}Referenced by:
IopfCompleteRequest
KeInsertQueueApc
KeRequestTerminationThread
KeTryToInsertQueueApc
KiInsertDeferredPreemptionApc
KiResumeThread
KiSchedulerApc
KiSuspendThread