MiLockPageTablePage

NTSTATUS __stdcall MiLockPageTablePage(_MMPFN *PageTablePfn, _MI_LOCK_PAGE_TABLE_TYPE PageTableType){
  NTSTATUS v2; 
  _MMPFN *v4; 
  _MMPFN *v5; 
  _MMPFN *PfnDb; 
  NTSTATUS v7; 
  unsigned __int64 v8; 
  UINT64 v9; 
  _MI_PARTITION *v10; 
  struct _KPRCB *CurrentPrcb; 
  UINT64 CachedResidentAvailable; 
  unsigned __int32 v13; 
  unsigned int i; 
  bool v15; 
  unsigned __int64 v16; 
  unsigned __int64 v17; 
  struct _KPRCB *v18; 
  __int64 v19; 
  signed __int32 v20; 
  char v22; 
  union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v23; 
  char v24; 
  unsigned __int64 v25; 
  struct _KPRCB *v26; 
  __int64 v27; 
  signed __int32 v28; 
  UINT64 v29; 
  UINT64 SpinCount; 
  _MMPFN *v31; 

  v2 = 0;
  v4 = PageTablePfn;
  if( PageTableType == PageTableLockShared )
  {
    v5 = PageTablePfn;
  }
  else
  {
    v5 = 0i64;
    if( PageTableType == PageTableLockPrivate )
      v5 = PageTablePfn;
  }
  v31 = v5;
  PfnDb = MmGetPfnDb();
  v7 = 1;
  while( 1 )
  {
LABEL_6:
    if( PageTableType == PageTableLockShared )
      v4 = &PfnDb[v5->u4._bf_0 & 0xFFFFFFFFFi64];
    if( (v4->u2._bf_0 & 0x3FFFFFFFFFFFFFFFui64) < 0x10000 )
      goto LABEL_18;
    LODWORD(SpinCount) = 0;
    if( _interlockedbittestandset64((volatile signed __int32 *)&v4->u2, 0x3Fui64) )
    {
      do
      {
        do
          KeYieldProcessorEx(&SpinCount);
        while( v4->u2._bf_0 < 0 );
      }
      while( _interlockedbittestandset64((volatile signed __int32 *)&v4->u2, 0x3Fui64) );
      PfnDb = MmGetPfnDb();
    }
    if( PageTableType == PageTableLockShared && v4 != &PfnDb[v5->u4._bf_0 & 0xFFFFFFFFFi64] )
    {
      _InterlockedAnd64(&v4->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
      continue;
    }
    v8 = v4->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64;
    if( v8 >= 0x10000 )
      break;
    _InterlockedAnd64(&v4->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
LABEL_18:
    if( PageTableType == PageTableLockPrivateFork )
    {
      v9 = 3i64;
    }
    else
    {
      v9 = 1i64;
      if( PageTableType == PageTableLockPrivate )
        v9 = 4i64;
    }
    v10 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)v4->u4._bf_0 >> 39) & 0x3FF));
    if( v10 == &Irp )
    {
      CurrentPrcb = KeGetCurrentPrcb();
      CachedResidentAvailable = CurrentPrcb->CachedResidentAvailable;
      if( v9 <= CachedResidentAvailable )
      {
        do
        {
          if( (_DWORD)CachedResidentAvailable == -1 )
            break;
          v13 = _InterlockedCompareExchange(
                  (volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
                  CachedResidentAvailable - v9,
                  CachedResidentAvailable);
          v15 = (_DWORD)CachedResidentAvailable == v13;
          LODWORD(CachedResidentAvailable) = v13;
          if( v15 )
            goto LABEL_28;
        }
        while( v9 <= v13 );
      }
    }
    if( MiChargePartitionResidentAvailable(v10, v9, 0x200ui64) == MiChargeFailed )
      return 0;
LABEL_28:
    for( i = 0; ; ++i )
    {
      v15 = i == v9;
      if( i >= v9 )
        goto LABEL_39;
      LODWORD(v29) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)&v4->u2, 0x3Fui64) )
      {
        do
          KeYieldProcessorEx(&v29);
        while( v4->u2._bf_0 < 0 );
      }
      if( PageTableType == PageTableLockShared )
      {
        PfnDb = MmGetPfnDb();
        if( v4 != &PfnDb[v31->u4._bf_0 & 0xFFFFFFFFFi64] )
          break;
      }
      v16 = v4->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64;
      if( i )
      {
        if( v16 >= 0x3FFFFFFFFFFEFDFFi64 )
          goto LABEL_56;
      }
      else if( v16 >= 0x3FFFFFFFFFFEFDFFi64 )
      {
        v7 = 0;
LABEL_38:
        _InterlockedAnd64(&v4->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
        v15 = i == v9;
LABEL_39:
        if( !v15 )
        {
          v17 = v9 - i;
          if( v10 == &Irp )
          {
            v18 = KeGetCurrentPrcb();
            v19 = (int)v18->CachedResidentAvailable;
            if( (_DWORD)v19 != -1 )
            {
              if( v17 + v19 <= 0x100 )
              {
                do
                {
                  if( v17 >= 0x80000 )
                    break;
                  v20 = _InterlockedCompareExchange(
                          (volatile signed __int32 *)&v18->CachedResidentAvailable,
                          v17 + v19,
                          v19);
                  v15 = (_DWORD)v19 == v20;
                  LODWORD(v19) = v20;
                  if( v15 )
                    return v7;
                }
                while( v20 != -1 && v17 + v20 <= 0x100 );
              }
              if( (int)v19 > 192
                && (_DWORD)v19 != -1
                && (_DWORD)v19 == _InterlockedCompareExchange(
                                    (volatile signed __int32 *)&v18->CachedResidentAvailable,
                                    192,
                                    v19) )
              {
                v17 += (int)v19 - 192;
              }
            }
          }
          if( v17 )
            _InterlockedExchangeAdd64((volatile signed __int64 *)&v10->Vp.ResidentAvailablePages, v17);
        }
        return v7;
      }
      v4->u2._bf_0 ^= ((v16 + 0x10000) ^ v4->u2._bf_0) & 0x3FFFFFFFFFFFFFFFi64;
LABEL_56:
      if( v16 >= 0x10000 )
        goto LABEL_38;
      v22 = *((_BYTE *)&v4->u3 + 2);
      v23.Long = 0i64;
      if( (v22 & 0x10) == 0 )
      {
        v24 = *((_BYTE *)&v4->u3 + 2);
        if( (*(_DWORD *)(&v4->3 + 1) & 0x400i64) == 0 && (v22 & 8) == 0 )
        {
          v23.Long = MiCapturePageFileInfoInline(&v4->OriginalPte, 1ui64, 0i64).u.Long;
          v24 = *((_BYTE *)&v4->u3 + 2);
        }
        *((_BYTE *)&v4->u3 + 2) = v24 | 0x10;
      }
      _InterlockedAnd64(&v4->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
      if( v23.Long )
        MiReleasePageFileInfo(v10, (_MMPTE)v23.Long, 1ui64);
      v4 = &MmGetPfnDb()[v4->u4._bf_0 & 0xFFFFFFFFFi64];
    }
    _InterlockedAnd64(&v4->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
    v25 = v9 - i;
    if( v10 == &Irp )
    {
      v26 = KeGetCurrentPrcb();
      v27 = (int)v26->CachedResidentAvailable;
      if( (_DWORD)v27 != -1 )
      {
        if( v25 + v27 <= 0x100 )
        {
          do
          {
            if( v25 >= 0x80000 )
              break;
            v28 = _InterlockedCompareExchange((volatile signed __int32 *)&v26->CachedResidentAvailable, v25 + v27, v27);
            v15 = (_DWORD)v27 == v28;
            v5 = v31;
            LODWORD(v27) = v28;
            if( v15 )
              goto LABEL_6;
          }
          while( v28 != -1 && v25 + v28 <= 0x100 );
        }
        if( (int)v27 > 192
          && (_DWORD)v27 != -1
          && (_DWORD)v27 == _InterlockedCompareExchange(
                              (volatile signed __int32 *)&v26->CachedResidentAvailable,
                              192,
                              v27) )
        {
          v25 += (int)v27 - 192;
        }
      }
    }
    v5 = v31;
    if( v25 )
      _InterlockedExchangeAdd64((volatile signed __int64 *)&v10->Vp.ResidentAvailablePages, v25);
  }
  if( v8 < 0x3FFFFFFFFFFEFDFFi64 )
  {
    v2 = 1;
    v4->u2._bf_0 ^= (v4->u2._bf_0 ^ (v4->u2._bf_0 + 0x10000)) & 0x3FFFFFFFFFFFFFFFi64;
  }
  _InterlockedAnd64(&v4->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
  return v2;
}

Referenced by:

MiBuildForkPte
MiLockPageTableRange
MiProbeLockFrame
NtLockVirtualMemory