MiMigratePfn

_MMPFN *__fastcall MiMigratePfn(UINT64 *a1, INT64 a2, __int64 a3, _QWORD *a4){
  UINT64 p_PageColor; 
  _MMPFN *PfnDb; 
  VOID *v8; 
  _MMSUPPORT_INSTANCE *v9; 
  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;} v10; 
  int v11; 
  struct _KPRCB *CurrentPrcb; 
  unsigned int NodeShiftedColor; 
  int v14; 
  unsigned int v15; 
  unsigned __int64 v16; 
  void *v17; 
  __int64 v18; 
  UINT8 v19; 
  wchar_t *v20; 
  signed __int32 v21; 
  _UNICODE_STRING *v22; 
  unsigned int v23; 
  unsigned int *v24; 
  unsigned int *v25; 
  __int64 v26; 
  __int64 v27; 
  int v28; 
  _MMPFN *v29; 
  _MI_PARTITION *v30; 
  unsigned int v31; 
  unsigned int v32; 
  int v33; 
  unsigned int v34; 
  INT64 v35; 
  UINT64 v36; 
  _MI_PARTITION *v37; 
  _MMPFN *v39; 
  __int64 v40; 
  __int64 v41; 
  unsigned int *v42; 
  __int64 v43; 
  __int64 v44; 
  __int64 v45; 
  __int64 v46; 
  int v47; 
  _MMPTE *v48; 
  INT64 v49; 
  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;} v50; 
  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;} v51; 
  int v52; 
  PVOID v53; 
  INT64 v54; 
  UINT64 v55; 
  unsigned __int16 ReferenceCount; 
  INT64 v57; 
  UINT64 v58; 
  UINT64 v59; 
  ULONG_PTR *Partition; 
  INT64 v61; 
  PVOID BugCheckParameter2; 
  __int64 v63; 
  UINT64 v64; 
  UINT64 SpinCount; 
  UINT64 v66; 
  _QWORD *v67; 

  v67 = a4;
  p_PageColor = a1[7];
  v64 = *a1;
  v61 = a1[2];
  if( (*(_QWORD *)(a2 + 40) & 0x2000000000000i64) != 0 )
    return(_MMPFN *)a2;
  PfnDb = MmGetPfnDb();
  if( *(&stru_140C50B28 + 4726) )
  {
    if( _bittest64(*(&stru_140C50B28 + 756), (unsigned __int64)((a2 - (__int64)PfnDb) / 48) >> 9) )
      return(_MMPFN *)a2;
  }
  if( (unsigned __int16)KeNumberNodes <= 1u
    || *(_WORD *)(a2 + 32)
    || ((__int64)KeGetCurrentThread()[1].Queue & 0x40) != 0
    || !MiCanPageMove((_MMPFN *)a2) )
  {
    return(_MMPFN *)a2;
  }
  v10.Long = 0i64;
  v63 = 0i64;
  MiComputeFaultNode(v9, 0i64, (_CONTROL_AREA *)&v63, v8, (_MMVAD **)v59);
  if( v11 )
  {
    CurrentPrcb = KeGetCurrentPrcb();
    NodeShiftedColor = (v11 - 1) << *(&stru_140C4DB30 + 156);
  }
  else
  {
    CurrentPrcb = *(&KiProcessorBlock + KeGetCurrentThread()->IdealProcessor);
    NodeShiftedColor = CurrentPrcb->NodeShiftedColor;
  }
  v14 = (1 << *(&stru_140C4DB30 + 157)) - 1;
  if( !p_PageColor || (*(_BYTE *)(p_PageColor + 184) & 7u) >= 2 )
    p_PageColor = (UINT64)&CurrentPrcb->PageColor;
  v15 = NodeShiftedColor >> *(&stru_140C4DB30 + 156);
  v16 = (__int64)((unsigned __int128)((a2 - (__int64)PfnDb) * (__int128)0x2AAAAAAAAAAAAAABi64) >> 64) >> 3;
  v17 = (void *)((v16 >> 63) + v16);
  BugCheckParameter2 = v17;
  LODWORD(v18) = MiSearchNumaNodeTable(v17);
  if( v15 == *(_DWORD *)(v18 + 8) )
    return(_MMPFN *)a2;
  Partition = *(ULONG_PTR **)(*(&stru_140C4DB30 + 267) + 8 * ((*(_QWORD *)(a2 + 40) >> 39) & 0x3FFi64));
  v21 = _InterlockedExchangeAdd((volatile signed __int32 *)p_PageColor, 1u);
  v22 = (_UNICODE_STRING *)(unsigned __int16)KeNumberNodes;
  v23 = v14 & v21 | NodeShiftedColor;
  v24 = (unsigned int *)(*(&stru_140C4DB30 + 21) + 4i64 * v15 * (unsigned __int16)KeNumberNodes);
  v25 = &v24[(unsigned __int16)KeNumberNodes];
  if( v24 < v25 )
  {
    while( 1 )
    {
      LODWORD(v26) = MiSearchNumaNodeTable(v17);
      v27 = *v24;
      if( (_DWORD)v27 == *(_DWORD *)(v26 + 8) )
        return(_MMPFN *)a2;
      if( *(_OWORD *)(*((_QWORD *)Partition + 2) + 4544 * v27 + 4128) == 0i64 && ++v24 < v25 )
        continue;
      break;
    }
  }
  LOBYTE(v28) = MI_PFN_IS_PROTO((_UNICODE_STRING *)a2, v22, v19, v20);
  if( v28 && (*(_DWORD *)(a2 + 16) & 0x400i64) != 0 )
  {
    v32 = v31;
  }
  else
  {
    MiIsPfnCommitNotCharged(v29);
    v32 = 0;
    if( v33 )
      v32 = 5;
  }
  if( !MiObtainFaultCharges(v30, v31, v32) )
    return(_MMPFN *)a2;
  v34 = 1;
  if( (v61 & 1) != 0 && *(_BYTE *)(v61 & 0xFFFFFFFFFFFFFFFEui64) == 4 || MiGetSystemRegionType(v64) == 12 )
    v34 = 9;
  LODWORD(v35) = MiGetPage(Partition, v23, v34);
  v61 = v35;
  if( v35 == -1 )
  {
    v36 = v32;
    v37 = (_MI_PARTITION *)Partition;
LABEL_31:
    MiReturnFaultCharges(v37, 1ui64, v36);
    return(_MMPFN *)a2;
  }
  v39 = &MmGetPfnDb()[v35];
  v40 = 48 * v35 / 48;
  LODWORD(v41) = MiSearchNumaNodeTable((PVOID)v40);
  if( v15 != *(_DWORD *)(v41 + 8) )
  {
    v42 = (unsigned int *)(*(&stru_140C4DB30 + 21) + 4i64 * v15 * (unsigned __int16)KeNumberNodes);
    if( v42 < v25 )
    {
      while( 1 )
      {
        LODWORD(v43) = MiSearchNumaNodeTable(BugCheckParameter2);
        if( *v42 == *(_DWORD *)(v43 + 8) )
          goto LABEL_40;
        LODWORD(v44) = MiSearchNumaNodeTable((PVOID)v40);
        if( *v42 != *(_DWORD *)(v44 + 8) && ++v42 < v25 )
          continue;
        break;
      }
    }
  }
  if( a3 )
  {
    MiGetInPageSupportBlock();
    if( !v45 )
    {
LABEL_40:
      MiLockNestedPageAtDpcInline(v39);
      MiReturnFreeZeroPage((INT64)v39);
      _InterlockedAnd64(&v39->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
      v37 = (_MI_PARTITION *)Partition;
      v36 = v32;
      goto LABEL_31;
    }
    v46 = v45;
  }
  else
  {
    v46 = 0i64;
  }
  v47 = *(unsigned __int8 *)(a2 + 34) >> 6;
  MiLockNestedPageAtDpcInline(v39);
  if( *((unsigned __int8 *)&v39->u3 + 2) >> 6 != v47 )
    MiChangePageAttribute(v39, (_MI_PFN_CACHE_ATTRIBUTE)v47, 1ui64);
  MiSetPfnTbFlushStamp(v39, 0i64, 1ui64);
  MiCopyPfnEntryEx((INT64)v39, a2);
  v39->u3.ReferenceCount = 1;
  v39->u2._bf_0 &= 0xC000000000000000ui64;
  *(_BYTE *)(a2 + 34) = *(_BYTE *)(a2 + 34) & 0xF8 | 5;
  if( v46 )
  {
    *(_DWORD *)(v46 + 192) |= 0x20u;
    *((_BYTE *)&v39->u3 + 2) |= 0x20u;
    v39->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = v46 + 32;
    *(_QWORD *)(v46 + 248) = v39;
  }
  v48 = (_MMPTE *)(v39->PteLong | 0x8000000000000000ui64);
  LODWORD(v49) = MI_READ_PTE_LOCK_FREE((INT64)v48);
  LODWORD(v50.Long) = MiUpdateTransitionPteFrame(v49, v61);
  v51.Long = v50.Long;
  LOBYTE(v52) = MiPteInShadowRange((UINT64)v48);
  if( v52 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v51.Long & 1) != 0 )
    v51.Long |= 0x8000000000000000ui64;
  v48->u.Long = v51.Long;
  _InterlockedAnd64(&v39->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
  if( a3 )
  {
    MiLockNestedPageAtDpcInline((_MMPFN *)a3);
    if( !MiAreChargesNeededToLockPage((_MMPFN *)a3) || MiChargeForLockedPage((_MMPFN *)a3, 3ui64) )
      ++*(_WORD *)(a3 + 32);
    _InterlockedAnd64((volatile signed __int64 *)(a3 + 24), 0x7FFFFFFFFFFFFFFFui64);
    _InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
    LODWORD(SpinCount) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)(a3 + 24), 0x3Fui64) )
    {
      do
        KeYieldProcessorEx(&SpinCount);
      while( *(__int64 *)(a3 + 24) < 0 );
    }
    *(_BYTE *)(a3 + 34) &= ~0x20u;
    MiRemoveLockedPageChargeAndDecRef((_MMPFN *)a3);
    _InterlockedAnd64((volatile signed __int64 *)(a3 + 24), 0x7FFFFFFFFFFFFFFFui64);
    *v67 = v46;
  }
  else
  {
    _InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
    __writecr8(2ui64);
  }
  v53 = BugCheckParameter2;
  MiCopyPage(v61, (UINT64)BugCheckParameter2, 0i64, 2ui64);
  if( a3 )
  {
    MiLockProtoPoolPage(v48, 0i64);
    LODWORD(v66) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)(a3 + 24), 0x3Fui64) )
    {
      do
        KeYieldProcessorEx(&v66);
      while( *(__int64 *)(a3 + 24) < 0 );
    }
    MiRemoveLockedPageChargeAndDecRef((_MMPFN *)a3);
    _InterlockedAnd64((volatile signed __int64 *)(a3 + 24), 0x7FFFFFFFFFFFFFFFui64);
    LODWORD(v59) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)(a2 + 24), 0x3Fui64) )
    {
      do
        KeYieldProcessorEx(&v59);
      while( *(__int64 *)(a2 + 24) < 0 );
    }
  }
  else
  {
    MiLockPageInline((_MMPFN *)a2);
  }
  *(_QWORD *)(a2 + 40) &= 0x8FFFFFFFFFFFFFFFui64;
  MiInsertPageInFreeOrZeroedList((UINT64)v53, 2ui64, v54, v55, v59, (UINT64)Partition);
  _InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
  HIDWORD(v59) = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)&v39->u2, 0x3Fui64) )
  {
    do
      KeYieldProcessorEx((UINT64 *)((char *)&v59 + 4));
    while( v39->u2._bf_0 < 0 );
  }
  ReferenceCount = v39->u3.ReferenceCount;
  *((_BYTE *)&v39->u3 + 2) &= ~0x20u;
  v39->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = 0i64;
  MiRemoveLockedPageCharge(v39);
  if( !v46 )
    return v39;
  *(_DWORD *)(v46 + 192) &= ~0x20u;
  if( (v39->u2._bf_0 & 0x4000000000000000i64) == 0 )
    return v39;
  if( ReferenceCount == 1 )
  {
    if( (*(_DWORD *)(&v39->3 + 1) & 0x400i64) == 0 )
      v10.Long = MiCapturePageFileInfoInline(&v39->OriginalPte, 0i64, 1ui64).u.Long;
    MiInsertPageInFreeOrZeroedList(v61, 2ui64, v57, v58, v59, (UINT64)Partition);
  }
  _InterlockedAnd64(&v39->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
  if( a3 )
    MiUnlockProtoPoolPage(a3, 2u);
  if( v10.Long )
    MiReleasePageFileInfo((_MI_PARTITION *)Partition, (_MMPTE)v10.Long, 1ui64);
  return 0i64;
}

Referenced by:

MiHandleTransitionFault