IopConnectInterrupt

NTSTATUS __stdcall IopConnectInterrupt(
        PIO_INTERRUPT_STRUCTURE *InterruptStructureOut,
        PKSERVICE_ROUTINE ServiceRoutine,
        PKMESSAGE_SERVICE_ROUTINE MessageServiceRoutine,
        PVOID ServiceContext,
        _KINTERRUPT *MessageIndex,
        PKSPIN_LOCK SpinLock,
        _KIRQL SynchronizeIrql,
        BOOL ShareVector,
        BOOL FloatingSave,
        PINTERRUPT_CONNECTION_DATA ConnectionData){
  _GROUP_AFFINITY TargetProcessors; 
  _KINTERRUPT_MODE Mode; 
  unsigned __int64 v14; 
  unsigned __int8 Irql; 
  unsigned __int64 v17; 
  VOID **PoolWithTag; 
  VOID **v19; 
  _KINTERRUPT_MODE v20; 
  VOID **v21; 
  char v22; 
  _GROUP_AFFINITY v23; 
  INT64 *v24; 
  unsigned __int8 v25; 
  _KINTERRUPT *Interrupt; 
  _KINTERRUPT *v27; 
  int v28; 
  int v29; 
  __int64 v30; 
  VOID **v31; 
  unsigned __int64 v32; 
  _OWORD *v33; 
  _OWORD *v34; 
  __int64 v35; 
  __int128 v36; 
  _KINTERRUPT **v38; 
  __int16 *v39; 
  _WORD *v40; 
  VOID **v41; 
  VOID **v42; 
  __int64 v43; 
  _WORD *v44; 
  __int64 v45; 
  _WORD *v46; 
  __int64 v47; 
  VOID *BugCheckParameter4; 
  _KINTERRUPT *v49; 
  VOID *v50; 
  UINT64 v51; 
  VOID *ServiceContexta; 
  UINT64 v53; 
  UINT64 *v54; 
  _KEVENT *v55; 
  UINT64 Vector; 
  UINT16 v57[4]; 
  _KINTERRUPT_MODE v58; 
  unsigned int v59; 
  UINT64 *v60; 
  _GROUP_AFFINITY GroupAffinity; 
  INT64 *v62; 
  UINT8 v63[8]; 
  _ACTIVE_CONNECT_BLOCK ConnectBlock[32]; 
  UINT8 v66; 
  bool ShareVectora; 
  char ShareVectorb; 
  char ConnectionDataa[8]; 
  _INTERRUPT_CONNECTION_DATA *v71; 
  char v72; 

  v66 = (unsigned __int8)MessageServiceRoutine;
  memset(ConnectBlock, 0i64, 0x50u);
  *(_QWORD *)InterruptStructureOut = 0i64;
  *(_DWORD *)&v57[2] = 0;
  ConnectionDataa[0] = 0;
  IopInitializeActiveConnectBlock(v71, ConnectBlock);
  TargetProcessors = v71->Vectors[0].TargetProcessors;
  Mode = v71->Vectors[0].Mode;
  v59 = v71->Vectors[0].Vector;
  GroupAffinity = TargetProcessors;
  v58 = Mode;
  v14 = TargetProcessors.Mask & KeActiveProcessors.Bitmap[(unsigned __int16)_mm_extract_epi16(
                                                                              (__m128i)TargetProcessors,
                                                                              4)];
  Irql = v71->Vectors[0].Irql;
  GroupAffinity.Mask = v14;
  LOBYTE(v57[0]) = Irql;
  if( v71->Vectors[0].Type == InterruptTypeControllerInput
    && !((unsigned __int8(__fastcall *)(_QWORD, _QWORD))off_140C00780[0])(0i64, v71->Vectors[0].ControllerInput.Gsiv)
    && (unsigned int)(v71->Vectors[0].Polarity - 3) <= 1 )
  {
    ConnectionDataa[0] = 1;
    v58 = LevelSensitive;
  }
  ShareVectora = !ShareVector;
  if( KeVerifyGroupAffinity(&GroupAffinity, 0)
    && (v17 = (0x101010101010101i64
             * ((((v14 - ((v14 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
               + (((v14 - ((v14 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)
               + ((((v14 - ((v14 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
                 + (((v14 - ((v14 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 56,
        (_BYTE)v17) )
  {
    PoolWithTag = ExAllocatePoolWithTag(0x200ui64, (unsigned int)(8 * (char)v17 + 496), 1852403529i64);
    v19 = PoolWithTag;
    if( PoolWithTag )
    {
      memset(PoolWithTag, 0i64, 8 * (char)v17 + 496);
      KeInitializeDpc((PRKDPC)(v19 + 54), 0i64, 0i64);
      v20 = v58;
      *((_OWORD *)v19 + 1) = *(_OWORD *)&v71->Count;
      v21 = v19;
      v22 = 0;
      *((_OWORD *)v19 + 2) = *(_OWORD *)&v71->Vectors[0].Irql;
      HIBYTE(v57[3]) = 0;
      *((_OWORD *)v19 + 3) = v71->Vectors[0].TargetProcessors;
      *((_OWORD *)v19 + 4) = v71->Vectors[0].IntRemapInfo;
      *((_OWORD *)v19 + 5) = *(_OWORD *)&v71->Vectors[0].ControllerInput.Gsiv;
      v23 = GroupAffinity;
      *((_OWORD *)v19 + 6) = v71->Vectors[0].72;
      *((_DWORD *)v19 + 10) = v20;
      *((_GROUP_AFFINITY *)v19 + 3) = v23;
      if( *(_QWORD *)&SynchronizeIrql )
        v21 = *(VOID ***)&SynchronizeIrql;
      v19[1] = (VOID *)v14;
      *((_BYTE *)v19 + 400) = ShareVectora;
      v24 = (INT64 *)(v19 + 51);
      if( ShareVector )
        v24 = 0i64;
      *(_QWORD *)v63 = v21;
      v62 = v24;
      v25 = 0;
      ShareVectorb = 0;
      v72 = 0;
      v57[2] = _mm_extract_epi16((__m128i)v23, 4);
      if( (char)v17 > 0 )
      {
        do
        {
          if( _bittest64((const __int64 *)&v14, v25) )
          {
            LOBYTE(v57[3]) = v25;
            LODWORD(v60) = KeGetProcessorIndexFromNumber(&v57[2]);
            Interrupt = KeAllocateInterrupt(*(&KiProcessorBlock + (unsigned int)v60));
            v27 = Interrupt;
            if( !Interrupt )
            {
              v29 = -1073741670;
              goto LABEL_33;
            }
            memset(Interrupt, 0i64, sizeof(_KINTERRUPT));
            LOBYTE(Vector) = ConnectionDataa[0];
            LODWORD(v54) = (_DWORD)v60;
            LOBYTE(v53) = FloatingSave;
            LODWORD(ServiceContexta) = v58;
            LOBYTE(v51) = ShareVector;
            LOBYTE(v50) = v57[0];
            LODWORD(v49) = v59;
            LODWORD(BugCheckParameter4) = (_DWORD)SpinLock;
            KeInitializeInterruptEx(
              v27,
              v66,
              (INT64 *)ServiceContext,
              MessageIndex,
              BugCheckParameter4,
              v63[0],
              v62,
              v49,
              v50,
              v51,
              ServiceContexta,
              v53,
              v54,
              v55,
              Vector,
              (_BYTE)v19 + 16,
              v57[0],
              v58,
              (UINT8)v60,
              GroupAffinity.Mask,
              GroupAffinity.Group,
              (UINT8)v62,
              *(_INTERRUPT_CONNECTION_DATA **)v63);
            v25 = v72;
            v19[ShareVectorb + 62] = v27;
            v22 = ++ShareVectorb;
          }
          v72 = ++v25;
        }
        while( v22 < (char)v17 );
      }
      if( !ShareVector )
      {
        v29 = IopAllocatePassiveInterruptBlock((_INTERRUPT_CONNECTION_DATA *)(v19 + 2), &GroupAffinity);
        if( v29 < 0 )
          goto LABEL_33;
      }
      IopAcquireActiveConnectLock(ConnectBlock);
      KeConnectInterrupt((_KINTERRUPT **)v19 + 62, v17, (_INTERRUPT_CONNECTION_DATA *)(v19 + 2));
      v29 = v28;
      IopReleaseActiveConnectLock(ConnectBlock);
      if( v29 < 0 )
      {
        if( !ShareVector )
          IopDestroyPassiveInterruptBlock(v59);
      }
      else
      {
        if( ServiceRoutine )
        {
          v30 = *(_QWORD *)(*((_QWORD *)ServiceRoutine + 39) + 40i64);
          if( !v30 || (*(_DWORD *)(v30 + 396) & 0x20000) != 0 )
          {
            IoAddTriageDumpDataBlock(ServiceRoutine, (_BYTE *)*((unsigned __int16 *)ServiceRoutine + 1));
            v39 = (__int16 *)*((_QWORD *)ServiceRoutine + 1);
            if( v39 )
            {
              IoAddTriageDumpDataBlock(v39, (_BYTE *)(unsigned int)v39[1]);
              v40 = (_WORD *)(*((_QWORD *)ServiceRoutine + 1) + 56i64);
              if( *v40 )
              {
                IoAddTriageDumpDataBlock(v40, (_BYTE *)2);
                IoAddTriageDumpDataBlock(
                  *(VOID **)(*((_QWORD *)ServiceRoutine + 1) + 64i64),
                  (_BYTE *)*(unsigned __int16 *)(*((_QWORD *)ServiceRoutine + 1) + 56i64));
              }
            }
            v41 = *(VOID ***)(*((_QWORD *)ServiceRoutine + 39) + 40i64);
            if( v41 )
            {
              v42 = v41 + 5;
              IoAddTriageDumpDataBlock(v41, (_BYTE *)0x310);
              if( *(_WORD *)v42 )
              {
                IoAddTriageDumpDataBlock(v42, (_BYTE *)2);
                IoAddTriageDumpDataBlock(v42[1], (_BYTE *)*(unsigned __int16 *)v42);
              }
              v43 = *((_QWORD *)ServiceRoutine + 39);
              v44 = (_WORD *)(*(_QWORD *)(v43 + 40) + 56i64);
              if( *v44 )
              {
                IoAddTriageDumpDataBlock(v44, (_BYTE *)2);
                IoAddTriageDumpDataBlock(
                  *(VOID **)(*(_QWORD *)(*((_QWORD *)ServiceRoutine + 39) + 40i64) + 64i64),
                  (_BYTE *)*(unsigned __int16 *)(*(_QWORD *)(*((_QWORD *)ServiceRoutine + 39) + 40i64) + 56i64));
                v43 = *((_QWORD *)ServiceRoutine + 39);
              }
              v45 = *(_QWORD *)(*(_QWORD *)(v43 + 40) + 16i64);
              if( v45 )
              {
                v46 = (_WORD *)(v45 + 56);
                if( *v46 )
                {
                  IoAddTriageDumpDataBlock(v46, (_BYTE *)2);
                  v47 = *(_QWORD *)(*(_QWORD *)(*((_QWORD *)ServiceRoutine + 39) + 40i64) + 16i64);
                  IoAddTriageDumpDataBlock(*(VOID **)(v47 + 64), (_BYTE *)*(unsigned __int16 *)(v47 + 56));
                }
              }
            }
            KeBugCheckEx(0xCAu, (PVOID)2, ServiceRoutine, 0i64, 0i64);
          }
          if( (char)v17 > 0 )
          {
            v31 = v19 + 62;
            v32 = (0x101010101010101i64
                 * ((((v14 - ((v14 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
                   + (((v14 - ((v14 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)
                   + ((((v14 - ((v14 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
                     + (((v14 - ((v14 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 56;
            do
            {
              ObfReferenceObjectWithTag(ServiceRoutine, 0x54706E50ui64);
              *((_QWORD *)*v31 + 35) = ServiceRoutine;
              _InterlockedIncrement((volatile signed __int32 *)(*((_QWORD *)ServiceRoutine + 39) + 96i64));
              ++v31;
              --v32;
            }
            while( v32 );
          }
        }
        v33 = v19[62];
        v34 = v19 + 14;
        v35 = 2i64;
        do
        {
          *v34 = *v33;
          v34[1] = v33[1];
          v34[2] = v33[2];
          v34[3] = v33[3];
          v34[4] = v33[4];
          v34[5] = v33[5];
          v34[6] = v33[6];
          v34 += 8;
          v36 = v33[7];
          v33 += 8;
          *(v34 - 1) = v36;
          --v35;
        }
        while( v35 );
        v29 = 0;
        *v34 = *v33;
        v34[1] = v33[1];
        *(_QWORD *)InterruptStructureOut = v19;
        PnpTraceInterruptConnection();
      }
      if( v29 < 0 )
      {
LABEL_33:
        if( (char)v17 > 0 )
        {
          v38 = (_KINTERRUPT **)(v19 + 62);
          do
          {
            if( *v38 )
              KeFreeInterrupt(*v38);
            ++v38;
            --v17;
          }
          while( v17 );
        }
        ExFreePoolWithTag(v19, 0x6E696F49u);
      }
    }
    else
    {
      v29 = -1073741670;
    }
  }
  else
  {
    v29 = -1073741811;
  }
  IopDestroyActiveConnectBlock(ConnectBlock);
  return v29;
}

Referenced by:

IoConnectInterruptEx
IopConnectInterruptFullySpecified
IopConnectLineBasedInterrupt
IopConnectMessageBasedInterrupt