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.