IopConnectLineBasedInterrupt

NTSTATUS __stdcall IopConnectLineBasedInterrupt(
        _DEVICE_OBJECT *PhysicalDeviceObject,
        _KINTERRUPT **InterruptObject,
        UINT8 *ServiceRoutine,
        _KINTERRUPT *a4,
        VOID *a5,
        VOID *ServiceContext,
        UINT64 *SpinLock,
        UINT64 SynchronizeIrql,
        UINT8 FloatingSave){
  VOID **v9; 
  unsigned int v10; 
  _DWORD *DeviceNode; 
  NTSTATUS result; 
  int v13; 
  _INTERRUPT_CONNECTION_DATA *v14; 
  unsigned int v15; 
  unsigned __int8 ShareVector; 
  _INTERRUPT_VECTOR_DATA *Vectors; 
  __int64 Count; 
  unsigned __int8 Irql; 
  VOID **PoolWithTag; 
  unsigned int v21; 
  __int64 v22; 
  __int128 v23; 
  __int128 v24; 
  __int128 v25; 
  __int128 v26; 
  __int64 v27; 
  VOID **v28; 
  _OWORD *v29; 
  __int128 v30; 
  VOID **v31; 
  __int64 v32; 
  unsigned __int64 *v33; 
  PINTERRUPT_CONNECTION_DATA v34; 
  _INTERRUPT_CONNECTION_DATA *ConnectionDataOut; 
  int i; 
  _DWORD v37[23]; 
  UINT32 MessageIndex; 

  MessageIndex = (unsigned int)a4;
  ConnectionDataOut = 0i64;
  v9 = 0i64;
  *InterruptObject = 0i64;
  v10 = 0;
  if( !PhysicalDeviceObject )
    return -1073741811;
  DeviceNode = PhysicalDeviceObject->DeviceObjectExtension->DeviceNode;
  if( !DeviceNode || (DeviceNode[99] & 0x20000) != 0 || !ServiceRoutine )
    return -1073741811;
  result = IopGetInterruptConnectionData(PhysicalDeviceObject, &ConnectionDataOut);
  v13 = result;
  if( result >= 0 )
  {
    v14 = ConnectionDataOut;
    if( ConnectionDataOut )
    {
      v15 = 0;
      ShareVector = 0;
      if( ConnectionDataOut->Count )
      {
        Vectors = ConnectionDataOut->Vectors;
        Count = ConnectionDataOut->Count;
        do
        {
          if( Vectors->Type == InterruptTypeControllerInput )
          {
            ++v15;
            Irql = ShareVector;
            if( ShareVector < Vectors->Irql )
              Irql = Vectors->Irql;
            ShareVector = Irql;
          }
          ++Vectors;
          --Count;
        }
        while( Count );
        if( v15 )
        {
          if( !(_BYTE)ServiceContext )
            goto LABEL_18;
          if( (unsigned __int8)ServiceContext >= ShareVector )
          {
            ShareVector = (unsigned __int8)ServiceContext;
LABEL_18:
            PoolWithTag = ExAllocatePoolWithTag(0x200ui64, 8 * v15 + 296, 1852403529i64);
            v9 = PoolWithTag;
            if( PoolWithTag )
            {
              memset(PoolWithTag, 0i64, 8 * v15 + 296);
              *((_BYTE *)v9 + 288) = ShareVector;
              *((_DWORD *)v9 + 73) = v15;
              memset(v37, 0i64, sizeof(v37));
              v21 = 0;
              for( i = 1; v21 < v14->Count; ++v21 )
              {
                v22 = v21;
                if( v14->Vectors[v22].Type == InterruptTypeControllerInput )
                {
                  v23 = *(_OWORD *)&v14->Vectors[v22].Mode;
                  *(_OWORD *)&v37[1] = *(_OWORD *)&v14->Vectors[v22].Type;
                  v24 = *(_OWORD *)&v14->Vectors[v22].TargetProcessors.Group;
                  *(_OWORD *)&v37[5] = v23;
                  v25 = *(_OWORD *)&v14->Vectors[v22].IntRemapInfo.u.MessageAddressLow;
                  *(_OWORD *)&v37[9] = v24;
                  v26 = *(_OWORD *)&v14->Vectors[v22].HvDeviceId;
                  *(_OWORD *)&v37[13] = v25;
                  *(_QWORD *)&v37[21] = *((_QWORD *)&v14->Vectors[v22].MessageRequest + 1);
                  LODWORD(v33) = 0;
                  *(_OWORD *)&v37[17] = v26;
                  v13 = IopConnectInterrupt(
                          (PIO_INTERRUPT_STRUCTURE *)&v9[v10 + 37],
                          (PKSERVICE_ROUTINE)PhysicalDeviceObject,
                          (PKMESSAGE_SERVICE_ROUTINE)ServiceRoutine,
                          0i64,
                          MessageIndex,
                          v33,
                          (_KIRQL)a5,
                          ShareVector,
                          1u,
                          v34);
                  if( v13 < 0 )
                    goto LABEL_26;
                  if( ++v10 >= v15 )
                    break;
                }
              }
              v27 = 2i64;
              v28 = v9;
              v29 = (char *)v9[37] + 112;
              do
              {
                *(_OWORD *)v28 = *v29;
                *((_OWORD *)v28 + 1) = v29[1];
                *((_OWORD *)v28 + 2) = v29[2];
                *((_OWORD *)v28 + 3) = v29[3];
                *((_OWORD *)v28 + 4) = v29[4];
                *((_OWORD *)v28 + 5) = v29[5];
                *((_OWORD *)v28 + 6) = v29[6];
                v28 += 16;
                v30 = v29[7];
                v29 += 8;
                *((_OWORD *)v28 - 1) = v30;
                --v27;
              }
              while( v27 );
              *(_OWORD *)v28 = *v29;
              *((_OWORD *)v28 + 1) = v29[1];
              *InterruptObject = (_KINTERRUPT *)v9;
            }
            else
            {
              v13 = -1073741670;
            }
            goto LABEL_26;
          }
        }
      }
      v13 = -1073741811;
LABEL_26:
      ExFreePoolWithTag(v14, 0);
      if( v13 < 0 && v9 )
      {
        if( v10 )
        {
          v31 = v9 + 37;
          v32 = v10;
          do
          {
            IoDisconnectInterrupt((_KINTERRUPT *)((char *)*v31++ + 112));
            --v32;
          }
          while( v32 );
        }
        ExFreePoolWithTag(v9, 0);
      }
      return v13;
    }
  }
  return result;
}

Referenced by:

IoConnectInterruptEx