MiMapPageFileHash

void __fastcall MiMapPageFileHash(__int64 a1, __int64 a2, __int64 a3, unsigned int a4, unsigned int a5){
  bool v5; 
  unsigned int v6; 
  __int64 v8; 
  __int64 v9; 
  CHAR *AnyMultiplexedVm; 
  _QWORD *v11; 
  volatile LONG *v12; 
  KIRQL v13; 
  __int64 v14; 
  unsigned __int64 v15; 
  __int16 v16; 
  UINT64 v17; 
  unsigned int v18; 
  UINT64 v19; 
  signed __int32 v20; 
  INT64 FileHashPage; 
  UINT64 v22; 
  char *v23; 
  unsigned __int8 v24; 
  unsigned __int64 v25; 
  INT64 v26; 
  unsigned __int64 v27; 
  unsigned __int64 v28; 
  INT64 v29; 
  INT64 v30; 
  unsigned int v31; 
  _QWORD *v32; 
  __int64 v33; 
  unsigned int v34; 
  unsigned int v35; 
  unsigned int v36; 
  char *v37; 
  INT64 v38; 
  unsigned __int64 v39; 
  __int64 v40; 
  unsigned __int64 v41; 
  struct _KPRCB *CurrentPrcb; 
  __int64 v43; 
  signed __int32 v44; 
  int v45[8]; 
  unsigned __int8 v46; 
  unsigned int v47; 
  int v48; 
  UINT64 updated; 
  _QWORD *v50; 
  INT64 a2a; 
  INT64 v52[2]; 
  unsigned int v55; 
  v55 = a4;
  v5 = *(_QWORD *)(a1 + 216) == 0i64;
  *(_OWORD *)v52 = 0i64;
  v6 = a4;
  v8 = a2;
  v9 = a1;
  if( v5 )
    return;
  AnyMultiplexedVm = MiGetAnyMultiplexedVm(3i64);
  MiInitializePageColorBase((INT64)AnyMultiplexedVm, 0i64, (INT64)v52);
  if( v8 )
  {
    if( (*(_BYTE *)(v8 + 10) & 5) == 0 )
      MmMapLockedPagesSpecifyCache((PMDL)v8, 0, MmCached, 0i64, 0, 0xC0000010);
    v11 = (_QWORD *)(v8 + 8 * a3 + 48);
  }
  else
  {
    v11 = 0i64;
  }
  v50 = v11;
  v12 = (volatile LONG *)(v9 + 232);
  while( 1 )
  {
    v13 = ExAcquireSpinLockExclusive(v12);
    v14 = *(_QWORD *)(v9 + 216);
    v15 = v13;
    v16 = v14 + 4 * v6;
    v17 = (UINT64)MmGetPteBase() + (((v14 + 4 * (unsigned __int64)v6) >> 9) & 0x7FFFFFFFF8i64);
    v18 = a5;
    if( (4096 - (v16 & 0xFFFu)) >> 2 <= a5 )
      v18 = (4096 - (v16 & 0xFFFu)) >> 2;
    v47 = v18;
    updated = MI_READ_PTE_LOCK_FREE(v17);
    v19 = updated;
    if( (updated & 1) != 0 )
    {
      MiPteInShadowRange((UINT64)&updated);
      v37 = (char *)MmGetPfnDb() + 48 * ((v19 >> 12) & 0xFFFFFFFFFi64);
      v38 = *((_QWORD *)v37 + 2);
      v39 = v38;
      if( qword_140C4DC80 && (v38 & 0x10) == 0 )
        v39 = v38 & ~qword_140C4DC80;
      updated = MiUpdatePageFileHighInPte(v38, v47 + HIDWORD(v39));
      *((_QWORD *)v37 + 2) = updated;
      ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v9 + 232));
      __writecr8(v15);
      v32 = v50;
      v34 = v55;
      v35 = v47;
      MiWritePageFileHash(v9, v8, v50, v55, v47);
      v33 = a2;
      goto LABEL_24;
    }
    ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)v12);
    __writecr8(v15);
    v20 = _InterlockedExchangeAdd((volatile signed __int32 *)v52[0], 1u);
    FileHashPage = MiGetFileHashPage(a1, v52[1] & v20 | HIDWORD(v52[1]));
    a2a = FileHashPage;
    v22 = FileHashPage;
    if( FileHashPage == -1 )
    {
      v23 = 0i64;
      v24 = 17;
    }
    else
    {
      v23 = (char *)MmGetPfnDb() + 48 * FileHashPage;
      _InterlockedOr(v45, 0);
      MiSetPfnTbFlushStamp((_MMPFN *)v23, (unsigned int)KiTbFlushTimeStamp, 0i64);
      updated = MI_READ_PTE_LOCK_FREE((INT64)MmGetPteBase() + ((v17 >> 9) & 0x7FFFFFFFF8i64));
      MiInitializePfnForOtherProcess(v22, (MMPTE *)v17, (updated >> 12) & 0xFFFFFFFFFi64, 0xA00ui64);
      v24 = MiLockPageInline((INT64)v23);
    }
    v46 = v24;
    v25 = ExAcquireSpinLockExclusive((PEX_SPIN_LOCK)(a1 + 232));
    if( v14 != *(_QWORD *)(a1 + 216) )
    {
      ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(a1 + 232));
      __writecr8(v25);
      if( v22 == -1i64 )
      {
LABEL_52:
        v36 = a5;
        v6 = v55;
        v9 = a1;
        v33 = a2;
        goto LABEL_27;
      }
      MiFreePageFileHashPfn(v22);
      _InterlockedAnd64((volatile signed __int64 *)v23 + 3, 0x7FFFFFFFFFFFFFFFui64);
      __writecr8(v24);
      v40 = *(_QWORD *)(a1 + 248);
      MiReturnCommit((_MI_PARTITION *)v40, 1ui64);
      v41 = 1i64;
      if( (ULONG_PTR *)v40 != &MiSystemPartition )
        goto LABEL_50;
      CurrentPrcb = KeGetCurrentPrcb();
      v43 = *((int *)CurrentPrcb + 8391);
      if( (_DWORD)v43 == -1 )
        goto LABEL_50;
      if( (unsigned __int64)(v43 + 1) <= 0x100 )
      {
        do
        {
          v44 = _InterlockedCompareExchange((volatile signed __int32 *)CurrentPrcb + 8391, v43 + 1, v43);
          v5 = (_DWORD)v43 == v44;
          LODWORD(v43) = v44;
          if( v5 )
            goto LABEL_51;
        }
        while( v44 != -1 && (unsigned __int64)(v44 + 1i64) <= 0x100 );
      }
      if( (int)v43 > 192
        && (_DWORD)v43 != -1
        && (_DWORD)v43 == _InterlockedCompareExchange((volatile signed __int32 *)CurrentPrcb + 8391, 192, v43) )
      {
        v41 = (int)v43 - 192 + 1i64;
      }
      if( v41 )
