IoConnectInterruptEx
NTSTATUS __stdcall IoConnectInterruptEx(_IO_CONNECT_INTERRUPT_PARAMETERS *Parameters){
ULONG Version;
NTSTATUS result;
KIRQL v4;
KIRQL Irql;
char v6;
__int16 v7;
_INTERRUPT_CONNECTION_DATA *v8;
unsigned int v9;
__int64 v10;
KIRQL v11;
__int128 v12;
__m128i v13;
__int128 v14;
__int128 v15;
int v16;
__int64 v18;
VOID *v19;
_KINTERRUPT *ServiceRoutine;
UINT8 *PhysicalDeviceObject;
_KINTERRUPT **InterruptObject;
PKSPIN_LOCK ServiceContext;
PKSPIN_LOCK SpinLock;
PKSPIN_LOCK SpinLocka;
UINT64 *SynchronizeIrql;
UINT64 *SynchronizeIrqla;
UINT64 ShareVector;
UINT64 ShareVectora;
UINT64 FloatingSave;
_KINTERRUPT_MODE InterruptMode;
_GROUP_AFFINITY *v32;
UINT8 v33[16];
int v34;
_DWORD v35[23];
_INTERRUPT_CONNECTION_DATA *ConnectionDataOut;
__int64 InterruptStructureOut;
ConnectionDataOut = 0i64;
InterruptStructureOut = 0i64;
if( KeGetCurrentIrql() )
KeBugCheckEx(0x121u, (PVOID)1, (PVOID)KeGetCurrentIrql(), 0i64, 0i64);
Version = Parameters->Version;
switch( Version )
{
case 1u:
goto LABEL_49;
case 2u:
LOBYTE(SpinLock) = Parameters->FullySpecified.SynchronizeIrql;
return IopConnectLineBasedInterrupt(
Parameters->FullySpecified.PhysicalDeviceObject,
Parameters->FullySpecified.InterruptObject,
(UINT8 *)Parameters->FullySpecified.ServiceRoutine,
(_KINTERRUPT *)Parameters->FullySpecified.ServiceContext,
Parameters->FullySpecified.SpinLock,
SpinLock,
SynchronizeIrql,
ShareVector,
FloatingSave);
case 3u:
goto LABEL_5;
case 4u:
LABEL_49:
if( !Parameters->FullySpecified.PhysicalDeviceObject )
return -1073741811;
if( !Parameters->FullySpecified.ServiceRoutine )
return -1073741811;
v4 = Parameters->FullySpecified.SynchronizeIrql;
Irql = Parameters->FullySpecified.Irql;
if( v4 < Irql )
return -1073741811;
if( v4 || Irql )
{
v6 = 0;
}
else
{
v6 = 1;
if( Parameters->FullySpecified.SpinLock )
return -1073741811;
}
if( Version == 4 )
v7 = Parameters[1].Version;
else
v7 = 0;
if( IopGetInterruptConnectionData(Parameters->FullySpecified.PhysicalDeviceObject, &ConnectionDataOut) >= 0 )
{
memset(v35, 0i64, sizeof(v35));
v8 = ConnectionDataOut;
v9 = 0;
v34 = 0;
if( ConnectionDataOut->Count )
{
while( 1 )
{
v10 = v9;
if( ConnectionDataOut->Vectors[v10].Vector == Parameters->FullySpecified.Vector )
{
v11 = Parameters->FullySpecified.Irql;
if( (ConnectionDataOut->Vectors[v10].Irql == v11 || !v11)
&& ConnectionDataOut->Vectors[v10].Mode == Parameters->FullySpecified.InterruptMode
&& ConnectionDataOut->Vectors[v10].TargetProcessors.Group == v7
&& ConnectionDataOut->Vectors[v10].TargetProcessors.Mask == *((_QWORD *)&Parameters->MessageBased + 7) )
{
break;
}
}
if( ++v9 >= ConnectionDataOut->Count )
goto LABEL_42;
}
v34 = 1;
v12 = *(_OWORD *)&ConnectionDataOut->Vectors[v9].TargetProcessors.Group;
v13 = *(__m128i *)&ConnectionDataOut->Vectors[v9].Type;
*(_OWORD *)&v35[5] = *(_OWORD *)&ConnectionDataOut->Vectors[v9].Mode;
v14 = *(_OWORD *)&ConnectionDataOut->Vectors[v9].IntRemapInfo.u.MessageAddressLow;
*(_OWORD *)&v35[9] = v12;
v15 = *(_OWORD *)&ConnectionDataOut->Vectors[v9].HvDeviceId;
*(_OWORD *)&v35[13] = v14;
*(_QWORD *)&v14 = *((_QWORD *)&ConnectionDataOut->Vectors[v9].MessageRequest + 1);
*(__m128i *)&v35[1] = v13;
*(_QWORD *)&v35[21] = v14;
*(_OWORD *)&v35[17] = v15;
if( !_mm_cvtsi128_si32(v13) && (v35[16] & 1) != 0 )
Parameters->FullySpecified.ShareVector = 1;
LODWORD(SpinLock) = 0;
v16 = IopConnectInterrupt(
(PIO_INTERRUPT_STRUCTURE *)&InterruptStructureOut,
(PKSERVICE_ROUTINE)Parameters->FullySpecified.PhysicalDeviceObject,
Parameters->MessageBased.MessageServiceRoutine,
0i64,
(UINT32)Parameters->FullySpecified.ServiceContext,
SpinLock,
(_KIRQL)Parameters->FullySpecified.SpinLock,
Parameters->FullySpecified.SynchronizeIrql,
Parameters->FullySpecified.ShareVector,
InterruptMode);
if( v16 >= 0 )
*Parameters->FullySpecified.InterruptObject = (PKINTERRUPT)(InterruptStructureOut + 112);
ExFreePoolWithTag(v8, 0);
return v16;
}
LABEL_42:
ExFreePoolWithTag(ConnectionDataOut, 0);
return -1073741637;
}
if( v6 )
return -1073741637;
v18 = *((_QWORD *)&Parameters->MessageBased + 7);
v19 = Parameters->FullySpecified.ServiceContext;
ServiceRoutine = (_KINTERRUPT *)Parameters->FullySpecified.ServiceRoutine;
PhysicalDeviceObject = (UINT8 *)Parameters->FullySpecified.PhysicalDeviceObject;
InterruptObject = Parameters->FullySpecified.InterruptObject;
*(_QWORD *)&v33[8] = 0i64;
*(_QWORD *)v33 = v18;
LOBYTE(InterruptMode) = Parameters->FullySpecified.ShareVector;
LODWORD(FloatingSave) = Parameters->FullySpecified.InterruptMode;
LOBYTE(ShareVector) = Parameters->FullySpecified.SynchronizeIrql;
LOBYTE(SynchronizeIrql) = Parameters->FullySpecified.Irql;
LODWORD(SpinLock) = Parameters->FullySpecified.Vector;
ServiceContext = Parameters->FullySpecified.SpinLock;
*(_WORD *)&v33[8] = v7;
return IopConnectInterruptFullySpecified(
InterruptObject,
PhysicalDeviceObject,
ServiceRoutine,
v19,
ServiceContext,
SpinLock,
(UINT64)SynchronizeIrql,
ShareVector,
FloatingSave,
InterruptMode,
(UINT8)v33,
v32,
v18);
}
if( Version != 5 )
{
Parameters->Version = 3;
return -1073741637;
}
LABEL_5:
LOBYTE(SynchronizeIrql) = Parameters->FullySpecified.SynchronizeIrql;
result = IopConnectMessageBasedInterrupt(
Version,
Parameters->FullySpecified.PhysicalDeviceObject,
Parameters->MessageBased.ConnectionContext.InterruptMessageTable,
Parameters->MessageBased.MessageServiceRoutine,
Parameters->FullySpecified.ServiceContext,
Parameters->FullySpecified.SpinLock,
(_KIRQL)SynchronizeIrql,
ShareVector);
if( result < 0 )
{
if( Parameters->MessageBased.FallBackServiceRoutine )
{
LOBYTE(SpinLocka) = Parameters->FullySpecified.SynchronizeIrql;
v16 = IopConnectLineBasedInterrupt(
Parameters->FullySpecified.PhysicalDeviceObject,
Parameters->FullySpecified.InterruptObject,
(UINT8 *)Parameters->MessageBased.FallBackServiceRoutine,
(_KINTERRUPT *)Parameters->FullySpecified.ServiceContext,
Parameters->FullySpecified.SpinLock,
SpinLocka,
SynchronizeIrqla,
ShareVectora,
FloatingSave);
Parameters->Version = 2;
return v16;
}
return -1073741637;
}
return result;
}Referenced by:
HalpInterruptConnect