MmRotatePhysicalView

NTSTATUS __fastcall MmRotatePhysicalView(UINT64 a1, UINT64 *a2, INT64 a3, INT64 a4, INT64 CopyFunction, INT64 Context){
  int v6; 
  _MDL *v7; 
  unsigned __int64 v9; 
  _EPROCESS *v10; 
  _MMVAD_SHORT *v11; 
  UINT64 v12; 
  _MMVAD_SHORT *v13; 
  union {unsigned int LongFlags;_MMVAD_FLAGS VadFlags;_MM_PRIVATE_VAD_FLAGS PrivateVadFlags;_MM_GRAPHICS_VAD_FLAGS GraphicsVadFlags;_MM_SHARED_VAD_FLAGS SharedVadFlags;volatile unsigned int VolatileVadLong;} v14; 
  _MI_PFN_CACHE_ATTRIBUTE v15; 
  UINT64 v16; 
  UINT64 *v17; 
  UINT64 v18; 
  UINT64 v19; 
  int v20; 
  __int64 v21; 
  NTSTATUS v22; 
  UINT64 v23; 
  _MDL *Pool; 
  INT64 v25; 
  INT64 v26; 
  INT64 v27; 
  NTSTATUS v29; 
  int v30; 
  UINT64 *v31; 
  UINT64 *v32; 
  UINT64 v33; 
  int v34; 
  UINT64 v35; 
  UINT64 v36; 
  _MDL *v37; 
  __int16 v38; 
  __int16 v39; 
  unsigned __int64 v40; 
  int v41; 
  UINT64 v42; 
  _MMVAD_SHORT *v43; 
  __int64 ByteCount; 
  _MDL *v45; 
  INT64 v46; 
  unsigned __int64 v47; 
  UINT64 *v48; 
  int v49; 
  INT64 v50; 
  INT64 v51; 
  PVOID v52; 
  UINT64 Priority; 
  int v54; 
  int CacheType; 
  _MEMORY_CACHING_TYPE CacheTypea; 
  char v58[12]; 
  _MM_ROTATE_DIRECTION Direction; 
  PVOID P; 
  UINT64 SizeInBytes; 
  UINT64 QuotaCharge; 
  _MI_PARTITION *Partition; 
  UINT64 v64; 
  VOID *EndingAddress; 
  _MMVAD_SHORT *v66; 
  INT64 v67; 
  int(__fastcall *v68)(_MDL *, INT64, INT64); 
  UINT64 *v69; 
  _MI_ROTATE_BLOCK RotateBlock[4]; 
  _ETHREAD *CurrentThread; 
  char v72[192]; 
  char Mdl[192]; 

  v6 = a4;
  Direction = (int)a4;
  v7 = (_MDL *)a3;
  v9 = a1;
  P = (PVOID)a1;
  v69 = a2;
  *(_QWORD *)&v58[4] = a3;
  v68 = (int(__fastcall *)(_MDL *, INT64, INT64))CopyFunction;
  v67 = Context;
  *(_DWORD *)v58 = 0;
  *(_OWORD *)RotateBlock = 0i64;
  CurrentThread = 0i64;
  memset(v72, 0i64, 0xB8u);
  memset(Mdl, 0i64, 0xB8u);
  v11 = 0i64;
  v54 = 0;
  v12 = *a2;
  v64 = 0i64;
  if( (v9 & 0xFFF) != 0 )
  {
    v22 = -1073741585;
    goto LABEL_29;
  }
  if( (v12 & 0xFFF) != 0 )
    goto LABEL_30;
  if( v6 >= 4 )
  {
    v22 = -1073741583;
    goto LABEL_29;
  }
  EndingAddress = (VOID *)(v12 + v9 - 1);
  if( (unsigned __int64)EndingAddress <= v9 )
  {
LABEL_30:
    v22 = -1073741584;
LABEL_29:
    v30 = 0;
    goto LABEL_40;
  }
  Partition = MiGetProcessPartition(KeGetCurrentThread()->ApcState.Process, v10);
  while( 1 )
  {
    LODWORD(v13) = MiObtainReferencedVadEx(v9, 0, (INT64 *)v58);
    v11 = v13;
    v66 = v13;
    if( !v13 )
    {
      v22 = *(_DWORD *)v58;
      v30 = 0;
      if( *(_DWORD *)v58 == -1073741664 )
        v22 = -1073741819;
LABEL_40:
      v31 = a2;
      if( v11 )
        MiUnlockAndDereferenceVad(v11);
      if( v22 < 0 )
      {
        v32 = (UINT64 *)&v7[1];
        while( v30 )
        {
          v33 = *v32;
          MiIsPfn(*v32);
          if( !v34 )
          {
            MiDereferenceIoPages(1i64, v33, 1i64);
            --v30;
          }
          ++v32;
        }
        v31 = a2;
      }
      *v31 = v64;
      return v22;
    }
    v14.LongFlags = (unsigned int)v13->u;
    if( (v14.LongFlags & 0x70) != 64
      || (v13->EndingVpn | ((unsigned __int64)v13->EndingVpnHigh << 32)) < (unsigned __int64)EndingAddress >> 12 )
    {
      v22 = -1073741800;
      goto LABEL_37;
    }
    if( (v14.LongFlags & 0x380) != 0 && (v14.LongFlags & 0xC00) == 3072 )
      v15 = MiWriteCombined;
    else
      v15 = (v14.LongFlags & 0xC00) != 1024;
    CacheType = v15;
    v16 = v12;
    SizeInBytes = v12;
    QuotaCharge = v12 >> 12;
    if( v6 <= 1 )
    {
      if( v12 <= 0xFFFFFFFF )
      {
        v17 = (UINT64 *)&v7[1];
        P = &v7[1];
        v18 = 0i64;
        while( 1 )
        {
          *(_DWORD *)v58 = v18;
          if( v18 >= v12 >> 12 )
            break;
          v19 = *v17;
          MiIsPfn(*v17);
          if( v20 )
          {
            v22 = MiLegitimatePageForDriversToMap((INT64)&MmGetPfnDb()[v19]);
            if( v22 < 0 )
              goto LABEL_39;
          }
          else
          {
            LODWORD(v21) = MiSanitizePage(v19);
            v22 = MiReferenceIoPages(1u, v21, 1i64, CacheType, 0i64, 0i64);
            if( v22 < 0 )
              goto LABEL_39;
            ++v54;
          }
          v18 = (unsigned int)(*(_DWORD *)v58 + 1);
          v17 = (UINT64 *)((char *)P + 8);
          P = (char *)P + 8;
        }
        if( MiChargeCommit(Partition, v12 >> 12, 0i64) )
        {
          LODWORD(v23) = MmSizeOfMdl((PVOID)v9, v12);
          Pool = (_MDL *)MiAllocatePool(64i64, v23, 0x6F666E49ui64);
          v25 = (INT64)Pool;
          P = Pool;
          if( Pool )
          {
            Pool->Next = 0i64;
            Pool->Size = 8 * (((v12 + (v9 & 0xFFF) + 4095) >> 12) + 6);
            Pool->MdlFlags = 0;
            Pool->StartVa = (void *)(v9 & 0xFFFFFFFFFFFFF000ui64);
            Pool->ByteOffset = v9 & 0xFFF;
            Pool->ByteCount = v12;
            MmProbeAndLockPages(Pool, 3841, IoReadAccess);
            *(_QWORD *)&RotateBlock[2] = v11;
            CurrentThread = (_ETHREAD *)KeGetCurrentThread();
            MiDeleteRotateAndStopFaults((VOID *)v9, EndingAddress, RotateBlock);
            if( Direction == MmToFrameBuffer )
            {
              *(_WORD *)(v25 + 10) |= 0x2000u;
              if( v68(v7, v25, v67) < 0 )
                MiSlowRotateCopy(v7, (_MDL *)v25, v11);
            }
            LODWORD(Priority) = 16;
            MiMapLockedPagesInUserSpaceHelper(
              (VOID *)v9,
              (UINT64 *)&v7[1],
              (UINT64 *)(v25 + 48),
              (_MEMORY_CACHING_TYPE)CacheType,
              v12 >> 12,
              0i64,
              Priority);
            MiRotateComplete(RotateBlock);
            MiUnlockAndDereferenceVad(v11);
            MmUnlockPages(v25, v26, v27);
            ExFreePoolWithTag((PVOID)v25, 0);
            *a2 = v12;
            return 0;
          }
          MiReturnCommit(Partition, v12 >> 12);
        }
        v22 = -1073741670;
LABEL_39:
        v30 = v54;
        goto LABEL_40;
      }
      v22 = -1073741306;
LABEL_37:
      v30 = 0;
      goto LABEL_40;
    }
    if( v6 == 3 )
      break;
    if( v12 > 0x10000 )
    {
      if( v12 <= 0xFFFFFFFF
        && (LODWORD(v35) = MmSizeOfMdl((PVOID)v9, v12),
            (*(_QWORD *)&v58[4] = MiAllocatePool(64i64, v35, 0x6F666E49ui64)) != 0i64) )
      {
        v16 = SizeInBytes;
      }
      else
      {
        *(_QWORD *)&v58[4] = v72;
        v16 = 0x10000i64;
        SizeInBytes = 0x10000i64;
      }
    }
    else
    {
      *(_QWORD *)&v58[4] = v72;
    }
    if( v16 > 0x10000 )
    {
      LODWORD(v36) = MmSizeOfMdl((PVOID)v9, v16);
      v7 = (_MDL *)MiAllocatePool(64i64, v36, 0x6F666E49ui64);
      if( v7 )
      {
        v16 = SizeInBytes;
      }
      else
      {
        v7 = (_MDL *)Mdl;
        v16 = 0x10000i64;
        SizeInBytes = 0x10000i64;
      }
    }
    else
    {
      v7 = (_MDL *)Mdl;
    }
    v37 = *(_MDL **)&v58[4];
    **(_QWORD **)&v58[4] = 0i64;
    v38 = v9;
    v39 = 8 * (((v16 + (v9 & 0xFFF) + 4095) >> 12) + 6);
    v37->Size = v39;
    v37->MdlFlags = 0;
    v40 = v9 & 0xFFFFFFFFFFFFF000ui64;
    v37->StartVa = (void *)v40;
    v41 = v38 & 0xFFF;
    v37->ByteOffset = v41;
    v37->ByteCount = v16;
    MmBuildMdlForNonPagedPool(v37);
    *(_WORD *)(*(_QWORD *)&v58[4] + 10i64) |= 0x2000u;
    v7->Next = 0i64;
    v7->Size = v39;
    v7->StartVa = (void *)v40;
    v7->ByteOffset = v41;
    v42 = SizeInBytes;
    v7->ByteCount = SizeInBytes;
    v7->MdlFlags = 0x2000;
    v43 = v66;
    CacheTypea = MiSwitchToTransition(v7, v66, (_MMVAD_SHORT *)(unsigned int)CacheType);
    ByteCount = v7->ByteCount;
    v45 = *(_MDL **)&v58[4];
    if( ByteCount != v42 )
    {
      SizeInBytes = v7->ByteCount;
      *(_DWORD *)(*(_QWORD *)&v58[4] + 40i64) = ByteCount;
      LODWORD(ByteCount) = v7->ByteCount;
    }
    if( (_DWORD)ByteCount )
    {
      *(_DWORD *)v58 = v68(v7, (INT64)v45, v67);
      if( *(int *)v58 < 0 )
        MiSlowRotateCopy(v7, v45, v43);
      MiMarkMdlComplete(v7, v43, v46);
      v47 = (unsigned __int64)v45->ByteCount >> 12;
      v48 = (UINT64 *)&v45[1];
      while( v47 )
      {
        QuotaCharge = *v48;
        MiIsPfn(QuotaCharge);
        if( !v49 )
          MiDereferenceIoPages(1i64, QuotaCharge, 1i64);
        ++v48;
        --v47;
      }
      v45 = *(_MDL **)&v58[4];
    }
    MiUnlockAndDereferenceVad(v43);
    v11 = 0i64;
    v52 = P;
    if( v45 != (_MDL *)v72 )
      ExFreePoolWithTag(v45, 0);
    if( v7->ByteCount )
      MmUnlockPages((INT64)v7, v50, v51);
    if( v7 != (_MDL *)Mdl )
      ExFreePoolWithTag(v7, 0);
    v64 += SizeInBytes;
    v9 = (unsigned __int64)v52 + SizeInBytes;
    P = (PVOID)v9;
    if( CacheTypea == MmCached )
    {
      v22 = 1073741849;
      goto LABEL_29;
    }
    v12 -= SizeInBytes;
    if( !v12 )
    {
      v22 = 0;
      v30 = 0;
      goto LABEL_40;
    }
    v7 = 0i64;
    *(_QWORD *)&v58[4] = 0i64;
  }
  v29 = MiReplaceRotateWithDemandZero((VOID *)v9, EndingAddress, v15);
  MiUnlockAndDereferenceVad(v11);
  *a2 = v12;
  if( v29 != 1 )
    return 0;
  return 1073741849;
}

Referenced by:

No references.