MiWaitForInPageComplete

INT64 __fastcall MiWaitForInPageComplete(INT64 a1, UINT64 a2, INT64 *a3){
  INT64 v3; 
  UINT64 v4; 
  INT64 v5; 
  ULONG_PTR v6; 
  __int64 v7; 
  __int64 v9; 
  unsigned __int64 v10; 
  _MMPFN *PfnDb; 
  UINT64 *v12; 
  __int64 v13; 
  void *v14; 
  int v15; 
  _MI_PARTITION *v16; 
  VOID(__stdcall *v17)(PVOID); 
  __int64 v18; 
  int v19; 
  int v20; 
  __int64 v21; 
  LARGE_INTEGER *v22; 
  INT64 v23; 
  int v24; 
  __int64 v25; 
  KIRQL v26; 
  int v27; 
  int v28; 
  int v29; 
  int v30; 
  _DWORD *v31; 
  unsigned int v32; 
  bool v33; 
  ULONG_PTR v34; 
  unsigned __int64 v35; 
  unsigned int v36; 
  __int64 v37; 
  void *v38; 
  unsigned __int64 v39; 
  _MMPFN *v40; 
  unsigned __int64 v41; 
  INT64 result; 
  UINT8 *Timeout; 
  UINT64 PreferredNode; 
  UINT64 PreferredChannel; 
  UINT64 Flags; 
  int v47; 
  INT64 v48; 
  int IsRetryIoStatus; 
  void *BugCheckParameter4; 
  void *v51; 
  unsigned __int64 v52; 
  __int64 v53; 
  ULONG_PTR BugCheckParameter1; 
  unsigned int v56; 
  unsigned __int64 v57; 
  UINT8 OldIrql; 
  INT64 *v59; 
  _MI_STORE_INPAGE_COMPLETE_FLAGS OutFlags; 
  v59 = a3;
  v3 = *(_QWORD *)(a1 + 56);
  v4 = a2 + 272;
  OldIrql = 0;
  OutFlags.EntireFlags = 0;
  v5 = a1;
  v6 = -1i64;
  v7 = *(_QWORD *)(a2 + 248);
  BugCheckParameter1 = *(_QWORD *)(a2 + 232);
  v9 = 0x2AAAAAAAAAAAAAABi64;
  BugCheckParameter4 = *(void **)(a2 + 224);
  v10 = *(_QWORD *)(v7 + 40);
  if( *(_QWORD *)(a2 + 256) )
    v4 = *(_QWORD *)(a2 + 256);
  v48 = v3;
  v53 = *(_QWORD *)(a2 + 248);
  PfnDb = MmGetPfnDb();
  v12 = (UINT64 *)(v4 + 48);
  if( (v10 & 0x1000000000i64) == 0 && *(__int64 *)(v7 + 8) > 0 )
  {
    v13 = (unsigned __int128)((v7 - (__int64)PfnDb) * (__int128)0x2AAAAAAAAAAAAAABi64) >> 64;
    v14 = (void *)(((unsigned __int64)v13 >> 63) + (v13 >> 3));
    v51 = v14;
    if( (unsigned __int64)v14 < 0xFFFFFFFFFi64 )
    {
      v15 = ~(*(_DWORD *)(v5 + 80) << 11) & 0x20000 | 0x40000000;
      v16 = *(_MI_PARTITION **)(qword_140C4E388 + 8 * ((v10 >> 39) & 0x3FF));
      v17 = (VOID(__stdcall *)(PVOID))*((_QWORD *)KeGetCurrentThread() + 154);
      LODWORD(v18) = MiSearchNumaNodeTable(v14);
      v19 = v15 | 8;
      v20 = *(_DWORD *)(v18 + 8);
      if( v17 != KeSwapProcessOrStack )
        v19 = v15;
      LODWORD(Flags) = v19;
      LODWORD(PreferredChannel) = 0x80000000;
      LODWORD(PreferredNode) = v20;
      MiFindContiguousPages(
        v16,
        (UINT64)v51 + 1,
        0xFFFFFFFFFui64,
        0i64,
        1ui64,
        (_MI_PFN_CACHE_ATTRIBUTE)(*(unsigned __int8 *)(v53 + 34) >> 6),
        PreferredNode,
        PreferredChannel,
        Flags,
        0i64);
      v5 = a1;
      v3 = v48;
    }
  }
  v21 = *(_QWORD *)(v5 + 16);
  if( (v21 & 1) != 0 )
  {
    v22 = (LARGE_INTEGER *)(v21 & 0xFFFFFFFFFFFFFFFEui64);
    if( LOBYTE(v22->LowPart) == 2 )
    {
      if( v3 )
        MiPrefetchRestOfCluster((RTL_SPLAY_LINKS *)a2, v22, (LARGE_INTEGER *)v3, (RTL_SPLAY_LINKS **)v9, Timeout);
    }
  }
  KeWaitForSingleObject((PVOID)(a2 + 32), WrPageIn, 0, 0, 0i64);
  if( *(_QWORD *)(a2 + 264) )
    KeBugCheckEx(0x1Au, 0x61947ui64, a2, *(_QWORD *)(a2 + 264), 0i64);
  if( v3 && (*(_BYTE *)(v3 + 187) & 0x60) == 96 && !MiGetSharedVm(v3)[4] )
    KiUnstackDetachProcess((KAPC_STATE *)(a2 + 104), 0i64);
  if( (*(_WORD *)(v4 + 10) & 0x200) != 0 )
  {
    MiRetardMdl((_MDL *)v4);
    *(_DWORD *)(a2 + 80) = -1073741670;
    *(_QWORD *)(a2 + 88) = 0i64;
  }
  v24 = *(_DWORD *)(a2 + 192);
  if( (v24 & 0x10) != 0 )
  {
    v25 = *(_QWORD *)(a2 + 336);
    if( v25 )
    {
      v26 = ExAcquireSpinLockExclusive((PEX_SPIN_LOCK)(v25 + 232));
      RtlAvlRemoveNode((unsigned __int64 *)(v25 + 240), (__int64 *)(a2 + 352));
      ExReleaseSpinLockExclusive((PEX_SPIN_LOCK)(v25 + 232), v26);
      v24 = *(_DWORD *)(a2 + 192);
      v3 = v48;
    }
  }
  v27 = 0;
  v56 = *(_DWORD *)(a2 + 184);
  v52 = (unsigned __int64)&v12[((((*(_DWORD *)(v4 + 32) + *(_DWORD *)(v4 + 44)) & 0xFFF)
                               + (unsigned __int64)*(unsigned int *)(v4 + 40)
                               + 4095) >> 12)
                             - 1];
  if( (v24 & 0x100) != 0 )
    MiStoreFaultComplete((_MMINPAGE_SUPPORT *)a2, &OutFlags);
  v28 = *(_DWORD *)(a2 + 80);
  if( *(_QWORD *)(a2 + 208) )
  {
    if( v28 >= 0 )
    {
      v27 = MiValidateInPage(a2);
      if( v27 == -1073740748 )
        *(_DWORD *)(a2 + 192) |= 0x100000u;
    }
    MiDereferenceControlAreaProbe(*(_CONTROL_AREA **)(a2 + 208), 0i64);
  }
  else if( v28 >= 0 && (*(_DWORD *)(a2 + 192) & 0x400000) != 0 )
  {
    v27 = MiValidatePagefilePageHash(a2);
  }
  v29 = *(_DWORD *)(a2 + 80);
  v30 = OutFlags.EntireFlags & 1;
  v47 = v30;
  if( (OutFlags.EntireFlags & 1) == 0 )
  {
    __incgsdword(0x2EA4u);
    __addgsdword(0x2EA0u, (v56 >> 12) + ((v56 & 0xFFF) != 0));
    if( v3 )
    {
      if( (*(_DWORD *)(a2 + 192) & 8) == 0 )
        _InterlockedIncrement((volatile signed __int32 *)(v3 + 168));
    }
  }
  v31 = v59;
  v32 = 2 * v30;
  if( *v59 )
  {
    PfHardFaultLog((_QWORD *)*v59, v32, v23);
    v31 = v59;
  }
  v33 = (*(_BYTE *)(v4 + 10) & 1) == 0;
  *v31 = v32;
  if( !v33 )
    MmUnmapLockedPages(*(PVOID *)(v4 + 24), (PMDL)v4);
  IsRetryIoStatus = 0;
  *(_DWORD *)(a2 + 188) = -1;
  if( v29 < 0 )
  {
    if( v29 != -1073741807 )
    {
      if( v29 == -2147483626 )
        goto LABEL_75;
      IsRetryIoStatus = MiIsRetryIoStatus((unsigned int)v29, *(unsigned int *)(v4 + 40));
      if( IsRetryIoStatus && !dword_140C4EA00 && (!v47 || (OutFlags.EntireFlags & 2) != 0) )
        dword_140C4EA00 = 32;
      if( (*(_DWORD *)(a2 + 192) & 8) != 0 )
      {
        v29 = -1073741801;
        goto LABEL_75;
      }
      goto LABEL_53;
    }
    if( (*(_DWORD *)(a2 + 192) & 0x200000) != 0 )
      KeBugCheckEx(0x7Au, 3ui64, 0xFFFFFFFFC0000011ui64, a2, (ULONG_PTR)BugCheckParameter4);
    v39 = 1i64;
    v40 = MmGetPfnDb();
    v41 = (v52 - (unsigned __int64)v12 + 8) >> 3;
    if( (unsigned __int64)v12 > v52 )
      v41 = 0i64;
    if( v41 )
    {
      do
      {
        MiZeroPhysicalPage(*v12, 3ui64, (_MI_PFN_CACHE_ATTRIBUTE)(*((unsigned __int8 *)v40 + 48 * *v12 + 34) >> 6));
        ++v39;
        ++v12;
      }
      while( v39 <= v41 );
    }
    v29 = 0;
  }
  else
  {
    v34 = *(_QWORD *)(a2 + 88);
    if( v34 != v56 )
    {
      if( v34 || (*(_DWORD *)(a2 + 192) & 8) == 0 )
      {
        if( (*(_DWORD *)(a2 + 192) & 0x200000) != 0 && !v47 )
          KeBugCheckEx(0x7Au, 4ui64, v34, a2, (ULONG_PTR)BugCheckParameter4);
        v35 = 8
            * ((((*(_DWORD *)(v4 + 32) + *(_DWORD *)(v4 + 44)) & 0xFFF)
              - (unsigned __int64)(v56 - *(_DWORD *)(v4 + 40))
              + v34
              + 4095) >> 12)
            + 40;
        v57 = v35;
        v36 = v34 & 0xFFF;
        if( v36 )
        {
          LODWORD(v37) = MiMapPageInHyperSpaceWorker(*(_QWORD *)(v35 + v4), &OldIrql, 0x80000000ui64);
          v38 = (void *)(v36 + v37);
          memset((INT64)v38, 0i64);
          MiUnmapPageInHyperSpaceWorker(v38, OldIrql, 0x80000000ui64);
          v35 = v57;
        }
        if( v35 + v4 + 8 <= v52 )
          *(_DWORD *)(a2 + 188) = ((__int64)(v35 - 48) >> 3) + 1;
      }
      else
      {
        v29 = -1073741801;
      }
    }
    if( v27 == -1073741761 )
    {
LABEL_53:
      if( (unsigned __int64)BugCheckParameter4 > 0x7FFFFFFEFFFFi64
        && (unsigned int)MiGetSystemRegionType((UINT64)BugCheckParameter4) != 8
        && !(unsigned int)MiExceptionForMappedVa(BugCheckParameter4) )
      {
        if( !IsRetryIoStatus )
        {
          if( MmIsAddressValidEx(BugCheckParameter1) )
            v6 = MI_READ_PTE_LOCK_FREE(BugCheckParameter1);
          MiFlushAllFilesystemPages();
          if( v27 >= 0 )
            v27 = v29;
          KeBugCheckEx(0x7Au, BugCheckParameter1, v27, v6, (ULONG_PTR)BugCheckParameter4);
        }
        if( v27 != -1073741761 )
          v29 = -1073741801;
      }
    }
  }
LABEL_75:
  result = OutFlags.EntireFlags;
  *(_MI_STORE_INPAGE_COMPLETE_FLAGS *)(a2 + 112) = OutFlags;
  *(_QWORD *)(a2 + 104) = 0i64;
  *(_DWORD *)(a2 + 80) = v29;
  return result;
}

Referenced by:

MiIssueHardFault
MiPfCompleteInPageSupport