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