MiConvertStandbyToProto
NTSTATUS __stdcall MiConvertStandbyToProto(
_MMSUPPORT_INSTANCE *Vm,
_MI_PAGE_COMBINING_SUPPORT *Pcs,
_MI_ARBITRARY_PAGE_MAP *PageMap,
_MI_COMBINE_BLOCK *CombineBlock,
_MMPFN *PrivatePfn,
_MMPTE *CapturedPte,
UINT64 ObtainedPage){
unsigned int v7;
__int64 v8;
__int64 v9;
__int64 v10;
__int64 v11;
char v12;
__int64 v13;
_MI_PARTITION *v14;
_MI_PARTITION **v15;
_MI_PARTITION *v16;
__int64 v17;
__int64 v18;
__int64 v19;
unsigned __int8 v20;
int v22;
_MMPTE *v23;
char v24;
int v25;
char v26;
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;} v27;
char v28;
bool v29;
_MMPFN *v30;
_MMPFN *v31;
int v32;
__int64 *v33;
int v34;
UINT8 v35;
UINT8 v36;
_MMPFN *PfnDb;
unsigned __int64 v38;
struct _KPRCB *CurrentPrcb;
__int64 CachedResidentAvailable;
signed __int32 v41;
_MMPFN *v42;
_MMPFN *v43;
UINT64 v44;
char v45;
char v46;
__int64 v47;
_MMPFN *Pfn1;
__int64 v49;
_MI_PARTITION *PointerPte;
_MI_PARTITION *Partition;
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;} PteContents;
UINT64 SpinCount;
UINT64 *SecondPage;
__int64 v55;
_MMPFN *v56;
_MI_PARTITION *v57;
unsigned __int64 Pcsb;
unsigned int v62;
INT64 v63;
v62 = (unsigned int)CombineBlock;
v7 = PrivatePfn->u4._bf_0 & 0x1F;
v47 = v7;
LODWORD(v8) = MiMakePrototypePteDirect((INT64)&PrivatePfn[1]);
v9 = v8 | 0x800;
v55 = v8 | 0x800;
v11 = (__int64)((*(_QWORD *)(v10 + 56) << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
SecondPage = (UINT64 *)v11;
v45 = 0;
v12 = 1;
v46 = 1;
v14 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8i64 * *(unsigned __int16 *)(v13 + 174));
PointerPte = v14;
v16 = *v15;
Partition = *v15;
v57 = *v15;
if( v63 == -1 )
{
v46 = 1;
if( v16 != v14 )
{
v20 = 1;
v45 = 1;
if( !MiGetCrossPartitionCombineCharges(v16, 1i64) )
goto LABEL_15;
v46 = 0;
}
v42 = MiLockProtoPoolPage((_MMPTE *)&PrivatePfn[1], 0i64);
v43 = v42;
v56 = v42;
if( v42 )
{
if( _interlockedbittestandset64((volatile signed __int32 *)&CapturedPte[3], 0x3Fui64) )
{
MiUnlockProtoPoolPage((ULONG_PTR)v42, 0x11u);
}
else
{
if( ObtainedPage == (CapturedPte[1].u.Long | 0x8000000000000000ui64)
&& PointerPte == *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * ((CapturedPte[5].u.Long >> 39) & 0x3FF))
&& MiRecheckCombineVm(Pcs, (_MMPFN *)v62, (_MMSUPPORT_INSTANCE *)CapturedPte) )
{
MiTryLockLeafPage((_MMPTE *)&PrivatePfn[1], v44);
}
MiUnlockNestedProtoPoolPage(v43);
_InterlockedAnd64((volatile signed __int64 *)&CapturedPte[3], 0x7FFFFFFFFFFFFFFFui64);
}
}
v20 = v45;
goto LABEL_15;
}
Pfn1 = &MmGetPfnDb()[v63];
if( !MiFillCombinePage((_MMPFN *)v16, Pfn1, CapturedPte, (VOID *)v11) )
goto LABEL_14;
LODWORD(v17) = MiMakeTransitionPte(v63, v7);
v18 = v17;
SecondPage = (UINT64 *)((unsigned __int64)&PrivatePfn[1] & 0x7FFFFFFFFFFFFFFFi64);
PteContents.Long = 0i64;
LODWORD(v19) = MiGetContainingPageTable((UINT64)&PrivatePfn[1]);
v49 = v19;
if( Partition != PointerPte )
{
if( MiGetCrossPartitionCombineCharges(Partition, 0i64) )
{
v12 = 0;
v46 = 0;
goto LABEL_6;
}
LABEL_14:
v20 = 0;
LABEL_15:
if( !v46 )
MiReturnCrossPartitionCombineCharges((_MI_CROSS_PARTITION_CHARGES *)Partition, v20);
return 0;
}
LABEL_6:
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CapturedPte[3], 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( CapturedPte[3].u.Hard._bf_0 < 0 );
}
if( (**((_BYTE **)PageMap + 7) & 1) == 0
|| (unsigned __int8)((BYTE2(CapturedPte[4].u.VolatileLong) & 7) - 2) > 1u
|| PointerPte != *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * ((CapturedPte[5].u.Long >> 39) & 0x3FF))
|| ObtainedPage != (CapturedPte[1].u.Long | 0x8000000000000000ui64)
|| !MiRecheckCombineVm(Pcs, (_MMPFN *)v62, (_MMSUPPORT_INSTANCE *)CapturedPte)
|| ((LODWORD(CapturedPte[2].u.Long) >> 5) & 0x1F) != (_DWORD)v47 )
{
goto LABEL_13;
}
MiUnlinkPageFromList((_MMPFN *)CapturedPte, 0i64);
if( !v22 )
{
MiDiscardTransitionPteEx((_MMPFN *)CapturedPte, 0i64);
LABEL_13:
_InterlockedAnd64((volatile signed __int64 *)&CapturedPte[3], 0x7FFFFFFFFFFFFFFFui64);
goto LABEL_14;
}
v23 = CapturedPte + 2;
if( (CapturedPte[4].u.VolatileLong & 0x100000) == 0 )
{
IS_PTE_NOT_DEMAND_ZERO();
if( !v25 )
BYTE2(CapturedPte[4].u.VolatileLong) = v24 | 0x10;
}
v26 = 0;
if( (v23->u.Long & 2) != 0 )
{
if( v12 && !MI_IS_PTE_IN_WS_SWAP_SET((_MMPTE *)PointerPte) )
PteContents.Long = v27.Long;
else
v26 = 1;
v28 = 1;
}
else
{
v29 = v12 == 0;
v28 = 0;
if( v29 && (v23->u.Long & 4) != 0 )
v26 = 1;
}
if( v26 )
{
PteContents.Long = MiCapturePageFileInfoInline(v23, 1ui64, 1ui64).u.Long;
BYTE2(CapturedPte[4].u.VolatileLong) |= 0x10u;
v23 = CapturedPte + 2;
}
if( v28 )
v23->u.Long &= ~2ui64;
v30 = &MmGetPfnDb()[v49];
MiLockNestedPageAtDpcInline(v30);
v30->u2._bf_0 ^= (v30->u2._bf_0 ^ ((v30->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64) + 1)) & 0x3FFFFFFFFFFFFFFFi64;
_InterlockedAnd64(&v30->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
MiLockNestedPageAtDpcInline(Pfn1);
MiFinalizePageAttribute(Pfn1, (_MI_PFN_CACHE_ATTRIBUTE)(BYTE2(CapturedPte[4].u.VolatileLong) >> 6), 1ui64);
MiCopyPfnEntryEx((INT64)Pfn1, (INT64)CapturedPte);
if( (unsigned int)MiGetPfnPriority(v31) < 5 )
*((_BYTE *)&Pfn1->u3 + 3) = *((_BYTE *)&Pfn1->u3 + 3) & 0xF8 | 5;
Pfn1->PteLong = (unsigned __int64)SecondPage;
Pfn1->u4._bf_0 = v49 & 0xFFFFFFFFFi64 | Pfn1->u4._bf_0 & 0xFFFFFFF000000000ui64 | 0x8000000000000000ui64;
Pfn1->u2._bf_0 &= 0xC000000000000000ui64;
MI_MAKE_PROTECT_WRITE_COPY(&Pfn1->OriginalPte);
if( !v46 )
PrivatePfn[1].PteLong = 1i64;
PrivatePfn[1].u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = 0i64;
LOBYTE(v32) = MiPteInShadowRange((UINT64)&PrivatePfn[1]);
if( v32 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v18 & 1) != 0 )
v18 |= 0x8000000000000000ui64;
PrivatePfn[1].u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = v18;
Pcsb = CapturedPte[5].u.Long & 0xFFFFFFFFFi64;
v33 = (__int64 *)((char *)MiMapPageInHyperSpaceWorker(Pcsb, 0i64, 0x80000000ui64) + (CapturedPte[1].u.Long & 0xFFF));
LOBYTE(v34) = MiPteInShadowRange((UINT64)v33);
if( v34 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v9 & 1) != 0 )
v9 |= 0x8000000000000000ui64;
*v33 = v9;
MiUnmapPageInHyperSpaceWorker(v33, 0x11u, 0x80000000ui64);
CapturedPte[3].u.Long |= 0x4000000000000000ui64;
MiPfnReferenceCountIsZero(Pfn1, v63, v35);
_InterlockedAnd64(&Pfn1->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( v46 )
{
if( (CapturedPte[2].u.Long & 4) != 0 )
{
CapturedPte[2].u.Long &= ~4ui64;
if( PteContents.Long )
PteContents.Long &= ~4ui64;
}
}
CapturedPte[3].u.Long &= 0xC000000000000000ui64;
PfnDb = MmGetPfnDb();
MiPfnReferenceCountIsZero((_MMPFN *)CapturedPte, ((char *)CapturedPte - (char *)PfnDb) / 48, v36);
_InterlockedAnd64((volatile signed __int64 *)&CapturedPte[3], 0x7FFFFFFFFFFFFFFFui64);
if( v46 )
{
MiReturnCommit(PointerPte, 1ui64);
v38 = 1i64;
if( PointerPte != &Irp )
goto LABEL_66;
CurrentPrcb = KeGetCurrentPrcb();
CachedResidentAvailable = (int)CurrentPrcb->CachedResidentAvailable;
if( (_DWORD)CachedResidentAvailable == -1 )
goto LABEL_66;
if( (unsigned __int64)(CachedResidentAvailable + 1) <= 0x100 )
{
do
{
v41 = _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
CachedResidentAvailable + 1,
CachedResidentAvailable);
v29 = (_DWORD)CachedResidentAvailable == v41;
LODWORD(CachedResidentAvailable) = v41;
if( v29 )
goto LABEL_67;
}
while( v41 != -1 && (unsigned __int64)(v41 + 1i64) <= 0x100 );
}
if( (int)CachedResidentAvailable > 192
&& (_DWORD)CachedResidentAvailable != -1
&& (_DWORD)CachedResidentAvailable == _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
192,
CachedResidentAvailable) )
{
v38 = (int)CachedResidentAvailable - 192 + 1i64;
}
if( v38 )
LABEL_66:
_InterlockedExchangeAdd64((volatile signed __int64 *)&PointerPte->Vp.ResidentAvailablePages, v38);
LABEL_67:
if( Partition == &Irp )
_InterlockedExchangeAdd64((_QWORD *)&stru_140C4DB30 + 569, 0xFFFFFFFFFFFFFFFFui64);
}
MiLockAndDecrementShareCount(&PfnDb[Pcsb], 0i64);
if( PteContents.Long )
MiReleasePageFileInfo(PointerPte, (_MMPTE)PteContents.Long, 1ui64);
if( (Vm->Flags._bf_0 & 7) == 0 )
_InterlockedExchangeAdd64(
(volatile signed __int64 *)&KeGetCurrentThread()->ApcState.Process->NumberOfPrivatePages,
0xFFFFFFFFFFFFFFFFui64);
return 1;
}Referenced by:
MiSharePages