IoDisconnectInterrupt

void __stdcall IoDisconnectInterrupt(PKINTERRUPT InterruptObject){
  unsigned __int64 v2; 
  unsigned __int64 v3; 
  unsigned int *p_Number; 
  _ETHREAD *CurrentThread; 
  char i; 
  _KINTERRUPT *v7; 
  ULONG_PTR PhysicalDeviceObject; 
  __int64 v9; 
  __int64 v10; 
  _ETHREAD *v11; 
  char v12; 
  unsigned __int64 v13; 
  __int64 v14; 
  __int16 *v15; 
  _WORD *v16; 
  PVOID *v17; 
  PVOID *v18; 
  __int64 v19; 
  _WORD *v20; 
  __int64 v21; 
  _WORD *v22; 
  __int64 v23; 
  __int64 a2[10]; 
  memset((INT64)a2, 0i64);
  KeRemoveQueueDpc((_KDPC *)&InterruptObject[1].MessageServiceRoutine);
  IopInitializeActiveConnectBlock((INT64)&InterruptObject[-1].IsrDpcStats.IsrCount, a2);
  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((INT64)a2);
  p_Number = &InterruptObject[1].Number;
  KeDisconnectInterrupt(
    (_KINTERRUPT **)&InterruptObject[1].Number,
    v3,
    (_INTERRUPT_CONNECTION_DATA *)&InterruptObject[-1].IsrDpcStats.IsrCount);
  IopReleaseActiveConnectLock((INT64)a2);
  if( LOBYTE(InterruptObject[1].Type) )
    IopDestroyPassiveInterruptBlock(HIDWORD(InterruptObject[-1].IsrDpcStats.DpcTime));
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --*((_WORD *)CurrentThread + 242);
  if( LOBYTE(InterruptObject[1].Type) )
  {
    v11 = (_ETHREAD *)KeGetCurrentThread();
    v12 = 0;
    if( (char)v3 <= 0 )
      goto LABEL_17;
    v13 = v3;
    do
    {
      v14 = *(_QWORD *)p_Number;
      p_Number += 2;
      if( *(_ETHREAD **)(v14 + 152) == v11 )
        v12 = 1;
      --v13;
    }
    while( v13 );
    if( !v12 )
LABEL_17:
      KeWaitForSingleObject(&InterruptObject[1].InterruptListEntry, Executive, 0, 0, 0i64);
  }
  KeLeaveCriticalRegion();
  for( i = 0; i < (char)v3; ++i )
  {
    v7 = (_KINTERRUPT *)*((_QWORD *)&InterruptObject[1].Number + i);
    PhysicalDeviceObject = (ULONG_PTR)v7->PhysicalDeviceObject;
    if( PhysicalDeviceObject )
    {
      v9 = *(_QWORD *)(PhysicalDeviceObject + 312);
      v10 = *(_QWORD *)(v9 + 40);
      if( !v10 || (*(_DWORD *)(v10 + 396) & 0x20000) != 0 )
      {
        IoAddTriageDumpDataBlock(v7->PhysicalDeviceObject, *(unsigned __int16 *)(PhysicalDeviceObject + 2));
        v15 = *(__int16 **)(PhysicalDeviceObject + 8);
        if( v15 )
        {
          IoAddTriageDumpDataBlock(v15, (unsigned int)v15[1]);
          v16 = (_WORD *)(*(_QWORD *)(PhysicalDeviceObject + 8) + 56i64);
          if( *v16 )
          {
            IoAddTriageDumpDataBlock(v16, 2ui64);
            IoAddTriageDumpDataBlock(
              *(PVOID *)(*(_QWORD *)(PhysicalDeviceObject + 8) + 64i64),
              *(unsigned __int16 *)(*(_QWORD *)(PhysicalDeviceObject + 8) + 56i64));
          }
        }
        v17 = *(PVOID **)(*(_QWORD *)(PhysicalDeviceObject + 312) + 40i64);
        if( v17 )
        {
          v18 = v17 + 5;
          IoAddTriageDumpDataBlock(v17, 0x310ui64);
          if( *(_WORD *)v18 )
          {
            IoAddTriageDumpDataBlock(v18, 2ui64);
            IoAddTriageDumpDataBlock(v18[1], *(unsigned __int16 *)v18);
          }
          v19 = *(_QWORD *)(PhysicalDeviceObject + 312);
          v20 = (_WORD *)(*(_QWORD *)(v19 + 40) + 56i64);
          if( *v20 )
          {
            IoAddTriageDumpDataBlock(v20, 2ui64);
            IoAddTriageDumpDataBlock(
              *(PVOID *)(*(_QWORD *)(*(_QWORD *)(PhysicalDeviceObject + 312) + 40i64) + 64i64),
              *(unsigned __int16 *)(*(_QWORD *)(*(_QWORD *)(PhysicalDeviceObject + 312) + 40i64) + 56i64));
            v19 = *(_QWORD *)(PhysicalDeviceObject + 312);
          }
          v21 = *(_QWORD *)(*(_QWORD *)(v19 + 40) + 16i64);
          if( v21 )
          {
            v22 = (_WORD *)(v21 + 56);
            if( *v22 )
            {
              IoAddTriageDumpDataBlock(v22, 2ui64);
              v23 = *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(PhysicalDeviceObject + 312) + 40i64) + 16i64);
              IoAddTriageDumpDataBlock(*(PVOID *)(v23 + 64), *(unsigned __int16 *)(v23 + 56));
            }
          }
        }
        KeBugCheckEx(0xCAu, 2ui64, PhysicalDeviceObject, 0i64, 0i64);
      }
      _InterlockedDecrement((volatile signed __int32 *)(v9 + 96));
      ObfDereferenceObjectWithTag((PVOID)PhysicalDeviceObject, 0x54706E50ui64);
      v7->PhysicalDeviceObject = 0i64;
    }
    KeFreeInterrupt(v7);
  }
  IopDestroyActiveConnectBlock((volatile INT32 *)a2);
  ExFreePoolWithTag(&InterruptObject[-1].IsrDpcStats, 0);
  PnpTraceInterruptConnection();
}

Referenced by:

IoDisconnectInterruptEx
IopConnectLineBasedInterrupt
IopConnectMessageBasedInterrupt