CcMapAndCopyInToCache

UINT8 __stdcall CcMapAndCopyInToCache(
        _SHARED_CACHE_MAP *SharedCacheMap,
        VOID *UserBuffer,
        _LARGE_INTEGER *FileOffset,
        UINT64 Length,
        UINT64 OptimizeFlags,
        _FILE_OBJECT *FileObject,
        _LARGE_INTEGER *ValidDataLength,
        UINT8 Wait,
        _ETHREAD *IoIssuerThread){
  _SHARED_CACHE_MAP *v9; 
  UINT8 v10; 
  _LARGE_INTEGER *v11; 
  bool v12; 
  int v13; 
  _WORK_QUEUE_ENTRY *v14; 
  char v15; 
  __int64 v16; 
  __int64 v17; 
  _IO_PRIORITY_HINT BaseIoPriorityThread; 
  __int64 v19; 
  int v20; 
  __int64 v21; 
  __int64 v22; 
  _ETHREAD *v23; 
  UINT64 WorkOnBehalfThread; 
  _EPROCESS *Process; 
  int v26; 
  _VACB *v27; 
  __int64 v28; 
  int v29; 
  char *VirtualAddress; 
  unsigned int v31; 
  ULONG v32; 
  char *v33; 
  unsigned int v34; 
  int v35; 
  ULONG v36; 
  unsigned int v37; 
  _BOOL8 v38; 
  int v39; 
  int v40; 
  ULONG v41; 
  int v42; 
  int v43; 
  unsigned int v44; 
  NTSTATUS v45; 
  _SHARED_CACHE_MAP *v46; 
  _KEVENT *v47; 
  NTSTATUS v48; 
  _MDL *v49; 
  UINT64 v50; 
  bool v51; 
  _MMPTE *v52; 
  int v53; 
  size_t v54; 
  int v55; 
  bool v56; 
  INT64 v57; 
  INT64 v58; 
  int v59; 
  unsigned int v60; 
  _ETHREAD *v61; 
  _ETHREAD *v62; 
  char v63; 
  NTSTATUS v64; 
  char v65; 
  UINT64 v66; 
  int Status; 
  NTSTATUS v68; 
  char v69; 
  unsigned int v70; 
  _ETHREAD *v71; 
  UINT64 v73; 
  unsigned __int64 v74; 
  volatile signed __int64 *DiskIoAttribution; 
  unsigned __int64 v76; 
  _SHARED_CACHE_MAP *v77; 
  __int64 v78; 
  _WORK_QUEUE_ENTRY **v79; 
  _KEVENT *v80; 
  char v81; 
  NTSTATUS v82; 
  UINT64 RequestHighPriorityMapping; 
  UINT64 PerformingReadAhead; 
  UINT8 v85; 
  bool v86; 
  char v87; 
  char v88; 
  bool v89; 
  char v90; 
  int v91; 
  UINT8 ReturnResult; 
  bool v93; 
  bool v94; 
  char v95; 
  UINT8 v96; 
  char v97; 
  UINT64 Lengtha; 
  ULONG Offset; 
  int Offset_4; 
  unsigned int ReceivedLength; 
  UINT64 ReceivedLength_4; 
  int v103; 
  VOID *v104; 
  _VACB *Vacb; 
  unsigned int v106; 
  unsigned int v107; 
  unsigned int v108; 
  int v109; 
  INT64 v110; 
  _IO_STATUS_BLOCK IoStatus; 
  LONGLONG v112; 
  _ETHREAD *CurrentThread; 
  _KLOCK_QUEUE_HANDLE LockHandle; 
  unsigned int Flags; 
  _BOOL4 Flags_4; 
  unsigned int v117; 
  int v118; 
  NTSTATUS v119; 
  int v120; 
  unsigned int v121; 
  _MDL *v122; 
  VOID *IoAttributionContext; 
  _KLOCK_QUEUE_HANDLE LockQueue; 
  _BOOL4 v125; 
  NTSTATUS v126; 
  UINT64 v127; 
  __int64 v128; 
  __int64 v129; 
  _KLOCK_QUEUE_HANDLE v130; 
  unsigned int er8; 

  er8 = Length;
  v108 = Length;
  v9 = SharedCacheMap;
  v10 = Wait;
  v11 = 0i64;
  ReceivedLength = 0;
  LODWORD(Lengtha) = 0;
  v112 = 0i64;
  IoStatus = 0i64;
  v12 = (FileObject->Flags & 0x10) != 0;
  v85 = v12;
  v118 = Length;
  Offset = FileOffset->anonymous_0.LowPart & 0xFFF;
  Vacb = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v13 = 0;
  v91 = 0;
  v95 = 0;
  v88 = 0;
  v14 = 0i64;
  IoAttributionContext = 0i64;
  ReturnResult = 1;
  v87 = 0;
  v90 = 0;
  memset(&LockHandle, 0, sizeof(LockHandle));
  memset(&LockQueue, 0, sizeof(LockQueue));
  v89 = (*((_DWORD *)SharedCacheMap + 38) & 0x1000) != 0;
  ReceivedLength_4 = FileOffset->QuadPart;
  v107 = CurrentThread->CacheManagerActive + 4 * CurrentThread->ReadClusterSize;
  v117 = v107;
  v15 = v12;
  v94 = v12;
  v97 = v12;
  if( !v12 )
  {
    v94 = 0;
    memset(&v130, 0, sizeof(v130));
    v16 = *((_QWORD *)SharedCacheMap + 66);
    if( *((_QWORD *)SharedCacheMap + 21) )
    {
      LODWORD(v17) = MmGetControlAreaPartition(*(_QWORD *)((*((_QWORD *)SharedCacheMap + 12) & 0xFFFFFFFFFFFFFFF0ui64)
                                                         + 0x28));
      if( v16 != *(_QWORD *)(v17 + 8) )
        KeBugCheckEx(0x34u, (PVOID)0x1313, (PVOID)0xFFFFFFFFC0000420i64, 0i64, 0i64);
    }
    if( (FileObject->Flags & 0x1000000) == 0
      || CcCanIWriteStreamEx((UINT8 *)v16, (INT64)FileObject, er8, 0i64, 0, 0i64) )
    {
      BaseIoPriorityThread = PsGetBaseIoPriorityThread((_ETHREAD *)KeGetCurrentThread());
      if( BaseIoPriorityThread < IoPriorityNormal
        && (struct _KTHREAD *)v19 == KeGetCurrentThread()
        && *(_DWORD *)(v19 + 1360)
        || BaseIoPriorityThread > IoPriorityVeryLow
        || (FileObject->Flags & 0x8000) != 0 )
      {
        v13 = 0;
LABEL_8:
        v97 = v15;
        v12 = v85;
        v10 = Wait;
        goto LABEL_9;
      }
      v13 = 0;
    }
    v15 = 1;
    v94 = 1;
    if( (*((_DWORD *)v9 + 38) & 0x400) == 0 )
    {
      KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)(v16 + 128), &v130);
      *((_DWORD *)v9 + 38) |= 0x400u;
      KeReleaseInStackQueuedSpinLockFromDpcLevel(&v130);
      __writecr8(v130.OldIrql);
    }
    goto LABEL_8;
  }
