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