MmRotatePhysicalView

NTSTATUS __stdcall MmRotatePhysicalView(
        PVOID VirtualAddress,
        PSIZE_T NumberOfBytes,
        PMDL NewMdl,
        MM_ROTATE_DIRECTION Direction,
        PMM_ROTATE_COPY_CALLBACK_FUNCTION CopyFunction,
        PVOID Context){
  PMDL p_Mdl; 
  unsigned __int64 v9; 
  void *v10; 
  ULONG_PTR v11; 
  _MI_PARTITION *v12; 
  INT64 v13; 
  int v14; 
  _MEMORY_CACHING_TYPE v15; 
  UINT64 v16; 
  UINT64 *v17; 
  ULONG_PTR v18; 
  UINT64 v19; 
  INT64 v20; 
  NTSTATUS v21; 
  _MDL *v22; 
  __int64 v23; 
  int v25; 
  int v26; 
  PSIZE_T v27; 
  UINT64 *v28; 
  UINT64 v29; 
  struct _MDL *v30; 
  struct _MDL *v31; 
  PMDL v32; 
  __int16 v33; 
  __int16 v34; 
  unsigned __int64 v35; 
  int v36; 
  UINT64 v37; 
  _MMVAD_SHORT *v38; 
  __int64 ByteCount; 
  PMDL v40; 
  unsigned __int64 v41; 
  UINT64 *v42; 
  PVOID v43; 
  UINT64 Priority; 
  int v45; 
  unsigned int a4; 
  int a4_4; 
  PMDL MemoryDescriptorList; 
  MM_ROTATE_DIRECTION Directiona; 
  PVOID P; 
  UINT64 SizeInBytes; 
  UINT64 QuotaCharge; 
  _MI_PARTITION *Partition; 
  ULONG_PTR v55; 
  UINT64 v56; 
  PVOID v57; 
  PVOID v58; 
  PMM_ROTATE_COPY_CALLBACK_FUNCTION v59; 
  PSIZE_T v60; 
  __int128 v61; 
  _ETHREAD *CurrentThread; 
  INT64 result[24]; 
  MDL Mdl; 
  Directiona = Direction;
  p_Mdl = NewMdl;
  v9 = (unsigned __int64)VirtualAddress;
  P = VirtualAddress;
  v60 = NumberOfBytes;
  MemoryDescriptorList = NewMdl;
  v59 = CopyFunction;
  v58 = Context;
  a4_4 = 0;
  v61 = 0i64;
  CurrentThread = 0i64;
  memset((INT64)result, 0i64);
  memset((INT64)&Mdl, 0i64);
  v10 = 0i64;
  v45 = 0;
  v11 = *NumberOfBytes;
  v55 = 0i64;
  if( (v9 & 0xFFF) != 0 )
  {
    v21 = -1073741585;
    goto LABEL_29;
  }
  if( (v11 & 0xFFF) != 0 )
    goto LABEL_30;
  if( Direction >= MmMaximumRotateDirection )
  {
    v21 = -1073741583;
    goto LABEL_29;
  }
  v56 = v11 + v9 - 1;
  if( v56 <= v9 )
  {
LABEL_30:
    v21 = -1073741584;
LABEL_29:
    v26 = 0;
    goto LABEL_40;
  }
  MiGetProcessPartition(*((_EPROCESS **)KeGetCurrentThread() + 23));
  Partition = v12;
  while( 1 )
  {
    v13 = MiObtainReferencedVadEx(v9, 0, (INT64 *)&a4_4);
    v10 = (void *)v13;
    v57 = (PVOID)v13;
    if( !v13 )
    {
      v21 = a4_4;
      v26 = 0;
      if( a4_4 == -1073741664 )
        v21 = -1073741819;
LABEL_40:
      v27 = NumberOfBytes;
      if( v10 )
        MiUnlockAndDereferenceVad(v10);
      if( v21 < 0 )
      {
        v28 = (UINT64 *)&p_Mdl[1];
        while( v26 )
        {
          v29 = *v28;
          if( !(unsigned int)MiIsPfn(*v28) )
          {
            MiDereferenceIoPages(1i64, v29, 1i64);
            --v26;
          }
          ++v28;
        }
        v27 = NumberOfBytes;
      }
      *v27 = v55;
      return v21;
    }
    v14 = *(_DWORD *)(v13 + 48);
    if( (v14 & 0x70) != 64
      || (*(unsigned int *)(v13 + 28) | ((unsigned __int64)*(unsigned __int8 *)(v13 + 33) << 32)) < v56 >> 12 )
    {
      v21 = -1073741800;
      goto LABEL_37;
    }
    if( (v14 & 0x380) != 0 && (v14 & 0xC00) == 3072 )
      v15 = MmWriteCombined;
    else
      v15 = (v14 & 0xC00) != 1024;
    a4 = v15;
    v16 = v11;
    SizeInBytes = v11;
    QuotaCharge = v11 >> 12;
    if( Direction <= MmToFrameBufferNoCopy )
    {
      if( v11 <= 0xFFFFFFFF )
      {
        v17 = (UINT64 *)&p_Mdl[1];
        P = &p_Mdl[1];
        v18 = 0i64;
        while( 1 )
        {
          a4_4 = v18;
          if( v18 >= v11 >> 12 )
            break;
          v19 = *v17;
          if( (unsigned int)MiIsPfn(*v17) )
          {
            v21 = MiLegitimatePageForDriversToMap((INT64)MmGetPfnDb() + 48 * v19);
            if( v21 < 0 )
              goto LABEL_39;
          }
          else
          {
            v20 = MiSanitizePage(v19);
            v21 = MiReferenceIoPages(1ui64, v20, 1i64, a4, 0i64, 0i64);
            if( v21 < 0 )
              goto LABEL_39;
            ++v45;
          }
          v18 = (unsigned int)(a4_4 + 1);
          v17 = (UINT64 *)((char *)P + 8);
          P = (char *)P + 8;
        }
        if( (unsigned int)MiChargeCommit(Partition, v11 >> 12, 0i64) )
        {
          MmSizeOfMdl((PVOID)v9, v11);
          LODWORD(v22) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
          v23 = (__int64)v22;
          P = v22;
          if( v22 )
          {
            v22->Next = 0i64;
            v22->Size = 8 * (((v11 + (v9 & 0xFFF) + 4095) >> 12) + 6);
            v22->MdlFlags = 0;
            v22->StartVa = (void *)(v9 & 0xFFFFFFFFFFFFF000ui64);
            v22->ByteOffset = v9 & 0xFFF;
            v22->ByteCount = v11;
            MmProbeAndLockPages(v22, 1, IoReadAccess);
            *((_QWORD *)&v61 + 1) = v10;
            CurrentThread = (_ETHREAD *)KeGetCurrentThread();
            MiDeleteRotateAndStopFaults(v9, v56, &v61);
            if( Directiona == MmToFrameBuffer )
            {
              *(_WORD *)(v23 + 10) |= 0x2000u;
              if( ((int(__fastcall *)(PMDL, __int64, PVOID))v59)(p_Mdl, v23, v58) < 0 )
                MiSlowRotateCopy((__int64)p_Mdl, v23, (__int64)v10);
            }
            LODWORD(Priority) = 16;
            MiMapLockedPagesInUserSpaceHelper(
              (VOID *)v9,
              (UINT64 *)&p_Mdl[1],
              (UINT64 *)(v23 + 48),
              (_MEMORY_CACHING_TYPE)a4,
              v11 >> 12,
              0i64,
              Priority);
            MiRotateComplete(&v61);
            MiUnlockAndDereferenceVad(v10);
            MmUnlockPages((_MDL *)v23);
            ExFreePoolWithTag((PVOID)v23, 0);
            *NumberOfBytes = v11;
            return 0;
          }
          MiReturnCommit(Partition, v11 >> 12);
        }
        v21 = -1073741670;
LABEL_39:
        v26 = v45;
        goto LABEL_40;
      }
      v21 = -1073741306;
LABEL_37:
      v26 = 0;
      goto LABEL_40;
    }
    if( Direction == MmToRegularMemoryNoCopy )
      break;
    if( v11 > 0x10000 )
    {
      if( v11 <= 0xFFFFFFFF
        && (MmSizeOfMdl((PVOID)v9, v11),
            LODWORD(v30) = MiAllocatePool((struct _SLIST_ENTRY *)0x40),
            (MemoryDescriptorList = v30) != 0i64) )
      {
        v16 = SizeInBytes;
      }
      else
      {
        MemoryDescriptorList = (PMDL)result;
        v16 = 0x10000i64;
        SizeInBytes = 0x10000i64;
      }
    }
    else
    {
      MemoryDescriptorList = (PMDL)result;
    }
    if( v16 > 0x10000 )
    {
      MmSizeOfMdl((PVOID)v9, v16);
      LODWORD(v31) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
      p_Mdl = v31;
      if( v31 )
      {
        v16 = SizeInBytes;
      }
      else
      {
        p_Mdl = &Mdl;
        v16 = 0x10000i64;
        SizeInBytes = 0x10000i64;
      }
    }
    else
    {
      p_Mdl = &Mdl;
    }
    v32 = MemoryDescriptorList;
    MemoryDescriptorList->Next = 0i64;
    v33 = v9;
    v34 = 8 * (((v16 + (v9 & 0xFFF) + 4095) >> 12) + 6);
    v32->Size = v34;
    v32->MdlFlags = 0;
    v35 = v9 & 0xFFFFFFFFFFFFF000ui64;
    v32->StartVa = (void *)v35;
    v36 = v33 & 0xFFF;
    v32->ByteOffset = v36;
    v32->ByteCount = v16;
    MmBuildMdlForNonPagedPool(v32);
    MemoryDescriptorList->MdlFlags |= 0x2000u;
    p_Mdl->Next = 0i64;
    p_Mdl->Size = v34;
    p_Mdl->StartVa = (void *)v35;
    p_Mdl->ByteOffset = v36;
    v37 = SizeInBytes;
    p_Mdl->ByteCount = SizeInBytes;
    p_Mdl->MdlFlags = 0x2000;
    v38 = (_MMVAD_SHORT *)v57;
    a4 = MiSwitchToTransition(p_Mdl, (INT64)v57, a4);
    ByteCount = p_Mdl->ByteCount;
    v40 = MemoryDescriptorList;
    if( ByteCount != v37 )
    {
      SizeInBytes = p_Mdl->ByteCount;
      MemoryDescriptorList->ByteCount = ByteCount;
      LODWORD(ByteCount) = p_Mdl->ByteCount;
    }
    if( (_DWORD)ByteCount )
    {
      a4_4 = ((__int64(__fastcall *)(PMDL, PMDL, PVOID))v59)(p_Mdl, v40, v58);
      if( a4_4 < 0 )
        MiSlowRotateCopy((__int64)p_Mdl, (__int64)v40, (__int64)v38);
      MiMarkMdlComplete(p_Mdl, v38);
      v41 = (unsigned __int64)v40->ByteCount >> 12;
      v42 = (UINT64 *)&v40[1];
      while( v41 )
      {
        QuotaCharge = *v42;
        if( !(unsigned int)MiIsPfn(QuotaCharge) )
          MiDereferenceIoPages(1i64, QuotaCharge, 1i64);
        ++v42;
        --v41;
      }
      v40 = MemoryDescriptorList;
    }
    MiUnlockAndDereferenceVad(v38);
    v10 = 0i64;
    v43 = P;
    if( v40 != (PMDL)result )
      ExFreePoolWithTag(v40, 0);
    if( p_Mdl->ByteCount )
      MmUnlockPages(p_Mdl);
    if( p_Mdl != &Mdl )
      ExFreePoolWithTag(p_Mdl, 0);
    v55 += SizeInBytes;
    v9 = (unsigned __int64)v43 + SizeInBytes;
    P = (PVOID)v9;
    if( a4 == 1 )
    {
      v21 = 1073741849;
      goto LABEL_29;
    }
    v11 -= SizeInBytes;
    if( !v11 )
    {
      v21 = 0;
      v26 = 0;
      goto LABEL_40;
    }
    p_Mdl = 0i64;
    MemoryDescriptorList = 0i64;
  }
  v25 = MiReplaceRotateWithDemandZero(v9, v56, (unsigned int)v15);
  MiUnlockAndDereferenceVad(v10);
  *NumberOfBytes = v11;
  if( v25 != 1 )
    return 0;
  return 1073741849;
}

Referenced by:

No references.