PspRundownUmsThreadForApcDelivery
NTSTATUS __fastcall PspRundownUmsThreadForApcDelivery(_ETHREAD *Thread, _DWORD *a2, INT64 a3, INT8 a4){
_QWORD *Object;
char v9;
NTSTATUS result;
NTSTATUS v11;
void *SparePtr;
_ADAPTER_OBJECT *v13;
UINT8 v14;
CHAR v15;
__int64 v16[2];
_KAPC Apc[2];
PETHREAD Threada;
INT64 v19;
v19 = a3;
memset(Apc, 0i64, 0x80u);
v16[0] = 0i64;
Threada = 0i64;
Object = Thread->Tcb.WaitBlock[3].Object;
v9 = 0;
result = KeSetUmsThreadKernelLock(a3, (UINT64 *)v16);
v11 = result;
if( result < 0 )
return result;
*a2 |= 4u;
--Thread->Tcb.SpecialApcDisable;
if( a4 )
{
SparePtr = (void *)_InterlockedExchange64((volatile __int64 *)&Thread->Tcb.WaitBlock[3].SparePtr, -1i64);
}
else
{
SparePtr = Thread->Tcb.WaitBlock[3].SparePtr;
if( SparePtr == (void *)-1i64 )
goto LABEL_18;
}
if( !Object[9] )
{
*a2 |= 1u;
LABEL_19:
v13 = (_ADAPTER_OBJECT *)Threada;
goto LABEL_20;
}
if( !SparePtr )
{
if( v16[0] )
{
v11 = PsLookupThreadByThreadId((VOID *)v16[0], &Threada);
if( v11 >= 0 )
{
v13 = (_ADAPTER_OBJECT *)Threada;
v9 = 1;
if( Threada->Tcb.Process != Thread->Tcb.Process )
{
*a2 |= 2u;
goto LABEL_20;
}
goto LABEL_9;
}
}
LABEL_18:
*a2 |= 2u;
goto LABEL_19;
}
v13 = (_ADAPTER_OBJECT *)*((_QWORD *)SparePtr + 12);
ObReferenceObjectSafe((INT64)v13);
LABEL_9:
KeInitializeGate((_KGATE *)&Apc[1].ApcListEntry, v14);
*(_QWORD *)&Apc[1].Type = a2;
KeInitializeApc((INT64)Apc, (INT64)v13, 0i64, (INT64)PspRelinquishUmsThreadSpecialApc, 0i64, 0i64, 0, 0i64);
if( KeInsertQueueApc((INT64)Apc, (INT64)v13, (INT64)Thread, 2i64) )
{
KeWaitForGate((_KGATE *)&Apc[1].ApcListEntry, Executive, v15);
v11 = (NTSTATUS)Apc[1].Thread;
v9 = 1;
if( SLODWORD(Apc[1].Thread) >= 0 && (*a2 & 1) != 0 )
{
KeSynchronizeUmsThread(&Thread->Tcb, a4);
LABEL_21:
HalPutDmaAdapter(v13);
goto LABEL_22;
}
}
else
{
*a2 |= 2u;
v9 = 1;
}
LABEL_20:
KiLeaveGuardedRegionUnsafe((__int64)Thread);
if( v9 )
goto LABEL_21;
LABEL_22:
if( v11 < 0 )
{
KeClearUmsThreadKernelLock(v19);
*a2 &= ~4u;
}
return v11;
}Referenced by:
KiSuspendUmsThread
PspGetSetContextInternal
PspUmsUnInitThread