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