KiCallInterruptServiceRoutine
VOID __fastcall KiCallInterruptServiceRoutine(_KINTERRUPT *Interrupt, UINT8 AcquireSpinlock){
_BYTE *RedirectObject;
struct _KPRCB *CurrentPrcb;
_QWORD *IsrDpcStats;
unsigned __int64 v7;
unsigned __int64 v8;
unsigned __int8 v9;
unsigned __int64 v10;
unsigned int DpcWatchdogSequenceNumber;
unsigned __int64 v12;
unsigned __int64 *ActualLock;
int v14;
unsigned int v15;
NTSTATUS FirstSetRightGroupAffinity;
unsigned __int64 v17;
if( Interrupt->Vector - 48 <= 0x9F && !KiForceIdleDisabled )
{
if( (_DWORD)KiForceIdleState == 4 )
{
KiResetForceIdle(1i64, 0);
}
else if( (unsigned int)(KiForceIdleState - 1) <= 1 )
{
KiCheckAndRearmForceIdle();
}
}
if( Interrupt->SynchronizeIrql )
{
RedirectObject = Interrupt->RedirectObject;
if( !RedirectObject || !RedirectObject[16] )
goto LABEL_4;
v14 = 0;
v15 = KiProcessorIndexToNumberMappingTable[KeGetPcr()->Prcb.Number];
if( v15 >> 6 == *((unsigned __int16 *)RedirectObject + 4) )
v14 = 1;
if( ((unsigned int)(*(_QWORD *)RedirectObject >> (v15 & 0x3F)) & v14) == 0 )
{
FirstSetRightGroupAffinity = KeFindFirstSetRightGroupAffinity((INT64)Interrupt->RedirectObject);
KiIntRedirectQueueRequestOnProcessor(FirstSetRightGroupAffinity, Interrupt->Vector);
}
else
{
LABEL_4:
CurrentPrcb = KeGetCurrentPrcb();
IsrDpcStats = CurrentPrcb->IsrDpcStats;
Interrupt->IsrDpcStats.IsrActive = 1;
CurrentPrcb->IsrDpcStats = &Interrupt->IsrDpcStats;
v7 = __rdtsc();
Interrupt->IsrDpcStats.IsrTimeStart = v7;
v8 = v7;
if( AcquireSpinlock )
{
ActualLock = Interrupt->ActualLock;
if( _interlockedbittestandset64((volatile signed __int32 *)ActualLock, 0i64) )
KxWaitForSpinLockAndAcquire(ActualLock);
}
v9 = Interrupt->ServiceRoutine(Interrupt, Interrupt->ServiceContext);
if( AcquireSpinlock )
_InterlockedAnd64((volatile signed __int64 *)Interrupt->ActualLock, 0i64);
v10 = __rdtsc();
DpcWatchdogSequenceNumber = CurrentPrcb->DpcWatchdogSequenceNumber;
v12 = v10 - Interrupt->IsrDpcStats.IsrTimeStart;
if( DpcWatchdogSequenceNumber != Interrupt->IsrDpcStats.DpcWatchdog.SequenceNumber )
{
Interrupt->IsrDpcStats.DpcWatchdog.SequenceNumber = DpcWatchdogSequenceNumber;
Interrupt->IsrDpcStats.DpcWatchdog.IsrTime = 0i64;
Interrupt->IsrDpcStats.DpcWatchdog.IsrCount = 0i64;
Interrupt->IsrDpcStats.DpcWatchdog.DpcTime = 0i64;
Interrupt->IsrDpcStats.DpcWatchdog.DpcCount = 0i64;
}
Interrupt->IsrDpcStats.IsrTime += v12;
Interrupt->IsrDpcStats.DpcWatchdog.IsrTime += v12;
if( IsrDpcStats != (_QWORD *)1 )
{
v17 = v10 - v8;
if( *((_BYTE *)IsrDpcStats + 48) )
IsrDpcStats[1] += v17;
else
IsrDpcStats[4] += v17;
}
CurrentPrcb->IsrDpcStats = IsrDpcStats;
Interrupt->IsrDpcStats.IsrActive = 0;
if( v9 )
{
++Interrupt->IsrDpcStats.IsrCount;
++Interrupt->IsrDpcStats.DpcWatchdog.IsrCount;
}
}
}
else
{
Interrupt->ServiceRoutine(Interrupt, Interrupt->ServiceContext);
}
}Referenced by:
KiInterruptSubDispatch
KiInterruptSubDispatchNoLock
KiInterruptSubDispatchNoLockNoEtw
KiInvokeInterruptServiceRoutine
KiScanInterruptObjectList