MiGatherPagefilePages
__int64 __fastcall MiGatherPagefilePages(__int64 a1){
__int64 v1;
_ETHREAD *CurrentThread;
__int64 v3;
unsigned int v4;
__int64 v5;
UINT64 *v6;
__int16 v7;
unsigned __int16 v8;
unsigned __int64 v9;
unsigned __int64 v10;
__int16 v11;
unsigned int v12;
ULONG v13;
unsigned int v14;
ULONG v15;
unsigned int v16;
unsigned int v17;
unsigned __int64 v18;
unsigned __int64 v19;
unsigned int v20;
unsigned int v21;
UINT64 *v22;
unsigned int v23;
UINT64 *v24;
unsigned int v25;
_MMPFN *v26;
_MI_PARTITION *v27;
int v28;
unsigned int v29;
int v30;
unsigned __int64 v31;
int v32;
unsigned __int64 v33;
unsigned int v34;
__int64 result;
unsigned __int64 v36;
__int64 v37;
NTSTATUS *v38;
NTSTATUS v39;
unsigned __int64 v40;
_MMPFN *PfnDb;
UINT64 *v42;
UINT64 *v43;
INT64 v44;
UINT8 *v45;
int v46;
unsigned __int8 CurrentIrql;
ULONG v48;
UINT64 ChargedPages;
_ETHREAD *v50;
unsigned __int64 v51;
UINT64 *Page;
unsigned __int64 v53;
_MI_PARTITION *Partition;
__int64 v55;
KIRQL v57;
unsigned int v58;
int v59;
unsigned __int8 v60;
UINT64 v61;
UINT64 ClusterSize;
v1 = *(_QWORD *)(a1 + 144);
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v3 = a1;
LODWORD(ChargedPages) = 0;
v4 = 0;
v55 = v1;
v5 = *(_QWORD *)(v1 + 248);
Partition = (_MI_PARTITION *)v5;
v50 = CurrentThread;
if( !*(_QWORD *)(v1 + 24) )
goto LABEL_72;
*(_QWORD *)(a1 + 208) = 0i64;
*(_DWORD *)(a1 + 216) = 131120;
*(_QWORD *)(a1 + 240) = 0i64;
*(_QWORD *)(a1 + 248) = 0i64;
v6 = (UINT64 *)(a1 + 256);
v7 = *(_WORD *)(v1 + 204);
Page = v6;
v8 = *(_WORD *)(v1 + 204);
if( *(_DWORD *)(v5 + 1160) )
v4 = 4;
v9 = *(_QWORD *)(v5 + 40i64 * (v7 & 0xF) + 2816);
if( !_bittest16((const __int16 *)&v8, 4u)
&& (v4 & 4) != 0
&& (v10 = *(_QWORD *)(v5 + 40i64 * *(unsigned int *)(v5 + 1156) + 2816)) != 0 )
{
v4 |= 2u;
}
else
{
if( *(_DWORD *)(v5 + 1152) )
goto LABEL_65;
v10 = *(_QWORD *)(v5 + 2752);
}
if( v9 )
{
v11 = v8 >> 4;
goto LABEL_10;
}
if( !v10 || (v11 = v8 >> 4, (v11 & 1) != 0) )
{
LABEL_65:
v36 = ExAcquireSpinLockExclusive((PEX_SPIN_LOCK)(v1 + 232));
*(_BYTE *)(v1 + 206) |= 1u;
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v1 + 232));
__writecr8(v36);
*(_QWORD *)v3 = 2575857425i64;
goto LABEL_51;
}
LABEL_10:
if( (v4 & 2) == 0
&& v10
&& (v11 & 1) == 0
&& (!v9
|| (*(_BYTE *)(v1 + 207) & 1) != 0
|| (unsigned int)MiPageFileLargestBitmapsRun(v1) >= *(_DWORD *)(v1 + 136) >> 2
&& (v10 >= (unsigned __int64)(unsigned int)dword_140CFA18C >> 2 || v10 >= v9)) )
{
v4 |= 2u;
}
v12 = dword_140CFA18C;
LODWORD(v61) = dword_140CFA18C;
if( (v4 & 2) != 0 )
{
if( v10 < (unsigned int)dword_140CFA18C )
v12 = v10;
LODWORD(v61) = v12;
}
if( *(_BYTE *)(v5 + 1000) )
{
v59 = 0;
v40 = ExAcquireSpinLockExclusive((PEX_SPIN_LOCK)(v5 + 996));
if( *(_BYTE *)(v5 + 1002) )
{
*(_BYTE *)(v5 + 1002) = 0;
*(_BYTE *)(v5 + 1000) = 0;
v59 = 1;
}
else if( *(_BYTE *)(v5 + 1000) )
{
v12 = *(unsigned __int8 *)(v5 + 1000);
LODWORD(v61) = v12;
}
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v5 + 996));
__writecr8(v40);
if( v59 )
KeDelayExecutionThread(0, 0, (PLARGE_INTEGER)&Mi30Milliseconds);
CurrentThread = v50;
}
if( (*(_DWORD *)(v3 + 40) & 0x1Cu) < 8 )
{
if( v12 > 0x100 )
v12 = 256;
LODWORD(v61) = v12;
}
v4 |= 1u;
--*((_WORD *)CurrentThread + 242);
if( (v4 & 2) != 0 )
{
v48 = 0;
MiFindPageFileWriteCluster(v1, &v48, (unsigned int *)&v61, 0);
if( (_DWORD)v61 )
{
v16 = MiFillNoReservationCluster((_MI_PARTITION *)v5, Page, (unsigned int)v61);
v15 = v48;
v14 = v16;
LODWORD(ClusterSize) = v16;
goto LABEL_23;
}
LABEL_72:
MiPageFileNoFreeSpace(v1, (_QWORD *)v3);
goto LABEL_51;
}
LODWORD(ClusterSize) = v12;
v13 = MiBuildReservationCluster(Page, (_MMPAGING_FILE *)v1, &ClusterSize, &ChargedPages);
v14 = ChargedPages;
v15 = v13;
v48 = v13;
v16 = ClusterSize;
LABEL_23:
if( v16 )
{
LODWORD(v61) = v16;
HIDWORD(ChargedPages) = v14 - 1;
v17 = v16;
LODWORD(ChargedPages) = v14 - 1;
v57 = ExAcquireSpinLockExclusive((PEX_SPIN_LOCK)(v1 + 232));
if( (v4 & 2) != 0 )
{
MiFindPageFileWriteCluster(v1, &v48, (unsigned int *)&v61, 1);
v15 = v48;
v17 = v61;
}
else
{
MiSetPageFileAllocationBits(v1, v15, (unsigned int)ClusterSize);
v18 = (unsigned int)ClusterSize;
v19 = 0i64;
v20 = -1;
v51 = 0i64;
if( Page > &Page[(unsigned int)ClusterSize] )
v18 = 0i64;
v53 = v18;
if( v18 )
{
v21 = v15;
v22 = Page;
do
{
v23 = v20;
if( *v22 != qword_140C4EAA8
|| (v19 = v51, v18 = v53, _bittest64(*(const signed __int64 **)(*(_QWORD *)(v1 + 112) + 32i64), v21)) )
{
if( v20 != -1 )
{
MiInvalidatePageFileBitmapsCache(v1, v20, v21 - v20, 0i64);
v19 = v51;
v18 = v53;
v20 = -1;
}
}
else
{
v20 = v21;
if( v23 != -1 )
v20 = v23;
}
++v19;
++v21;
++v22;
v51 = v19;
}
while( v19 < v18 );
v3 = a1;
}
}
if( (v4 & 2) == 0 )
*(_DWORD *)(v1 + 136) = v17 + *(_DWORD *)(v1 + 136) - (*(_DWORD *)(v1 + 136) >> 2);
MiUpdatePagefilePeakUsage((_QWORD *)v1);
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v1 + 232));
__writecr8(v57);
KeLeaveCriticalRegionThread((__int64)v50);
v4 &= ~1u;
LODWORD(v51) = v4;
if( v17 != (_DWORD)ClusterSize )
{
PfnDb = MmGetPfnDb();
v42 = &Page[(unsigned int)ClusterSize];
v43 = &Page[v17];
do
{
v44 = (INT64)PfnDb + 48 * *v43;
v60 = MiLockPageInline(v44);
MiWriteCompletePfn((_MMPFN *)v44, 1, v45);
_InterlockedAnd64((volatile signed __int64 *)(v44 + 24), 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v60);
++v43;
}
while( v43 < v42 );
v17 = v61;
HIDWORD(ChargedPages) = v61 - ClusterSize + ChargedPages;
LODWORD(ChargedPages) = HIDWORD(ChargedPages);
MiReleaseWriteInProgressCharges(Partition, (unsigned int)(ClusterSize - v61), 0i64);
v15 = v48;
v4 = v51;
v3 = a1;
v1 = v55;
}
v24 = Page;
*(_DWORD *)(v3 + 248) = v17 << 12;
*(_DWORD *)(v3 + 136) = v17 << 12;
*(_DWORD *)(v3 + 140) = HIDWORD(ChargedPages);
v25 = 0;
LODWORD(ClusterSize) = v17;
v58 = 0;
LODWORD(v51) = v15;
v26 = MmGetPfnDb();
do
{
if( *v24 != qword_140C4EAA8 )
{
MiUpdatePfnBackingStore((INT64)v26 + 48 * *v24, v1, v15, 0i64);
v25 = v58;
}
++v25;
++v24;
++v15;
v58 = v25;
LODWORD(v61) = v25;
}
while( v25 < v17 );
v27 = Partition;
v48 = v15;
*(_WORD *)(a1 + 216) = 8 * (dword_140CFA18C + 6);
*(_DWORD *)(a1 + 40) &= ~2u;
v28 = *(_DWORD *)(a1 + 40) >> 2;
*(_QWORD *)(a1 + 184) = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
v29 = v28 & 7;
v30 = *((_DWORD *)v27 + 215);
v31 = *((_QWORD *)v27 + 888);
if( v30 )
{
if( v31 >= 0x420 )
{
v46 = 0;
}
else
{
v29 = 4;
v46 = v30 - 1;
}
*((_DWORD *)v27 + 215) = v46;
}
else
{
if( v31 < 0xA0 )
{
*((_DWORD *)v27 + 215) = 32;
}
else
{
if( v31 >= 0x120 )
goto LABEL_44;
*((_DWORD *)v27 + 215) = 8;
}
v29 = 4;
}
LABEL_44:
*(_DWORD *)(a1 + 40) = (4 * v29) | *(_DWORD *)(a1 + 40) & 0xFFFFFFE3;
if( v29 < 2 )
{
v37 = (__int64)v50;
--*((_WORD *)v50 + 243);
++*((_DWORD *)v27 + 173);
KiLeaveGuardedRegionUnsafe(v37);
}
MI_PAGEFILE_WRITE(a1, (_QWORD *)(a1 + 184), v29, ((v4 >> 1) & 1) == 0, -1);
v32 = *((_DWORD *)v27 + 212);
v33 = *((_QWORD *)v27 + 105);
if( v32 == 512 )
v33 -= v33 >> 9;
else
*((_DWORD *)v27 + 212) = v32 + 1;
*((_QWORD *)v27 + 105) = v33 + (unsigned int)ClusterSize;
v34 = v51;
*(_DWORD *)(a1 + 40) &= ~0x20u;
*(_QWORD *)(a1 + 176) = (unsigned __int64)v34 << 12;
if( v4 >= 4 && (int)MiStoreWriteModifiedPages(a1) >= 0 )
goto LABEL_50;
__incgsdword(0x2EACu);
__addgsdword(0x2EA8u, ClusterSize);
MiMapPageFileHash(v1, a1 + 208, 0i64, v34, ClusterSize);
v38 = (NTSTATUS *)(a1 + 16);
if( (*(_WORD *)(v1 + 204) & 0x800) != 0 )
{
*v38 = 0;
*(_QWORD *)(a1 + 24) = *(unsigned int *)(a1 + 248);
}
else
{
v39 = IoAsynchronousPageWrite(
*(_FILE_OBJECT **)(v1 + 56),
a1 + 208,
(_QWORD *)(a1 + 176),
(void(__fastcall *)(__int64, __int64, _QWORD))MiWriteComplete,
a1,
v29,
*(_DWORD *)(v1 + 200),
0,
0i64,
a1 + 16,
(_QWORD *)(a1 + 32));
if( (v39 & 0xC0000000) != -1073741824 )
{
LABEL_50:
CurrentThread = v50;
goto LABEL_51;
}
*v38 = v39;
*(_QWORD *)(a1 + 24) = 0i64;
}
CurrentIrql = KeGetCurrentIrql();
__writecr8(1ui64);
MiWriteComplete((PVOID)a1, (IO_STATUS_BLOCK *)(a1 + 16), 0i64);
__writecr8(CurrentIrql);
goto LABEL_50;
}
CurrentThread = v50;
--*((_WORD *)v50 + 243);
MiMakePagefileWriterEntryAvailable(v3);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
LABEL_51:
result = 1i64;
if( (v4 & 1) != 0 )
return(__int64)KeLeaveCriticalRegionThread((__int64)CurrentThread);
return result;
}Referenced by:
MiModifiedPageWriter