MiBuildReservationCluster
VOID __fastcall MiBuildReservationCluster(
UINT64 *Page,
_MMPAGING_FILE *PagingFile,
UINT64 *ClusterSize,
UINT64 *ChargedPages){
_MI_PARTITION *Partition;
__int16 bf_cc;
__int64 v6;
__int64 v7;
unsigned __int64 Flink;
_MMPFN *PfnDb;
_MMPFN *v10;
unsigned __int64 v11;
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;} v12;
unsigned __int64 Long_high;
_MMPTE v14;
UINT8 v15;
unsigned int v16;
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;} v17;
unsigned __int64 v18;
_MMPFN *v19;
__int64 bf_0;
PWCHAR v21;
int v22;
int v23;
unsigned __int64 v24;
_MMPTE *v25;
UINT64 v26;
__int64 v27;
__int64 v28;
int v29;
__int64 v30;
__int64 v31;
INT64 v32;
__int64 v33;
unsigned __int64 Long;
__int64 v35;
INT64 v36;
unsigned __int64 v37;
INT64 v38;
_KTBFLUSH_TYPE v39;
INT64 v40;
_MMPTE v41;
_MMPTE *v42;
UINT64 v43;
_KTBFLUSH_TYPE v44;
unsigned int v45;
__int64 v46;
unsigned __int64 v47;
__int64 v48;
INT64 v49;
_QWORD *v50;
_MMPTE v51;
_MMPTE *v52;
__int64 v53;
_QWORD *v54;
_QWORD *v55;
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;} v56;
_MMPFN *v57;
unsigned __int64 v58;
__int64 v59;
int v60;
_MMPAGING_FILE *v61;
_MI_PAGING_FILE_SPACE_BITMAPS *v62;
UINT64 *MdlPage;
UINT64 *MdlPagea;
UINT64 *DummyGapLength;
INT64 v66;
INT64 v67;
UINT64 v68;
INT64 v69;
VOID *Src;
_KTBFLUSH_TYPE v71[2];
INT64 v72;
INT64 v73;
_MMPFN *Pfn1;
_MI_PAGING_FILE_SPACE_BITMAPS ReferencedBitmaps;
_MMPTE *PointerPte;
_MI_PAGEFILE_SECTION_RESERVE_INFO Info[4];
__int128 v78;
__int64 v79;
UINT64 *v80;
v80 = Page;
Partition = PagingFile->Partition;
bf_cc = PagingFile->_bf_cc;
LODWORD(v69) = 0;
v79 = 0i64;
memset(&ReferencedBitmaps.AllocationBitmap.Buffer, 0, 24);
*(_OWORD *)Info = 0i64;
v78 = 0i64;
MiRefPageFileSpaceBitmaps(
PagingFile,
&ReferencedBitmaps,
(INT64)ClusterSize,
(INT64)ChargedPages,
(INT64)MdlPage,
(INT64)DummyGapLength,
v66,
v67,
0i64,
v69,
(INT64)Page,
*(INT64 *)v71,
v72,
v73,
(INT64)Pfn1,
0i64,
0i64,
0i64);
v71[0] = FlushKernel;
v6 = bf_cc & 0xF;
v7 = v6;
Flink = Partition->PageLists.ModifiedPageListByReservation[v6].Flink;
if( Flink == 0xFFFFFFFFFi64 )
{
LABEL_70:
v16 = 0;
LODWORD(Long_high) = 0;
LABEL_71:
v54 = Src;
goto LABEL_72;
}
PfnDb = MmGetPfnDb();
while( 1 )
{
v10 = &PfnDb[Flink];
v11 = MiLockPageInline(v10);
if( Flink == Partition->PageLists.ModifiedPageListByReservation[v7].Flink )
break;
_InterlockedAnd64(&v10->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v11);
LABEL_11:
Flink = Partition->PageLists.ModifiedPageListByReservation[v7].Flink;
PfnDb = MmGetPfnDb();
if( Flink == 0xFFFFFFFFFi64 )
goto LABEL_70;
}
v12.Long = (unsigned __int64)v10->OriginalPte.u;
if( *(&stru_140C4DB30 + 42) && (v12.Long & 0x10) == 0 )
v12.Long &= ~*(&stru_140C4DB30 + 42);
Long_high = HIDWORD(v12.Long);
if( (unsigned int)Long_high >= ReferencedBitmaps.AllocationBitmap.SizeOfBitMap )
{
_InterlockedAnd64(&v10->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v11);
goto LABEL_70;
}
if( _bittest64((const signed __int64 *)ReferencedBitmaps.AllocationBitmap.Buffer, Long_high) )
{
MiUnlinkPageFromList(v10, 0i64);
v14.u.Long = v10->OriginalPte.u.Long;
v10->OriginalPte.u.Long = v14.u.Long & 0xFFFFFFFFFFFFFFFDui64;
MiInsertPageInList(v10, 8ui64, v15);
_InterlockedAnd64(&v10->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v11);
MiReleasePageFileInfo(Partition, v14, 0i64);
goto LABEL_11;
}
MiReferencePageForModifiedWrite(v10, 1ui64);
v16 = 1;
*v80 = Flink;
if( *(_DWORD *)ClusterSize == 1 )
{
_InterlockedAnd64(&v10->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v11);
goto LABEL_71;
}
v17.Long = (unsigned __int64)v10->OriginalPte.u;
v18 = v10->PteLong | 0x8000000000000000ui64;
v72 = v10->u4._bf_0 & 0xFFFFFFFFFi64;
Pfn1 = &MmGetPfnDb()[v72];
MiLockNestedPageAtDpcInline(Pfn1);
v19 = Pfn1;
bf_0 = Pfn1->u2._bf_0;
Pfn1->u2._bf_0 = bf_0 ^ ((bf_0 + 1) ^ bf_0) & 0x3FFFFFFFFFFFFFFFi64;
_InterlockedAnd64(&v19->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
_InterlockedAnd64(&v10->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v11);
LOBYTE(v22) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v10, (_UNICODE_STRING *)bf_0, (UINT8)v19, v21);
if( v22
&& ((MiGetPageFileSectionForReservation((_MMPTE *)v18, Info, 0i64), !v23)
|| (v24 = (unsigned __int64)v10->u2._bf_0 >> 62, LODWORD(v69) = 1, (v24 & 1) != 0))
|| (v25 = MiReservePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), 1ui64),
PointerPte = v25,
(v26 = (UINT64)v25) == 0) )
{
v54 = Src;
}
else
{
LODWORD(v27) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v25, v72, 536870913i64);
v28 = v27;
LOBYTE(v29) = MiPteInShadowRange(v26);
if( v29 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v28 & 1) != 0 )
v28 |= 0x8000000000000000ui64;
*(_QWORD *)v26 = v28;
v30 = (v26 << 25) - ((_QWORD)MmGetPteBase() << 25);
v31 = 8 * ((v18 >> 3) & 0x1FF);
v32 = v31 + (v30 >> 16);
v72 = v32;
if( (_DWORD)v69 )
v33 = 8 * ((*((_QWORD *)&v78 + 1) >> 3) & 0x1FFi64);
else
v33 = 4088i64;
Long = v17.Long & 0xFFFFFFFFFC00FC1Fui64;
v35 = (v33 - v31) >> 3;
v36 = Long;
v37 = Long;
LODWORD(v73) = *(_DWORD *)ClusterSize;
if( (unsigned int)v35 >= (int)v73 - 1 )
LODWORD(v35) = v73 - 1;
if( *(&stru_140C4DB30 + 42) && (Long & 0x10) == 0 )
v37 = Long & ~*(&stru_140C4DB30 + 42);
v38 = HIDWORD(v37);
if( v38 + (unsigned __int64)(unsigned int)v35 >= ReferencedBitmaps.AllocationBitmap.SizeOfBitMap )
LODWORD(v35) = ReferencedBitmaps.AllocationBitmap.SizeOfBitMap - v38 - 1;
v39 = v71[0];
v40 = v32;
if( (_DWORD)v35 )
{
do
{
++v38;
*(_QWORD *)v71 = v40 + 8;
LODWORD(v41.u.Long) = MiUpdatePageFileHighInPte(v36, v38);
v36 = v41.u.Hard._bf_0;
MiGetPageForWriteCluster(
&ReferencedBitmaps.AllocationBitmap,
v42,
v41,
v42,
(UINT64)MdlPagea,
&v68,
(_MI_RESAVAIL_CHARGE *)&v68 + 1);
if( v43 == -1i64 )
break;
LODWORD(v35) = v35 - 1;
++v16;
*++v80 = v43;
if( v43 == *(&stru_140C4DB30 + 495) )
++v39;
if( HIDWORD(v68) == 3 && v16 >= 0x10 )
break;
v40 = *(_QWORD *)v71;
}
while( (_DWORD)v35 );
LOWORD(v32) = v72;
}
v16 -= v68;
v44 = v39 - v68;
v45 = v73 - v16;
v71[0] = v44;
if( (_DWORD)v69 )
v46 = v31 - 8 * (((unsigned __int64)v78 >> 3) & 0x1FF);
else
v46 = v32 & 0xFFF;
v47 = Long;
v48 = v46 >> 3;
if( (unsigned int)v48 >= v45 )
v48 = v45;
if( *(&stru_140C4DB30 + 42) && (Long & 0x10) == 0 )
v47 = Long & ~*(&stru_140C4DB30 + 42);
v49 = HIDWORD(v47);
if( (unsigned int)v48 > (unsigned __int64)(v49 - 1) )
v48 = (unsigned int)(v49 - 1);
if( (_DWORD)v48 )
{
v50 = (char *)Src + 8 * v48;
memmove(v50, Src, 8 * v16);
LODWORD(v68) = 0;
do
{
--v49;
v72 -= 8i64;
LODWORD(v51.u.Long) = MiUpdatePageFileHighInPte(Long, v49);
Long = v51.u.Long;
MiGetPageForWriteCluster(
&ReferencedBitmaps.AllocationBitmap,
v52,
v51,
v52,
(UINT64)MdlPagea,
&v68,
(_MI_RESAVAIL_CHARGE *)&v68 + 1);
if( v53 == -1 )
break;
--v50;
LODWORD(v48) = v48 - 1;
++v16;
*v50 = v53;
if( v53 == *(&stru_140C4DB30 + 495) )
++v44;
}
while( (HIDWORD(v68) != 3 || v16 < 0x10) && (_DWORD)v48 );
v54 = Src;
v16 -= v68;
v71[0] = v44 - v68;
v55 = &v50[(unsigned int)v68];
if( Src != v55 )
memmove(Src, v55, 8 * v16);
}
else
{
v54 = Src;
}
v56.Long = (unsigned __int64)MmGetPfnDb()[*v54].OriginalPte.u;
if( *(&stru_140C4DB30 + 42) && (v56.Long & 0x10) == 0 )
v56.Long &= ~*(&stru_140C4DB30 + 42);
Long_high = HIDWORD(v56.Long);
MiReleasePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), PointerPte, 1ui64, (_KTBFLUSH_TYPE)v40);
}
v57 = Pfn1;
v58 = MiLockPageInline(Pfn1);
MiDecrementShareCount(v57);
_InterlockedAnd64(&v57->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v58);
if( (_DWORD)v69 )
MiReleasePageFileSectionInfo(Info);
LABEL_72:
v59 = *(unsigned int *)ClusterSize;
if( v16 < (unsigned int)v59
&& v16
&& v16 + (unsigned __int64)(unsigned int)Long_high < ReferencedBitmaps.AllocationBitmap.SizeOfBitMap )
{
if( (unsigned __int64)(unsigned int)Long_high + v59 <= ReferencedBitmaps.AllocationBitmap.SizeOfBitMap )
v60 = *(_DWORD *)ClusterSize;
else
v60 = ReferencedBitmaps.AllocationBitmap.SizeOfBitMap - Long_high;
v61 = PagingFile;
v16 += MiAddToReservationCluster(
PagingFile,
&ReferencedBitmaps.AllocationBitmap,
v60 - v16,
(unsigned int)Long_high + v16,
&v54[v16],
(UINT64 *)v71);
}
else
{
v61 = PagingFile;
}
v62 = MiDerefPageFileSpaceBitmaps(v61, &ReferencedBitmaps, 0i64);
if( v62 )
ExFreePoolWithTag(v62, 0);
*(_DWORD *)ClusterSize = v16;
*(_DWORD *)ChargedPages = v16 - v71[0];
}Referenced by:
MiGatherPagefilePages