MiWaitForFreePagesToZero
INT64 __fastcall MiWaitForFreePagesToZero(INT64 a1, INT64 *a2, UINT64 a3){
__int64 v3;
void *v4;
VOID *v5;
unsigned int v6;
unsigned int v9;
int v10;
int v12;
__int64 v13;
unsigned int v14;
_QWORD *v15;
UINT64 v16;
UINT8 v17;
UINT8 v18;
_BYTE *v19;
IRP *WaitMode;
struct _KLOCK_QUEUE_HANDLE LockHandle;
PVOID Object[3];
struct _KWAIT_BLOCK WaitBlockArray;
v3 = *(_QWORD *)(a1 + 16);
v4 = (void *)(a1 + 104);
Object[0] = (PVOID)(a1 + 104);
v5 = (VOID *)(a1 + 6272);
memset(&LockHandle, 0, sizeof(LockHandle));
Object[1] = (PVOID)(a1 + 6272);
v6 = a3;
v9 = a3;
while( 1 )
{
while( 1 )
{
if( *a2 )
{
MiDereferencePageRunsEx(*a2, 1i64);
*a2 = 0i64;
}
KeWaitForMultipleObjects((_BYTE *)2, Object, WaitAny, WrFreePage, 0, 0, 0i64, &WaitBlockArray);
if( !v10 )
return 0xFFFFFFFFi64;
LABEL_16:
if( *(_QWORD *)(a1 + 2304) )
break;
KeAcquireInStackQueuedSpinLock((UINT64 *)(a1 + 4928), &LockHandle);
if( !*(_QWORD *)(a1 + 2304) )
{
if( KeNumberNodes )
{
v19 = (_BYTE *)(v3 + 4490);
v16 = (unsigned __int16)KeNumberNodes;
do
{
*v19 = 0;
v19 += 4544;
--v16;
}
while( v16 );
}
KeResetEvent(v5, v16, v17, v18, WaitMode);
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
if( !*(_DWORD *)(a1 + 6340) && !dword_140C4EC18 )
break;
KeWaitForSingleObject(v4, WrFreePage, 0, 0, (PLARGE_INTEGER)&MiFiveSeconds);
}
v12 = dword_140C4EC18 + 1;
if( (unsigned __int16)KeNumberNodes > (unsigned __int16)(dword_140C4EC18 + 1) )
{
v9 = v6;
while( 1 )
{
v13 = 4544i64 * v9;
if( *(_QWORD *)(v13 + v3 + 4136) )
break;
v14 = 0;
v15 = (_QWORD *)(v3 + v13 + 8);
do
{
if( *v15 )
break;
v14 += v12;
v15 += 134;
}
while( v14 < 3 );
if( v14 != 3 )
break;
v9 = (v9 + 1) % (unsigned __int16)KeNumberNodes;
v12 = 1;
if( v9 == v6 )
goto LABEL_16;
}
}
*a2 = (INT64)MiReferencePageRuns((_MI_PARTITION *)a1, 0i64);
return v9;
}Referenced by:
MiZeroPageThread