MiResolveTransitionFault

INT64 __fastcall MiResolveTransitionFault(
        VOID *FaultingAddress,
        _MMPTE *PoINTerPte,
        _MMPFN *ProtoPfn,
        _MMSUPPORT_INSTANCE *Vm,
        VOID *TrapInformation,
        UINT64 StoreInstruction,
        INT64 VmIrql,
        CHAR PreviousMode,
        _MMINPAGE_SUPPORT **ReadBlock){
  VOID *v9; 
  __int64 v10; 
  INT64 v12; 
  unsigned __int64 v13; 
  _DWORD *v14; 
  ULONG_PTR v15; 
  char *v16; 
  _MMPFN *PfnDb; 
  unsigned __int64 v18; 
  char *v19; 
  INT64 result; 
  unsigned __int64 v21; 
  _MMPTE *Pml4eBase; 
  _MMPTE *PxeUserLimit; 
  unsigned __int64 v24; 
  unsigned int v25; 
  char v26; 
  __int64 v27; 
  _QWORD *v28; 
  WCHAR *v29; 
  _MMSUPPORT_INSTANCE *v30; 
  __int64 v31; 
  unsigned __int64 v32; 
  __int64 v33; 
  unsigned __int64 v34; 
  __int64 v35; 
  __int64 v36; 
  INT64 v37; 
  unsigned __int64 v38; 
  INT64 v39; 
  __int64 v40; 
  __int64 v41; 
  int v42; 
  INT64 v43; 
  int v44; 
  unsigned __int64 v45; 
  unsigned __int64 v46; 
  __int64 CurrentPrcb; 
  _MMPFN *v48; 
  int v49; 
  int v50; 
  bool v51; 
  __int64 v52; 
  _MMPTE *PteBase; 
  char v54; 
  int v55; 
  unsigned __int64 v56; 
  unsigned __int64 v57; 
  unsigned __int64 v58; 
  __int64 v59; 
  __int64 v60; 
  signed __int32 v61; 
  struct _SLIST_ENTRY *v62; 
  int v63; 
  WCHAR *v64; 
  _BYTE *v65; 
  __int64 v66; 
  __int64 v67; 
  char v68; 
  int v69; 
  __int16 v70; 
  UNICODE_STRING *v71; 
  int v72; 
  char v73; 
  INT64 *BugCheckParameter4; 
  _DWORD *a6; 
  PSLIST_ENTRY *a7; 
  INT64 v77; 
  INT64 a9; 
  INT64 v79; 
  INT64 a11; 
  INT64 a5; 
  PSLIST_ENTRY ListEntry; 
  INT64 v83; 
  _MMPTE *v84; 
  __int64 v85; 
  v9 = TrapInformation;
  v10 = *((_QWORD *)FaultingAddress + 7);
  v12 = *((_QWORD *)FaultingAddress + 2);
  v13 = (unsigned __int64)PoINTerPte;
  LODWORD(a9) = 0;
  v14 = FaultingAddress;
  *(_QWORD *)TrapInformation = 0i64;
  v85 = v10;
  a11 = v12;
  ListEntry = 0i64;
  if( !ProtoPfn )
  {
    v15 = MI_READ_PTE_LOCK_FREE((INT64)PoINTerPte);
    if( (v15 & 0x800) != 0 )
    {
      v16 = (char *)MmGetPfnDb() + 40;
      do
      {
        PfnDb = MmGetPfnDb();
        if( (v15 & 1) == 0 && (!v15 || !qword_140C4DC80 || (qword_140C4DC80 & v15) != 0) )
        {
          v18 = v15;
          if( qword_140C4DC80 && (v15 & 0x10) == 0 )
            v18 = v15 & ~qword_140C4DC80;
          if( (*(_QWORD *)&v16[48 * ((v18 >> 12) & 0xFFFFFFFFFi64)] & 0x4000000000000i64) != 0 )
          {
            v19 = (char *)PfnDb + 48 * ((v18 >> 12) & 0xFFFFFFFFFi64);
            HIDWORD(a9) = 0;
            while( _interlockedbittestandset64((volatile signed __int32 *)v19 + 6, 0x3Fui64) )
            {
              do
                KeYieldProcessorEx((UINT64 *)((char *)&a9 + 4));
              while( *((__int64 *)v19 + 3) < 0 );
            }
            if( MI_READ_PTE_LOCK_FREE(v13) == v15 )
            {
              PoINTerPte = (_MMPTE *)0x8000000000000000i64;
              if( (*((_QWORD *)v19 + 1) | 0x8000000000000000ui64) != v13 )
              {
                PoINTerPte = (_MMPTE *)0x1000000000i64;
                if( (*((_QWORD *)v19 + 5) & 0x1000000000i64) == 0 )
                  KeBugCheckEx(0x1Au, 0x411ui64, v13, v15, *((_QWORD *)v19 + 1));
              }
              v21 = *(_QWORD *)v13;
              Pml4eBase = MmGetPml4eBase();
              PxeUserLimit = MmGetPxeUserLimit();
              v9 = TrapInformation;
              v12 = a11;
              v14 = FaultingAddress;
              goto LABEL_26;
            }
            _InterlockedAnd64((volatile signed __int64 *)v19 + 3, 0x7FFFFFFFFFFFFFFFui64);
          }
        }
        v15 = MI_READ_PTE_LOCK_FREE(v13);
      }
      while( (v15 & 0x800) != 0 );
    }
    return 3221226548i64;
  }
  v21 = *(_QWORD *)PoINTerPte;
  Pml4eBase = MmGetPml4eBase();
  PxeUserLimit = MmGetPxeUserLimit();
  v24 = *(_QWORD *)PoINTerPte;
  if( qword_140C4DC80 && (v21 & 0x10) == 0 )
    v24 = v21 & ~qword_140C4DC80;
  v19 = (char *)MmGetPfnDb() + 48 * ((v24 >> 12) & 0xFFFFFFFFFi64);
LABEL_26:
  if( (v19[35] & 0x10) != 0 )
  {
    v25 = -1073740023;
LABEL_39:
    _InterlockedAnd64((volatile signed __int64 *)v19 + 3, 0x7FFFFFFFFFFFFFFFui64);
    if( ProtoPfn )
    {
      LOBYTE(PoINTerPte) = 17;
      MiUnlockProtoPoolPage(ProtoPfn, (UINT64)PoINTerPte);
    }
    return v25;
  }
  PoINTerPte = (_MMPTE *)(v12 & 1);
  v84 = PoINTerPte;
  if( (v12 & 1) != 0 && *(_BYTE *)(v12 & 0xFFFFFFFFFFFFFFFEui64) == 1 )
  {
    MiUpdatePfnPriority((INT64)v19);
    v25 = 0;
    goto LABEL_39;
  }
  __incgsdword(0x2E98u);
  v26 = v19[34];
  if( (v26 & 8) != 0 )
  {
    if( (MiFlags & 0x40000) != 0 && (v27 = *((_QWORD *)v19 + 2) >> 5, (v27 & 0x1F) == 0) && (v27 & 2) != 0
      || (v12 & 1) != 0
      && *(_BYTE *)(v12 & 0xFFFFFFFFFFFFFFFEui64) == 5
      && (*(_DWORD *)((v12 & 0xFFFFFFFFFFFFFFFEui64) + 56) & 0x20) != 0 )
    {
      v14[20] |= 0x80u;
      v25 = -1073741801;
      goto LABEL_39;
    }
  }
  if( (v26 & 0x20) != 0 )
  {
    result = MiHandleCollidedFault((INT64)v14, (_MMPTE *)v13, (INT64)ProtoPfn, (INT64)v19, (INT64)v9, &a9);
    if( (unsigned int)a9 <= 1 || (int)result < 0 )
      return result;
  }
  else
  {
    a5 = 0i64;
    a7 = &ListEntry;
    a6 = (_DWORD *)v21;
    BugCheckParameter4 = &a5;
    result = MiHandleTransitionFault();
    if( (int)result < 0 )
      return result;
    if( a5 )
      v19 = (char *)a5;
  }
  v30 = Vm;
  v31 = *((_QWORD *)FaultingAddress + 2);
  if( (v31 & 1) != 0 && *(_BYTE *)(v31 & 0xFFFFFFFFFFFFFFFEui64) == 4 )
  {
    v21 = -865i64;
    *(_QWORD *)v13 = *(_QWORD *)v13 & 0xFFFFFFFFFFFFFC1Fui64 | 0x80;
  }
  if( ((v21 >> 5) & 0x1F) == 24 )
    MiMakeProtoReadOnly((UINT64 *)v13, (INT64)v19);
  v32 = *(_QWORD *)v13;
  v33 = *(_QWORD *)v13;
  if( qword_140C4DC80 && (v32 & 0x10) == 0 )
    v33 = v32 & ~qword_140C4DC80;
  v34 = v33 & 0xFFFFFFFFF000i64 | MmProtectToPteMask[(v32 >> 5) & 0x1F] & 0xFFFF000000000E7Fui64 | 0x21;
  if( v13 < (unsigned __int64)MmGetPteBase() || v13 > (unsigned __int64)MmGetPteLimit() )
  {
    v36 = v34 | 0x100;
  }
  else
  {
    v35 = (__int64)((v13 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
    if( v13 >= (unsigned __int64)MmGetPdeBase() && v13 <= (unsigned __int64)MmGetPdeLimit() )
    {
      if( (_MMPTE *)v13 == MmGetPxeSelfRef() )
        v34 |= 0x8000000000000000ui64;
      else
        v34 &= ~0x8000000000000000ui64;
      if( (unsigned int)MiUserPdeOrAbove(v13) )
        v34 |= 4ui64;
    }
    if( v13 <= (unsigned __int64)MmGetPteBase() + 0x3FFFFFFF78i64 )
      v34 |= 4ui64;
    v36 = v34 | 0x100;
    if( !(unsigned int)MiIsAddressGlobal(v35) )
      v36 = (__int64)v28;
  }
  v37 = ZeroPte;
  v38 = v36 & 0xF0FFFFFFFFFFFFFFui64 | 0xA00000000000000i64;
  v39 = *(_QWORD *)(qword_140C4E388 + 8 * ((*((_QWORD *)v19 + 5) >> 39) & 0x3FFi64));
  v40 = *((_QWORD *)v19 + 2);
  v83 = v39;
  if( (v40 & 0x400) == 0 && (v40 & 4) != 0 && (unsigned __int16)v40 >> 12 == *(_DWORD *)(v39 + 1156) )
    v37 = MiCaptureDirtyBitToPfn((INT64)v19);
  v41 = *((_QWORD *)v19 + 2);
  if( (v41 & 0x400) == 0 && (v41 & 0x4000000) != 0 )
    v38 |= 0x40ui64;
  if( (v38 & 0x800) != 0 )
  {
    v28 = FaultingAddress;
    if( Vm && !MiOkToSetPteDirtyForNotValidFault(v38, *(_QWORD *)FaultingAddress) )
      v30 = 0i64;
    if( (v19[34] & 0x10) != 0 )
    {
      if( v30 || *v28 >= 0xFFFF800000000000ui64 )
        goto LABEL_90;
    }
    else if( v30 )
    {
      LOBYTE(v42) = MI_PFN_IS_PROTO((UNICODE_STRING *)v19, (UNICODE_STRING *)v39, (UINT8)v28, v29);
      if( !v42 )
      {
        v37 = MiCaptureDirtyBitToPfn(v43);
LABEL_90:
        v38 |= 0x42ui64;
      }
    }
  }
  LOBYTE(v44) = MI_PFN_IS_PROTO((UNICODE_STRING *)v19, (UNICODE_STRING *)v39, (UINT8)v28, v29);
  if( v44 )
  {
    v45 = v38;
    if( v13 >= (unsigned __int64)Pml4eBase
      && v13 <= (unsigned __int64)PxeUserLimit
      && (*(_DWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 2172i64) & 0x1000) != 0 )
    {
      v45 = v38 | 0x8000000000000000ui64;
    }
    *(_QWORD *)v13 = v45;
  }
  _InterlockedAnd64((volatile signed __int64 *)v19 + 3, 0x7FFFFFFFFFFFFFFFui64);
  v48 = ProtoPfn;
  v49 = 0;
  v50 = 1;
  if( !ProtoPfn )
    goto LABEL_146;
  LODWORD(v79) = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)ProtoPfn + 6, 0x3Fui64) )
  {
    do
      KeYieldProcessorEx((UINT64 *)&v79);
    while( *((__int64 *)ProtoPfn + 3) < 0 );
  }
  *((_BYTE *)ProtoPfn + 34) &= ~0x20u;
  v45 = *((unsigned __int16 *)ProtoPfn + 16);
  if( !(_WORD)v45 )
    MiBadRefCount(ProtoPfn, v45);
  v51 = (_WORD)v45 == 1;
  LOWORD(v45) = v45 - 1;
  *((_WORD *)ProtoPfn + 16) = v45;
  if( v51 && MiIsPfnFileOnly((INT64)ProtoPfn) )
    goto LABEL_144;
  CurrentPrcb = *((_QWORD *)ProtoPfn + 5);
  if( (CurrentPrcb & 0x1000000000i64) != 0 || (CurrentPrcb & 0x2000000000000i64) != 0 )
    goto LABEL_145;
  v52 = *((_QWORD *)ProtoPfn + 3) & 0x3FFFFFFFFFFFFFFFi64;
  if( !(_WORD)v45 )
    goto LABEL_114;
  if( (_WORD)v45 != 1 )
  {
    if( (_WORD)v45 != 2 || !v52 )
      goto LABEL_145;
LABEL_112:
    if( (*((_BYTE *)ProtoPfn + 34) & 8) == 0 )
      goto LABEL_145;
    goto LABEL_113;
  }
  if( !v52 )
    goto LABEL_112;
