HalpIommuBlockDevice

NTSTATUS __stdcall HalpIommuBlockDevice(INT64 *a1){
  UINT8 v1; 
  NTSTATUS result; 
  char v3; 
  ULONG *v5; 
  int AcpiDeviceMapping; 
  ULONG *v7; 
  _HALP_ALLOC_CONTEXT *v8; 
  NTSTATUS v9; 
  _ETHREAD *CurrentThread; 
  unsigned int SessionId; 
  unsigned __int8 v12; 
  int v13; 
  bool v14; 
  __int64 v15; 
  _KLOCK_ENTRY *v16; 
  int v17; 
  unsigned int v18; 
  __int64 v19; 
  ULONG SortKey[4]; 
  __int64 v21; 
  UINT64 a3; 
  __int64 v23; 

  v23 = 0i64;
  result = 0;
  v3 = 0;
  v21 = 0i64;
  *(_OWORD *)SortKey = 0i64;
  if( !a1 )
    return result;
  v5 = (ULONG *)a1[4];
  if( *v5 == 2 )
  {
    AcpiDeviceMapping = (unsigned int)HalpIommuQueryAcpiDeviceMapping((PKDEVICE_QUEUE)a1[4], (ULONG)SortKey);
    v7 = SortKey;
    if( AcpiDeviceMapping < 0 )
      v7 = v5;
    v5 = v7;
  }
  if( *v5 != 1 )
    goto LABEL_10;
  ExAcquirePushLockExclusiveEx(&qword_140C49BA0, 0i64);
  v3 = 1;
  v9 = HalpIommuDecreaseAliasTrack((INT64)v5, &v23);
  if( v9 < 0 )
    goto LABEL_10;
  if( *(__int64 *)(v23 + 24) <= 0 )
  {
    HalpMmAllocCtxFree(v8, *(VOID **)(v23 + 16));
LABEL_10:
    v9 = (unsigned int)HalpIommuLeaveDmaDomain((_KDEVICE_QUEUE *)a1, ::SortKey, v1);
  }
  HalpIommuDeleteDevice((UINT64 *)a1);
  if( v3 )
  {
    if( (_InterlockedExchangeAdd64(&qword_140C49BA0._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(&qword_140C49BA0);
    LODWORD(a3) = 0;
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    if( MiGetSystemRegionType((UINT64)&qword_140C49BA0) == 1 )
      SessionId = MmGetSessionIdEx(CurrentThread->Tcb.ApcState.Process);
    else
      SessionId = -1;
    --CurrentThread->Tcb.SpecialApcDisable;
    v12 = ++CurrentThread->Tcb.AbAllocationRegionCount;
    v13 = ((char)CurrentThread->Tcb.AbEntrySummary | (char)CurrentThread->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
    while( 1 )
    {
      v14 = !_BitScanReverse((unsigned int *)&v15, v13);
      if( v14 )
        break;
      v16 = &CurrentThread->Tcb.LockEntries[v15];
      v13 &= ~(1 << v15);
      if( (v16->AcquiredByte & 1) != 0
        && (v16->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
        && (v16->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == ((unsigned __int64)&qword_140C49BA0 & 0x7FFFFFFFFFFFFFFCi64)
        && v16->LockState.SessionId == SessionId )
      {
        v16->AcquiredByte &= ~1u;
        if( v16->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
        {
          if( v16 )
          {
            v16->CrossThreadReleasableAndBusyByte |= 2u;
            if( v16->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
              KiAbEntryRemoveFromTree(v16);
            v17 = v16->BoostBitmap.AllFields & 0x1FFFF;
            v18 = v16->BoostBitmap.AllFields & 0xFFFE0000;
            v16->ThreadLocalFlags &= ~1u;
            LODWORD(a3) = v17;
            v16->BoostBitmap.AllFields = v18;
            v16->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
            v19 = v16 - CurrentThread->Tcb.LockEntries;
            if( v12 == 1 )
              CurrentThread->Tcb.AbEntrySummary |= 1 << v19;
            else
              _InterlockedOr8((volatile signed __int8 *)&CurrentThread->Tcb.AbOrphanedEntrySummary, 1 << v19);
            goto LABEL_29;
          }
          break;
        }
      }
    }
    if( (*(&CurrentThread->Tcb.MiscFlags + 1) & 0x10000) == 0 )
      KeBugCheckEx(0x162u, CurrentThread, &qword_140C49BA0, (PVOID)SessionId, 0i64);
LABEL_29:
    --CurrentThread->Tcb.AbAllocationRegionCount;
    KiAbThreadRemoveBoosts(&CurrentThread->Tcb, &qword_140C49BA0, &a3);
    v14 = CurrentThread->Tcb.SpecialApcDisable++ == -1;
    if( v14
      && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)CurrentThread->Tcb.ApcState.ApcListHead[0].Flink != &CurrentThread->Tcb.152 )
    {
      KiCheckForKernelApcDelivery();
    }
  }
  return v9;
}

Referenced by:

No references.