MiHandleForkTransitionPte

NTSTATUS __stdcall MiHandleForkTransitionPte(
        _EPROCESS *CurrentProcess,
        _MMPTE *PointerPte,
        _MMPTE *PointerNewPte,
        _MMCLONE_BLOCK *ForkProtoPte,
        UINT64 *PrivatePageCount,
        _MI_TB_FLUSH_LIST *TbFlushList,
        UINT64 *NewPage,
        UINT64 CloneFlags,
        UINT8 WsIrql,
        _MI_CLONE_CHARGES *CommitBlock){
  unsigned __int64 v10; 
  _MMPTE *v11; 
  __int64 v13; 
  unsigned int v14; 
  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; 
  int v17; 
  __int64 v18; 
  __int64 v19; 
  _MI_PARTITION *v20; 
  __int64 v21; 
  __int64 v22; 
  _MMPFN *v24; 
  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;} v25; 
  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;} v26; 
  UINT64 v27; 
  __int64 v28; 
  signed __int32 v29; 
  __int64 v30; 
  UINT8 v31; 
  _MI_PARTITION *v32; 
  UINT64 v33; 
  _MMSUPPORT_SHARED *v34; 
  UINT8 v35; 
  __int64 v36; 
  int v37; 
  int v38; 
  __int64 v39; 
  int v40; 
  UINT8 v41; 
  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;} v42; 
  int v43; 
  __int64 v44; 
  INT64 v45; 
  unsigned __int64 v46; 
  unsigned __int64 v47; 
  _MMPFN *PfnDb; 
  _MMPFN *v49; 
  unsigned __int64 v50; 
  int v51; 
  unsigned __int64 Long; 
  int v53; 
  _MMPFN *v54; 
  _MMSUPPORT_SHARED *SharedVm; 
  UINT64 Flags; 
  int Color; 
  unsigned int Colora; 
  int Color_4; 
  int v60; 
  unsigned int Vm; 
  _MMSUPPORT_FULL *Vma; 
  INT64 v63; 
  __int64 v64; 
  ULONG_PTR *Partition; 
  __int128 ColorBase; 
  __int64 v67; 
  __int64 bf_0; 
  _QWORD *v72; 
  _DWORD *v73; 

  v10 = (unsigned __int64)PrivatePageCount;
  v11 = PointerNewPte;
  v63 = 0i64;
  ColorBase = 0i64;
  v13 = MiSwizzleInvalidPte(((_QWORD)PrivatePageCount << 16) | 0x400i64);
  v15.Long = ZeroPte.u.Long;
  v16 = v14;
  v67 = v13;
  v17 = v14;
  v19 = *(unsigned __int16 *)(v18 + 1838);
  bf_0 = ZeroPte.u.Hard._bf_0;
  Color_4 = v14;
  v60 = v14;
  v20 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * v19);
  v22 = *(unsigned __int16 *)(v21 + 1838);
  v64 = (__int64)v20;
  Partition = *(ULONG_PTR **)(*(&stru_140C4DB30 + 267) + 8 * v22);
  if( Partition != (ULONG_PTR *)v20 )
  {
    if( (WsIrql & 1) != 0 )
    {
      if( !MiChargeCommit(v20, v14 + 1, 0i64) )
      {
        MiWriteUselessChildPte(&ForkProtoPte->ProtoPte.u.Long);
        *v73 = 1;
        return 1;
      }
      v17 = 1;
      v60 = 1;
    }
    if( MiGetCrossPartitionCloneCharges((INT64)v20) )
    {
      v16 = 1;
      Color_4 = 1;
      goto LABEL_12;
    }
    MiWriteUselessChildPte(&ForkProtoPte->ProtoPte.u.Long);
    *v73 = 1;
    if( v17 )
      MiReturnCommit(v20, 1ui64);
    return 1;
  }
  while( 1 )
  {
LABEL_12:
    v24 = MiLockTransitionLeafPage((ULONG_PTR)v11, 0i64);
    if( !v24 )
      goto LABEL_22;
    LODWORD(v25.Long) = MI_READ_PTE_LOCK_FREE((INT64)v11);
    v26.Long = v25.Long;
    v27 = 0i64;
    v28 = (v25.Long >> 5) & 0x1F;
    Vm = v28;
    if( !v24->u3.ReferenceCount
      && (v28 & 0xFFFFFFF8) != 16
      && !(unsigned int)MI_IS_SOFTWARE_PTE_SHADOW_STACK((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;} *)&v24->OriginalPte.u.Long) )
    {
      break;
    }
    Color = *((unsigned __int8 *)&v24->u3 + 2) >> 6;
    Vma = &CurrentProcess->Vm;
    if( *(_QWORD *)CloneFlags != -1i64 )
    {
      if( v17 )
      {
        MiReturnCommit(v20, 1ui64);
        LODWORD(v27) = 0;
        v17 = 0;
      }
      if( v16 )
      {
        MiReturnCrossPartitionCloneCharges((_MI_CROSS_PARTITION_CHARGES *)v20);
        LODWORD(v27) = 0;
      }
      v16 = v27;
      v54 = &MmGetPfnDb()[*(_QWORD *)CloneFlags];
      MiLockNestedPageAtDpcInline(v54);
      MiFinalizePageAttribute(v54, (_MI_PFN_CACHE_ATTRIBUTE)Color, 1ui64);
      _InterlockedAnd64(&v54->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
      if( (*(_BYTE *)(&v24->u3 + 1) & 0x20) != 0
        && (MiFlushTbList((_MI_TB_FLUSH_LIST *)NewPage), (*(_BYTE *)(&v24->u3 + 1) & 8) != 0) )
      {
        _InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
        MiUnlockWorkingSetExclusive(&Vma->Instance, (UINT8)CommitBlock);
        KeDelayExecutionThread(0, 0, (_LARGE_INTEGER *)&Interval);
        SharedVm = MiGetSharedVm(&Vma->Instance);
        ExAcquireSpinLockExclusive((INT64 *)&SharedVm->WorkingSetLock);
        SharedVm->GoodCitizenWaiting = 0;
      }
      else if( MiDuplicateCloneLeaf(
                  PointerNewPte,
                  &ForkProtoPte->ProtoPte,
                  *(_QWORD *)CloneFlags,
                  (UINT8)CommitBlock,
                  2u) )
      {
        *(_QWORD *)CloneFlags = -1i64;
        ++*(_QWORD *)TbFlushList;
        return 1;
      }
LABEL_22:
      if( v17 )
        MiReturnCommit(v20, 1ui64);
      if( v16 )
        MiReturnCrossPartitionCloneCharges((_MI_CROSS_PARTITION_CHARGES *)v20);
      return 0;
    }
    _InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
    MiInitializePageColorBase(&CurrentProcess->Vm.Instance, v27, (_MI_COLOR_BASE *)&ColorBase);
    v29 = _InterlockedExchangeAdd((volatile signed __int32 *)ColorBase, 1u);
    Colora = HIDWORD(ColorBase) | v29 & DWORD2(ColorBase);
    LODWORD(v30) = MiGetPage(Partition, Colora, 0i64);
    *(_QWORD *)CloneFlags = v30;
    if( v30 == -1 )
    {
      v31 = (unsigned __int8)CommitBlock;
      v32 = (_MI_PARTITION *)Partition;
      do
      {
        MiFlushTbList((_MI_TB_FLUSH_LIST *)NewPage);
        MiUnlockWorkingSetExclusive(&Vma->Instance, v31);
        MiWaitForFreePage(v32, v33);
        v34 = MiGetSharedVm(&Vma->Instance);
        v35 = ExAcquireSpinLockExclusive((INT64 *)&v34->WorkingSetLock);
        v34->GoodCitizenWaiting = 0;
        LODWORD(Flags) = 1;
        v31 = v35;
        MiMakeSystemAddressValid(PointerNewPte, 0i64, 0i64, v35, Flags);
        LODWORD(v36) = MiGetPage((ULONG_PTR *)&v32->Core.PartitionId, Colora, 0i64);
        *(_QWORD *)CloneFlags = v36;
      }
      while( v36 == -1 );
      v13 = v67;
      v15.Long = bf_0;
      v20 = (_MI_PARTITION *)v64;
      v16 = Color_4;
      v17 = v60;
      LOBYTE(CommitBlock) = v31;
      v10 = (unsigned __int64)PrivatePageCount;
    }
    v11 = PointerNewPte;
    if( (MI_READ_PTE_LOCK_FREE((INT64)PointerNewPte) & 0x401) != 0 )
      goto LABEL_22;
  }
  *(_QWORD *)v10 = v27;
  LOBYTE(v37) = MiPteInShadowRange(v10);
  if( v37 )
  {
    v40 = v38;
    if( (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v26.Long & 1) != 0 )
      v26.Long |= v39;
  }
  else
  {
    v40 = 0;
  }
  *(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 = (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;})v26.Long;
  if( v40 )
    MiWritePteShadow();
  MI_MAKE_PROTECT_WRITE_COPY((_MMPTE *)v10);
  v41 = 1;
  *(_QWORD *)(v10 + 8) = v16;
  *(_QWORD *)(v10 + 24) = 2i64;
  if( (WsIrql & 1) != 0 )
  {
    *(_QWORD *)(v10 + 16) = 1i64;
    if( v17 )
      ++*v72;
    else
      ++v72[1];
    _InterlockedExchangeAdd64((volatile signed __int64 *)&v20->Vp.SharedCommit, 1ui64);
    v42.Long = *(unsigned __int64 *)(v10 + 16);
  }
  else
  {
    v42.Long = 0i64;
  }
  *(_QWORD *)(v10 + 16) = v42.Long & 0x7FFFFFFFFFFFFFFi64 | ((unsigned __int64)Vm << 59);
  if( (v24->OriginalPte.u.Long & 2) != 0 )
  {
    v15.Long = (unsigned __int64)v24->OriginalPte.u;
    if( (*(_BYTE *)(&v24->u3 + 1) & 7) == 3 )
    {
      MiUnlinkPageFromList(v24, 0i64);
      v43 = 1;
    }
    else
    {
      v43 = 0;
    }
    v24->OriginalPte.u.Long &= ~2ui64;
    if( v43 )
      MiInsertPageInList(v24, 8ui64, v41);
  }
  v24->PteLong = v10;
  v24->u4._bf_0 |= 0x8000000000000000ui64;
  MI_MAKE_PROTECT_WRITE_COPY(&v24->OriginalPte);
  v44 = v24->u4._bf_0;
  v64 = v44 & 0xFFFFFFFFFi64;
  LODWORD(v45) = MI_READ_PTE_LOCK_FREE((INT64)MmGetPteBase() + ((v10 >> 9) & 0x7FFFFFFFF8i64));
  v63 = v45;
  LODWORD(v46) = MI_READ_PTE_LOCK_FREE((INT64)&v63);
  v24->u4._bf_0 = v44 ^ (v44 ^ (v46 >> 12)) & 0xFFFFFFFFFi64;
  LODWORD(v47) = MI_READ_PTE_LOCK_FREE((INT64)&v63);
  PfnDb = MmGetPfnDb();
  v49 = &PfnDb[(v47 >> 12) & 0xFFFFFFFFFi64];
  MiLockNestedPageAtDpcInline(v49);
  v49->u2._bf_0 ^= (v49->u2._bf_0 ^ (v49->u2._bf_0 + 1)) & 0x3FFFFFFFFFFFFFFFi64;
  _InterlockedAnd64(&v49->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
  v50 = v13;
  LOBYTE(v51) = MiPteInShadowRange((UINT64)PointerNewPte);
  if( v51 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v13 & 1) != 0 )
    v50 = v13 | 0x8000000000000000ui64;
  PointerNewPte->u.Long = v50;
  _InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
  if( v15.Long )
  {
    Long = v15.Long & 0xFFFFFFFFFFFFFFFBui64;
    if( (v15.Long & 4) == 0 )
      Long = v15.Long;
    MiReleasePageFileInfo(v20, (_MMPTE)Long, 1ui64);
  }
  if( (WsIrql & 1) != 0 && Vm != 24 )
    v13 |= 8ui64;
  LOBYTE(v53) = MiPteInShadowRange((UINT64)ForkProtoPte);
  if( v53 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v13 & 1) != 0 )
    v13 |= 0x8000000000000000ui64;
  ForkProtoPte->ProtoPte.u.Long = v13;
  MiLockAndDecrementShareCount(&PfnDb[v64], 0i64);
  _InterlockedExchangeAdd64((volatile signed __int64 *)&CurrentProcess->NumberOfPrivatePages, 0xFFFFFFFFFFFFFFFFui64);
  return 2;
}

Referenced by:

MiBuildForkPte