LABEL_113:
  v50 = 0;
LABEL_114:
  PteBase = MmGetPteBase();
  v46 = *((_QWORD *)ProtoPfn + 1) | 0x8000000000000000ui64;
  if( v46 > (unsigned __int64)PteBase + 0x3FFFFFFF78i64 || v46 < (unsigned __int64)PteBase )
  {
    v54 = *((_BYTE *)ProtoPfn + 35);
    if( (v54 & 0x20) != 0 )
    {
      *((_BYTE *)ProtoPfn + 35) = v54 & 0xDF;
      goto LABEL_143;
    }
  }
  LOBYTE(v55) = MI_PFN_IS_PROTO((UNICODE_STRING *)ProtoPfn, 0i64, *((_BYTE *)ProtoPfn + 8), (PWCHAR)CurrentPrcb);
  if( v55 && (*((_DWORD *)ProtoPfn + 4) & 0x400i64) != 0 )
  {
    v45 = 1i64;
  }
  else if( v56 <= v58 && v56 >= (unsigned __int64)MmGetPteBase() && (*((_BYTE *)ProtoPfn + 35) & 0x20) != 0 )
  {
    v45 = 1i64;
  }
  else if( v50 == 1 && (v59 & 0x4000000000000000i64) != 0 )
  {
    v45 = 1i64;
  }
  CurrentPrcb = (v57 >> 39) & 0x3FF;
  v60 = *(_QWORD *)(qword_140C4E388 + 8 * CurrentPrcb);
  if( (_DWORD)v45 == 1 )
    MiReturnCommit(*(_MI_PARTITION **)(qword_140C4E388 + 8 * CurrentPrcb), 1ui64);
  v46 = 1i64;
  if( (ULONG_PTR *)v60 != &MiSystemPartition )
    goto LABEL_141;
  CurrentPrcb = (__int64)KeGetCurrentPrcb();
  v45 = *(int *)(CurrentPrcb + 33564);
  if( (_DWORD)v45 == -1 )
    goto LABEL_141;
  if( v45 + 1 <= 0x100 )
  {
    do
    {
      v61 = _InterlockedCompareExchange((volatile signed __int32 *)(CurrentPrcb + 33564), v45 + 1, v45);
      v51 = (_DWORD)v45 == v61;
      v45 = v61;
      if( v51 )
        goto LABEL_142;
    }
    while( v61 != -1 && (unsigned __int64)(v61 + 1i64) <= 0x100 );
  }
  if( (int)v45 > 192
    && (_DWORD)v45 != -1
    && (_DWORD)v45 == _InterlockedCompareExchange((volatile signed __int32 *)(CurrentPrcb + 33564), 192, v45) )
  {
    v46 = (int)v45 - 192 + 1i64;
  }
  if( v46 )
