MiWriteAwePtes

NTSTATUS __stdcall MiWriteAwePtes(INT64 a1, INT64 rdx0, UINT64 a3, INT64 a4, UINT64 a5, CHAR a6){
  UINT64 v6; 
  __int64 v8; 
  __int64 v9; 
  _DWORD *v10; 
  __int64 v11; 
  __int64 v12; 
  UINT64 v13; 
  _MMPTE *PteBase; 
  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;} v15; 
  unsigned int v16; 
  unsigned int v17; 
  int v18; 
  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;} v19; 
  unsigned int v20; 
  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;} v21; 
  UINT64 v22; 
  UINT8 v23; 
  _BOOL4 v24; 
  VOID *v25; 
  UINT64 v26; 
  INT64 v27; 
  INT64 v28; 
  _QWORD *v29; 
  __int64 v30; 
  unsigned __int64 v31; 
  _MMPTE *v32; 
  unsigned int v33; 
  unsigned int v34; 
  unsigned int v35; 
  unsigned __int8 v36; 
  int v37; 
  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;} v38; 
  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;} v39; 
  _MMPTE *v40; 
  __int64 v41; 
  char *v42; 
  NTSTATUS updated; 
  UINT64 v44; 
  VOID *v45; 
  UINT64 v46; 
  CHAR v47; 
  UINT8 v48; 
  __int64 v49; 
  INT64 v50; 
  INT64 v51; 
  INT64 v52; 
  __int64 v53; 
  INT64 v54; 
  UINT64 v55; 
  unsigned __int64 v56; 
  unsigned __int64 v57; 
  unsigned __int64 v58; 
  __int64 v59; 
  _MMPFN *v60; 
  unsigned __int64 v61; 
  __int64 v62; 
  __int64 v63; 
  unsigned __int64 v64; 
  unsigned __int64 v65; 
  _MMSUPPORT_INSTANCE *p_Instance; 
  int v67; 
  int IsContended; 
  __int64 v69; 
  int ShouldYieldProcessor; 
  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;} v71; 
  bool v72; 
  NTSTATUS v73; 
  __int64 v74; 
  UINT64 v75; 
  VOID *v76; 
  UINT64 v77; 
  CHAR v78; 
  NTSTATUS v79; 
  VOID *v80; 
  UINT64 v81; 
  CHAR v82; 
  UINT64 Flags; 
  UINT8 WsIrql; 
  unsigned int WsIrql_4; 
  UINT64 NumberOfEntries; 
  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;} v88; 
  unsigned int v89; 
  __int64 v90; 
  INT64 v91; 
  _BOOL4 v92; 
  __int64 v93; 
  _MMSUPPORT_FULL *p_Vm; 
  unsigned int a2; 
  INT64 v96; 
  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;} v97; 
  __int64 v98; 
  UINT64 SpinCount; 
  __int64 v100; 
  unsigned __int64 v101; 
  UINT64 v102; 
  __int64 v103; 
  INT64 v104; 
  INT64 v105; 
  UINT64 ReserveSize; 
  __int64 v107; 
  INT64 v108; 
  UINT64 v109; 
  __int64 v110; 
  _MI_TB_FLUSH_LIST TbFlushList[48]; 

  v6 = a5;
  v102 = a3;
  v104 = rdx0;
  v105 = a4;
  memset(TbFlushList, 0i64, 0xB8u);
  v107 = *(_QWORD *)(a1 + 32);
  p_Vm = &KeGetCurrentThread()->ApcState.Process->Vm;
  v98 = *(_QWORD *)(v107 + 8);
  LODWORD(v8) = MiGetAweViewPageSize(a1);
  TbFlushList[2] = 20;
  v93 = 0i64;
  v91 = 0i64;
  v11 = v9;
  WsIrql_4 = 0;
  if( v8 )
    v11 = v8;
  ReserveSize = 0i64;
  v90 = v11;
  LOWORD(TbFlushList[1]) = 0;
  *(_QWORD *)&TbFlushList[4] = 0i64;
  a2 = v11 == 512;
  TbFlushList[0] = 1;
  v12 = v9;
  *(_QWORD *)&TbFlushList[6] = 0i64;
  v13 = 0i64;
  PteBase = MmGetPteBase();
  if( v11 == 512 )
    v12 = 1i64;
  NumberOfEntries = v12;
  if( (a6 & 1) != 0 )
  {
    v15.Long = *(unsigned __int64 *)(a1 + 24);
    v88.Long = v15.Long;
    v16 = (a2 << 26) | 0x80000000;
    v17 = *(_DWORD *)(v15.Long + 48);
    if( (v17 & 0x300000) == 3145728 )
      v16 = a2 << 26;
    if( (*v10 & 1) != 0 )
      v18 = 4;
    else
      v18 = (v17 >> 7) & 0x1F;
    LODWORD(v19.Long) = MiMakeValidPte((_XSTATE_CONFIGURATION *)&PteBase[0x7FFFFFFEFi64], 0i64, v18 | v16);
    v97.Long = v19.Long;
    v20 = (v17 >> 12) & 0x3F;
    v21.Long = v19.Long;
    v89 = v20;
    MiLockWorkingSetShared();
    v22 = NumberOfEntries;
    WsIrql = v23;
    v24 = (v17 & 0x1100000) == 17825792;
  }
  else
  {
    v15.Long = 0i64;
    v88.Long = 0i64;
    v21.Long = 0i64;
    v97.Long = 0i64;
    v20 = 0;
    v89 = 0;
    WsIrql = 17;
    LODWORD(v25) = MiGetLeafVa(a5);
    v24 = (MiLocateAddress(v25)->Core.u.LongFlags & 0x1100000) == 17825792;
  }
  v26 = 0i64;
  v92 = v24;
  v101 = 0i64;
  if( !v102 )
  {
    v71.Long = v88.Long;
    goto LABEL_116;
  }
  v27 = v104;
  v28 = v105;
  v29 = (_QWORD *)v104;
  v109 = 8 * v22;
  v30 = v105 - v104;
  v103 = 0i64;
  v110 = v105 - v104;
  v96 = v104;
  while( 1 )
  {
    if( v28 )
    {
      v31 = *(_QWORD *)((char *)v29 + v30);
      v32 = MmGetPteBase();
      v33 = a2;
      v6 = (UINT64)v32 + ((v31 >> 9) & 0x7FFFFFFFF8i64);
      if( v90 == 512 )
      {
        do
        {
          v6 = (UINT64)v32 + ((v6 >> 9) & 0x7FFFFFFFF8i64);
          --v33;
        }
        while( v33 );
      }
      if( v31 < (*(unsigned int *)(v15.Long + 24) | ((unsigned __int64)*(unsigned __int8 *)(v15.Long + 32) << 32)) << 12
        || v31 > (((*(unsigned int *)(v15.Long + 28) | ((unsigned __int64)*(unsigned __int8 *)(v15.Long + 33) << 32)) << 12) | 0xFFF) )
      {
        v15.Long = (unsigned __int64)MiGetAweNode(v31)[3].u;
        v88.Long = v15.Long;
        v35 = *(_DWORD *)(v15.Long + 48);
        if( ((unsigned __int8)*(_DWORD *)v107 & v36) != 0 )
          v37 = 4;
        else
          v37 = (v35 >> 7) & 0x1F;
        LODWORD(v38.Long) = MiMakeValidPte((_XSTATE_CONFIGURATION *)&v32[0x7FFFFFFEFi64], 0i64, v37 | v34);
        v29 = (_QWORD *)v96;
        v21.Long = v38.Long;
        v20 = (v35 >> 12) & 0x3F;
        v97.Long = v38.Long;
        v89 = v20;
      }
      if( !v27 || (v39.Long = v21.Long, !*v29) )
        v39.Long = ZeroPte.u.Long;
    }
    else
    {
      v39.Long = ZeroPte.u.Long;
      if( v27 )
        v39.Long = v21.Long;
    }
    if( (v39.Long & 1) != 0 )
      v39.Long ^= (v39.Long ^ (*v29 << 12)) & 0xFFFFFFFFF000i64;
    v40 = MmGetPteBase();
    v41 = (v6 >> 9) & 0x7FFFFFFFF8i64;
    if( v15.Long )
    {
      v42 = (char *)v40 + v41;
      if( (_MMPTE *)v13 != (_MMPTE *)((char *)v40 + v41) )
      {
        if( v13 )
        {
          updated = MiUpdateAwePageTable(v13, v91, WsIrql_4);
          MiFlushTbList(TbFlushList);
          if( v92 )
            v93 = 0i64;
          MiUnlockPageTableInternal((INT64)p_Vm, v13);
          v44 = 0i64;
          if( updated )
          {
            LOBYTE(v44) = WsIrql;
            MiUnlockWorkingSetShared(&p_Vm->Instance, v44);
            MiGetLeafVa(v13 + 8);
            LODWORD(v45) = MiGetLeafVa(v13);
            MiDeleteEmptyPageTables(v45, v46, v47);
            MiLockWorkingSetShared();
            WsIrql = v48;
          }
          v91 = 0i64;
          WsIrql_4 = 0;
        }
        LODWORD(Flags) = 0;
        MiMakeSystemAddressValid((VOID *)v6, 0i64, v20, WsIrql, Flags);
        v13 = (UINT64)v42;
      }
      v15.Long = v88.Long;
    }
    else
    {
      v13 = (UINT64)v40 + v41;
    }
    v49 = v6;
    v50 = *(_QWORD *)v6;
    v51 = 0i64;
    v108 = *(_QWORD *)v6;
    if( v93 )
      v49 = v93;
    v93 = v49;
    v100 = v49;
    if( (v39.Long & 1) == 0 )
    {
      if( v50 )
      {
        WsIrql_4 -= NumberOfEntries;
        v91 -= NumberOfEntries;
        if( (v50 & 1) == 0 || (v51 = 3i64, v90 != 512) )
          v51 = 4i64;
      }
      goto LABEL_57;
    }
    if( (v50 & 1) != 0 )
    {
      if( v39.Long != v50 )
      {
        LOBYTE(v51) = v90 == 512;
        v51 = (unsigned int)(v51 + 1);
      }
LABEL_57:
      v52 = NumberOfEntries;
      goto LABEL_58;
    }
    v52 = NumberOfEntries;
    v51 = 5i64;
    if( (v50 & 0x800) == 0 )
    {
      v91 += NumberOfEntries;
      if( !v50 )
        WsIrql_4 += NumberOfEntries;
    }
LABEL_58:
    MiWriteAweClusterPte((INT64)p_Vm, (INT64 *)v6, v39.Hard._bf_0, v51, v52);
    if( v50 )
    {
      if( (v50 & 1) != 0 )
      {
        if( v15.Long )
        {
          if( v90 == 512 )
          {
            if( NumberOfEntries )
            {
              v54 = v6;
              v55 = NumberOfEntries;
              do
              {
                MiInsertLargeTbFlushEntry(TbFlushList, a2, v54);
                v54 += 8i64;
                --v55;
              }
              while( v55 );
              v20 = v89;
              v21.Long = v97.Long;
            }
          }
          else
          {
            MiInsertTbFlushEntry(
              TbFlushList,
              (VOID *)((__int64)((v6 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16),
              NumberOfEntries,
              0i64);
          }
        }
        LODWORD(v56) = MI_READ_PTE_LOCK_FREE((INT64)&v108);
        v57 = v56 >> 12;
      }
      else
      {
        v58 = v50;
        if( *(&stru_140C4DB30 + 42) && (v50 & 0x10) == 0 )
          v58 = v50 & ~*(&stru_140C4DB30 + 42);
        v57 = v58 >> 12;
      }
      v53 = 0xFFFFFFFFFi64;
      v59 = v57 & 0xFFFFFFFFFi64;
    }
    else
    {
      v59 = -1i64;
    }
    if( !v50 )
    {
      v63 = v98;
LABEL_90:
      v62 = v90;
      goto LABEL_91;
    }
    v60 = &MmGetPfnDb()[v59];
    v61 = 0i64;
    v62 = v90;
    v63 = v98;
    if( v90 )
    {
      v64 = v90;
      do
      {
        if( (v60->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64) == 1 )
          goto LABEL_86;
        LODWORD(SpinCount) = 0;
        if( _interlockedbittestandset64((volatile signed __int32 *)&v60->u2, 0x3Fui64) )
        {
          do
          {
            do
              KeYieldProcessorEx(&SpinCount);
            while( v60->u2._bf_0 < 0 );
          }
          while( _interlockedbittestandset64((volatile signed __int32 *)&v60->u2, 0x3Fui64) );
          v64 = v90;
        }
        v53 = v60->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64;
        if( v53 == 1 )
          v53 = 1i64;
        else
          v60->u2._bf_0 ^= (v60->u2._bf_0 ^ (v53 - 1)) & 0x3FFFFFFFFFFFFFFFi64;
        _InterlockedAnd64(&v60->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
        if( v53 == 1 )
LABEL_86:
          MiDecrementAweMapCount((VOID *)v53, (UINT64)v60, (UINT64)&ReserveSize);
        v63 = v98;
        v60 += v98;
        v61 += v98;
      }
      while( v61 < v64 );
      v20 = v89;
      v21.Long = v97.Long;
      goto LABEL_90;
    }
LABEL_91:
    v65 = v101 + 1;
    v29 = (_QWORD *)(v96 + 8);
    v6 += v109;
    ++v101;
    v96 += 8i64;
    v103 += NumberOfEntries;
    if( (v103 & 0x3F) == 0 || v62 != v63 )
      break;
    v71.Long = v88.Long;
    v26 = 0i64;
    p_Instance = &p_Vm->Instance;
LABEL_98:
    v72 = v65 < v102;
    v27 = v104;
    v30 = v110;
    v28 = v105;
    if( !v72 )
      goto LABEL_112;
    v15.Long = v88.Long;
  }
  p_Instance = &p_Vm->Instance;
  LOBYTE(v67) = MiWorkingSetIsContended((INT64)p_Vm);
  v26 = 0i64;
  if( v67 )
  {
    v69 = v100;
  }
  else
  {
    IsContended = MiPageTableLockIsContended((__int64)p_Vm, v13);
    v69 = v100;
    v26 = 0i64;
    if( !IsContended )
    {
      v93 = v100;
      ShouldYieldProcessor = KeShouldYieldProcessor();
      v26 = 0i64;
      if( !ShouldYieldProcessor )
      {
        v71.Long = v88.Long;
LABEL_97:
        v29 = (_QWORD *)v96;
        goto LABEL_98;
      }
    }
  }
  if( v65 != v102 )
  {
    v73 = MiUpdateAwePageTable(v13, v91, WsIrql_4);
    MiFlushTbList(TbFlushList);
    v93 = v69;
    if( v92 )
    {
      v74 = v69;
      if( v69 )
        v74 = 0i64;
      v93 = v74;
    }
    MiUnlockPageTableInternal((INT64)p_Vm, v13);
    LOBYTE(v75) = WsIrql;
    MiUnlockWorkingSetShared(&p_Vm->Instance, v75);
    v71.Long = v88.Long;
    if( v73 && v88.Long )
    {
      MiGetLeafVa(v13 + 8);
      LODWORD(v76) = MiGetLeafVa(v13);
      MiDeleteEmptyPageTables(v76, v77, v78);
    }
    v91 = 0i64;
    v13 = 0i64;
    WsIrql_4 = 0;
    MiLockWorkingSetShared();
    v65 = v101;
    v26 = 0i64;
    goto LABEL_97;
  }
  v71.Long = v88.Long;
LABEL_112:
  if( v13 )
  {
    v79 = MiUpdateAwePageTable(v13, v91, WsIrql_4);
    if( v71.Long )
    {
      MiFlushTbList(TbFlushList);
      MiUnlockPageTableInternal((INT64)p_Instance, v13);
      goto LABEL_117;
    }
    return ReserveSize;
  }
LABEL_116:
  p_Instance = &p_Vm->Instance;
  v79 = 0;
LABEL_117:
  LOBYTE(v26) = WsIrql;
  MiUnlockWorkingSetShared(p_Instance, v26);
  if( v79 && v71.Long )
  {
    MiGetLeafVa(v13 + 8);
    LODWORD(v80) = MiGetLeafVa(v13);
    MiDeleteEmptyPageTables(v80, v81, v82);
  }
  return ReserveSize;
}

Referenced by:

MiDeleteVadAwePtes
NtMapUserPhysicalPages
NtMapUserPhysicalPagesScatter