LABEL_9:
  if( v15 && !v10 )
    return 0;
  v20 = 6;
  if( v10 )
    v20 = 4;
  Flags = v20;
  v21 = *((_QWORD *)v9 + 66);
  v128 = v21;
  if( *((_QWORD *)v9 + 21) )
  {
    LODWORD(v22) = MmGetControlAreaPartition(*(_QWORD *)((*((_QWORD *)v9 + 12) & 0xFFFFFFFFFFFFFFF0ui64) + 0x28));
    if( v21 != *(_QWORD *)(v22 + 8) )
      KeBugCheckEx(0x34u, (PVOID)0x1313, (PVOID)0xFFFFFFFFC0000420i64, 0i64, 0i64);
  }
  v129 = v21;
  if( v12 )
  {
    KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)(v21 + 128), &LockHandle);
    if( (*((_DWORD *)v9 + 38) & 0x20) != 0 )
    {
      LockQueue.LockQueue.Lock = (unsigned __int64 *volatile)(v21 + 192);
      LockQueue.LockQueue.Next = 0i64;
      KxAcquireQueuedSpinLock(&LockQueue.LockQueue, (UINT64 *)(v21 + 192));
      v14 = (_WORK_QUEUE_ENTRY *)*((_QWORD *)v9 + 62);
      if( !v14 )
      {
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
        KeReleaseInStackQueuedSpinLock(&LockHandle);
        KeDelayExecutionThread(0, 0, &Cc5Milliseconds);
        RtlRaiseStatus(-1073741608);
      }
      v78 = *(_QWORD *)v14;
      v79 = (_WORK_QUEUE_ENTRY **)*((_QWORD *)v14 + 1);
      if( *(_WORK_QUEUE_ENTRY **)(*(_QWORD *)v14 + 8i64) != v14 || *v79 != v14 )
        __fastfail(3u);
      *v79 = (_WORK_QUEUE_ENTRY *)v78;
      *(_QWORD *)(v78 + 8) = v79;
      *((_QWORD *)v14 + 1) = 0i64;
      *(_QWORD *)v14 = 0i64;
      *((_QWORD *)v9 + 62) = 0i64;
      *((_DWORD *)v9 + 38) &= ~0x20u;
      v88 = 1;
      KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
    }
    ++*((_DWORD *)v9 + 129);
    v95 = 1;
    KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
    __writecr8(LockHandle.OldIrql);
  }
  if( v14 )
    CcFreeWorkQueueEntry(v14);
  v23 = IoIssuerThread;
  if( !IoIssuerThread )
  {
    v23 = (_ETHREAD *)KeGetCurrentThread();
    IoIssuerThread = v23;
    v13 = 0;
  }
  WorkOnBehalfThread = (UINT64)v23->WorkOnBehalfThread;
  v109 = 0;
  if( !WorkOnBehalfThread )
    goto LABEL_20;
  if( v23 != (_ETHREAD *)KeGetCurrentThread() )
  {
    v76 = (unsigned __int8)ExAcquireSpinLockShared(&PspThreadWorkOnBehalfLock);
    WorkOnBehalfThread = (UINT64)v23->WorkOnBehalfThread;
    if( WorkOnBehalfThread )
    {
      ObfReferenceObjectWithTag(v23->WorkOnBehalfThread, 0x746C6644ui64);
      v109 = 1;
    }
    ExReleaseSpinLockSharedFromDpcLevel((PEX_SPIN_LOCK)&PspThreadWorkOnBehalfLock);
    __writecr8(v76);
  }
  v13 = 0;
  if( WorkOnBehalfThread )
    Process = *(_EPROCESS **)(WorkOnBehalfThread + 544);
  else
