MiDecommitHardwareEnclavePages

NTSTATUS __stdcall MiDecommitHardwareEnclavePages(INT64 a1, INT64 a2, INT64 r8_0, UINT64 a4, INT64 a5){
  _MMSUPPORT_INSTANCE *v7; 
  char *v8; 
  unsigned int v9; 
  unsigned int v10; 
  UINT64 v11; 
  UINT8 v12; 
  unsigned int v13; 
  _MMPTE *PteBase; 
  __int64 v15; 
  VOID *v16; 
  unsigned __int64 v17; 
  int v18; 
  int v19; 
  UINT64 v20; 
  UINT8 v21; 
  UINT64 v22; 
  UINT64 v23; 
  __int64 v24; 
  UINT64 v25; 
  NTSTATUS v26; 
  int v27; 
  int v28; 
  __int64 v29; 
  unsigned int v30; 
  unsigned int v31; 
  __int64 v32; 
  unsigned int v33; 
  __int64 *v34; 
  __int64 i; 
  _MMSUPPORT_INSTANCE *v36; 
  UINT64 v37; 
  NTSTATUS v38; 
  unsigned __int64 v39; 
  _ETHREAD *v40; 
  __int64 SessionId; 
  unsigned __int8 v42; 
  _KLOCK_ENTRY *v43; 
  int v44; 
  __int64 v45; 
  bool v46; 
  __int64 v47; 
  __int64 v48; 
  unsigned int v49; 
  volatile signed __int32 *v50; 
  __int64 v51; 
  int v52; 
  UINT64 Flags; 
  UINT8 WsIrql; 
  int WsIrql_4; 
  unsigned int v57; 
  int v58; 
  __int64 v59; 
  UINT64 a3; 
  VOID *PageTableVirtualAddress; 
  char *v62; 
  UINT64 v63; 
  INT64 v64; 
  int v65; 
  PVOID BugCheckParameter2; 
  unsigned __int64 v67; 
  INT64 v68; 
  __int64 v69; 
  INT64 v70; 
  INT64 v71; 
  INT64 v72; 
  _ETHREAD *CurrentThread; 
  _MI_TB_FLUSH_LIST TbFlushList[48]; 

  PageTableVirtualAddress = (VOID *)r8_0;
  v64 = a2;
  v70 = a2;
  v71 = r8_0;
  v63 = 0i64;
  memset(TbFlushList, 0i64, 0xB8u);
  v68 = a2;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v7 = (_MMSUPPORT_INSTANCE *)(a1 + 1664);
  v72 = (INT64)v7;
  v8 = 0i64;
  v62 = 0i64;
  v9 = 0;
  v59 = 0i64;
  v69 = 0i64;
  TbFlushList[0] = 1;
  LOWORD(TbFlushList[1]) = 0;
  *(_QWORD *)&TbFlushList[4] = 0i64;
  TbFlushList[2] = 20;
  *(_QWORD *)&TbFlushList[6] = 0i64;
  v10 = 2;
  v58 = 2;
  MiLockWorkingSetShared();
  WsIrql = v12;
  v13 = 0;
  while( 1 )
  {
    PteBase = MmGetPteBase();
    v57 = v13;
    if( v13 >= v10 )
      break;
    if( v13 == 2 )
    {
      v15 = (_QWORD)PteBase << 25;
      KeTrackEnclaveTbFlush();
      MiInsertTbFlushEntry(TbFlushList, (VOID *)((((_QWORD)PageTableVirtualAddress << 25) - v15) >> 16), 1ui64, 0i64);
      MiFlushTbList(TbFlushList);
    }
    v16 = PageTableVirtualAddress;
    v17 = (unsigned __int64)PageTableVirtualAddress;
    v67 = (unsigned __int64)PageTableVirtualAddress;
    while( v17 <= a4 )
    {
      if( (v17 & 0x78) != 0 || (VOID *)v17 == v16 )
        goto LABEL_18;
      v18 = 0;
      LOBYTE(v19) = MiWorkingSetIsContended((INT64)v7);
      if( v19
        || (unsigned int)KeShouldYieldProcessor()
        || v8 && (unsigned int)MiPageTableLockIsContended((__int64)v7, (UINT64)v8) )
      {
        v18 = 1;
      }
      if( v18 != 1 )
      {
LABEL_18:
        v21 = WsIrql;
      }
      else
      {
        if( v8 )
        {
          MiFlushTbList(TbFlushList);
          MiUnlockPageTableInternal((INT64)v7, (UINT64)v8);
          v8 = 0i64;
          v62 = 0i64;
        }
        v21 = WsIrql;
        LOBYTE(v20) = WsIrql;
        MiUnlockWorkingSetShared(v7, v20);
        MiLockWorkingSetShared();
      }
      if( v8 )
      {
        if( (v17 & 0xFFF) != 0 )
          goto LABEL_23;
        MiFlushTbList(TbFlushList);
        MiUnlockPageTableInternal((INT64)v7, (UINT64)v8);
      }
      v8 = (char *)MmGetPteBase() + ((v17 >> 9) & 0x7FFFFFFFF8i64);
      v62 = v8;
      LODWORD(Flags) = 0;
      MiMakeSystemAddressValid((VOID *)v17, 0i64, (*(_DWORD *)(v68 + 48) >> 12) & 0x3F, v21, Flags);
LABEL_23:
      LODWORD(v22) = MI_READ_PTE_LOCK_FREE(v17);
      v23 = v22;
      v63 = v22;
      if( !v22 )
        goto LABEL_51;
      v24 = (__int64)((v17 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
      BugCheckParameter2 = (PVOID)v24;
      if( v57 )
      {
        if( v57 == 1 )
        {
          v26 = KeRemoveEnclavePage((PVOID)v24);
          v27 = v26;
          WsIrql_4 = v26;
          if( v26 < 0 )
          {
            if( v26 != -1073741757 || (_DWORD)a5 )
            {
              v27 = 0;
            }
            else
            {
              if( !v59 )
              {
                while( 1 )
                {
                  v28 = **(&stru_140C4DB30 + 532);
                  v29 = *(_QWORD *)(*(&stru_140C4DB30 + 532) + 8i64);
                  v30 = (*(_DWORD *)(*(&stru_140C4DB30 + 532) + 8i64) & 4) != 0i64 ? 0x20 : 0;
                  v65 = 0;
                  v31 = v30 + v28 - 1;
                  v32 = v29 - ((v29 & 4) != 0 ? 4 : 0);
                  if( v28 )
                  {
                    v34 = (__int64 *)(v32 + 8 * ((unsigned __int64)v30 >> 6));
                    for( i = *v34 | ((1i64 << v30) - 1); i == -1; i = *v34 )
                    {
                      if( (unsigned __int64)++v34 > v32 + 8 * ((unsigned __int64)v31 >> 6) )
                        goto LABEL_32;
                    }
                    _BitScanForward64((unsigned __int64 *)&i, ~i);
                    v65 = i;
                    v33 = i + ((unsigned int)(((__int64)v34 - v32) >> 3) << 6);
                    if( v33 > v31 )
                      v33 = -1;
                  }
                  else
                  {
LABEL_32:
                    v33 = -1;
                  }
                  v9 = v33 - v30;
                  if( v33 == -1 )
                    v9 = -1;
                  if( v9 == -1 )
                    break;
                  if( RtlInterlockedSetClearRun(*(&stru_140C4DB30 + 532), v9, 1ui64) )
                    goto LABEL_45;
                }
                MiFlushTbList(TbFlushList);
                v36 = (_MMSUPPORT_INSTANCE *)v72;
                MiUnlockPageTableInternal(v72, (UINT64)v8);
                LOBYTE(v37) = WsIrql;
                MiUnlockWorkingSetShared(v36, v37);
                --CurrentThread->Tcb.SpecialApcDisable;
                ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)&stru_140C4DB30 + 533, 0i64);
                v9 = 0;
                MiLockWorkingSetShared();
                LODWORD(Flags) = 0;
                MiMakeSystemAddressValid((VOID *)v17, 0i64, (*(_DWORD *)(v68 + 48) >> 12) & 0x3F, WsIrql, Flags);
LABEL_45:
                v59 = *(&stru_140C4DB30 + 531) + 8 * v9;
                ++v58;
                v27 = WsIrql_4;
              }
              KeBlockEnclavePage();
            }
          }
          if( v27 < 0 )
            goto LABEL_50;
        }
        else
        {
          do
          {
            ExAcquireSpinLockShared((INT64 *)&stru_140C4DB30 + 534);
            v38 = KeOutPageEnclavePage(v24, *(_QWORD *)(v64 + 88));
            ExReleaseSpinLockSharedFromDpcLevel((PEX_SPIN_LOCK)&stru_140C4DB30 + 1068);
          }
          while( v38 == -1073741802 );
          if( v38 < 0 )
            KeBugCheckEx(0x1Au, (PVOID)0x18011713, (PVOID)v24, (PVOID)v38, 0i64);
        }
        MiDeleteEnclavePage((_MMPTE *)v17, (_MI_TB_FLUSH_LIST *)1);
      }
      else
      {
        MiPteInShadowRange((UINT64)&v63);
        LODWORD(v25) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v17, (v23 >> 12) & 0xFFFFFFFFFi64, 3221225476i64);
        v63 = v25;
        MiWriteValidPteNewProtection((INT64 *)v17, v25);
      }
LABEL_50:
      MiInsertTbFlushEntry(TbFlushList, (VOID *)v24, 1ui64, 0i64);
      v7 = (_MMSUPPORT_INSTANCE *)v72;
LABEL_51:
      v17 += 8i64;
      v67 = v17;
      v16 = PageTableVirtualAddress;
    }
    MiFlushTbList(TbFlushList);
    if( v8 )
    {
      MiUnlockPageTableInternal((INT64)v7, (UINT64)v8);
      v8 = 0i64;
      v62 = 0i64;
    }
    v13 = v57 + 1;
    v10 = v58;
  }
  LOBYTE(v11) = WsIrql;
  MiUnlockWorkingSetShared(v7, v11);
  if( v59 )
  {
    if( v9 )
    {
      v49 = 1;
      v50 = (volatile signed __int32 *)(*(_QWORD *)(*(&stru_140C4DB30 + 532) + 8i64) + 4 * ((unsigned __int64)v9 >> 5));
      v51 = v9 & 0x1F;
      LODWORD(v39) = v51 + 1;
      if( (unsigned __int64)(v51 + 1) > 0x20 )
      {
        v52 = v9 & 0x1F;
        if( v52 )
        {
          LODWORD(v39) = ~(((1 << (32 - v52)) - 1) << v51);
          _InterlockedAnd(v50, v39);
          v49 = 1 - (32 - v52);
          ++v50;
        }
        if( v49 >= 0x20 )
        {
          v39 = (unsigned __int64)v49 >> 5;
          do
          {
            *v50++ = 0;
            v49 -= 32;
            --v39;
          }
          while( v39 );
        }
        if( v49 )
          _InterlockedAnd(v50, -1 << v49);
      }
      else
      {
        _InterlockedAnd(v50, ~(1 << v51));
      }
    }
    else
    {
      if( (_InterlockedExchangeAdd64((_QWORD *)&stru_140C4DB30 + 533, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
        ExfTryToWakePushLock((_EX_PUSH_LOCK *)&stru_140C4DB30 + 533);
      LODWORD(a3) = 0;
      v40 = (_ETHREAD *)KeGetCurrentThread();
      if( MiGetSystemRegionType((UINT64)&stru_140C4DB30 + 4264) == 1 )
        SessionId = (unsigned int)MmGetSessionIdEx(v40->Tcb.ApcState.Process);
      else
        SessionId = 0xFFFFFFFFi64;
      --v40->Tcb.SpecialApcDisable;
      v42 = ++v40->Tcb.AbAllocationRegionCount;
      v43 = 0i64;
      v44 = ((char)v40->Tcb.AbEntrySummary | (char)v40->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
      while( 1 )
      {
        v46 = !_BitScanReverse((unsigned int *)&v47, v44);
        if( v46 )
          break;
        v44 &= ~(1 << v47);
        v45 = (__int64)&v40->Tcb.LockEntries[v47];
        if( (*(_BYTE *)(v45 + 26) & 1) != 0
          && (*(_DWORD *)(v45 + 32) & 1) == 0
          && (*(_QWORD *)(v45 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (((unsigned __int64)&stru_140C4DB30 + 4264) & 0x7FFFFFFFFFFFFFFCi64)
          && *(_DWORD *)(v45 + 40) == (_DWORD)SessionId )
        {
          *(_BYTE *)(v45 + 26) &= ~1u;
          if( *(_QWORD *)(v45 + 32) )
          {
            v43 = (_KLOCK_ENTRY *)v45;
            break;
          }
        }
      }
      if( v43 )
      {
        v43->CrossThreadReleasableAndBusyByte |= 2u;
        if( v43->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
          KiAbEntryRemoveFromTree(v43);
        LODWORD(a3) = v43->BoostBitmap.AllFields & 0x1FFFF;
        v43->BoostBitmap.AllFields &= 0xFFFE0000;
        v43->ThreadLocalFlags &= ~1u;
        v43->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
        v48 = v43 - v40->Tcb.LockEntries;
        if( v42 == 1 )
          v40->Tcb.AbEntrySummary |= 1 << v48;
        else
          _InterlockedOr8((volatile signed __int8 *)&v40->Tcb.AbOrphanedEntrySummary, 1 << v48);
      }
      else if( (*(&v40->Tcb.MiscFlags + 1) & 0x10000) == 0 )
      {
        KeBugCheckEx(0x162u, v40, (char *)&stru_140C4DB30 + 4264, (PVOID)SessionId, 0i64);
      }
      --v40->Tcb.AbAllocationRegionCount;
      KiAbThreadRemoveBoosts(&v40->Tcb, (char *)&stru_140C4DB30 + 4264, &a3);
      v46 = v40->Tcb.SpecialApcDisable++ == -1;
      if( v46 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v40->Tcb.ApcState.ApcListHead[0].Flink != &v40->Tcb.152 )
        KiCheckForKernelApcDelivery();
      KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
    }
  }
  return v39;
}

Referenced by:

MiDecommitEnclavePages
MiTerminateHardwareEnclave