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