IopConnectMessageBasedInterrupt

NTSTATUS __stdcall IopConnectMessageBasedInterrupt(
        UINT32 Version,
        PDEVICE_OBJECT PhysicalDeviceObject,
        PIO_INTERRUPT_MESSAGE_INFO *MessageTableOut,
        PKMESSAGE_SERVICE_ROUTINE ServiceRoutine,
        PVOID ServiceContext,
        PKSPIN_LOCK SpinLock,
        _KIRQL SynchronizeIrql,
        BOOL FloatingSave){
  unsigned int v8; 
  int v12; 
  VOID **v13; 
  unsigned __int8 v14; 
  _DWORD *DeviceNode; 
  NTSTATUS InterruptConnectionData; 
  _INTERRUPT_CONNECTION_DATA *v17; 
  NTSTATUS MessageRoutingInfo; 
  unsigned int v19; 
  unsigned __int8 *p_Irql; 
  unsigned __int8 v21; 
  VOID **PoolWithTag; 
  __int64 v23; 
  _INTERRUPT_VECTOR_DATA *v24; 
  unsigned __int8 Irql; 
  __int128 v26; 
  int v27; 
  __int128 v28; 
  __int128 v29; 
  __int128 v30; 
  __int64 v31; 
  __int128 TargetProcessors; 
  ULONG LowPart; 
  __int128 IntRemapInfo; 
  unsigned __int64 *v36; 
  BOOL ShareVector; 
  PINTERRUPT_CONNECTION_DATA v38; 
  char v39; 
  _INTERRUPT_CONNECTION_DATA *ConnectionDataOut; 
  PIO_INTERRUPT_STRUCTURE InterruptStructureOut[2]; 
  PVOID v42; 
  PKSERVICE_ROUTINE ServiceRoutinea; 
  PIO_INTERRUPT_MESSAGE_INFO *v44; 
  __int128 v45; 
  __int128 v46; 
  __int128 v47[2]; 
  _QWORD v48[12]; 

  v8 = 0;
  v44 = MessageTableOut;
  ServiceRoutinea = (PKSERVICE_ROUTINE)PhysicalDeviceObject;
  *MessageTableOut = 0i64;
  v42 = ServiceRoutine;
  *(_QWORD *)InterruptStructureOut = 0i64;
  ConnectionDataOut = 0i64;
  v39 = 0;
  v12 = 0;
  v45 = 0i64;
  v13 = 0i64;
  v14 = 0;
  v46 = 0i64;
  memset(v47, 0, 24);
  memset(v48, 0i64, sizeof(v48));
  if( !PhysicalDeviceObject )
    return -1073741811;
  DeviceNode = PhysicalDeviceObject->DeviceObjectExtension->DeviceNode;
  if( !DeviceNode || (DeviceNode[99] & 0x20000) != 0 || !ServiceRoutine )
    return -1073741811;
  InterruptConnectionData = IopGetInterruptConnectionData(PhysicalDeviceObject, &ConnectionDataOut);
  v17 = ConnectionDataOut;
  MessageRoutingInfo = InterruptConnectionData;
  if( InterruptConnectionData >= 0 )
  {
    v19 = 0;
    if( !ConnectionDataOut->Count )
      goto LABEL_39;
    p_Irql = &ConnectionDataOut->Vectors[0].Irql;
    do
    {
      v21 = v14;
      if( (unsigned int)(*((_DWORD *)p_Irql - 2) - 1) <= 2 )
      {
        ++v12;
        if( Version == 5 )
        {
          v39 = 1;
        }
        else if( Version == 3 )
        {
          if( (_BYTE)SynchronizeIrql )
          {
            if( (unsigned __int8)SynchronizeIrql < *p_Irql )
              goto LABEL_39;
            v14 = SynchronizeIrql;
          }
          else if( SpinLock )
          {
            v14 = *p_Irql;
            if( *p_Irql <= v21 )
              v14 = v21;
          }
          else
          {
            v14 = 0;
          }
        }
      }
      ++v19;
      p_Irql += 88;
    }
    while( v19 < ConnectionDataOut->Count );
    if( v12 )
    {
      PoolWithTag = ExAllocatePoolWithTag(0x200ui64, (unsigned int)(48 * v12 + 8), 1852403529i64);
      v13 = PoolWithTag;
      if( PoolWithTag )
      {
        memset(PoolWithTag, 0i64, 48 * v12 + 8);
        v23 = 0i64;
        *(_BYTE *)v13 = v14;
        for( LODWORD(ConnectionDataOut) = 0; (unsigned int)v23 < v17->Count; LODWORD(ConnectionDataOut) = v23 )
        {
          v24 = &v17->Vectors[v23];
          if( (unsigned int)(v24->Type - 1) <= 2 )
          {
            if( v39 )
            {
              Irql = 0;
            }
            else if( v14 )
            {
              Irql = v14;
            }
            else
            {
              Irql = v24->Irql;
            }
            v26 = *(_OWORD *)&v24->Mode;
            ShareVector = Irql;
            v27 = *((_DWORD *)v13 + 1);
            *(_OWORD *)&v48[1] = *(_OWORD *)&v24->Type;
            LODWORD(v36) = v27;
            v28 = *(_OWORD *)&v24->TargetProcessors.Group;
            *(_OWORD *)&v48[3] = v26;
            LODWORD(v48[0]) = 1;
            v29 = *(_OWORD *)&v24->IntRemapInfo.u.MessageAddressLow;
            *(_OWORD *)&v48[5] = v28;
            v30 = *(_OWORD *)&v24->HvDeviceId;
            *(_OWORD *)&v48[7] = v29;
            *(_QWORD *)&v29 = *((_QWORD *)&v24->MessageRequest + 1);
            *(_OWORD *)&v48[9] = v30;
            v48[11] = v29;
            MessageRoutingInfo = IopConnectInterrupt(
                                   InterruptStructureOut,
                                   ServiceRoutinea,
                                   0i64,
                                   v42,
                                   (UINT32)ServiceContext,
                                   v36,
                                   (_KIRQL)SpinLock,
                                   ShareVector,
                                   1u,
                                   v38);
            if( MessageRoutingInfo < 0 )
              goto LABEL_29;
            v31 = 6i64 * *((unsigned int *)v13 + 1);
            if( v24->Type == InterruptTypeMessageRequest )
            {
              TargetProcessors = (__int128)v24->TargetProcessors;
              DWORD2(v45) = v24->Vector;
              LowPart = v24->XapicMessage.Address.anonymous_0.LowPart;
              v46 = TargetProcessors;
              LODWORD(v45) = 0;
              IntRemapInfo = (__int128)v24->IntRemapInfo;
              LODWORD(v47[0]) = LowPart;
              *(__int128 *)((char *)v47 + 4) = IntRemapInfo;
              MessageRoutingInfo = HalGetMessageRoutingInfo((int *)&v45, v48);
              if( MessageRoutingInfo < 0 )
                goto LABEL_29;
              v24 = (_INTERRUPT_VECTOR_DATA *)&v48[1];
            }
            v13[v31 + 1] = (VOID *)v24->XapicMessage.Address.QuadPart;
            LODWORD(v13[v31 + 4]) = v24->XapicMessage.DataPayload;
            v13[v31 + 2] = (VOID *)v24->TargetProcessors.Mask;
            v13[v31 + 3] = (VOID *)(*(_QWORD *)InterruptStructureOut + 112i64);
            HIDWORD(v13[v31 + 4]) = v24->Vector;
            LOBYTE(v13[v31 + 5]) = v24->Irql;
            HIDWORD(v13[v31 + 5]) = v24->Mode;
            LODWORD(v13[v31 + 6]) = v24->Polarity;
            ++*((_DWORD *)v13 + 1);
          }
          v23 = (unsigned int)((_DWORD)ConnectionDataOut + 1);
        }
        MessageRoutingInfo = 0;
        *v44 = (PIO_INTERRUPT_MESSAGE_INFO)v13;
      }
      else
      {
        MessageRoutingInfo = -1073741670;
      }
    }
    else
    {
LABEL_39:
      MessageRoutingInfo = -1073741811;
    }
  }
LABEL_29:
  if( v17 )
    ExFreePoolWithTag(v17, 0);
  if( MessageRoutingInfo < 0 && v13 )
  {
    if( *((_DWORD *)v13 + 1) )
    {
      do
        IoDisconnectInterrupt((_KINTERRUPT *)v13[6 * v8++ + 3]);
      while( v8 < *((_DWORD *)v13 + 1) );
    }
    ExFreePoolWithTag(v13, 0);
  }
  return MessageRoutingInfo;
}

Referenced by:

IoConnectInterruptEx