KiDisconnectInterruptCommon
__int64 __fastcall KiDisconnectInterruptCommon(int a1, __int64 a2, struct _KEVENT *a3){
_ETHREAD *v4;
unsigned int v7;
char v8;
UINT64 *v9;
_INTERRUPT_CONNECTION_DATA *v10;
char OldIrql[8];
__int128 v13;
__int64 v14;
VOID *a1a[2];
__int64 v16;
struct _GROUP_AFFINITY PreviousAffinity;
a1a[1] = a3;
a1a[0] = 0i64;
v14 = 0i64;
v16 = 0i64;
v4 = *(_ETHREAD **)(a2 + 152);
v13 = 0i64;
OldIrql[0] = 0;
v7 = -1073741585;
v8 = 0;
PreviousAffinity = 0i64;
if( v4 != (_ETHREAD *)KeGetCurrentThread() )
{
LOWORD(v13) = 1;
v14 = (__int64)&v13 + 8;
*((_QWORD *)&v13 + 1) = (char *)&v13 + 8;
a1a[0] = &v13;
BYTE2(v13) = 6;
DWORD1(v13) = 0;
}
if( a1 )
{
v9 = (UINT64 *)(KiGlobalSecondaryIDT + 48i64 * (unsigned int)(*(_DWORD *)(a2 + 88) - 256));
KiAcquireSecondaryInterruptConnectLock(v9, (UINT8 *)OldIrql);
}
else
{
v9 = 0i64;
KiAcquireInterruptConnectLock(*(unsigned int *)(a2 + 96), (UINT8 *)OldIrql, &PreviousAffinity);
}
if( *(_BYTE *)(a2 + 95) && (*(_DWORD *)(a2 + 104) & 2) == 0 )
{
if( *(_WORD *)(a2 + 102) )
{
_InterlockedOr((volatile signed __int32 *)(a2 + 104), 2u);
v8 = 1;
*(_QWORD *)(a2 + 144) = a1a;
}
else
{
if( !a1 )
{
v7 = KiDisconnectInterruptInternal((_KINTERRUPT *)a2, (_INTERRUPT_CONNECTION_DATA *)a3);
goto LABEL_10;
}
v7 = KiDisconnectSecondaryInterruptInternal((_KINTERRUPT *)a2, v10);
}
}
if( a1 )
{
KxReleaseSpinLock(v9);
__writecr8((unsigned __int8)OldIrql[0]);
goto LABEL_11;
}
LABEL_10:
__writecr8((unsigned __int8)OldIrql[0]);
KeRevertToUserGroupAffinityThread(&PreviousAffinity);
LABEL_11:
if( a1a[0] && v8 )
{
KiSignalWaitDisconnectLock(a1a[0], 1);
return(unsigned int)v16;
}
return v7;
}Referenced by:
KeDisconnectInterrupt
KiDisconnectSecondaryInterrupt