IoDisconnectInterrupt
VOID __stdcall IoDisconnectInterrupt(_KINTERRUPT *InterruptObject){
unsigned __int64 v2;
unsigned __int64 v3;
unsigned int *p_Number;
INT64 v5;
_ETHREAD *CurrentThread;
char i;
_KINTERRUPT *v8;
unsigned __int16 *PhysicalDeviceObject;
__int64 v10;
__int64 v11;
_ETHREAD *v12;
char v13;
unsigned __int64 v14;
__int64 v15;
__int16 *v16;
_WORD *v17;
VOID **v18;
VOID **v19;
__int64 v20;
_WORD *v21;
__int64 v22;
_WORD *v23;
__int64 v24;
_ACTIVE_CONNECT_BLOCK ConnectBlock[20];
memset(ConnectBlock, 0i64, sizeof(ConnectBlock));
KeRemoveQueueDpc((_KDPC *)&InterruptObject[1].MessageServiceRoutine);
IopInitializeActiveConnectBlock((_INTERRUPT_CONNECTION_DATA *)&InterruptObject[-1].IsrDpcStats.IsrCount, ConnectBlock);
v2 = InterruptObject[-1].IsrDpcStats.IsrTimeStart
- ((InterruptObject[-1].IsrDpcStats.IsrTimeStart >> 1) & 0x5555555555555555i64);
v3 = (0x101010101010101i64
* (((v2 & 0x3333333333333333i64)
+ ((v2 >> 2) & 0x3333333333333333i64)
+ (((v2 & 0x3333333333333333i64) + ((v2 >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 56;
IopAcquireActiveConnectLock(ConnectBlock);
p_Number = &InterruptObject[1].Number;
LOBYTE(v5) = v3;
KeDisconnectInterrupt(
(_KINTERRUPT **)&InterruptObject[1].Number,
v5,
(_INTERRUPT_CONNECTION_DATA *)&InterruptObject[-1].IsrDpcStats.IsrCount);
IopReleaseActiveConnectLock(ConnectBlock);
if( LOBYTE(InterruptObject[1].Type) )
IopDestroyPassiveInterruptBlock(HIDWORD(InterruptObject[-1].IsrDpcStats.DpcTime));
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
--CurrentThread->Tcb.KernelApcDisable;
if( LOBYTE(InterruptObject[1].Type) )
{
v12 = (_ETHREAD *)KeGetCurrentThread();
v13 = 0;
if( (char)v3 <= 0 )
goto LABEL_17;
v14 = v3;
do
{
v15 = *(_QWORD *)p_Number;
p_Number += 2;
if( *(_ETHREAD **)(v15 + 152) == v12 )
v13 = 1;
--v14;
}
while( v14 );
if( !v13 )
LABEL_17:
KeWaitForSingleObject((UINT64)&InterruptObject[1].InterruptListEntry, 0, 0, 0, 0i64);
}
KeLeaveCriticalRegion();
for( i = 0; i < (char)v3; ++i )
{
v8 = (_KINTERRUPT *)*((_QWORD *)&InterruptObject[1].Number + i);
PhysicalDeviceObject = (unsigned __int16 *)v8->PhysicalDeviceObject;
if( PhysicalDeviceObject )
{
v10 = *((_QWORD *)PhysicalDeviceObject + 39);
v11 = *(_QWORD *)(v10 + 40);
if( !v11 || (*(_DWORD *)(v11 + 396) & 0x20000) != 0 )
{
IoAddTriageDumpDataBlock(v8->PhysicalDeviceObject, (_BYTE *)PhysicalDeviceObject[1]);
v16 = (__int16 *)*((_QWORD *)PhysicalDeviceObject + 1);
if( v16 )
{
IoAddTriageDumpDataBlock(v16, (_BYTE *)(unsigned int)v16[1]);
v17 = (_WORD *)(*((_QWORD *)PhysicalDeviceObject + 1) + 56i64);
if( *v17 )
{
IoAddTriageDumpDataBlock(v17, (_BYTE *)2);
IoAddTriageDumpDataBlock(
*(VOID **)(*((_QWORD *)PhysicalDeviceObject + 1) + 64i64),
(_BYTE *)*(unsigned __int16 *)(*((_QWORD *)PhysicalDeviceObject + 1) + 56i64));
}
}
v18 = *(VOID ***)(*((_QWORD *)PhysicalDeviceObject + 39) + 40i64);
if( v18 )
{
v19 = v18 + 5;
IoAddTriageDumpDataBlock(v18, (_BYTE *)0x310);
if( *(_WORD *)v19 )
{
IoAddTriageDumpDataBlock(v19, (_BYTE *)2);
IoAddTriageDumpDataBlock(v19[1], (_BYTE *)*(unsigned __int16 *)v19);
}
v20 = *((_QWORD *)PhysicalDeviceObject + 39);
v21 = (_WORD *)(*(_QWORD *)(v20 + 40) + 56i64);
if( *v21 )
{
IoAddTriageDumpDataBlock(v21, (_BYTE *)2);
IoAddTriageDumpDataBlock(
*(VOID **)(*(_QWORD *)(*((_QWORD *)PhysicalDeviceObject + 39) + 40i64) + 64i64),
(_BYTE *)*(unsigned __int16 *)(*(_QWORD *)(*((_QWORD *)PhysicalDeviceObject + 39) + 40i64) + 56i64));
v20 = *((_QWORD *)PhysicalDeviceObject + 39);
}
v22 = *(_QWORD *)(*(_QWORD *)(v20 + 40) + 16i64);
if( v22 )
{
v23 = (_WORD *)(v22 + 56);
if( *v23 )
{
IoAddTriageDumpDataBlock(v23, (_BYTE *)2);
v24 = *(_QWORD *)(*(_QWORD *)(*((_QWORD *)PhysicalDeviceObject + 39) + 40i64) + 16i64);
IoAddTriageDumpDataBlock(*(VOID **)(v24 + 64), (_BYTE *)*(unsigned __int16 *)(v24 + 56));
}
}
}
KeBugCheckEx(0xCAu, (PVOID)2, PhysicalDeviceObject, 0i64, 0i64);
}
_InterlockedDecrement((volatile signed __int32 *)(v10 + 96));
ObfDereferenceObjectWithTag(PhysicalDeviceObject, 0x54706E50ui64);
v8->PhysicalDeviceObject = 0i64;
}
KeFreeInterrupt(v8);
}
IopDestroyActiveConnectBlock(ConnectBlock);
ExFreePoolWithTag(&InterruptObject[-1].IsrDpcStats, 0);
PnpTraceInterruptConnection();
}Referenced by:
IoDisconnectInterruptEx
IopConnectLineBasedInterrupt
IopConnectMessageBasedInterrupt