MiMapPageFileHash

VOID __stdcall MiMapPageFileHash(
        _MMPAGING_FILE *PagingFile,
        _MDL *Mdl,
        UINT64 MdlPageOffset,
        UINT64 ClusterStart,
        UINT64 ClusterSize){
  bool v5; 
  unsigned int v6; 
  _MDL *v8; 
  _MMPAGING_FILE *v9; 
  _MMSUPPORT_INSTANCE *AnyMultiplexedVm; 
  UINT64 *v11; 
  INT64 *p_SpinLock; 
  unsigned __int8 v13; 
  unsigned int *PageHash; 
  unsigned __int64 v15; 
  __int16 v16; 
  UINT64 v17; 
  unsigned int v18; 
  UINT64 v19; 
  UINT64 v20; 
  signed __int32 v21; 
  INT64 v22; 
  UINT64 v23; 
  _MMPFN *v24; 
  UINT64 v25; 
  UINT8 v26; 
  unsigned __int64 v27; 
  INT64 v28; 
  unsigned __int64 v29; 
  unsigned __int64 v30; 
  INT64 v31; 
  UINT64 v32; 
  char v33; 
  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;} v34; 
  int v35; 
  int v36; 
  UINT64 v37; 
  char v38; 
  UINT64 v39; 
  int v40; 
  unsigned int v41; 
  UINT64 *v42; 
  _MDL *v43; 
  unsigned int v44; 
  unsigned int v45; 
  int v46; 
  _MMPFN *v47; 
  INT64 bf_0; 
  unsigned __int64 v49; 
  UINT64 v50; 
  char v51; 
  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;} v52; 
  int v53; 
  _MI_PARTITION *Partition; 
  unsigned __int64 v55; 
  struct _KPRCB *CurrentPrcb; 
  __int64 CachedResidentAvailable; 
  signed __int32 v58; 
  UINT64 v59; 
  char v60; 
  UINT64 v61; 
  int v62; 
  int v63[8]; 
  UINT64 v64; 
  UINT64 Priority; 
  unsigned __int8 v66; 
  unsigned int v67; 
  int v68; 
  UINT64 v69; 
  UINT64 *Page; 
  INT64 v71; 
  _MI_COLOR_BASE ColorBase[4]; 
  unsigned int ClusterStarta; 

  ClusterStarta = ClusterStart;
  v5 = PagingFile->PageHash == 0i64;
  *(_OWORD *)ColorBase = 0i64;
  v6 = ClusterStart;
  v8 = Mdl;
  v9 = PagingFile;
  if( v5 )
    return;
  AnyMultiplexedVm = MiGetAnyMultiplexedVm(MiWorkingSetTypeSystemPtes, Mdl);
  MiInitializePageColorBase(AnyMultiplexedVm, 0i64, ColorBase);
  if( v8 )
  {
    if( (v8->MdlFlags & 5) == 0 )
    {
      LODWORD(Priority) = -1073741808;
      LODWORD(v64) = 0;
      MmMapLockedPagesSpecifyCache(v8, 0, MmCached, 0i64, v64, Priority);
    }
    v11 = (UINT64 *)(&v8[1].Next + MdlPageOffset);
  }
  else
  {
    v11 = 0i64;
  }
  Page = v11;
  p_SpinLock = (INT64 *)&v9->SpinLock;
  while( 1 )
  {
    v13 = ExAcquireSpinLockExclusive(p_SpinLock);
    PageHash = v9->PageHash;
    v15 = v13;
    v16 = (_WORD)PageHash + 4 * v6;
    v17 = (UINT64)MmGetPteBase() + (((unsigned __int64)&PageHash[v6] >> 9) & 0x7FFFFFFFF8i64);
    v18 = ClusterSize;
    if( (4096 - (v16 & 0xFFFu)) >> 2 <= (unsigned int)ClusterSize )
      v18 = (4096 - (v16 & 0xFFFu)) >> 2;
    v67 = v18;
    LODWORD(v19) = MI_READ_PTE_LOCK_FREE(v17);
    v69 = v19;
    v20 = v19;
    if( (v19 & 1) != 0 )
    {
      MiPteInShadowRange((UINT64)&v69);
      v47 = &MmGetPfnDb()[(v20 >> 12) & 0xFFFFFFFFFi64];
      bf_0 = v47->OriginalPte.u.Hard.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0;
      v49 = bf_0;
      if( *(&stru_140C4DB30 + 42) && (bf_0 & 0x10) == 0 )
        v49 = bf_0 & ~*(&stru_140C4DB30 + 42);
      LODWORD(v50) = MiUpdatePageFileHighInPte(bf_0, v67 + HIDWORD(v49));
      v69 = v50;
      v51 = v50;
      v52.Long = v50;
      LOBYTE(v53) = MiPteInShadowRange((UINT64)&v47->OriginalPte.u.Long);
      if( v53 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v51 & 1) != 0 )
        v52.Long |= 0x8000000000000000ui64;
      v47->OriginalPte.u = (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;})v52.Long;
      ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&v9->SpinLock);
      __writecr8(v15);
      v42 = Page;
      v44 = ClusterStarta;
      v45 = v67;
      LODWORD(v64) = v67;
      MiWritePageFileHash(v9, v8, Page, ClusterStarta, v64);
      v43 = Mdl;
      goto LABEL_28;
    }
    ExReleaseSpinLockExclusiveFromDpcLevel(p_SpinLock);
    __writecr8(v15);
    v21 = _InterlockedExchangeAdd(*(volatile signed __int32 **)ColorBase, 1u);
    LODWORD(v22) = MiGetFileHashPage(PagingFile, ColorBase[2] & (unsigned int)v21 | ColorBase[3]);
    v71 = v22;
    v23 = v22;
    if( v22 == -1 )
    {
      v24 = 0i64;
      v26 = 17;
    }
    else
    {
      v24 = &MmGetPfnDb()[v22];
      _InterlockedOr(v63, 0);
      MiSetPfnTbFlushStamp(v24, (unsigned int)KiTbFlushTimeStamp, 0i64);
      LODWORD(v25) = MI_READ_PTE_LOCK_FREE((INT64)MmGetPteBase() + ((v17 >> 9) & 0x7FFFFFFFF8i64));
      v69 = v25;
      MiInitializePfnForOtherProcess(v23, (_MMPTE *)v17, (v25 >> 12) & 0xFFFFFFFFFi64, 0xA00ui64);
      v26 = MiLockPageInline(v24);
    }
    v66 = v26;
    v27 = (unsigned __int8)ExAcquireSpinLockExclusive((INT64 *)&PagingFile->SpinLock);
    if( PageHash != PagingFile->PageHash )
    {
      ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&PagingFile->SpinLock);
      __writecr8(v27);
      if( v23 == -1i64 )
      {
LABEL_60:
        v46 = ClusterSize;
        v6 = ClusterStarta;
        v9 = PagingFile;
        v43 = Mdl;
        goto LABEL_31;
      }
      MiFreePageFileHashPfn(v23);
      _InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
      __writecr8(v26);
      Partition = PagingFile->Partition;
      MiReturnCommit(Partition, 1ui64);
      v55 = 1i64;
      if( Partition != &Irp )
        goto LABEL_58;
      CurrentPrcb = KeGetCurrentPrcb();
      CachedResidentAvailable = (int)CurrentPrcb->CachedResidentAvailable;
      if( (_DWORD)CachedResidentAvailable == -1 )
        goto LABEL_58;
      if( (unsigned __int64)(CachedResidentAvailable + 1) <= 0x100 )
      {
        do
        {
          v58 = _InterlockedCompareExchange(
                  (volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
                  CachedResidentAvailable + 1,
                  CachedResidentAvailable);
          v5 = (_DWORD)CachedResidentAvailable == v58;
          LODWORD(CachedResidentAvailable) = v58;
          if( v5 )
            goto LABEL_59;
        }
        while( v58 != -1 && (unsigned __int64)(v58 + 1i64) <= 0x100 );
      }
      if( (int)CachedResidentAvailable > 192
        && (_DWORD)CachedResidentAvailable != -1
        && (_DWORD)CachedResidentAvailable == _InterlockedCompareExchange(
                                                (volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
                                                192,
                                                CachedResidentAvailable) )
      {
        v55 = (int)CachedResidentAvailable - 192 + 1i64;
      }
      if( v55 )
LABEL_58:
        _InterlockedExchangeAdd64((volatile signed __int64 *)&Partition->Vp.ResidentAvailablePages, v55);
LABEL_59:
      _InterlockedDecrement64((_QWORD *)&stru_140C4DB30 + 839);
      goto LABEL_60;
    }
    LODWORD(v28) = MI_READ_PTE_LOCK_FREE(v17);
    v29 = v28;
    if( *(&stru_140C4DB30 + 42) )
    {
      if( (v28 & 0x10) != 0 )
        v29 = v28 & 0xFFFFFFFFFFFFFFEFui64;
      else
        v29 = v28 & ~*(&stru_140C4DB30 + 42);
    }
    v30 = HIDWORD(v29);
    v31 = (unsigned int)v30 + v67;
    if( v23 == -1i64 )
    {
      LODWORD(v59) = MiUpdatePageFileHighInPte(v28, v31);
      v69 = v59;
      v60 = v59;
      v61 = v59;
      LOBYTE(v62) = MiPteInShadowRange(v17);
      if( v62 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v60 & 1) != 0 )
        v61 |= 0x8000000000000000ui64;
      *(_QWORD *)v17 = v61;
      ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&PagingFile->SpinLock);
      __writecr8(v27);
      v43 = Mdl;
      v45 = v67;
      v42 = Page;
      v44 = ClusterStarta;
    }
    else
    {
      LODWORD(v32) = MiUpdatePageFileHighInPte(
                       v24->OriginalPte.u.Hard.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0,
                       v31);
      v68 = 0;
      v33 = v32;
      v69 = v32;
      v34.Long = v32;
      LOBYTE(v35) = MiPteInShadowRange((UINT64)&v24->OriginalPte.u.Long);
      if( v35 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v33 & 1) != 0 )
        v34.Long |= 0x8000000000000000ui64;
      v36 = v68;
      v24->OriginalPte.u = (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;})v34.Long;
      if( v36 )
        MiWritePteShadow();
      if( (_DWORD)v30 )
        *((_BYTE *)&v24->u3 + 2) &= ~0x10u;
      LODWORD(v37) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v17, v71, 2684354564i64);
      v69 = v37;
      v38 = v37;
      v39 = v37;
      LOBYTE(v40) = MiPteInShadowRange(v17);
      if( v40 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v38 & 1) != 0 )
        v39 |= 0x8000000000000000ui64;
      *(_QWORD *)v17 = v39;
      v41 = ++PagingFile->PageHashPages;
      if( v41 > PagingFile->PageHashPagesPeak )
        PagingFile->PageHashPagesPeak = v41;
      ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&PagingFile->SpinLock);
      __writecr8(v27);
      _InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
      __writecr8(v66);
      v42 = Page;
      v43 = Mdl;
      v44 = ClusterStarta;
      v45 = v67;
      LODWORD(v64) = v67;
      MiWritePageFileHash(PagingFile, Mdl, Page, ClusterStarta, v64);
    }
    v9 = PagingFile;
LABEL_28:
    if( v42 )
      Page = &v42[v45];
    v6 = v45 + v44;
    v46 = ClusterSize - v45;
    ClusterStarta = v6;
    LODWORD(ClusterSize) = ClusterSize - v45;
LABEL_31:
    p_SpinLock = (INT64 *)&v9->SpinLock;
    if( !v46 )
      break;
    v8 = Mdl;
  }
  if( v43 )
  {
    if( (v43->MdlFlags & 1) != 0 )
      MmUnmapLockedPages(v43->MappedSystemVa, v43);
  }
}

Referenced by:

MiGatherPagefilePages
MiStoreUpdatePagefileHash