LABEL_20:
    Process = v23->Tcb.Process;
  if( Process->DiskIoAttribution )
  {
    v74 = (unsigned __int8)ExAcquireSpinLockShared((INT64 *)&stru_140C452E0 + 139);
    DiskIoAttribution = (volatile signed __int64 *)Process->DiskIoAttribution;
    if( DiskIoAttribution )
    {
      if( _InterlockedIncrement64(DiskIoAttribution + 4) <= 1 )
        __fastfail(0xEu);
      IoAttributionContext = (VOID *)DiskIoAttribution;
      v13 = 0;
    }
    ExReleaseSpinLockSharedFromDpcLevel((PEX_SPIN_LOCK)&stru_140C452E0 + 278);
    __writecr8(v74);
    if( DiskIoAttribution )
      v26 = 0;
    else
      v26 = -1073741275;
  }
  else
  {
    v26 = -1073741275;
  }
  if( v109 )
    ObDereferenceObjectDeferDelete(WorkOnBehalfThread);
  Offset_4 = v26;
  if( v26 >= 0 )
  {
    MmUpdateSectionIoAttribution(FileObject->SectionObjectPointer, IoAttributionContext);
    IoDiskIoAttributionDereference(IoAttributionContext);
  }
  v27 = Vacb;
  LODWORD(v28) = Lengtha;
  while( er8 )
  {
    if( v89 )
    {
      v29 = 0;
      LODWORD(OptimizeFlags) = 0;
    }
    else
    {
      v29 = OptimizeFlags;
    }
    LODWORD(Lengtha) = 0;
    LODWORD(PerformingReadAhead) = 0;
    LODWORD(RequestHighPriorityMapping) = 0;
    VirtualAddress = (char *)CcGetVirtualAddress(
                               v9,
                               (_LARGE_INTEGER)ReceivedLength_4,
                               &Vacb,
                               (UINT64 *)&ReceivedLength,
                               RequestHighPriorityMapping,
                               PerformingReadAhead);
    v104 = VirtualAddress;
    v31 = ReceivedLength;
    if( ReceivedLength > er8 )
    {
      v31 = er8;
      ReceivedLength = er8;
    }
    LODWORD(Lengtha) = v31;
    er8 -= v31;
    v32 = Offset;
    v33 = &VirtualAddress[-Offset];
    v104 = v33;
    v34 = Offset + v31;
    v106 = v34;
    ReceivedLength = v34;
    v35 = 1;
    v103 = 1;
    HIDWORD(v112) = HIDWORD(ReceivedLength_4);
    v36 = ReceivedLength_4 - Offset;
    LODWORD(v112) = ReceivedLength_4 - Offset;
    v87 = 0;
    v86 = 0;
    v37 = v34;
    while( 1 )
    {
      ReturnResult = 1;
      v38 = v37 > 0x1000;
      Flags_4 = v37 > 0x1000;
      v125 = Flags_4;
      Offset_4 = 0;
      if( (v35 & v29) != 0 )
      {
        if( v112 >= ValidDataLength->QuadPart )
        {
          v13 |= 1u;
          v91 = v13;
        }
        v39 = *((_DWORD *)v9 + 38);
        if( (v39 & 0x40) != 0 )
        {
          v13 |= 2u;
          v91 = v13;
        }
        if( (v39 & 0x40000000) != 0 )
        {
          v63 = 0;
          if( v37 <= 0x1000 )
            v63 = v34;
          if( (((unsigned __int8)v32 | (unsigned __int8)(v63 - v32)) & 0x3F) != 0 )
          {
            v13 &= 0xFFFFFFF3;
            v91 = v13;
            v86 = 1;
          }
          else
          {
            v13 |= 4u;
            v91 = v13;
            if( v85 )
            {
              v13 |= 8u;
              v91 = v13;
            }
          }
        }
        v40 = 4096;
        if( v37 <= 0x1000 )
          v40 = v34;
        v41 = v40 - v32;
        v42 = v13;
        v120 = v13;
        v43 = 0;
        v119 = 0;
        v44 = 1;
        v121 = 1;
        while( v44 <= 2 )
        {
          LODWORD(RequestHighPriorityMapping) = v42;
          v45 = MmCopyToCachedPage(v33, UserBuffer, v32, v41, RequestHighPriorityMapping);
          v43 = v45;
          v119 = v45;
          if( (v42 & 8) == 0 || v45 != -1073741670 )
          {
            v32 = Offset;
            break;
          }
          v42 &= 0xFFFFFFF3;
          v120 = v42;
          v121 = ++v44;
          v32 = Offset;
          v33 = (char *)v104;
        }
        v93 = (v42 & 4) == 0;
        Offset_4 = v43;
        if( v43 < 0 )
        {
          FsRtlIsNtstatusExpected((unsigned int)v43);
          v64 = -1073741592;
          if( v65 )
            v64 = v43;
          RtlRaiseStatus(v64);
        }
        v87 = 1;
        if( !v86 )
          v86 = (v42 & 4) == 0;
        v9 = SharedCacheMap;
      }
      else
      {
        if( v37 > 0x1000 && (v29 & 4) != 0 )
        {
          v62 = CurrentThread;
          CurrentThread->CacheManagerActive = 1;
          if( !v62->ReadClusterSize )
            v62->ReadClusterSize = 1;
        }
        MmCheckCachedPageStates(v33, 1ui64, Flags, &ReturnResult);
        v126 = v48;
        if( !ReturnResult && !Wait )
        {
          v96 = 0;
          v27 = Vacb;
          v23 = IoIssuerThread;
          LODWORD(v28) = Lengtha;
          goto LABEL_122;
        }
        v49 = 0i64;
        v122 = 0i64;
        v50 = 0i64;
        v127 = 0i64;
        LODWORD(v110) = 0;
        if( v48 < 0 )
          RtlRaiseStatus(v48);
        v51 = v89;
        if( v89 )
        {
          v66 = v34;
          if( v38 )
            v66 = 4096i64;
          v50 = CcLockSystemCacheBuffer(v104, &v122, v66, 1i64, &v110);
          v127 = v50;
          if( !v50 )
            RtlRaiseStatus(v110);
          v49 = v122;
          v51 = v89;
        }
        if( v51 )
          v52 = (_MMPTE *)(Offset + v50);
        else
          v52 = (_MMPTE *)((char *)v104 + Offset);
        if( v38 )
          v53 = 4096;
        else
          v53 = v34;
        v54 = v53 - Offset;
        v55 = 0;
        HIDWORD(v110) = 0;
        v56 = (*((_DWORD *)v9 + 38) & 0x40000000) != 0;
        if( v51 )
        {
          if( (*((_DWORD *)v9 + 38) & 0x40000000) != 0 )
          {
            HviCopyMemoryNonTemporal(v52, (UINT64)UserBuffer, (_MEMORY_CACHING_TYPE)v54);
            v55 = v59;
            HIDWORD(v110) = v59;
          }
          else
          {
            HviCopyMemory((INT64)v52, (INT64)UserBuffer, v54);
          }
        }
        else if( (*((_DWORD *)v9 + 38) & 0x40000000) != 0 )
        {
          LODWORD(RequestHighPriorityMapping) = 2;
          v55 = RtlWriteNonVolatileMemory(
                  (PVOID)0xFFFFFFFFFFFFFFFFi64,
                  v52,
                  (UINT8 *)UserBuffer,
                  v54,
                  RequestHighPriorityMapping);
          HIDWORD(v110) = v55;
        }
        else
        {
          memmove(v52, UserBuffer, v54);
        }
        if( v55 < 0 )
          RtlRaiseStatus(v55);
        v93 = !v56;
        v87 = 1;
        if( !v86 )
          v86 = !v56;
        if( v49 )
        {
          MmUnlockPages((INT64)v49, v57, v58);
          IoFreeMdl(v49);
          v122 = 0i64;
        }
        v60 = v107;
        v61 = CurrentThread;
        CurrentThread->CacheManagerActive = v107 & 3;
        v61->ReadClusterSize = v60 >> 2;
        v32 = Offset;
      }
      UserBuffer = (char *)UserBuffer + 4096 - v32;
      v32 = 0;
      Offset = 0;
      if( !Flags_4 )
        break;
      v33 = (char *)v104 + 4096;
      v104 = (char *)v104 + 4096;
      v34 = v106 - 4096;
      v106 = v34;
      v37 = v34;
      ReceivedLength = v34;
      v36 += 4096;
      LODWORD(v112) = v36;
      if( er8 )
      {
        v35 = 2;
      }
      else if( v34 <= 0x1000 )
      {
        v35 = 4;
      }
      else
      {
        v35 = 2;
      }
      v103 = v35;
      v29 = OptimizeFlags;
    }
    v87 = 0;
    v46 = Vacb->SharedCacheMap;
    if( !(unsigned __int16)_InterlockedDecrement((volatile signed __int32 *)&Vacb->Overlay) )
    {
      v47 = (_KEVENT *)*((_QWORD *)v46 + 23);
      if( v47 )
        KeSetEvent(v47, 0, 0);
      _InterlockedDecrement((volatile signed __int32 *)v46 + 136);
    }
    v27 = 0i64;
    Vacb = 0i64;
    v23 = IoIssuerThread;
    v28 = (unsigned int)Lengtha;
    CcSetDirtyInMask(v9, (_LARGE_INTEGER *)&ReceivedLength_4, (unsigned int)Lengtha, &IoIssuerThread->Tcb);
    if( (*((_DWORD *)v9 + 38) & 0x40000000) == 0 && v108 - er8 > 0x1000000
      || (*((_DWORD *)v9 + 38) & 0x40000000) != 0 && v86 )
    {
      CcFlushCachePriv(
        FileObject->SectionObjectPointer,
        (_LARGE_INTEGER *)&ReceivedLength_4,
        (unsigned int)v28,
        0i64,
        v85,
        &IoStatus);
      Status = IoStatus.Status;
      if( IoStatus.Status < 0 )
      {
        FsRtlIsNtstatusExpected((unsigned int)IoStatus.Status);
        v68 = -1073741591;
        if( v69 )
          v68 = Status;
        RtlRaiseStatus(v68);
      }
    }
    if( er8 >= 0x1000 )
    {
      LODWORD(OptimizeFlags) = OptimizeFlags | 1;
    }
    else if( (OptimizeFlags & 4) == 0 )
    {
      LODWORD(OptimizeFlags) = 0;
    }
    ReceivedLength_4 += v28;
    v13 = v91;
  }
  v96 = 1;
