MiCopyToUserVa
INT64 __fastcall MiCopyToUserVa(VOID *Va, _MMVAD *Vad, VOID *SourceAddress, UINT64 NumberOfBytes){
__int64 v4;
unsigned __int64 v5;
int v6;
unsigned int v7;
UINT8 v8;
UINT8 v9;
unsigned __int64 v10;
UNICODE_STRING *v11;
UINT8 v12;
PWCHAR v13;
int v14;
__int64 v15;
_QWORD *CloneAddress;
int v17;
INT64 v18;
UINT8 *v19;
UINT8 *v20;
UINT8 i;
int v23;
INT64 ValidPte;
INT64 v25;
UINT64 v26;
_QWORD *v27;
INT64 v28;
__int64 v29;
v4 = *((_QWORD *)KeGetCurrentThread() + 23);
v29 = v4;
v5 = (unsigned __int64)MmGetPteBase() + (((unsigned __int64)Va >> 9) & 0x7FFFFFFFF8i64);
v25 = v5;
v6 = 0;
v23 = 0;
v7 = (*((_DWORD *)Vad + 12) >> 12) & 0x3F;
LABEL_2:
v8 = MiLockWorkingSetShared(v4 + 1664);
LABEL_3:
v9 = v8;
for( i = v8; ; v9 = i )
{
v26 = (UINT64)MmGetPteBase() + ((v5 >> 9) & 0x7FFFFFFFF8i64);
MiMakeSystemAddressValid(v5, 0i64, v7, v9, 0);
ValidPte = MI_READ_PTE_LOCK_FREE(v5);
if( (ValidPte & 1) == 0 )
{
MiUnlockPageTable(v4 + 1664, v26);
MiUnlockWorkingSetShared(v4 + 1664, i);
goto LABEL_2;
}
v10 = ((unsigned __int64)MI_READ_PTE_LOCK_FREE((INT64)&ValidPte) >> 12) & 0xFFFFFFFFFi64;
v28 = (INT64)MmGetPfnDb() + 48 * v10;
LOBYTE(v14) = MI_PFN_IS_PROTO((UNICODE_STRING *)v28, v11, v12, v13);
if( !v14 )
break;
v27 = 0i64;
if( (*(_QWORD *)(v15 + 40) & 0x1000000000i64) != 0 || *(__int64 *)(v15 + 8) <= 0 )
{
if( *(_QWORD *)(v4 + 1264) )
{
CloneAddress = MiLocateCloneAddress(v4, *(_QWORD *)(v15 + 8) | 0x8000000000000000ui64);
v27 = CloneAddress;
if( CloneAddress )
{
if( *(_QWORD *)(*(_QWORD *)(v4 + 1680) + 360i64) <= CloneAddress[12] )
{
v27 = 0i64;
}
else if( !v6 )
{
MiUnlockPageTable(v4 + 1664, v26);
MiUnlockWorkingSetShared(v4 + 1664, i);
v17 = MiChargeFullProcessCommitment(v4, 1ui64);
if( v17 < 0 )
goto LABEL_30;
v6 = 1;
v23 = 1;
v8 = MiLockWorkingSetShared(v4 + 1664);
v5 = v25;
goto LABEL_3;
}
}
}
}
v5 = v25;
LODWORD(ValidPte) = MiCopyOnWrite((UINT64)Va, (UINT64 *)v25, -1i64, 0i64);
if( (int)ValidPte >= 0 )
{
ValidPte = MI_READ_PTE_LOCK_FREE(v5);
v10 = ((unsigned __int64)MI_READ_PTE_LOCK_FREE((INT64)&ValidPte) >> 12) & 0xFFFFFFFFFi64;
v28 = (INT64)MmGetPfnDb() + 48 * v10;
if( v27 )
v6 = 0;
v23 = v6;
break;
}
MiUnlockPageTable(v4 + 1664, v26);
MiUnlockWorkingSetShared(v4 + 1664, i);
MiCopyOnWriteCheckConditions(v4 + 1664, (unsigned int)ValidPte);
MiLockWorkingSetShared(v4 + 1664);
}
v18 = MiReservePtes((INT64)&qword_140C4EC80, 1ui64);
if( v18 )
{
v25 = ((v18 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
ValidPte = MiMakeValidPte(v18, v10, 2684354564i64);
*(_QWORD *)v18 = ValidPte;
v20 = (UINT8 *)v25;
}
else
{
LODWORD(v19) = MiMapPageInHyperSpaceWorker(v10, 0i64, 0x80000000ui64);
v20 = v19;
}
memmove(&v20[(unsigned __int16)Va & 0xFFF], (UINT8 *)SourceAddress, NumberOfBytes);
if( v18 )
MiReleasePtes((INT64)&qword_140C4EC80, v18, 1ui64);
else
MiUnmapPageInHyperSpaceWorker(v20, 0x11u, 0x80000000ui64);
MiLockPageAndSetDirty(v28, 1i64);
if( v26 )
MiUnlockPageTable(v4 + 1664, v26);
MiUnlockWorkingSetShared(v4 + 1664, i);
v17 = 0;
v6 = v23;
LABEL_30:
if( v6 )
MiReturnFullProcessCommitment(v4, 1ui64);
return(unsigned int)v17;
}Referenced by:
MiCopyToCfgBitMap