MiCopyDataPageToImagePage
NTSTATUS __stdcall MiCopyDataPageToImagePage(
_MMINPAGE_SUPPORT *InPageSupport,
_SUBSECTION *Subsection,
_MMPTE *ImageProtoPte,
VOID *TrapInformation,
UINT64 PageFrameIndex,
_MMPFN *LockedProtoPfn){
_MMINPAGE_SUPPORT *v8;
VOID *FaultingAddress;
unsigned int v10;
_CONTROL_AREA *ControlArea;
INT16 v12;
unsigned int v13;
_LARGE_INTEGER v14;
INT64 *p_ControlAreaLock;
_LARGE_INTEGER v16;
unsigned __int64 v17;
__int64 v18;
UINT64 v19;
_MMPFN *v20;
unsigned int v22;
unsigned __int64 v23;
unsigned __int64 v24;
__int64 v25;
unsigned int v26;
_MMPFN **v27;
__int64 v28;
unsigned __int64 v29;
__int64 v30;
unsigned __int64 v31;
_MMPFN *v32;
_MMPFN *v33;
_ETHREAD *CurrentThread;
_MMPFN **v35;
_MMPFN *v36;
char v37;
int v38;
_MI_RESAVAIL_CHARGE v39;
_MMPFN *v40;
_MMPFN **v41;
UINT64 v42;
_MMPFN *v43;
_MMPTE *v44;
char v45;
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;} v46;
_MMPFN *v47;
UINT64 v48;
UINT64 v49;
UINT64 v50;
__int64 v51;
__int64 v52;
__int64 v53;
int v54;
__int64 v55;
__int64 v56;
__int64 v57;
int v58;
__int64 v59;
__int64 v60;
int v61;
_KTBFLUSH_TYPE v62;
int v63;
_MMPFN *DecayPfn;
_MMPFN *v65;
_MMPFN *PfnDb;
UINT8 v67;
UINT8 v68;
UINT64 v69;
UINT8 v70;
unsigned int v71;
INT64 *SpinLock;
unsigned int NumberOfPtes;
_CONTROL_AREA *Src;
_ETHREAD *v75;
_LARGE_INTEGER v76;
PVOID LockedPfns;
UINT64 SpinCount;
_MMPFN *v79;
_MMPFN *Pfn1[10];
unsigned __int64 v81;
UINT8 PageIrql;
_MMPTE *PointerPte;
unsigned __int64 v85;
v85 = (unsigned __int64)TrapInformation;
PointerPte = ImageProtoPte;
PageIrql = 0;
v8 = InPageSupport;
memset(Pfn1, 0i64, sizeof(Pfn1));
FaultingAddress = v8->FaultingAddress;
LOBYTE(v10) = 0;
v79 = 0i64;
ControlArea = Subsection->ControlArea;
Src = Subsection->ControlArea;
MiGetSessionIdForVa(FaultingAddress, v12);
v14.anonymous_0.LowPart = MiStartingOffset(Subsection, ImageProtoPte, v13);
p_ControlAreaLock = (INT64 *)&ControlArea->ControlAreaLock;
v76 = v14;
SpinLock = (INT64 *)&ControlArea->ControlAreaLock;
v16 = v14;
ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)&ControlArea->ControlAreaLock);
v17 = ControlArea->FilePointer.Value & 0xFFFFFFFFFFFFFFF0ui64;
ExAcquireSpinLockExclusiveAtDpcLevel(&::SpinLock);
v18 = **(_QWORD **)(v17 + 40);
if( !v18 || !(unsigned int)ExTryAcquireSpinLockExclusiveAtDpcLevel((INT64 *)(v18 + 72)) )
{
ExReleaseSpinLockExclusiveFromDpcLevel(&::SpinLock);
LABEL_3:
if( (v10 & 1) != 0 )
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v18 + 72));
if( (v10 & 2) == 0 )
ExReleaseSpinLockExclusiveFromDpcLevel(p_ControlAreaLock);
if( Pfn1[5] )
_InterlockedAnd64(&Pfn1[5]->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( Pfn1[6] )
MiUnlockNestedProtoPoolPage(Pfn1[6]);
v20 = Pfn1[0];
if( BYTE1(Pfn1[4]) == 1 )
MiRemoveLockedPageChargeAndDecRef(Pfn1[0]);
if( v20 )
_InterlockedAnd64(&v20->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( Pfn1[1] )
MiUnlockProtoPoolPage((ULONG_PTR)Pfn1[1], 2u);
if( (v10 & 4) != 0 )
MiDereferenceControlAreaPfnList(Src, 0i64, v19, 3ui64);
return 0;
}
ExReleaseSpinLockExclusiveFromDpcLevel(&::SpinLock);
v19 = 0i64;
LOBYTE(v10) = 1;
if( !*(_QWORD *)(v18 + 32) || (*(_DWORD *)(v18 + 56) & 3) != 0 )
goto LABEL_3;
MiEndingOffset(Subsection);
v81 = v23;
v24 = (unsigned __int64)v16.QuadPart >> 12;
v10 = v22 + 8;
v25 = v18 + 128;
if( (unsigned int)((unsigned __int64)v16.QuadPart >> 12) != (unsigned int)((v23 - 1) >> 12) )
v10 = v22;
while( 1 )
{
v26 = *(_DWORD *)(v25 + 44);
if( (unsigned int)v24 < v26 )
break;
v25 = *(_QWORD *)(v25 + 16);
LODWORD(v24) = v24 - v26;
if( !v25 )
goto LABEL_3;
}
v27 = Pfn1;
NumberOfPtes = 2;
while( 1 )
{
if( *(_DWORD *)(v25 + 104) == (_DWORD)v19 )
goto LABEL_90;
v28 = *(_QWORD *)(v25 + 8);
if( !v28 )
goto LABEL_90;
v29 = v28 + 8i64 * (unsigned int)v24;
if( !v29 )
goto LABEL_90;
v30 = (v29 >> 9) & 0x7FFFFFFFF8i64;
v31 = ((unsigned __int64)PointerPte >> 9) & 0x7FFFFFFFF8i64;
v27[2] = (_MMPFN *)v29;
if( v30 == v31 || v27 != Pfn1 && v30 == (((unsigned __int64)*(v27 - 3) >> 9) & 0x7FFFFFFFF8i64) )
{
MiTryLockLeafPage((_MMPTE *)v29, 0x7FFFFFFFF8ui64);
}
else
{
if( (int)MiTryLockProtoPoolPageAtDpc((_MMPTE *)v29, 0x7FFFFFFFF8ui64) < 0 )
goto LABEL_90;
v27[1] = v79;
}
v32 = *v27;
if( !*v27
|| (*(_BYTE *)(&v32->u3 + 1) & 0x20) != 0
|| (*((_BYTE *)&v32->u3 + 3) & 0x40) != 0
|| v32->u3.ReferenceCount >= 0x7FFFu )
{
goto LABEL_90;
}
LODWORD(v33) = MI_READ_PTE_LOCK_FREE(v29);
v27[3] = v33;
if( v27 != Pfn1 || (v76.anonymous_0.LowPart & 0xFFF) == 0 || v10 >= 8 )
break;
v27 += 5;
++NumberOfPtes;
LODWORD(v24) = v24 + 1;
v19 = 0i64;
if( (unsigned int)v24 >= *(_DWORD *)(v25 + 44) )
{
v25 = *(_QWORD *)(v25 + 16);
LODWORD(v24) = 0;
if( !v25 )
goto LABEL_90;
}
}
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)(v18 + 72));
++Src->NumberOfPfnReferences;
ExReleaseSpinLockExclusiveFromDpcLevel(SpinLock);
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v35 = Pfn1;
v36 = Pfn1[0];
LOBYTE(v10) = v10 & 0xF8 | 6;
v75 = CurrentThread;
LockedPfns = Pfn1[0];
if( !Pfn1[0] )
goto LABEL_55;
while( 1 )
{
v37 = 0;
if( ((_BYTE)v35[3] & 1) == 0 && !v36->u3.ReferenceCount )
{
*((_BYTE *)v35 + 32) = (*((_BYTE *)&v36->u3 + 3) & 8) != 0;
MiUnlinkPageFromList(v36, 0i64);
if( !v38 )
{
MiDiscardTransitionPteEx(v36, 0i64);
LABEL_90:
p_ControlAreaLock = SpinLock;
goto LABEL_3;
}
v37 = 1;
v36->u2._bf_0 &= 0xC000000000000000ui64;
}
v39 = MiAddLockedPageCharge(v36, 0i64);
v19 = 0i64;
if( v39 == MiChargeFailed )
{
if( v37 )
MiPfnReferenceCountIsZero(v36, v36 - MmGetPfnDb(), 0);
goto LABEL_90;
}
*((_BYTE *)v35 + 33) = 1;
if( v35 != Pfn1 )
break;
v35 += 5;
v36 = *v35;
LockedPfns = v36;
if( !v36 )
goto LABEL_54;
}
_InterlockedAnd64(&v36->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v40 = v35[1];
if( v40 )
{
MiUnlockNestedProtoPoolPage(v40);
v35[1] = 0i64;
}
LABEL_54:
CurrentThread = v75;
LABEL_55:
v8->u1.e1._bf_0 |= 0x20u;
v41 = Pfn1;
_InterlockedAnd64(&Pfn1[0]->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( Pfn1[1] )
MiUnlockProtoPoolPage((ULONG_PTR)Pfn1[1], 2u);
v42 = PageFrameIndex;
v43 = &MmGetPfnDb()[PageFrameIndex];
LODWORD(SpinCount) = 0;
if( _interlockedbittestandset64((volatile signed __int32 *)&v43->u2, 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( v43->u2._bf_0 < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)&v43->u2, 0x3Fui64) );
CurrentThread = v75;
}
v44 = PointerPte;
MiInitializeTransitionPfn(v42, PointerPte);
v45 = *(_BYTE *)(&v43->u3 + 1) & 0xF8 | 2;
*((_BYTE *)&v43->u3 + 2) = v45;
v43->u3.ReferenceCount = 1;
*((_BYTE *)&v43->u3 + 2) = v45 | 0x20;
v43->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = (__int64)&v8->ListHead[1];
if( (v85 & 1) != 0 && *(_BYTE *)(v85 & 0xFFFFFFFFFFFFFFFEui64) == 1 )
{
MiAdvanceFaultList((_MI_FAULT_VA_LIST *)(v85 & 0xFFFFFFFFFFFFFFFEui64));
v8->u1.e1._bf_0 |= 8u;
}
*((_BYTE *)&v43->u3 + 3) ^= (*((_BYTE *)&v43->u3 + 3) ^ ((unsigned __int32)v8->u1.e1._bf_0 >> 9)) & 7;
_InterlockedAnd64(&v43->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
LODWORD(v46.Long) = MI_READ_PTE_LOCK_FREE((INT64)v44);
v8->PteContents.u = (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;})v46.Long;
v8->PointerPte = v44;
if( PsGetIoPriorityThread(CurrentThread) < IoPriorityNormal )
v8->u1.e1._bf_0 |= 0x80u;
v47 = LockedProtoPfn;
v8->Mdl.Next = 0i64;
v8->Mdl.StartVa = 0i64;
*(_DWORD *)&v8->Mdl.Size = 56;
*(_QWORD *)&v8->Mdl.ByteCount = 4096i64;
v8->Page[0] = v42;
MiObtainProtoReference(v47, 0i64);
MiUnlockProtoPoolPage((ULONG_PTR)v47, 2u);
v8->Mdl.MdlFlags |= 0x42u;
v8->Pfn = v43;
v8->ControlArea = Src;
v8->ReadOffset = v76;
v8->BasePte = v44;
v8->FilePointer = 0i64;
v8->LockedProtoPfn = v47;
v48 = (UINT64)MiReservePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), NumberOfPtes);
v50 = v48;
if( v48 )
{
v51 = (__int64)((v48 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
LODWORD(v52) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v48, v42, 2684354564i64);
v53 = v52;
LOBYTE(v54) = MiPteInShadowRange(v50);
if( v54 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v53 & 1) != 0 )
v53 |= v55;
*(_QWORD *)v50 = v53;
LODWORD(v56) = MiMakeValidPte((_XSTATE_CONFIGURATION *)(v50 + 8), Pfn1[0] - MmGetPfnDb(), 536870913i64);
v57 = v56;
LOBYTE(v58) = MiPteInShadowRange(v50 + 8);
if( v58 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v57 & 1) != 0 )
v57 |= 0x8000000000000000ui64;
*(_QWORD *)(v50 + 8) = v57;
if( Pfn1[5] )
{
LODWORD(v59) = MiMakeValidPte((_XSTATE_CONFIGURATION *)(v50 + 16), Pfn1[5] - MmGetPfnDb(), 536870913i64);
v60 = v59;
LOBYTE(v61) = MiPteInShadowRange(v50 + 16);
if( v61 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v60 & 1) != 0 )
v60 |= 0x8000000000000000ui64;
*(_QWORD *)(v50 + 16) = v60;
}
if( v76.QuadPart + 4096 > v81 )
{
v71 = ((_WORD)v81 - LOWORD(v76.anonymous_0.LowPart)) & 0xFFF;
memmove((VOID *)v51, (const VOID *)(v51 + (v76.anonymous_0.LowPart & 0xFFF) + 4096i64), v71);
memset((VOID *)(v71 + v51), 0i64, 4096 - v71);
}
else
{
KeCopyPage((PVOID)v51);
}
MiReleasePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), (_MMPTE *)v50, NumberOfPtes, v62);
__incgsdword(0x2E98u);
v47 = LockedProtoPfn;
v63 = 0;
}
else
{
v63 = -1073741670;
}
v8->IoStatus.Status = v63;
DecayPfn = 0i64;
if( LOBYTE(Pfn1[4]) || LOBYTE(Pfn1[9]) )
DecayPfn = MiCreateDecayPfn(v49);
v65 = Pfn1[0];
LockedPfns = Pfn1[0];
if( Pfn1[0] )
{
PfnDb = MmGetPfnDb();
while( 1 )
{
PageIrql = MiLockPageInline(v65);
v67 = PageIrql;
if( !MiRemoveLockedPageCharge(v65) )
goto LABEL_77;
if( !DecayPfn || !*((_BYTE *)v41 + 32) || (v65->u2._bf_0 & 0x4000000000000000i64) != 0 )
break;
LOBYTE(v69) = v67;
MiInsertAndUnlockStandbyPages(DecayPfn, &LockedPfns, (UINT8 *)1, v69);
PageIrql = 17;
LABEL_79:
if( v41 == Pfn1 )
{
v41 += 5;
v65 = *v41;
LockedPfns = v65;
if( v65 )
continue;
}
v8 = InPageSupport;
v47 = LockedProtoPfn;
goto LABEL_82;
}
MiPfnReferenceCountIsZero(v65, v65 - PfnDb, v68);
LABEL_77:
if( v67 != 17 )
{
_InterlockedAnd64(&v65->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(PageIrql);
}
goto LABEL_79;
}
LABEL_82:
if( DecayPfn )
MiDecayPfnFullyInitialized(DecayPfn);
MiRelockProtoPoolPage(v47, &PageIrql);
v70 = PageIrql;
v8->u1.e1._bf_0 &= ~0x20u;
MiUnlockProtoPoolPage((ULONG_PTR)v47, v70);
v8->IoStatus.Information = 4096i64;
KeSetEvent((PRKEVENT)&v8->ListHead[1], 0, 0);
return 1;
}Referenced by:
MiResolveMappedFileFault