KiInterruptDispatchCommon

bool __fastcall KiInterruptDispatchCommon(int a1, unsigned int a2, char a3, __int128 *a4, _DWORD *a5){
  int v5; 
  _LIST_ENTRY *v7; 
  bool v8; 
  unsigned __int8 v9; 
  __int64 v10; 
  __int64 v11; 
  __int64 v12; 
  __int64 v13; 
  unsigned int v14; 
  char v15; 
  UINT64 *v16; 
  __int64 v17; 
  int v18; 
  __int64 v19; 
  UINT8 OldIrql; 
  char v22; 
  int v23; 
  int v24; 
  struct _PROCESSOR_NUMBER ProcNumber; 
  unsigned int v26; 
  _DWORD Vector[3]; 
  int v28; 
  _LIST_ENTRY *v29; 
  __int64 CurrentIrql; 
  _DWORD *v31; 
  struct _GROUP_AFFINITY Affinity; 
  __int128 v33; 
  struct _GROUP_AFFINITY PreviousAffinity; 
  v26 = a2;
  v23 = a1;
  v5 = a1;
  OldIrql = 0;
  v31 = a5;
  ProcNumber = 0;
  v24 = 0;
  v33 = 0i64;
  CurrentIrql = KeGetCurrentIrql();
  v7 = (_LIST_ENTRY *)&v33;
  v22 = 0;
  if( a4 )
    v7 = (_LIST_ENTRY *)a4;
  Vector[0] = 0;
  v29 = v7;
  v8 = 0;
  PreviousAffinity = 0i64;
  v7->Blink = v7;
  v7->Flink = v7;
  if( a1 )
  {
    v11 = a2 - 256;
    *(_QWORD *)&Vector[1] = KiGlobalSecondaryIDT + 48 * v11;
    KiAcquireSecondaryInterruptConnectLock(*(UINT64 **)&Vector[1], &OldIrql);
    v10 = 0i64;
    if( (unsigned int)v11 < 0x100 )
      v10 = *(_QWORD *)(KiGlobalSecondaryIDT + 48 * v11 + 40);
    v7 = v29;
    v5 = v23;
  }
  else
  {
    *(_QWORD *)&Vector[1] = 0i64;
    KeGetCurrentProcessorNumberEx(&ProcNumber);
    *(_QWORD *)&Affinity.Group = ProcNumber.Group;
    Affinity.Mask = 1i64 << ProcNumber.Number;
    KeSetSystemGroupAffinityThread(&Affinity, &PreviousAffinity);
    v9 = KeGetCurrentIrql();
    __writecr8(0xFui64);
    v10 = 0i64;
    OldIrql = v9;
    if( v26 > 0xFF )
      goto LABEL_10;
    _mm_lfence();
    v10 = *((_QWORD *)KeGetCurrentPrcb() + v26 + 1576);
  }
  v9 = OldIrql;
LABEL_10:
  if( v10 )
  {
    v12 = v10;
    ++*(_WORD *)(v10 + 102);
    if( (a3 & 1) != 0 )
    {
      while( *(_BYTE *)(v12 + 93) )
      {
        v13 = *(_QWORD *)(v12 + 8);
        if( !v13 )
        {
          v12 = 0i64;
          break;
        }
        v12 = v13 - 8;
        if( v12 == v10 )
        {
          if( *(_BYTE *)(v12 + 93) )
            v12 = 0i64;
          break;
        }
      }
    }
    if( v12 )
    {
      v14 = 0;
      v28 = *(_DWORD *)(v10 + 108);
      v15 = 0;
      while( (unsigned __int8)CurrentIrql <= 2u || *(_BYTE *)(v12 + 93) )
      {
        if( (*(_DWORD *)(v12 + 104) & 1) != 0 )
        {
          v19 = *(_QWORD *)(v12 + 8);
        }
        else
        {
          ++*(_WORD *)(v12 + 102);
          ++v14;
          v16 = *(UINT64 **)&Vector[1];
          if( v23 )
            KxReleaseSpinLock(*(UINT64 **)&Vector[1]);
          __writecr8(v9);
          v8 = KiInvokeInterruptServiceRoutine(v12, v9, v26);
          v24 = 2;
          if( v23 )
          {
            KiAcquireSecondaryInterruptConnectLock(v16, &OldIrql);
            v9 = OldIrql;
          }
          else
          {
            v9 = KeGetCurrentIrql();
            __writecr8(0xFui64);
            OldIrql = v9;
          }
          v17 = (__int64)v29;
          v18 = v23;
          --*(_WORD *)(v12 + 102);
          v19 = *(_QWORD *)(v12 + 8);
          KiProcessPendingDisconnect(v18, v12, v17);
        }
        v12 = v19 - 8;
        if( v28 )
        {
          if( v8 )
            v15 = 1;
          if( v12 == v10 )
          {
            if( !v15 || v14 <= 1 )
            {
              v8 = 1;
              goto LABEL_46;
            }
            v14 = 0;
            v15 = 0;
            v8 = 0;
          }
        }
        else if( v8 || v12 == v10 )
        {
          goto LABEL_46;
        }
      }
      v22 = 1;
      if( v24 != 2 )
        v24 = 1;
      Vector[0] = *(_DWORD *)(v12 + 88);
LABEL_46:
      v5 = v23;
    }
    --*(_WORD *)(v10 + 102);
    v7 = v29;
    KiProcessPendingDisconnect(v5, v10, (__int64)v29);
  }
  if( v5 )
  {
    KxReleaseSpinLock(*(UINT64 **)&Vector[1]);
    __writecr8(v9);
  }
  else
  {
    __writecr8(v9);
    KeRevertToUserGroupAffinityThread(&PreviousAffinity);
  }
  if( v22 )
    IoProcessPassiveInterrupts(Vector[0]);
  if( (unsigned __int8)CurrentIrql < 2u )
    KiProcessDisconnectList(v7);
  if( v31 )
    *v31 = v24;
  return v8;
}

Referenced by:

IopPassiveInterruptWorker
KeDispatchSecondaryInterrupt