KeConnectInterrupt

NTSTATUS __stdcall KeConnectInterrupt(
        _KINTERRUPT **InterruptObject,
        UINT8 ProcessorCount,
        _INTERRUPT_CONNECTION_DATA *ConnectionData){
  __int64 v4; 
  _INTERRUPT_CONNECTION_DATA *v5; 
  char v6; 
  UINT8 v7; 
  UINT8 IsInterruptTypeSecondary; 
  _KINTERRUPT *v9; 
  int v10; 
  NTSTATUS v11; 
  _KINTERRUPT **v12; 
  __int64 v13; 
  _QWORD *IntTrackEntry; 
  __int64 v15; 
  int v16; 
  _BYTE *RedirectObject; 
  _KINTERRUPT **v18; 
  __int64 v19; 
  int v21; 
  UINT64 Gsiv; 
  _INTERRUPT_CONNECTION_DATA *v23; 
  v23 = ConnectionData;
  LODWORD(Gsiv) = 0;
  v4 = ProcessorCount;
  v5 = ConnectionData;
  v6 = 0;
  v7 = 0;
  IsInterruptTypeSecondary = KiIsInterruptTypeSecondary(ConnectionData);
  if( (_BYTE)v4 )
  {
    do
    {
      v9 = InterruptObject[v7];
      v9->InternalState |= 1u;
      v10 = IsInterruptTypeSecondary ? KiConnectSecondaryInterrupt(v9) : KiConnectInterrupt((__int64)v9);
      v11 = v10;
      if( v10 < 0 )
        goto LABEL_35;
      if( v10 == 295 )
        v6 = 1;
    }
    while( ++v7 < (unsigned __int8)v4 );
  }
  v11 = KiIntSteerConnect((__int64 *)InterruptObject, v4, (__int64)v5 + 8);
  if( v11 < 0 )
    goto LABEL_34;
  v7 = 0;
  if( (_BYTE)v4 )
  {
    v12 = InterruptObject;
    v7 = v4;
    v13 = v4;
    do
    {
      _InterlockedAnd(&(*v12++)->InternalState, 0xFFFFFFFE);
      --v13;
    }
    while( v13 );
  }
  if( v6 )
  {
    if( ((int(__fastcall *)(char *, UINT64 *))off_140C008E0[0])((char *)v5 + 8, &Gsiv) < 0 )
      return 295;
    v21 = IsInterruptTypeSecondary ? KiUnmaskSecondaryInterruptInternal((*InterruptObject)->Vector, (unsigned int)Gsiv) : ((__int64(__fastcall *)(_QWORD, _QWORD))off_140C00778[0])((unsigned int)Gsiv, 0i64);
    v11 = v21;
    if( v21 >= 0 )
      return 295;
LABEL_34:
    v5 = v23;
LABEL_35:
    if( v7 )
      KeDisconnectInterrupt(InterruptObject, v7, v5);
    return v11;
  }
  v5 = v23;
  v11 = HalEnableInterrupt((__int64)v23);
  if( v11 < 0 )
    goto LABEL_35;
  IntTrackEntry = (*InterruptObject)->IntTrackEntry;
  if( IntTrackEntry && *((_BYTE *)IntTrackEntry + 56) )
  {
    v15 = IntTrackEntry[2];
    v16 = *(_DWORD *)(v15 + 128);
    if( v16 == 2 )
    {
      if( !(_BYTE)v4 || (RedirectObject = (*InterruptObject)->RedirectObject) == 0i64 )
        __fastfail(5u);
      RedirectObject[16] = 1;
    }
    else if( v16 != 1 )
    {
      return v11;
    }
    *(_BYTE *)(v15 + 132) = 1;
    _InterlockedExchange(&KiIntTrackRootEnabled, 1);
    if( (_BYTE)v4 )
    {
      v18 = InterruptObject;
      v19 = v4;
      do
      {
        _InterlockedOr(&(*v18++)->InternalState, 4u);
        --v19;
      }
      while( v19 );
    }
  }
  return v11;
}

Referenced by:

IopConnectInterrupt