AlpcpDisconnectPort

INT64 __fastcall AlpcpDisconnectPort(INT64 DmaAdapter, CHAR a2){
  INT64 *v2; 
  volatile signed __int64 *v5; 
  int v6; 
  unsigned int v7; 
  int v8; 
  INT64 v9; 
  INT64 v10; 
  int v11; 
  int v12; 
  int v13; 
  _LIST_ENTRY *Flink; 
  ULONG_PTR v16; 
  _LIST_ENTRY CanceledQueue; 
  INT64 v18; 
  v2 = *(INT64 **)(DmaAdapter + 16);
  CanceledQueue = 0i64;
  ExAcquirePushLockExclusiveEx((UINT64)(v2 - 2), 0i64);
  v5 = (volatile signed __int64 *)(DmaAdapter + 352);
  ExAcquirePushLockExclusiveEx(DmaAdapter + 352, 0i64);
  if( (a2 & 1) != 0 )
    *(_DWORD *)(DmaAdapter + 416) |= 0x80u;
  v6 = *(_DWORD *)(DmaAdapter + 416);
  if( (v6 & 0x20) != 0 )
  {
    if( (_InterlockedExchangeAdd64(v5, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((volatile INT64 *)(DmaAdapter + 352));
    KeAbPostRelease((PVOID)(DmaAdapter + 352));
    if( (_InterlockedExchangeAdd64(v2 - 2, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(v2 - 2);
    KeAbPostRelease(v2 - 2);
    return 3221225527i64;
  }
  else
  {
    *(_DWORD *)(DmaAdapter + 416) = v6 | 0x20;
    if( (_InterlockedExchangeAdd64(v5, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((volatile INT64 *)(DmaAdapter + 352));
    KeAbPostRelease((PVOID)(DmaAdapter + 352));
    v7 = *(_DWORD *)(DmaAdapter + 416);
    if( (v7 & 6) == 2 )
    {
      AlpcpWalkConnectionList(DmaAdapter);
      v7 = *(_DWORD *)(DmaAdapter + 416);
    }
    v8 = ((v7 >> 1) & 3) - 1;
    if( v8 )
    {
      if( v8 == 1 )
      {
        v9 = *v2;
        v10 = DmaAdapter;
      }
      else
      {
        v9 = v2[2];
        v10 = *v2;
      }
    }
    else
    {
      v9 = 0i64;
      v10 = 0i64;
    }
    v18 = v10;
    if( v9 )
      v9 &= -(__int64)(ObReferenceObjectSafe((PVOID)v9) != 0);
    if( v10 )
    {
      v10 &= -(__int64)(ObReferenceObjectSafe((PVOID)v10) != 0);
      v18 = v10;
    }
    if( (_InterlockedExchangeAdd64(v2 - 2, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(v2 - 2);
    KeAbPostRelease(v2 - 2);
    if( v9 )
    {
      CanceledQueue.Blink = &CanceledQueue;
      CanceledQueue.Flink = &CanceledQueue;
      do
      {
        v11 = AlpcpCancelMessagesByRequestor(
                (_ALPC_PORT *)DmaAdapter,
                (_ALPC_PORT *)v9,
                (_LIST_ENTRY *)(v9 + 144),
                1ui64,
                &CanceledQueue);
        v12 = AlpcpCancelMessagesByRequestor(
                (_ALPC_PORT *)DmaAdapter,
                (_ALPC_PORT *)v9,
                (_LIST_ENTRY *)(v9 + 160),
                2ui64,
                &CanceledQueue) | v11;
        v13 = AlpcpCancelMessagesByRequestor(
                (_ALPC_PORT *)DmaAdapter,
                (_ALPC_PORT *)v9,
                (_LIST_ENTRY *)(v9 + 184),
                3ui64,
                &CanceledQueue) | v12;
      }
      while( v13 | (unsigned int)AlpcpCancelMessagesByRequestor(
                                    (_ALPC_PORT *)DmaAdapter,
                                    (_ALPC_PORT *)v9,
                                    (_LIST_ENTRY *)(v9 + 208),
                                    4ui64,
                                    &CanceledQueue) );
      HalPutDmaAdapter((PADAPTER_OBJECT)v9);
      v10 = v18;
      while( 1 )
      {
        Flink = CanceledQueue.Flink;
        if( CanceledQueue.Flink == &CanceledQueue )
          break;
        CanceledQueue.Flink = CanceledQueue.Flink->Flink;
        v16 = (ULONG_PTR)&Flink[-5];
        CanceledQueue.Flink->Blink = &CanceledQueue;
        AlpcpLockForCachedReferenceBlob((PVOID)v16);
        if( v18 )
        {
          ExAcquirePushLockSharedEx(v18 + 352, 0i64);
          if( (*(_DWORD *)(v18 + 416) & 0x40) != 0 )
          {
            --*(_WORD *)(v16 - 30);
            if( _InterlockedCompareExchange64((volatile signed __int64 *)(v18 + 352), 0i64, 17i64) != 17 )
              ExfReleasePushLockShared((INT64 *)(v18 + 352));
            KeAbPostRelease((PVOID)(v18 + 352));
          }
          else
          {
            *(_DWORD *)(v16 + 72) = _InterlockedIncrement((volatile signed __int32 *)(DmaAdapter + 400));
            *(_QWORD *)(v16 + 128) = *(_QWORD *)(DmaAdapter + 56);
            *(_QWORD *)(v16 + 56) = DmaAdapter;
            *(_QWORD *)(v16 + 64) = v18;
            AlpcpInsertMessageCanceledQueue(v18, v16);
            AlpcpSignalPortAndUnlock(v18);
          }
        }
        else
        {
          --*(_WORD *)(v16 - 30);
        }
        AlpcpUnlockMessage(v16);
      }
    }
    if( v10 )
      HalPutDmaAdapter((PADAPTER_OBJECT)v10);
    return 0i64;
  }
}

Referenced by:

AlpcpDoPortCleanup
NtAlpcDisconnectPort