MiOutSwapWorkingSetPte
NTSTATUS __stdcall MiOutSwapWorkingSetPte(INT64 a1, UINT64 a2, INT64 a3){
__int64 v3;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v5;
unsigned __int64 Long;
char v7;
_MMPFN *v8;
unsigned __int64 v9;
_UNICODE_STRING *v10;
UINT8 v11;
wchar_t *v12;
unsigned __int64 v13;
_MMPFN *v14;
char v15;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v16;
UINT8 v17;
char v18;
unsigned __int64 v19;
int v20;
unsigned __int64 v21;
int v22;
_MMPTE *PteBase;
_QWORD *v24;
_MIPFNBLINK *p_u2;
struct {unsigned __int16 ReferenceCount;} *v26;
_MMPTE *p_OriginalPte;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v28;
_MMPTE *v29;
unsigned __int8 ReferenceCount;
char v31;
unsigned __int8 v32;
char v33;
_MI_PARTITION *v34;
__int64 v35;
_MMPAGING_FILE *v36;
unsigned __int64 v37;
__int16 bf_cc;
unsigned __int64 v39;
unsigned __int64 v40;
unsigned int v41;
__int64 v42;
unsigned __int64 v43;
__int64 v44;
bool v45;
unsigned __int64 v46;
__int64 *v47;
__int64 v48;
__int64 v49;
__int64 *v50;
unsigned __int64 v51;
_MI_PARTITION *Partition;
__int64 v54;
UINT64 SpinCount;
unsigned __int64 v56;
v3 = *(_QWORD *)(a1 + 168);
v54 = *(_QWORD *)(v3 + 16);
if( (_DWORD)a3 )
return 0;
v5.Long = 0i64;
Long = 0i64;
v7 = 0;
v8 = 0i64;
Partition = *(_MI_PARTITION **)(v3 + 24);
while( 1 )
{
LODWORD(v9) = MI_READ_PTE_LOCK_FREE(a2);
v13 = v9;
v56 = v9;
if( (v9 & 1) != 0 )
break;
if( (v9 & 0x400) != 0 )
goto LABEL_93;
if( (v9 & 0x800) == 0 )
{
if( (v9 & 2) != 0 )
{
v18 = v9 & 0xFD;
v56 = v9 & 0xFFFFFFFFFFFFFFFDui64;
v19 = v9 & 0xFFFFFFFFFFFFFFFDui64;
LOBYTE(v20) = MiPteInShadowRange(a2);
if( v20 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v18 & 1) != 0 )
v19 = v13 & 0x7FFFFFFFFFFFFFFDi64 | 0x8000000000000000ui64;
*(_QWORD *)a2 = v19;
Long = v13;
}
goto LABEL_93;
}
v14 = MiLockTransitionLeafPage(a2, 0i64);
v8 = v14;
if( v14 )
{
v15 = *((_BYTE *)&v14->u3 + 2);
v7 = 1;
if( (v15 & 0x28) == 0 )
{
v16.Long = (unsigned __int64)v8->OriginalPte.u;
if( (v16.Long & 2) != 0 )
{
Long = v8->OriginalPte.u.Long;
if( v8->u3.ReferenceCount || (v15 & 7) != 3 )
{
v8->OriginalPte.u.Long = v16.Long & 0xFFFFFFFFFFFFFFFDui64;
}
else
{
MiUnlinkPageFromList(v8, 0i64);
v8->OriginalPte.u.Long &= ~2ui64;
MiInsertPageInList(v8, 8ui64, v17);
}
}
}
goto LABEL_93;
}
}
v21 = 48 * ((v9 >> 12) & 0xFFFFFFFFFi64);
if( (((unsigned __int64)MmGetPfnDb()[v21 / 0x30].u4._bf_0 >> 50) & 1) == 0 )
goto LABEL_93;
v8 = &MmGetPfnDb()[v21 / 0x30];
LOBYTE(v22) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v8, v10, v11, v12);
PteBase = MmGetPteBase();
if( v22 )
{
v24 = *(_QWORD **)(v3 + 8);
if( !v24 )
goto LABEL_93;
}
else
{
if( (MmGetPfnDb()[v21 / 0x30].PteLong | 0x8000000000000000ui64) != a2 )
goto LABEL_93;
v7 = 1;
LODWORD(SpinCount) = 0;
p_u2 = &MmGetPfnDb()->u2;
if( _interlockedbittestandset64((volatile signed __int32 *)&p_u2[v21 / 8], 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( p_u2[v21 / 8]._bf_0 < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)&p_u2[v21 / 8], 0x3Fui64) );
PteBase = MmGetPteBase();
}
v26 = &MmGetPfnDb()->u3 + 1;
if( (v26[v21 / 2].ReferenceCount & 8) != 0 )
goto LABEL_93;
p_OriginalPte = &MmGetPfnDb()->OriginalPte;
v28.Long = (unsigned __int64)p_OriginalPte[v21 / 8].u;
v29 = &p_OriginalPte[v21 / 8];
if( (v28.Long & 2) != 0 )
{
Long = p_OriginalPte[v21 / 8].u.Long;
v29->u.Long = v28.Long & 0xFFFFFFFFFFFFFFFDui64;
}
if( !*(_DWORD *)(v3 + 144)
&& (MmGetPfnDb()[v21 / 0x30].u3.ReferenceCount != 1
|| (*(_BYTE *)(v54 + 184) & 7) == 0
&& (HIBYTE(*(unsigned __int64 *)((char *)&PteBase->u.Long
+ ((((__int64)((a2 << 25) - ((_QWORD)PteBase << 25)) >> 16) & 0xFFFFFFFFF000ui64) >> 9))) & 0xF) == 8) )
{
goto LABEL_93;
}
ReferenceCount = v26[v21 / 2].ReferenceCount;
if( (v56 & 0x42) == 0 && (ReferenceCount & 0x10) == 0 )
{
if( (v29->u.Long & 4) == 0 )
goto LABEL_93;
v7 = 3;
}
if( (ReferenceCount & 0x10) == 0 )
{
v31 = v26[v21 / 2].ReferenceCount;
if( (v29->u.Long & 0x400) == 0 && (ReferenceCount & 8) == 0 )
{
v5.Long = MiCapturePageFileInfoInline(v29, 1ui64, 0i64).u.Long;
v26 = &MmGetPfnDb()->u3 + 1;
v31 = v26[v21 / 2].ReferenceCount;
}
v32 = v31 | 0x10;
LOBYTE(v26[v21 / 2].ReferenceCount) = v32;
ReferenceCount = v32;
}
v33 = ReferenceCount >> 6;
if( v33 != 1 )
{
if( v33 == 2 )
{
v7 |= 4u;
}
else if( !v33 )
{
v7 |= 8u;
}
}
v34 = Partition;
if( *(_DWORD *)(v3 + 32) == -1 )
{
v35 = -9i64;
v36 = Partition->Vp.PagingFile[Partition->Store.VirtualPageFileNumber];
if( (v29->u.Long & 0x400) != 0 )
v35 = -2049i64;
v37 = v29->u.Long & v35;
if( (v29->u.Long & 0x400) == 0 )
v37 &= 0xFFFFFFFFFFFFFFF9ui64;
if( v36 )
{
bf_cc = v36->_bf_cc;
if( v37 )
{
if( *(&stru_140C4DB30 + 42) )
{
if( (v37 & 0x10) != 0 )
LODWORD(v37) = v37 & 0xFFFFFFEF;
else
LODWORD(v37) = ~*(&stru_140C4DB30 + 84) & v37;
}
v39 = v37 | 0xFFFFFFFF00000000ui64;
if( *(&stru_140C4DB30 + 42) )
{
if( (v39 & *(&stru_140C4DB30 + 42)) != 0 )
v39 |= 0x10ui64;
else
v39 |= *(&stru_140C4DB30 + 42);
}
}
else
{
v39 = MiSwizzleInvalidPte(0xFFFFFFFF00000000ui64);
}
v37 = (unsigned __int16)(v39 ^ (bf_cc << 12)) & 0xF000 ^ v39;
}
v56 = v37;
if( v29 >= MmGetPml4eBase()
&& v29 <= MmGetPxeUserLimit()
&& (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 )
{
v40 = v37 | 0x8000000000000000ui64;
if( (v37 & 1) == 0 )
v40 = v37;
v29->u.Long = v40;
}
else
{
v29->u.Long = v37;
}
}
_InterlockedAnd64(&MmGetPfnDb()[v21 / 0x30].u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v41 = *(_DWORD *)(v3 + 32);
v7 &= ~1u;
v24 = *(_QWORD **)v3;
if( v41 != -1 )
{
v42 = v3 + 16i64 * v41;
if( v41 >= 5 || !*(_DWORD *)(v42 + 48) )
goto LABEL_93;
MiReservePageFileSpaceForPage(v34, a2, 128, (UINT64 *)(v42 + 40));
v43 = *(_QWORD *)(v42 + 40);
if( *(&stru_140C4DB30 + 42) && (v43 & 0x10) == 0 )
v43 &= ~*(&stru_140C4DB30 + 42);
LODWORD(v44) = MiUpdatePageFileHighInPte(*(_QWORD *)(v42 + 40), HIDWORD(v43) + 1);
v45 = (*(_DWORD *)(v42 + 48))-- == 1;
*(_QWORD *)(v42 + 40) = v44;
if( v45 )
++*(_DWORD *)(v3 + 32);
v7 |= 0x10u;
}
PteBase = MmGetPteBase();
}
v46 = v24[2];
if( v46 < v24[1] )
{
v47 = (__int64 *)(*v24 + 16 * v46);
v48 = (__int64)((a2 << 25) - ((_QWORD)PteBase << 25)) >> 16;
if( !v46 || (v49 = *(v47 - 1), v50 = v47 - 1, v49 + *(v47 - 2) != v48) )
{
v24[2] = v46 + 1;
v50 = v47 + 1;
*v47 = v48;
v47[1] = 0i64;
v49 = 0i64;
}
*v50 = v49 + 4096;
++v24[3];
if( (v7 & 2) != 0 )
++*(_QWORD *)(v3 + 136);
if( (v7 & 4) != 0 )
{
++*(_QWORD *)(v3 + 120);
}
else if( (v7 & 8) != 0 )
{
++*(_QWORD *)(v3 + 128);
}
}
LABEL_93:
if( (v7 & 1) != 0 )
_InterlockedAnd64(&v8->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( Long )
{
v51 = Long & 0xFFFFFFFFFFFFFFFBui64;
if( (Long & 4) == 0 )
v51 = Long;
MiReleasePageFileInfo(Partition, (_MMPTE)v51, 0i64);
}
if( v5.Long )
MiReleasePageFileInfo(Partition, (_MMPTE)v5.Long, 0i64);
return 0;
}Referenced by:
No references.