LABEL_122:
  v70 = v107;
  v71 = CurrentThread;
  CurrentThread->CacheManagerActive = v107 & 3;
  v71->ReadClusterSize = v70 >> 2;
  if( v27 )
  {
    v77 = v27->SharedCacheMap;
    if( !(unsigned __int16)_InterlockedDecrement((volatile signed __int32 *)&v27->Overlay) )
    {
      v80 = (_KEVENT *)*((_QWORD *)v77 + 23);
      if( v80 )
        KeSetEvent(v80, 0, 0);
      _InterlockedDecrement((volatile signed __int32 *)v77 + 136);
    }
    LODWORD(v28) = Lengtha;
  }
  if( v87 && (_DWORD)v28 )
    CcSetDirtyInMask(v9, (_LARGE_INTEGER *)&ReceivedLength_4, (unsigned int)v28, &v23->Tcb);
  if( CcRemoteFileDPInlineFlushThreshold != -1
    && (FileObject->Flags & 0x1000000) != 0
    && !v85
    && *((_DWORD *)v9 + 28) >= (unsigned int)CcRemoteFileDPInlineFlushThreshold )
  {
    v88 = 1;
    v90 = 1;
  }
  if( v94 || v90 )
  {
    IoStatus.Status = 0;
    if( !v85 || (*((_DWORD *)v9 + 38) & 0x40000000) == 0 )
    {
      v73 = 0i64;
      if( !v88 )
        v73 = v108;
      if( !v88 )
        v11 = FileOffset;
      CcFlushCachePriv(FileObject->SectionObjectPointer, v11, v73, 0i64, v85, &IoStatus);
      LODWORD(v11) = IoStatus.Status;
    }
    if( v95 )
    {
      KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)(v128 + 128), &LockHandle);
      --*((_DWORD *)v9 + 129);
      KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
      __writecr8(LockHandle.OldIrql);
      LODWORD(v11) = IoStatus.Status;
    }
    if( (int)v11 < 0 )
    {
      FsRtlIsNtstatusExpected((unsigned int)v11);
      v82 = -1073741591;
      if( v81 )
        v82 = (int)v11;
      RtlRaiseStatus(v82);
    }
  }
  return v96;
}

Referenced by:

CcCopyWriteEx