IopConnectInterrupt
NTSTATUS __stdcall IopConnectInterrupt(
PIO_INTERRUPT_STRUCTURE *InterruptStructureOut,
PKSERVICE_ROUTINE ServiceRoutine,
PKMESSAGE_SERVICE_ROUTINE MessageServiceRoutine,
PVOID ServiceContext,
_KINTERRUPT *MessageIndex,
PKSPIN_LOCK SpinLock,
_KIRQL SynchronizeIrql,
BOOL ShareVector,
BOOL FloatingSave,
PINTERRUPT_CONNECTION_DATA ConnectionData){
_GROUP_AFFINITY TargetProcessors;
_KINTERRUPT_MODE Mode;
unsigned __int64 v14;
unsigned __int8 Irql;
unsigned __int64 v17;
VOID **PoolWithTag;
VOID **v19;
_KINTERRUPT_MODE v20;
VOID **v21;
char v22;
_GROUP_AFFINITY v23;
INT64 *v24;
unsigned __int8 v25;
_KINTERRUPT *Interrupt;
_KINTERRUPT *v27;
int v28;
int v29;
__int64 v30;
VOID **v31;
unsigned __int64 v32;
_OWORD *v33;
_OWORD *v34;
__int64 v35;
__int128 v36;
_KINTERRUPT **v38;
__int16 *v39;
_WORD *v40;
VOID **v41;
VOID **v42;
__int64 v43;
_WORD *v44;
__int64 v45;
_WORD *v46;
__int64 v47;
VOID *BugCheckParameter4;
_KINTERRUPT *v49;
VOID *v50;
UINT64 v51;
VOID *ServiceContexta;
UINT64 v53;
UINT64 *v54;
_KEVENT *v55;
UINT64 Vector;
UINT16 v57[4];
_KINTERRUPT_MODE v58;
unsigned int v59;
UINT64 *v60;
_GROUP_AFFINITY GroupAffinity;
INT64 *v62;
UINT8 v63[8];
_ACTIVE_CONNECT_BLOCK ConnectBlock[32];
UINT8 v66;
bool ShareVectora;
char ShareVectorb;
char ConnectionDataa[8];
_INTERRUPT_CONNECTION_DATA *v71;
char v72;
v66 = (unsigned __int8)MessageServiceRoutine;
memset(ConnectBlock, 0i64, 0x50u);
*(_QWORD *)InterruptStructureOut = 0i64;
*(_DWORD *)&v57[2] = 0;
ConnectionDataa[0] = 0;
IopInitializeActiveConnectBlock(v71, ConnectBlock);
TargetProcessors = v71->Vectors[0].TargetProcessors;
Mode = v71->Vectors[0].Mode;
v59 = v71->Vectors[0].Vector;
GroupAffinity = TargetProcessors;
v58 = Mode;
v14 = TargetProcessors.Mask & KeActiveProcessors.Bitmap[(unsigned __int16)_mm_extract_epi16(
(__m128i)TargetProcessors,
4)];
Irql = v71->Vectors[0].Irql;
GroupAffinity.Mask = v14;
LOBYTE(v57[0]) = Irql;
if( v71->Vectors[0].Type == InterruptTypeControllerInput
&& !((unsigned __int8(__fastcall *)(_QWORD, _QWORD))off_140C00780[0])(0i64, v71->Vectors[0].ControllerInput.Gsiv)
&& (unsigned int)(v71->Vectors[0].Polarity - 3) <= 1 )
{
ConnectionDataa[0] = 1;
v58 = LevelSensitive;
}
ShareVectora = !ShareVector;
if( KeVerifyGroupAffinity(&GroupAffinity, 0)
&& (v17 = (0x101010101010101i64
* ((((v14 - ((v14 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v14 - ((v14 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)
+ ((((v14 - ((v14 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v14 - ((v14 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 56,
(_BYTE)v17) )
{
PoolWithTag = ExAllocatePoolWithTag(0x200ui64, (unsigned int)(8 * (char)v17 + 496), 1852403529i64);
v19 = PoolWithTag;
if( PoolWithTag )
{
memset(PoolWithTag, 0i64, 8 * (char)v17 + 496);
KeInitializeDpc((PRKDPC)(v19 + 54), 0i64, 0i64);
v20 = v58;
*((_OWORD *)v19 + 1) = *(_OWORD *)&v71->Count;
v21 = v19;
v22 = 0;
*((_OWORD *)v19 + 2) = *(_OWORD *)&v71->Vectors[0].Irql;
HIBYTE(v57[3]) = 0;
*((_OWORD *)v19 + 3) = v71->Vectors[0].TargetProcessors;
*((_OWORD *)v19 + 4) = v71->Vectors[0].IntRemapInfo;
*((_OWORD *)v19 + 5) = *(_OWORD *)&v71->Vectors[0].ControllerInput.Gsiv;
v23 = GroupAffinity;
*((_OWORD *)v19 + 6) = v71->Vectors[0].72;
*((_DWORD *)v19 + 10) = v20;
*((_GROUP_AFFINITY *)v19 + 3) = v23;
if( *(_QWORD *)&SynchronizeIrql )
v21 = *(VOID ***)&SynchronizeIrql;
v19[1] = (VOID *)v14;
*((_BYTE *)v19 + 400) = ShareVectora;
v24 = (INT64 *)(v19 + 51);
if( ShareVector )
v24 = 0i64;
*(_QWORD *)v63 = v21;
v62 = v24;
v25 = 0;
ShareVectorb = 0;
v72 = 0;
v57[2] = _mm_extract_epi16((__m128i)v23, 4);
if( (char)v17 > 0 )
{
do
{
if( _bittest64((const __int64 *)&v14, v25) )
{
LOBYTE(v57[3]) = v25;
LODWORD(v60) = KeGetProcessorIndexFromNumber(&v57[2]);
Interrupt = KeAllocateInterrupt(*(&KiProcessorBlock + (unsigned int)v60));
v27 = Interrupt;
if( !Interrupt )
{
v29 = -1073741670;
goto LABEL_33;
}
memset(Interrupt, 0i64, sizeof(_KINTERRUPT));
LOBYTE(Vector) = ConnectionDataa[0];
LODWORD(v54) = (_DWORD)v60;
LOBYTE(v53) = FloatingSave;
LODWORD(ServiceContexta) = v58;
LOBYTE(v51) = ShareVector;
LOBYTE(v50) = v57[0];
LODWORD(v49) = v59;
LODWORD(BugCheckParameter4) = (_DWORD)SpinLock;
KeInitializeInterruptEx(
v27,
v66,
(INT64 *)ServiceContext,
MessageIndex,
BugCheckParameter4,
v63[0],
v62,
v49,
v50,
v51,
ServiceContexta,
v53,
v54,
v55,
Vector,
(_BYTE)v19 + 16,
v57[0],
v58,
(UINT8)v60,
GroupAffinity.Mask,
GroupAffinity.Group,
(UINT8)v62,
*(_INTERRUPT_CONNECTION_DATA **)v63);
v25 = v72;
v19[ShareVectorb + 62] = v27;
v22 = ++ShareVectorb;
}
v72 = ++v25;
}
while( v22 < (char)v17 );
}
if( !ShareVector )
{
v29 = IopAllocatePassiveInterruptBlock((_INTERRUPT_CONNECTION_DATA *)(v19 + 2), &GroupAffinity);
if( v29 < 0 )
goto LABEL_33;
}
IopAcquireActiveConnectLock(ConnectBlock);
KeConnectInterrupt((_KINTERRUPT **)v19 + 62, v17, (_INTERRUPT_CONNECTION_DATA *)(v19 + 2));
v29 = v28;
IopReleaseActiveConnectLock(ConnectBlock);
if( v29 < 0 )
{
if( !ShareVector )
IopDestroyPassiveInterruptBlock(v59);
}
else
{
if( ServiceRoutine )
{
v30 = *(_QWORD *)(*((_QWORD *)ServiceRoutine + 39) + 40i64);
if( !v30 || (*(_DWORD *)(v30 + 396) & 0x20000) != 0 )
{
IoAddTriageDumpDataBlock(ServiceRoutine, (_BYTE *)*((unsigned __int16 *)ServiceRoutine + 1));
v39 = (__int16 *)*((_QWORD *)ServiceRoutine + 1);
if( v39 )
{
IoAddTriageDumpDataBlock(v39, (_BYTE *)(unsigned int)v39[1]);
v40 = (_WORD *)(*((_QWORD *)ServiceRoutine + 1) + 56i64);
if( *v40 )
{
IoAddTriageDumpDataBlock(v40, (_BYTE *)2);
IoAddTriageDumpDataBlock(
*(VOID **)(*((_QWORD *)ServiceRoutine + 1) + 64i64),
(_BYTE *)*(unsigned __int16 *)(*((_QWORD *)ServiceRoutine + 1) + 56i64));
}
}
v41 = *(VOID ***)(*((_QWORD *)ServiceRoutine + 39) + 40i64);
if( v41 )
{
v42 = v41 + 5;
IoAddTriageDumpDataBlock(v41, (_BYTE *)0x310);
if( *(_WORD *)v42 )
{
IoAddTriageDumpDataBlock(v42, (_BYTE *)2);
IoAddTriageDumpDataBlock(v42[1], (_BYTE *)*(unsigned __int16 *)v42);
}
v43 = *((_QWORD *)ServiceRoutine + 39);
v44 = (_WORD *)(*(_QWORD *)(v43 + 40) + 56i64);
if( *v44 )
{
IoAddTriageDumpDataBlock(v44, (_BYTE *)2);
IoAddTriageDumpDataBlock(
*(VOID **)(*(_QWORD *)(*((_QWORD *)ServiceRoutine + 39) + 40i64) + 64i64),
(_BYTE *)*(unsigned __int16 *)(*(_QWORD *)(*((_QWORD *)ServiceRoutine + 39) + 40i64) + 56i64));
v43 = *((_QWORD *)ServiceRoutine + 39);
}
v45 = *(_QWORD *)(*(_QWORD *)(v43 + 40) + 16i64);
if( v45 )
{
v46 = (_WORD *)(v45 + 56);
if( *v46 )
{
IoAddTriageDumpDataBlock(v46, (_BYTE *)2);
v47 = *(_QWORD *)(*(_QWORD *)(*((_QWORD *)ServiceRoutine + 39) + 40i64) + 16i64);
IoAddTriageDumpDataBlock(*(VOID **)(v47 + 64), (_BYTE *)*(unsigned __int16 *)(v47 + 56));
}
}
}
KeBugCheckEx(0xCAu, (PVOID)2, ServiceRoutine, 0i64, 0i64);
}
if( (char)v17 > 0 )
{
v31 = v19 + 62;
v32 = (0x101010101010101i64
* ((((v14 - ((v14 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v14 - ((v14 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)
+ ((((v14 - ((v14 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v14 - ((v14 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 56;
do
{
ObfReferenceObjectWithTag(ServiceRoutine, 0x54706E50ui64);
*((_QWORD *)*v31 + 35) = ServiceRoutine;
_InterlockedIncrement((volatile signed __int32 *)(*((_QWORD *)ServiceRoutine + 39) + 96i64));
++v31;
--v32;
}
while( v32 );
}
}
v33 = v19[62];
v34 = v19 + 14;
v35 = 2i64;
do
{
*v34 = *v33;
v34[1] = v33[1];
v34[2] = v33[2];
v34[3] = v33[3];
v34[4] = v33[4];
v34[5] = v33[5];
v34[6] = v33[6];
v34 += 8;
v36 = v33[7];
v33 += 8;
*(v34 - 1) = v36;
--v35;
}
while( v35 );
v29 = 0;
*v34 = *v33;
v34[1] = v33[1];
*(_QWORD *)InterruptStructureOut = v19;
PnpTraceInterruptConnection();
}
if( v29 < 0 )
{
LABEL_33:
if( (char)v17 > 0 )
{
v38 = (_KINTERRUPT **)(v19 + 62);
do
{
if( *v38 )
KeFreeInterrupt(*v38);
++v38;
--v17;
}
while( v17 );
}
ExFreePoolWithTag(v19, 0x6E696F49u);
}
}
else
{
v29 = -1073741670;
}
}
else
{
v29 = -1073741811;
}
IopDestroyActiveConnectBlock(ConnectBlock);
return v29;
}Referenced by:
IoConnectInterruptEx
IopConnectInterruptFullySpecified
IopConnectLineBasedInterrupt
IopConnectMessageBasedInterrupt