LABEL_50:
        _InterlockedExchangeAdd64((volatile signed __int64 *)(v40 + 7168), v41);
LABEL_51:
      _InterlockedDecrement64(&qword_140C4F568);
      goto LABEL_52;
    }
    v26 = MI_READ_PTE_LOCK_FREE(v17);
    v27 = v26;
    if( qword_140C4DC80 )
    {
      if( (v26 & 0x10) != 0 )
        v27 = v26 & 0xFFFFFFFFFFFFFFEFui64;
      else
        v27 = v26 & ~qword_140C4DC80;
    }
    v28 = HIDWORD(v27);
    v29 = (unsigned int)v28 + v47;
    if( v22 == -1i64 )
    {
      updated = MiUpdatePageFileHighInPte(v26, v29);
      *(_QWORD *)v17 = updated;
      ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(a1 + 232));
      __writecr8(v25);
      v33 = a2;
      v35 = v47;
      v32 = v50;
      v34 = v55;
    }
    else
    {
      v30 = MiUpdatePageFileHighInPte(*((_QWORD *)v23 + 2), v29);
      v48 = 0;
      updated = v30;
      *((_QWORD *)v23 + 2) = v30;
      if( (_DWORD)v28 )
        v23[34] &= ~0x10u;
      updated = MiMakeValidPte(v17, a2a, 2684354564i64);
      *(_QWORD *)v17 = updated;
      v31 = ++*(_DWORD *)(a1 + 208);
      if( v31 > *(_DWORD *)(a1 + 212) )
        *(_DWORD *)(a1 + 212) = v31;
      ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(a1 + 232));
      __writecr8(v25);
      _InterlockedAnd64((volatile signed __int64 *)v23 + 3, 0x7FFFFFFFFFFFFFFFui64);
      __writecr8(v46);
      v32 = v50;
      v33 = a2;
      v34 = v55;
      v35 = v47;
      MiWritePageFileHash(a1, a2, v50, v55, v47);
    }
    v9 = a1;
LABEL_24:
    if( v32 )
      v50 = &v32[v35];
    v6 = v35 + v34;
    v36 = a5 - v35;
    v55 = v6;
    a5 -= v35;
LABEL_27:
    v12 = (volatile LONG *)(v9 + 232);
    if( !v36 )
      break;
    v8 = a2;
  }
  if( v33 )
  {
    if( (*(_BYTE *)(v33 + 10) & 1) != 0 )
      MmUnmapLockedPages(*(PVOID *)(v33 + 24), (PMDL)v33);
  }
}

Referenced by:

MiGatherPagefilePages
MiStoreUpdatePagefileHash