KiDisconnectInterruptInternal

VOID __fastcall KiDisconnectInterruptInternal(_KINTERRUPT *Interrupt, _INTERRUPT_CONNECTION_DATA *ConnectionData){
  char v4; 
  __int64 Vector; 
  _KINTERRUPT *p_Blink; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *v8; 
  _LIST_ENTRY *Blink; 
  __int64 v10; 

  v4 = 0;
  if( Interrupt->Connected )
  {
    Vector = Interrupt->Vector;
    p_Blink = (_KINTERRUPT *)KeGetCurrentPrcb()->InterruptObject[Vector];
    if( !p_Blink->SynchronizeIrql )
    {
      Flink = p_Blink->InterruptListEntry.Flink;
      if( !Flink || Flink == &p_Blink->InterruptListEntry )
        v4 = 1;
    }
    if( (NTSTATUS(__stdcall *)())p_Blink->DispatchAddress != KiChainedDispatch || v4 )
    {
      HalDisableInterrupt(ConnectionData);
      KeGetCurrentPrcb()->InterruptObject[Vector] = 0i64;
    }
    else
    {
      if( Interrupt == p_Blink )
      {
        p_Blink = (_KINTERRUPT *)&p_Blink->InterruptListEntry.Flink[-1].Blink;
        p_Blink->DispatchAddress = (void(__fastcall *)())KiChainedDispatch;
        KeGetCurrentPrcb()->InterruptObject[Vector] = p_Blink;
      }
      v8 = Interrupt->InterruptListEntry.Flink;
      Blink = Interrupt->InterruptListEntry.Blink;
      if( v8->Blink != &Interrupt->InterruptListEntry || Blink->Flink != &Interrupt->InterruptListEntry )
        __fastfail(3u);
      Blink->Flink = v8;
      v8->Blink = Blink;
      v10 = (__int64)&p_Blink->InterruptListEntry.Flink[-1].Blink;
      if( p_Blink == (_KINTERRUPT *)v10 )
      {
        if( *(_BYTE *)(v10 + 93) )
        {
          *(_QWORD *)(v10 + 80) = KiInterruptDispatch;
          KeGetCurrentPrcb()->InterruptObject[Vector] = (void *)v10;
        }
      }
    }
    Interrupt->Connected = 0;
  }
}

Referenced by:

KiDisconnectInterruptCommon
KiProcessPendingDisconnect