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.