LABEL_141:
    v46 = _InterlockedExchangeAdd64((volatile signed __int64 *)(v60 + 7168), v46);
LABEL_142:
  v48 = ProtoPfn;
LABEL_143:
  if( v50 )
LABEL_144:
    MiPfnReferenceCountIsZero(v48, (v48 - MmGetPfnDb()) / 48, (UINT8 *)v46);
LABEL_145:
  _InterlockedAnd64((volatile signed __int64 *)v48 + 3, 0x7FFFFFFFFFFFFFFFui64);
LABEL_146:
  if( v37 )
    MiReleasePageFileInfo(
      v83,
      v37,
      1,
      CurrentPrcb,
      (INT64)BugCheckParameter4,
      (INT64)a6,
      (INT64)a7,
      v77,
      a9,
      v79,
      a11,
      a5);
  v62 = ListEntry;
  if( ListEntry )
  {
    if( SLODWORD(ListEntry[11].Next) > 1 )
      KeSetEvent((PRKEVENT)(&ListEntry[3].Next + 1), 0);
    MiFreeInPageSupportBlock(v62);
  }
  LOBYTE(v63) = MI_PFN_IS_PROTO((UNICODE_STRING *)v19, (UNICODE_STRING *)v45, v46, (PWCHAR)CurrentPrcb);
  if( v63 )
  {
    result = MiCompleteProtoPteFault((INT64)FaultingAddress, v38, (__int64)Vm, 0, a11);
    if( (int)result < 0 )
      return result;
  }
  else
  {
    v65 = (_BYTE *)(a11 & 0xFFFFFFFFFFFFFFFEui64);
    if( v84 && *v65 == 4 )
    {
      *(_QWORD *)v13 = v38;
    }
    else
    {
      v66 = 0i64;
      if( v84 )
      {
        if( *v65 == 3 )
        {
          v38 &= ~0x20ui64;
          v49 = 1;
        }
        else if( *v65 == 5 )
        {
          v66 = a11 & 0xFFFFFFFFFFFFFFFEui64;
        }
      }
      if( (*((_BYTE *)FaultingAddress + 69) & 8) != 0 )
      {
        v67 = *((_QWORD *)FaultingAddress + 2);
        if( (v67 & 1) == 0 || *(_BYTE *)(v67 & 0xFFFFFFFFFFFFFFFEui64) != 2 )
          v38 &= ~0x20ui64;
      }
      v68 = *((_BYTE *)FaultingAddress + 69);
      if( (v68 & 5) == 4 && (v68 & 2) == 0 )
      {
        v69 = *((unsigned __int16 *)FaultingAddress + 33);
        if( (_WORD)v69
          && (v69 + *((unsigned __int16 *)FaultingAddress + 32) != (((unsigned int)v13 >> 3) & 0x1FF)
           || (v68 & 0x10) == 0) )
        {
          MiEmptyDeferredWorkingSetEntries((INT64)FaultingAddress + 56);
        }
        v70 = *((_WORD *)FaultingAddress + 33);
        if( v70 )
        {
          *((_WORD *)FaultingAddress + 33) = v70 + 1;
        }
        else
        {
          v71 = (UNICODE_STRING *)*((unsigned __int8 *)FaultingAddress + 69);
          *((_WORD *)FaultingAddress + 33) = 1;
          *((_WORD *)FaultingAddress + 32) = ((unsigned int)v13 >> 3) & 0x1FF;
          LOBYTE(v72) = MI_PFN_IS_PROTO((UNICODE_STRING *)v19, v71, 0xFFu, v64);
          if( v72 )
            *((_BYTE *)FaultingAddress + 69) = v73 & 0xEF;
          else
            *((_BYTE *)FaultingAddress + 69) = v73 | 0x10;
        }
        v49 |= 4u;
      }
      LODWORD(a6) = v49;
      if( !(unsigned int)MiAllocateWsle(v85, v13, v19, 0, v38, (__int64)a6, v66) )
      {
        MiLockAndDecrementShareCount((UINT64)v19, 0);
        return 3221225495i64;
      }
    }
  }
  return 272i64;
}

Referenced by:

MiDispatchFault
MiResolveProtoPteFault