MiPfPrepareSequentialReadList

INT64 __fastcall MiPfPrepareSequentialReadList(
        INT64 rcx0,
        INT64 rdx0,
        UINT64 a3,
        INT64 a4,
        UINT64 a5,
        UINT64 DesiredPriority,
        UINT64 a7,
        INT64 *a8){
  bool v8; 
  INT64 v10; 
  unsigned __int64 ControlAreaPtes; 
  UINT64 v13; 
  INT64 v14; 
  INT64 v15; 
  _QWORD *v16; 
  unsigned int *v17; 
  UNICODE_STRING *v18; 
  UNICODE_STRING *v19; 
  UNICODE_STRING *v20; 
  UINT64 v21; 
  INT64 v22; 
  UINT8 v23; 
  WCHAR *v24; 
  unsigned int v25; 
  _MMPTE *PxeUserLimit; 
  __int64 v27; 
  INT64 v28; 
  _BYTE *v29; 
  _QWORD *v30; 
  _MI_PARTITION *v31; 
  UINT64 *v32; 
  _QWORD *v33; 
  _BYTE *v34; 
  unsigned __int64 v35; 
  _QWORD *v36; 
  MMPTE *PteAddress; 
  MMPTE *v38; 
  _MI_PARTITION *v39; 
  UINT64 v40; 
  int v41; 
  unsigned __int64 v42; 
  _QWORD *v43; 
  __int64 v44; 
  __int64 v45; 
  _QWORD *v46; 
  unsigned __int64 v47; 
  UINT64 v48; 
  _QWORD *v49; 
  __int64 v50; 
  unsigned int v51; 
  unsigned int v52; 
  UINT64 v53; 
  _MI_PARTITION *v54; 
  _MMPFN *PageChain; 
  UINT64 v56; 
  _MMPFN *v57; 
  _MMPFN *PfnDb; 
  __int64 v59; 
  _MMPFN *v60; 
  _MMPFN *v61; 
  __int64 v62; 
  unsigned int Mdls; 
  UINT64 *v65; 
  __int64 *SharedProtos; 
  int v67; 
  INT64 SlabAllocator; 
  _QWORD *v69; 
  __int64 v70; 
  __int64 v71; 
  int v72; 
  int v73; 
  UINT64 InputGetPageFlags; 
  _MI_PARTITION *a1; 
  unsigned __int64 v76; 
  __int64 v77; 
  _QWORD *v78; 
  UINT64 NumberOfPages; 
  _BYTE *a2; 
  _BYTE *v81; 
  UINT64 *p_Length; 
  _QWORD *v83; 
  UINT64 PteOffset; 
  UINT64 ProtectionMask; 
  UNICODE_STRING *v86; 
  UNICODE_STRING *v87; 
  PVOID Va; 
  INT64 AvailablePagesExcludeSlists; 
  _MMSUPPORT_INSTANCE *Vm; 
  __int128 v91; 
  int v94; 
  v8 = (*(_DWORD *)(rdx0 + 56) & 0x400) == 0;
  v10 = rdx0;
  v91 = 0i64;
  *a8 = 0i64;
  if( !v8 || !*(_QWORD *)(rdx0 + 64) )
    return 3221225711i64;
  ControlAreaPtes = MiGetControlAreaPtes(rdx0);
  if( a5 )
  {
    v13 = a5 >> 12;
    if( a5 >> 12 < 0x100000000i64 && (unsigned int)v13 <= ControlAreaPtes )
      goto LABEL_6;
    return 3221225713i64;
  }
  if( ControlAreaPtes >= 0x100000000i64 )
    return 3221225713i64;
  LODWORD(v13) = ControlAreaPtes;
LABEL_6:
  LODWORD(v14) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
  v15 = v14;
  if( !v14 )
    return 3221225626i64;
  *(_QWORD *)(v14 + 8) = v10;
  v16 = (_QWORD *)(v14 + 120);
  PteOffset = 0i64;
  v77 = 0i64;
  v16[1] = v16;
  *v16 = v16;
  *(_QWORD *)(v15 + 32) = v15 + 24;
  *(_QWORD *)(v15 + 24) = v15 + 24;
  a2 = (_BYTE *)(v10 + 128);
  LODWORD(v16) = (*(unsigned __int16 *)(v10 + 160) >> 1) & 0x1F;
  v76 = 0i64;
  v78 = 0i64;
  Va = 0i64;
  LODWORD(ProtectionMask) = (_DWORD)v16;
  if( a5 )
  {
    v17 = (unsigned int *)MiOffsetToProtos((_CONTROL_AREA *)v10, a3, &PteOffset);
    a2 = v17;
  }
  else
  {
    v17 = (unsigned int *)(v10 + 128);
  }
  a1 = MiGetControlAreaPartition((_CONTROL_AREA *)v10);
  AvailablePagesExcludeSlists = MiGetAvailablePagesExcludeSlists((INT64)a1);
  v19 = v18;
  v87 = v18;
  v20 = v18;
  v86 = v18;
  if( rcx0 )
  {
    v65 = *(UINT64 **)(rcx0 + 32);
    NumberOfPages = __PAIR64__(HIDWORD(v18), *(_DWORD *)(rcx0 + 12) & 0x1FF | 0x200u);
    v21 = NumberOfPages;
    p_Length = v65;
  }
  else
  {
    p_Length = (UINT64 *)&v18->Length;
    v21 = (UINT64)v18;
  }
  *(_DWORD *)(v15 + 80) = DesiredPriority;
  *(_DWORD *)(v15 + 84) = 5;
  *(_DWORD *)(v15 + 88) = 7;
  v22 = (*(_DWORD *)(v10 + 56) >> 20) & 0x3F;
  v83 = (_QWORD *)(v15 + 136);
  Vm = (_MMSUPPORT_INSTANCE *)(*((_QWORD *)KeGetCurrentThread() + 23) + 1664i64);
  MiInitializePageColorBase((INT64)Vm, v22, (INT64)&v91);
  v94 = 0;
  v25 = 0;
  v81 = 0i64;
  if( !(_DWORD)v13 )
  {
    v40 = 0i64;
    v49 = 0i64;
    v50 = 0i64;
    v51 = 0;
    goto LABEL_55;
  }
  while( 1 )
  {
    PxeUserLimit = MmGetPxeUserLimit();
    if( v19 >= v20 )
    {
      if( v19 )
      {
        v17 = (unsigned int *)*((_QWORD *)v17 + 2);
        a2 = v17;
        if( !v17 )
        {
LABEL_53:
          v40 = v76;
          v49 = v78;
          v50 = v77;
          goto LABEL_54;
        }
        PteOffset = 0i64;
      }
      v41 = *(_DWORD *)(v10 + 56);
      if( (v41 & 0x20) != 0 )
      {
        v42 = *((_QWORD *)v17 + 1);
        if( (*((_BYTE *)v17 + 34) & 2) != 0 && (v41 & 0x4000000) != 0 )
        {
          if( !*((_QWORD *)v17 + 3) )
          {
            v19 = (UNICODE_STRING *)((char *)v20 - 8);
            goto LABEL_31;
          }
          SharedProtos = MiGetSharedProtos(rdx0, a7, (__int64)v17);
          if( !SharedProtos )
          {
            v19 = (UNICODE_STRING *)((char *)v20 - 8);
            goto LABEL_31;
          }
          v42 = SharedProtos[9];
        }
      }
      else
      {
        v94 = MiAddViewsForSection((ULONG_PTR)v17, v17[11], 4);
        if( v94 < 0 )
        {
          if( v76 )
            MiReturnFaultCharges(a1, v76, 1ui64);
          MiReleaseReadListResources(v15);
          ExFreePoolWithTag((PVOID)v15, 0);
          return(unsigned int)v94;
        }
        v42 = *((_QWORD *)v17 + 1);
        v43 = (_QWORD *)(v15 + 24);
        v44 = *(_QWORD *)(v15 + 32);
        if( (_QWORD *)*v43 == v43 || *(_DWORD *)(v44 + 16) == 5 )
        {
          LODWORD(v45) = MiAllocatePool((struct _SLIST_ENTRY *)0x100);
          v44 = v45;
          if( !v45 )
          {
            MiRemoveViewsFromSectionWithPfn((ULONG_PTR)v17, v17[11], 4u);
            MiReleaseReadListResources(v15);
            ExFreePoolWithTag((PVOID)v15, 0);
            return 3221225626i64;
          }
          v46 = *(_QWORD **)(v15 + 32);
          if( (_QWORD *)*v46 != v43 )
            __fastfail(3u);
          *(_QWORD *)v44 = v43;
          *(_QWORD *)(v44 + 8) = v46;
          *v46 = v44;
          *(_QWORD *)(v15 + 32) = v44;
        }
        if( !*(_QWORD *)(v15 + 16) )
          *(_QWORD *)(v15 + 16) = v17;
        *(_QWORD *)(v44 + 8i64 * (unsigned int)(*(_DWORD *)(v44 + 16))++ + 24) = v17;
      }
      v19 = (UNICODE_STRING *)(v42 + 8 * PteOffset);
      v20 = (UNICODE_STRING *)(v42 + 8i64 * v17[11]);
      v47 = MiStartingOffset((__int64)v17, v42, a7);
      v48 = MiEndingOffsetWithLock((__int64)a2);
      if( (((_WORD)v48 - (_WORD)v47) & 0xFFF) != 0 )
        v87 = (UNICODE_STRING *)(v42 + 8 * (((v48 - v47 + 4095) >> 12) - 1));
      else
        v87 = 0i64;
      PxeUserLimit = MmGetPxeUserLimit();
      if( p_Length )
      {
        NumberOfPages = v47;
        v86 = (UNICODE_STRING *)v42;
        LODWORD(NumberOfPages) = v47 & 0xFFFFFE00 | *(_DWORD *)(rcx0 + 12) & 0x1FF | 0x200;
        v21 = NumberOfPages;
      }
      v10 = rdx0;
    }
    v27 = *(_QWORD *)&v19->Length;
    if( v19 >= (UNICODE_STRING *)MmGetPml4eBase() && v19 <= (UNICODE_STRING *)PxeUserLimit )
      LOWORD(v27) = MiReadPteShadow(v19, *(UNICODE_STRING **)&v19->Length, v23, v24);
    if( (v27 & 1) != 0 )
    {
LABEL_37:
      MiUpdatePfnPriorityByPte((_MMPTE *)v19, (unsigned int)DesiredPriority);
      goto LABEL_31;
    }
    if( (v27 & 0x400) != 0 )
      break;
    if( (v27 & 0x800) != 0 )
      goto LABEL_37;
    if( IS_PTE_NOT_DEMAND_ZERO(v27) )
      goto LABEL_20;
LABEL_31:
    ++v25;
    v19 = (UNICODE_STRING *)((char *)v19 + 8);
    if( v25 >= (unsigned int)v13 )
      goto LABEL_53;
    v10 = rdx0;
    v17 = (unsigned int *)a2;
  }
  if( MiControlAreaUsingExtents(v10) )
  {
    v67 = MiRefillPurgedExtents((__int64 *)a2, (ULONG_PTR)v19);
    v94 = v67;
    if( v67 < 0 )
    {
      v50 = v77;
      v40 = v76;
      v49 = v78;
      if( v77 )
      {
        v51 = v67;
      }
      else
      {
        v51 = -1073741670;
        v94 = -1073741670;
      }
      goto LABEL_55;
    }
    goto LABEL_31;
  }
  if( MiControlAreaUsingCopyExtents(v28) )
    goto LABEL_31;
  v32 = p_Length;
  if( p_Length )
  {
    v21 += ((char *)v19 - (char *)v86) >> 3 << 12;
    v86 = v19;
    *p_Length = v21;
    p_Length = v32 + 1;
  }
LABEL_20:
  v33 = v30;
  v34 = a2;
  *v30 = v19;
  v35 = (unsigned __int64)v19;
  if( v78 )
    v33 = v78;
  v78 = v33;
  v36 = v33;
  if( v29 != v34 || (MiGetPteAddress(Va), PteAddress = MiGetPteAddress(v19), v38 != PteAddress) )
  {
    v35 |= 2ui64;
    v81 = v34;
    *v30 = v35;
  }
  Va = v19;
  if( v19 == v87 )
    *v30 = v35 | 1;
  v83 = v30 + 1;
  if( (unsigned int)MiObtainFaultCharges(v31, 1ui64, 1ui64) )
  {
    if( (unsigned int)MiUseSlabAllocator((INT64)a1, a2, v27, 0i64) )
    {
      LODWORD(InputGetPageFlags) = 0x20000;
      if( MiGetSlabPage(
             (UINT64)v39,
             (*((unsigned __int16 *)a2 + 16) >> 1) & 0x1F,
             0i64,
             (INT64 *)0xFFFFFFFFFFFFFFFFi64,
             InputGetPageFlags) == -1 )
      {
        v40 = v76;
        v39 = a1;
LABEL_105:
        MiReturnFaultCharges(v39, 1ui64, 1ui64);
        v49 = v36;
        v50 = v77;
        if( !v77 )
        {
          v51 = -1073741801;
          v94 = -1073741801;
          goto LABEL_55;
        }
LABEL_54:
        v51 = v94;
        goto LABEL_55;
      }
      SlabAllocator = MiGetSlabAllocator((INT64)a1, 0i64, (*((unsigned __int16 *)a2 + 16) >> 1) & 0x1F);
      MiSetPfnLink(v69, *(_QWORD *)(v15 + 8i64 * *(int *)(SlabAllocator + 52) + 48));
      *(_QWORD *)(v15 + 8i64 * *(int *)(v70 + 52) + 48) = v71;
    }
    else
    {
      v40 = v76;
      if( v76 > AvailablePagesExcludeSlists + 160 )
        goto LABEL_105;
      ++v76;
    }
    ++v77;
    goto LABEL_31;
  }
  v72 = v94;
  v50 = v77;
  v49 = v78;
  v40 = v76;
  if( !v77 )
    v72 = -1073741670;
  v94 = v72;
  v51 = v72;
LABEL_55:
  if( rcx0 )
    *(_QWORD *)(rcx0 + 24) = p_Length;
  if( !v50 )
    goto LABEL_73;
  if( v40 )
  {
    NumberOfPages = v40;
    v52 = MiProtectionToCacheAttribute((unsigned int)ProtectionMask);
    LODWORD(InputGetPageFlags) = 0;
    PageChain = MiGetPageChain(v54, Vm, v53, v52, InputGetPageFlags, 0xFFFFFFFFFFFFFFFFui64, &NumberOfPages);
    v56 = NumberOfPages;
    v57 = PageChain;
    if( NumberOfPages != v76 )
    {
      MiReturnFaultCharges(a1, v76 - NumberOfPages, 1ui64);
      v73 = v94;
      v50 += v56 - v76;
      if( !v50 )
        v73 = -1073741801;
      v94 = v73;
      v51 = v73;
    }
    if( v57 )
    {
      PfnDb = MmGetPfnDb();
      do
      {
        v59 = *((_QWORD *)v57 + 3) & 0xFFFFFFFFFi64;
        if( v59 == 0xFFFFFFFFFi64 )
          v60 = 0i64;
        else
          v60 = (_MMPFN *)((char *)PfnDb + 48 * v59);
        MiSetPfnLink(v57, *(_QWORD *)(v15 + 40));
        *(_QWORD *)(v15 + 40) = v57;
        MiSetPfnBlink(v61, 0i64, 0i64);
        v57 = v60;
      }
      while( v60 );
      v51 = v94;
    }
  }
  if( v50 )
  {
    v62 = (__int64)v83 - v15 - 136;
    *(_QWORD *)(v15 + 96) = v49;
    *(_DWORD *)(v15 + 92) = v62 >> 3;
    Mdls = MiPfAllocateMdls(v15, (unsigned int)a7, 0i64);
    if( *(_QWORD *)(v15 + 120) == v15 + 120 )
    {
      MiReleaseReadListResources(v15);
      ExFreePoolWithTag((PVOID)v15, 0);
      v15 = 0i64;
    }
    else
    {
      Mdls = 0;
    }
    *a8 = v15;
    return Mdls;
  }
  else
  {
LABEL_73:
    MiReleaseReadListResources(v15);
    ExFreePoolWithTag((PVOID)v15, 0);
    return v51;
  }
}

Referenced by:

MiPrefetchControlArea
MmPrefetchForCacheManager