KeRemoveQueueDpcEx
VOID __stdcall KeRemoveQueueDpcEx(_KDPC *Dpc, _BYTE *WaitIfActive){
char v2;
void *DpcData;
bool v5;
int v6;
__int64 v7;
__int64 v8;
__int64 v9;
_SINGLE_LIST_ENTRY *p_DpcListEntry;
_SINGLE_LIST_ENTRY **p_Next;
_SINGLE_LIST_ENTRY *i;
_SINGLE_LIST_ENTRY *Next;
__int64 v14;
unsigned int v15;
unsigned __int64 ProcessorHistory;
__int64 v17;
struct _KPRCB *CurrentPrcb;
__int64 Group;
int v20;
__int64 v21;
__int64 v22;
__int64 v23;
int v24[8];
char v25;
unsigned int ProcIndex;
_BYTE ProcIndex_4[88];
_KAFFINITY_EX NonDeepIdleMask;
_KAFFINITY_EX DeepIdleMask;
int v30;
v2 = (char)WaitIfActive;
memset(&ProcIndex_4[24], 0i64, 0x40u);
memset(&DeepIdleMask, 0i64, sizeof(DeepIdleMask));
*(_DWORD *)&ProcIndex_4[18] = 0;
*(_WORD *)&ProcIndex_4[22] = 0;
ProcIndex = 0;
memset(&NonDeepIdleMask, 0i64, sizeof(NonDeepIdleMask));
v25 = 0;
_disable();
DpcData = Dpc->DpcData;
v5 = (v30 & 0x200) != 0;
if( DpcData )
{
*(_DWORD *)&ProcIndex_4[24] = Dpc->TargetInfoAsUlong;
v6 = HIWORD(*(_DWORD *)&ProcIndex_4[24]);
if( *(_WORD *)&ProcIndex_4[26] >= 0x500u )
LOWORD(v6) = *(_WORD *)&ProcIndex_4[26] - 1280;
v7 = (__int64)*(&KiProcessorBlock + (unsigned __int16)v6);
if( ProcIndex_4[24] != 26 || (v8 = 12520i64, !*(_BYTE *)(v7 + 12584)) )
v8 = 12480i64;
v9 = v7 + v8;
KxAcquireSpinLock((UINT64 *)(v7 + v8 + 16));
if( DpcData == Dpc->DpcData && *(_DWORD *)&ProcIndex_4[24] == Dpc->TargetInfoAsUlong )
{
p_DpcListEntry = &Dpc->DpcListEntry;
p_Next = (_SINGLE_LIST_ENTRY **)v9;
--*(_DWORD *)(v9 + 24);
for( i = *(_SINGLE_LIST_ENTRY **)v9; i != p_DpcListEntry; i = i->Next )
p_Next = &i->Next;
Next = p_DpcListEntry->Next;
*p_Next = p_DpcListEntry->Next;
if( !Next )
*(_QWORD *)(v9 + 8) = p_Next;
Dpc->DpcData = 0i64;
v14 = *(_QWORD *)(v7 + 33976);
v25 = 1;
if( v14 && v9 == v7 + 12480 )
--*(_DWORD *)(v14 + 28);
}
KxReleaseSpinLock((UINT64 *)(v9 + 16));
}
if( v5 )
_enable();
if( v2 && Dpc->ProcessorHistory )
{
KiGetDeepIdleProcessors(&DeepIdleMask, &NonDeepIdleMask);
v15 = 0;
if( NonDeepIdleMask.Count )
{
ProcessorHistory = Dpc->ProcessorHistory;
do
{
v17 = v15++;
NonDeepIdleMask.Bitmap[v17] &= ProcessorHistory;
}
while( v15 < NonDeepIdleMask.Count );
}
CurrentPrcb = KeGetCurrentPrcb();
Group = CurrentPrcb->Group;
if( NonDeepIdleMask.Count > (unsigned __int16)Group )
NonDeepIdleMask.Bitmap[Group] &= ~CurrentPrcb->GroupSetMember;
*(_QWORD *)&ProcIndex_4[8] = NonDeepIdleMask.Bitmap[0];
*(_QWORD *)ProcIndex_4 = &NonDeepIdleMask;
*(_WORD *)&ProcIndex_4[16] = 0;
while( 1 )
{
KeEnumerateNextProcessor((UINT64 *)&ProcIndex, (_KAFFINITY_ENUMERATION_CONTEXT *)ProcIndex_4);
if( v20 )
break;
v21 = (__int64)*(&KiProcessorBlock + ProcIndex);
if( Dpc->Type != 26 || (v22 = 12520i64, !*(_BYTE *)(v21 + 12584)) )
v22 = 12480i64;
if( !DpcData )
{
_InterlockedOr(v24, 0);
v23 = v21 + v22;
if( *(_QWORD *)(v21 + v22 + 16) )
{
_disable();
KxAcquireSpinLock((UINT64 *)(v23 + 16));
KxReleaseSpinLock((UINT64 *)(v23 + 16));
if( (v30 & 0x200) != 0 )
_enable();
}
}
if( *(_KDPC **)(v21 + v22 + 32) != Dpc && (unsigned int)NonDeepIdleMask.Count > *(unsigned __int8 *)(v21 + 208) )
NonDeepIdleMask.Bitmap[*(unsigned __int8 *)(v21 + 208)] &= ~*(_QWORD *)(v21 + 200);
}
if( !KeIsEmptyAffinityEx(&NonDeepIdleMask.Count) )
KeGenericProcessorCallback(
(__int64 *)&NonDeepIdleMask,
(void(__fastcall *)(struct _KPRCB *, __int64))xHalTimerWatchdogStop,
0i64,
2);
}
}Referenced by:
EtwpCancelPendingStackwalkApcs
EtwpFreeCompression
ExpCancelTimer
ExpSetTimerObject
KeClearForceIdle
KeMaskInterrupt
KeRemoveQueueDpc
KiCheckAndRearmForceIdle
VfWdCheckForSettingsChange