MiGatherPagefilePages
VOID __stdcall MiGatherPagefilePages(_MMMOD_WRITER_MDL_ENTRY *ModWriterEntry){
_MMPAGING_FILE *PagingFile;
_ETHREAD *CurrentThread;
_MMMOD_WRITER_MDL_ENTRY *v3;
unsigned int v4;
_MI_PARTITION *v5;
unsigned __int64 *v6;
__int16 bf_cc;
unsigned __int16 v8;
unsigned __int64 Total;
unsigned __int64 v10;
__int16 v11;
unsigned int MaximumClusterPages;
unsigned int v13;
unsigned int v14;
unsigned int v15;
unsigned int v16;
unsigned int v17;
unsigned __int64 v18;
UINT64 v19;
unsigned int v20;
unsigned int v21;
UINT64 *v22;
unsigned int v23;
UINT64 *v24;
unsigned int v25;
_MMPFN *v26;
_MI_PARTITION *v27;
int v28;
int v29;
unsigned int WriteBurstCount;
unsigned __int64 AvailablePages;
unsigned int WritesIssued;
unsigned __int64 PagesWritten;
unsigned int v34;
unsigned __int64 v35;
_ETHREAD *v36;
union {_IO_STATUS_BLOCK IoStatus;} *p_u;
NTSTATUS v38;
unsigned __int64 v39;
_MMPFN *PfnDb;
UINT64 *v41;
UINT64 *v42;
_MMPFN *v43;
unsigned int v44;
unsigned __int8 CurrentIrql;
INT64 Status;
INT64 Statusa;
_IO_STATUS_BLOCK *v48;
UINT64 v49;
VOID *ApcContext;
VOID *v51;
UINT64 StartingIndex;
_IRP **v53;
_ETHREAD *Thread;
UINT64 ClusterStart;
UINT64 *Page;
unsigned __int64 v57;
_MI_PARTITION *Partition;
_MMPAGING_FILE *v59;
unsigned __int8 v61;
unsigned int v62;
int v63;
UINT8 v64;
UINT64 ClusterSizeInOut;
UINT64 ClusterSize;
PagingFile = ModWriterEntry->PagingFile;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v3 = ModWriterEntry;
HIDWORD(StartingIndex) = 0;
v4 = 0;
v59 = PagingFile;
v5 = PagingFile->Partition;
Partition = v5;
Thread = CurrentThread;
if( !PagingFile->FreeSpace )
goto LABEL_72;
ModWriterEntry->Mdl.Next = 0i64;
*(_DWORD *)&ModWriterEntry->Mdl.Size = 131120;
ModWriterEntry->Mdl.StartVa = 0i64;
*(_QWORD *)&ModWriterEntry->Mdl.ByteCount = 0i64;
v6 = ModWriterEntry->Page;
bf_cc = PagingFile->_bf_cc;
Page = v6;
v8 = PagingFile->_bf_cc;
if( v5->Store.Registered )
v4 = 4;
Total = v5->PageLists.ModifiedPageListByReservation[bf_cc & 0xF].Total;
if( !_bittest16((const __int16 *)&v8, 4u)
&& (v4 & 4) != 0
&& (v10 = v5->PageLists.ModifiedPageListByReservation[v5->Store.VirtualPageFileNumber].Total) != 0 )
{
v4 |= 2u;
}
else
{
if( v5->Store.WriteAllStoreHintedPages._bf_0 )
goto LABEL_65;
v10 = v5->PageLists.ModifiedPageListNoReservation.Total;
}
if( Total )
{
v11 = v8 >> 4;
goto LABEL_10;
}
if( !v10 || (v11 = v8 >> 4, (v11 & 1) != 0) )
{
LABEL_65:
v35 = (unsigned __int8)ExAcquireSpinLockExclusive((INT64 *)&PagingFile->SpinLock);
BYTE2(PagingFile->_bf_cc) |= 1u;
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&PagingFile->SpinLock);
__writecr8(v35);
v3->Links.Flink = (_LIST_ENTRY *)2575857425i64;
goto LABEL_51;
}
LABEL_10:
if( (v4 & 2) == 0
&& v10
&& (v11 & 1) == 0
&& (!Total
|| (PagingFile->_bf_cc & 0x1000000) != 0
|| MiPageFileLargestBitmapsRun(PagingFile) >= PagingFile->ReservedClusterSizeAggregate >> 2
&& (v10 >= (unsigned __int64)(unsigned int)MaxIoSize >> 2 || v10 >= Total)) )
{
v4 |= 2u;
}
MaximumClusterPages = MaxIoSize;
LODWORD(ClusterSizeInOut) = MaxIoSize;
if( (v4 & 2) != 0 )
{
if( v10 < (unsigned int)MaxIoSize )
MaximumClusterPages = v10;
LODWORD(ClusterSizeInOut) = MaximumClusterPages;
}
if( v5->Modwriter.ClusterRestrictions[0].MaximumClusterPages )
{
v63 = 0;
v39 = (unsigned __int8)ExAcquireSpinLockExclusive((INT64 *)&v5->Modwriter.ClusterRestrictionLock);
if( v5->Modwriter.ClusterRestrictions[0].ImposeDelay )
{
v5->Modwriter.ClusterRestrictions[0].ImposeDelay = 0;
v5->Modwriter.ClusterRestrictions[0].MaximumClusterPages = 0;
v63 = 1;
}
else if( v5->Modwriter.ClusterRestrictions[0].MaximumClusterPages )
{
MaximumClusterPages = v5->Modwriter.ClusterRestrictions[0].MaximumClusterPages;
LODWORD(ClusterSizeInOut) = MaximumClusterPages;
}
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&v5->Modwriter.ClusterRestrictionLock);
__writecr8(v39);
if( v63 )
KeDelayExecutionThread(0, 0, (_LARGE_INTEGER *)&Mi30Milliseconds);
CurrentThread = Thread;
}
if( (*(_DWORD *)&v3->u1 & 0x1Cu) < 8 )
{
if( MaximumClusterPages > 0x100 )
MaximumClusterPages = 256;
LODWORD(ClusterSizeInOut) = MaximumClusterPages;
}
v4 |= 1u;
--CurrentThread->Tcb.KernelApcDisable;
if( (v4 & 2) != 0 )
{
LODWORD(StartingIndex) = 0;
MiFindPageFileWriteCluster(PagingFile, &StartingIndex, &ClusterSizeInOut, 0i64, Status);
if( (_DWORD)ClusterSizeInOut )
{
v16 = MiFillNoReservationCluster(v5, Page, (unsigned int)ClusterSizeInOut);
v15 = StartingIndex;
v13 = v16;
LODWORD(ClusterSize) = v16;
goto LABEL_23;
}
LABEL_72:
MiPageFileNoFreeSpace(PagingFile, v3);
goto LABEL_51;
}
LODWORD(ClusterSize) = MaximumClusterPages;
MiBuildReservationCluster(Page, PagingFile, &ClusterSize, (UINT64 *)((char *)&StartingIndex + 4));
v13 = HIDWORD(StartingIndex);
v15 = v14;
LODWORD(StartingIndex) = v14;
v16 = ClusterSize;
LABEL_23:
if( v16 )
{
LODWORD(ClusterSizeInOut) = v16;
LODWORD(v53) = v13 - 1;
v17 = v16;
HIDWORD(StartingIndex) = v13 - 1;
v61 = ExAcquireSpinLockExclusive((INT64 *)&PagingFile->SpinLock);
if( (v4 & 2) != 0 )
{
MiFindPageFileWriteCluster(PagingFile, &StartingIndex, &ClusterSizeInOut, 1ui64, Status);
v15 = StartingIndex;
v17 = ClusterSizeInOut;
}
else
{
MiSetPageFileAllocationBits(PagingFile, v15, (unsigned int)ClusterSize);
v18 = (unsigned int)ClusterSize;
v19 = 0i64;
v20 = -1;
ClusterStart = 0i64;
if( Page > &Page[(unsigned int)ClusterSize] )
v18 = 0i64;
v57 = v18;
if( v18 )
{
v21 = v15;
v22 = Page;
do
{
v23 = v20;
if( *v22 != *(&stru_140C4DB30 + 495)
|| (v19 = ClusterStart,
v18 = v57,
_bittest64((const signed __int64 *)PagingFile->Bitmaps->ReservationBitmap.Buffer, v21)) )
{
if( v20 != -1 )
{
MiInvalidatePageFileBitmapsCache(PagingFile, v20, v21 - v20, 0i64);
v19 = ClusterStart;
v18 = v57;
v20 = -1;
}
}
else
{
v20 = v21;
if( v23 != -1 )
v20 = v23;
}
++v19;
++v21;
++v22;
ClusterStart = v19;
}
while( v19 < v18 );
v3 = ModWriterEntry;
}
}
if( (v4 & 2) == 0 )
PagingFile->ReservedClusterSizeAggregate = v17
+ PagingFile->ReservedClusterSizeAggregate
- (PagingFile->ReservedClusterSizeAggregate >> 2);
MiUpdatePagefilePeakUsage(PagingFile);
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&PagingFile->SpinLock);
__writecr8(v61);
KeLeaveCriticalRegionThread(&Thread->Tcb);
v4 &= ~1u;
LODWORD(ClusterStart) = v4;
if( v17 != (_DWORD)ClusterSize )
{
PfnDb = MmGetPfnDb();
v41 = &Page[(unsigned int)ClusterSize];
v42 = &Page[v17];
do
{
v43 = &PfnDb[*v42];
v64 = MiLockPageInline(v43);
MiWriteCompletePfn(v43);
_InterlockedAnd64(&v43->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v64);
++v42;
}
while( v42 < v41 );
v17 = ClusterSizeInOut;
LODWORD(v53) = ClusterSizeInOut - ClusterSize + HIDWORD(StartingIndex);
HIDWORD(StartingIndex) = (_DWORD)v53;
MiReleaseWriteInProgressCharges(Partition, (unsigned int)(ClusterSize - ClusterSizeInOut), 0i64);
v15 = StartingIndex;
v4 = ClusterStart;
v3 = ModWriterEntry;
PagingFile = v59;
}
v24 = Page;
v3->Mdl.ByteCount = v17 << 12;
v3->ByteCount = v17 << 12;
v3->ChargedPages = (unsigned int)v53;
v25 = 0;
LODWORD(ClusterSize) = v17;
v62 = 0;
LODWORD(ClusterStart) = v15;
v26 = MmGetPfnDb();
do
{
if( *v24 != *(&stru_140C4DB30 + 495) )
{
MiUpdatePfnBackingStore(&v26[*v24], PagingFile, v15, 0i64);
v25 = v62;
}
++v25;
++v24;
++v15;
v62 = v25;
LODWORD(ClusterSizeInOut) = v25;
}
while( v25 < v17 );
v27 = Partition;
LODWORD(StartingIndex) = v15;
ModWriterEntry->Mdl.Size = 8 * (MaxIoSize + 6);
*(_DWORD *)&ModWriterEntry->u1 &= ~2u;
v28 = *(_DWORD *)&ModWriterEntry->u1 >> 2;
ModWriterEntry->IssueTime.QuadPart = *(_QWORD *)&KUSER_SHARED_DATA.SystemTime.LowPart;
v29 = v28 & 7;
WriteBurstCount = v27->Modwriter.ModWriteData.WriteBurstCount;
AvailablePages = v27->Vp.AvailablePages;
if( WriteBurstCount )
{
if( AvailablePages >= 0x420 )
{
v44 = 0;
}
else
{
v29 = 4;
v44 = WriteBurstCount - 1;
}
v27->Modwriter.ModWriteData.WriteBurstCount = v44;
}
else
{
if( AvailablePages < 0xA0 )
{
v27->Modwriter.ModWriteData.WriteBurstCount = 32;
}
else
{
if( AvailablePages >= 0x120 )
goto LABEL_44;
v27->Modwriter.ModWriteData.WriteBurstCount = 8;
}
v29 = 4;
}
LABEL_44:
ModWriterEntry->u1 = (_MODWRITER_FLAGS)((4 * v29) | *(_DWORD *)&ModWriterEntry->u1 & 0xFFFFFFE3);
if( (unsigned int)v29 < 2 )
{
v36 = Thread;
--Thread->Tcb.SpecialApcDisable;
++v27->Modwriter.LowPriorityModWritesOutstanding;
KiLeaveGuardedRegionUnsafe((__int64)v36);
}
LODWORD(Status) = -1;
MI_PAGEFILE_WRITE(
ModWriterEntry,
&ModWriterEntry->IssueTime,
(_IO_PAGING_PRIORITY)v29,
((v4 >> 1) & 1) == 0,
Status);
WritesIssued = v27->Modwriter.ModWriteData.WritesIssued;
PagesWritten = v27->Modwriter.ModWriteData.PagesWritten;
if( WritesIssued == 512 )
PagesWritten -= PagesWritten >> 9;
else
v27->Modwriter.ModWriteData.WritesIssued = WritesIssued + 1;
v27->Modwriter.ModWriteData.PagesWritten = PagesWritten + (unsigned int)ClusterSize;
v34 = ClusterStart;
*(_DWORD *)&ModWriterEntry->u1 &= ~0x20u;
ModWriterEntry->WriteOffset.QuadPart = (unsigned __int64)v34 << 12;
if( v4 >= 4 && MiStoreWriteModifiedPages(ModWriterEntry) >= 0 )
goto LABEL_50;
__incgsdword(0x2EACu);
__addgsdword(0x2EA8u, ClusterSize);
LODWORD(Statusa) = ClusterSize;
MiMapPageFileHash(PagingFile, &ModWriterEntry->Mdl, 0i64, v34, Statusa);
p_u = &ModWriterEntry->u;
if( (PagingFile->_bf_cc & 0x800) != 0 )
{
p_u->IoStatus.Status = 0;
ModWriterEntry->u.IoStatus.Information = ModWriterEntry->Mdl.ByteCount;
}
else
{
LOBYTE(ApcContext) = 0;
LODWORD(v49) = PagingFile->ToBeEvictedCount;
LODWORD(v48) = v29;
v38 = IoAsynchronousPageWrite(
PagingFile->File,
&ModWriterEntry->Mdl,
&ModWriterEntry->WriteOffset,
MiWriteComplete,
ModWriterEntry,
v48,
v49,
ApcContext,
IoPriorityVeryLow,
(UINT64)&ModWriterEntry->u,
(_BYTE)ModWriterEntry + 32,
v51,
(_IO_STATUS_BLOCK *)StartingIndex,
v53);
if( (v38 & 0xC0000000) != -1073741824 )
{
LABEL_50:
CurrentThread = Thread;
goto LABEL_51;
}
p_u->IoStatus.Status = v38;
ModWriterEntry->u.IoStatus.Information = 0i64;
}
CurrentIrql = KeGetCurrentIrql();
__writecr8(1ui64);
MiWriteComplete(ModWriterEntry, &ModWriterEntry->u.IoStatus, 0i64);
__writecr8(CurrentIrql);
goto LABEL_50;
}
CurrentThread = Thread;
--Thread->Tcb.SpecialApcDisable;
MiMakePagefileWriterEntryAvailable(v3);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
LABEL_51:
if( (v4 & 1) != 0 )
KeLeaveCriticalRegionThread(&CurrentThread->Tcb);
}Referenced by:
MiModifiedPageWriter