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