MiFlushControlArea

VOID __stdcall MiFlushControlArea(
        _CONTROL_AREA *ControlArea,
        _BYTE *OldIrql,
        _MI_CONTROL_AREA_WAIT_BLOCK **Gate,
        _FILE_OBJECT **AcquiredFileObject){
  unsigned __int64 v4; 
  _FILE_OBJECT *v6; 
  _WORK_QUEUE_ITEM *Pool; 
  _BOOL4 v8; 
  unsigned __int64 v9; 
  signed __int64 v10; 
  NTSTATUS v11; 
  char v12; 
  UINT64 v13; 
  unsigned int v14; 
  int v15; 
  UINT64 v16; 
  _MI_CROSS_PARTITION_CHARGES *v17; 
  UINT64 Flags; 
  INT64 *SpinLock; 
  _IO_STATUS_BLOCK IoStatus; 
  _MI_CONTROL_AREA_WAIT_BLOCK *WaitList; 
  __int64 v22; 
  __int64 v23; 
  __int64 v24[10]; 
  _BOOL4 v25; 

  ControlArea->u.LongFlags |= 0x100u;
  v24[1] = (__int64)v24;
  v4 = (unsigned __int8)OldIrql;
  v24[0] = (__int64)v24;
  WaitList = ControlArea->WaitList;
  v23 = 393479i64;
  ControlArea->WaitList = (_MI_CONTROL_AREA_WAIT_BLOCK *)&WaitList;
  IoStatus = 0i64;
  *AcquiredFileObject = 0i64;
  *Gate = 0i64;
  v22 = 4i64;
  v6 = MiPreventControlAreaDelete(ControlArea);
  SpinLock = (INT64 *)&ControlArea->ControlAreaLock;
  ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&ControlArea->ControlAreaLock);
  __writecr8(v4);
  Pool = 0i64;
  v8 = FsRtlAcquireFileForCcFlushEx(v6) >= 0;
  v25 = v8;
  v9 = (unsigned __int8)ExAcquireSpinLockExclusive((INT64 *)&ControlArea->ControlAreaLock);
  v10 = _InterlockedDecrement64((volatile signed __int64 *)&ControlArea->LockedPages);
  *(_QWORD *)(*(_QWORD *)(*(&stru_140C4DB30 + 267) + 8i64 * (ControlArea->u1.Flags._bf_0 & 0x3FF)) + 1688i64) = 0i64;
  if( !v8 || (ControlArea->u.LongFlags & 1) != 0 )
  {
    ControlArea->u.LongFlags &= ~0x100u;
    HIDWORD(v22) = 1;
    if( !v10 )
    {
      MiRemoveWakeListEntry(ControlArea, (_MI_CONTROL_AREA_WAIT_BLOCK *)&WaitList);
      ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&ControlArea->ControlAreaLock);
      __writecr8(v9);
      if( v8 )
        FsRtlReleaseFileForCcFlush(v6);
      MiDeleteControlArea(ControlArea);
      ObfDereferenceObjectWithTag(v6, 0x746C6644ui64);
      return;
    }
    v11 = 0;
  }
  else
  {
    ++ControlArea->ModifiedWriteCount;
    ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&ControlArea->ControlAreaLock);
    __writecr8(v9);
    KeGetCurrentThread()[1].TrapFrame = (_KTRAP_FRAME *)1;
    LODWORD(Flags) = 2;
    v11 = MiFlushSectionInternal(0i64, 0i64, (_SUBSECTION *)&ControlArea[1], 0i64, 0i64, Flags, &IoStatus);
    KeGetCurrentThread()[1].TrapFrame = 0i64;
    if( v11 < 0 )
      Pool = (_WORK_QUEUE_ITEM *)MiAllocatePool(64i64, 0x38ui64, 0x70646D4Dui64);
    v12 = ExAcquireSpinLockExclusive((INT64 *)&ControlArea->ControlAreaLock);
    ControlArea->u.LongFlags &= ~0x100u;
    LOBYTE(v9) = v12;
    *Gate = MiDecrementModifiedWriteCount(ControlArea, 1ui64);
  }
  v13 = 0i64;
  MiRemoveWakeListEntry(ControlArea, (_MI_CONTROL_AREA_WAIT_BLOCK *)&WaitList);
  if( ControlArea->NumberOfSectionReferences | ControlArea->NumberOfMappedViews | ControlArea->u.LongFlags & 1i64 )
    goto LABEL_20;
  if( !HIDWORD(v22) || !ControlArea->NumberOfPfnReferences )
  {
    if( v11 >= 0 || !ControlArea->NumberOfPfnReferences )
      goto LABEL_17;
    if( v11 != -1073740749 )
    {
      MmIsWriteErrorFatal((_BYTE *)1, v14, (unsigned int)v11);
      if( v15 )
      {
        if( Pool )
        {
          Pool[1].List.Flink = (_LIST_ENTRY *)ObFastReferenceObjectLocked(&ControlArea->FilePointer);
          LOBYTE(Pool[1].WorkerRoutine) = 1;
          LODWORD(Pool[1].List.Blink) = v11;
          Pool->List.Flink = 0i64;
          Pool->WorkerRoutine = (void(__fastcall *)(void *))MiLdwPopupWorker;
          Pool->Parameter = Pool;
          ExQueueWorkItem(Pool, DelayedWorkQueue);
        }
LABEL_17:
        *AcquiredFileObject = v6;
        return;
      }
    }
  }
  MiInsertUnusedSegment(ControlArea);
  v13 = v16;
  if( !v16 )
LABEL_20:
    v17 = 0i64;
  else
    v17 = *(_MI_CROSS_PARTITION_CHARGES **)(*(&stru_140C4DB30 + 267) + 8i64 * (ControlArea->u1.Flags._bf_0 & 0x3FF));
  ExReleaseSpinLockExclusiveFromDpcLevel(SpinLock);
  __writecr8((unsigned __int8)v9);
  if( v25 )
    FsRtlReleaseFileForCcFlush(v6);
  ObfDereferenceObjectWithTag(v6, 0x746C6644ui64);
  if( v13 )
    MiReturnCrossPartitionSectionCharges(v17, 1i64, v13);
  if( Pool )
    ExFreePoolWithTag(Pool, 0);
}

Referenced by:

MiDeleteCachedSegment
MiProcessDeleteOnClose