MiAllocateUserPhysicalPages
NTSTATUS __stdcall MiAllocateUserPhysicalPages(_MDL *a1, UINT64 *a2, VOID *a3, INT64 *a4, UINT64 arg20){
_ETHREAD *CurrentThread;
char v8;
VOID *v9;
NTSTATUS result;
unsigned __int64 v11;
UINT64 v12;
__int64 v13;
char v14;
_EPROCESS *v15;
signed int v16;
int v17;
unsigned __int64 v18;
UINT64 v19;
_EPROCESS *v20;
_EPROCESS *v21;
_ETHREAD *v22;
int v23;
_MI_PARTITION *v24;
_MI_PARTITION *v25;
unsigned __int64 v26;
_EWOW64PROCESS *WoW64Process;
unsigned __int16 Machine;
unsigned __int64 v29;
unsigned int v30;
UINT16 IdealNode;
int v32;
_LARGE_INTEGER v33;
_LARGE_INTEGER v34;
UINT64 v35;
_MDL *PagesForMdl;
unsigned __int64 v37;
VOID *v38;
VOID *v39;
UINT64 v40;
unsigned __int64 v41;
__int64 v42;
unsigned __int64 v43;
_MDL *v44;
__int64 v45;
UINT64 v46;
_MDL *v47;
_QWORD *v48;
unsigned __int64 v49;
unsigned __int64 i;
_MDL *j;
_MDL *Next;
UINT64 Flags;
CHAR PreviousMode;
_MDL *MemoryDescriptorList;
_EPROCESS *PROCESS;
__int64 v57;
_EPROCESS *P;
_MDL *Pa;
unsigned __int64 v60;
int v61;
UINT64 v62;
_ETHREAD *Thread;
unsigned __int64 v64;
UINT64 v65;
_MDL *v66;
_HANDLE Handle;
unsigned __int64 v68;
_MI_PARTITION *v69;
_LARGE_INTEGER v70;
unsigned __int64 v71;
unsigned __int64 v73;
_MDL *v74;
__int64 v76[9];
_KAPC_STATE ApcState;
Handle = (int)a1;
memset(&ApcState, 0, sizeof(ApcState));
memset(v76, 0i64, sizeof(v76));
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Thread = CurrentThread;
P = CurrentThread->Tcb.ApcState.Process;
v8 = CurrentThread->Tcb.PreviousMode;
PreviousMode = v8;
LOBYTE(v9) = v8;
result = MiCaptureAllocateMapExtendedParameters(a4, (unsigned int)arg20, v9);
if( result >= 0 )
{
if( (v76[7] & 0xFFFFFFFFFFFFFFF5ui64) != 0 || (v76[7] & 0xA) == 10 )
return -1073741811;
v11 = (v76[7] & 2) != 0 ? 16i64 : (unsigned __int64)(v76[7] & 8) << 6;
v64 = v11;
if( LODWORD(v76[4]) > (unsigned __int16)KeNumberNodes )
return -1073741811;
if( v8 )
{
v13 = (__int64)a2;
if( (unsigned __int64)a2 >= 0x7FFFFFFF0000i64 )
v13 = 0x7FFFFFFF0000i64;
*(_QWORD *)v13 = *(_QWORD *)v13;
v12 = *a2;
v62 = *a2;
v65 = *a2;
if( !*a2 )
return 0;
if( v12 > 0x1FFFFFFFFFFFFFFFi64 )
return -1073741584;
ProbeForWrite((UINT64)a3, 8 * v12, 8i64);
}
else
{
v12 = *a2;
v62 = *a2;
v65 = *a2;
if( !*a2 )
return 0;
}
result = MiReferenceAweHandle(Handle, 2i64);
if( result >= 0 )
{
v14 = 8;
v15 = P;
PROCESS = P;
if( SeSinglePrivilegeCheck(*(_QWORD *)&SeLockMemoryPrivilege, PreviousMode) )
{
v57 = 0i64;
MiCreateProcessDefaultAweInfo();
v16 = v17;
if( v17 >= 0 )
{
ExGetCallBackBlockRoutine(0i64);
v68 = v18;
if( v11 )
{
if( v11 <= v18 || v11 % v18 || ((v11 - 1) & v11) != 0 )
{
v16 = -1073741811;
goto LABEL_89;
}
}
else
{
v11 = v18;
v64 = v18;
}
if( v11 > 1 )
{
v19 = v11 * v12;
if( v12 >= v11 * v12 )
{
v16 = -1073741584;
goto LABEL_89;
}
v12 *= v11;
v62 = v19;
v65 = v19;
}
LOCK_ADDRESS_SPACE_SHARED(CurrentThread, P);
if( (P->Flags & 0x20) != 0 )
{
UNLOCK_ADDRESS_SPACE_SHARED(CurrentThread, P);
v16 = -1073741558;
}
else
{
if( MiChargeProcessPhysicalPages(P, v12) )
{
v14 = 12;
MiChargeProcessCommitment(v20, v12);
v21 = P;
v22 = CurrentThread;
if( v23 )
{
UNLOCK_ADDRESS_SPACE_SHARED(CurrentThread, P);
v14 = 14;
LODWORD(v24) = MiGetAweInfoPartition(0i64);
v25 = v24;
v69 = v24;
v26 = v24->Vp.HighestPhysicalPage + 1;
Pa = 0i64;
WoW64Process = v15->WoW64Process;
if( WoW64Process )
{
Machine = WoW64Process->Machine;
if( (Machine == 332 || Machine == 452) && v26 > 0x100000000i64 )
v26 = 0x100000000i64;
}
v29 = v26 << 12;
v30 = 0x80000000;
if( LODWORD(v76[4]) )
{
IdealNode = LOWORD(v76[4]) - 1;
if( BYTE1(v76[6]) == 1 )
v30 = -2147483646;
}
else
{
IdealNode = (*(&KiProcessorBlock + CurrentThread->Tcb.IdealProcessor))->ParentNode->Affinity.Reserved[0];
}
v32 = v30 | 1;
if( (MEMORY[0] & 4) == 0 )
v32 = v30;
v33.QuadPart = v11 << 12;
v34.QuadPart = 0i64;
if( v64 != 1 )
v34 = v33;
v70 = v34;
if( v64 != 1 )
v32 |= 0x30u;
v61 = v32;
v35 = v62;
while( 2 )
{
PagesForMdl = 0i64;
MemoryDescriptorList = 0i64;
v37 = v35 - v57;
if( v35 - v57 > 0xC0000 )
v37 = 786432i64;
v60 = v37;
if( v37 >= 0x10 && (v14 & 0x10) == 0 )
{
LODWORD(Flags) = v32 | 0x42;
PagesForMdl = MiAllocatePagesForMdl(
v25,
0i64,
(_LARGE_INTEGER)(v29 - 4096),
v33,
v37 << 12,
MEMORY[0x48],
IdealNode,
Flags);
MemoryDescriptorList = PagesForMdl;
v37 = v60;
v25 = v69;
v32 = v61;
v34 = v70;
if( !PagesForMdl )
v14 |= 0x10u;
}
if( PagesForMdl
|| (LODWORD(Flags) = v32,
PagesForMdl = MiAllocatePagesForMdl(
v25,
0i64,
(_LARGE_INTEGER)(v29 - 4096),
v34,
v37 << 12,
MEMORY[0x48],
IdealNode,
Flags),
(MemoryDescriptorList = PagesForMdl) != 0i64) )
{
MiSortMdlFrames((INT64)PagesForMdl);
v66 = PagesForMdl + 1;
v71 = (unsigned __int64)PagesForMdl->ByteCount >> 12;
v74 = (_MDL *)((char *)PagesForMdl + 8 * v71 + 48);
v73 = *(_QWORD *)&v74[-1].ByteCount / v68;
while( 1 )
{
LOCK_ADDRESS_SPACE_SHARED(Thread, v15);
if( (v15->Flags & 0x20) != 0 )
{
UNLOCK_ADDRESS_SPACE_SHARED(Thread, v15);
MiFreePagesFromMdl(MemoryDescriptorList, 0i64, v46);
ExFreePoolWithTag(MemoryDescriptorList, 0);
v16 = -1073741558;
v41 = v57;
goto LABEL_74;
}
LODWORD(v38) = MiLockAwePagesShared(0i64, (INT64)Thread);
v39 = v38;
if( v73 < MEMORY[0x10] )
break;
MiUnlockAweVadsShared(&Thread->Tcb, v38);
UNLOCK_ADDRESS_SPACE_SHARED(Thread, v15);
v16 = MiResizeAweBitMap(0i64);
if( v16 < 0 && v73 >= MEMORY[0x10] )
{
MiFreePagesFromMdl(MemoryDescriptorList, 0i64, v40);
ExFreePoolWithTag(MemoryDescriptorList, 0);
v41 = v57;
goto LABEL_74;
}
}
v42 = MEMORY[0x18];
v43 = v68;
v44 = v66;
do
{
_InterlockedOr(
(volatile signed __int32 *)(v42 + 4 * (((unsigned __int64)v44->Next / v43) >> 5)),
1 << (((unsigned __int64)v44->Next / v43) & 0x1F));
v44 = (_MDL *)((char *)v66 + 8 * v68);
v66 = v44;
v43 = v68;
}
while( v44 != v74 );
MiUnlockAweVadsShared(&Thread->Tcb, v39);
UNLOCK_ADDRESS_SPACE_SHARED(Thread, PROCESS);
MemoryDescriptorList->Next = Pa;
Pa = MemoryDescriptorList;
v25 = v69;
_InterlockedExchangeAdd64((volatile signed __int64 *)&v69->Vp.VadPhysicalPages, v71);
v45 = v71 + v57;
v57 = v45;
v16 = 0;
v35 = v65;
v62 = v65;
v15 = PROCESS;
if( v45 != v65 )
{
v32 = v61;
v34 = v70;
continue;
}
v41 = v45;
}
else
{
v41 = v57;
v16 = v57 == 0 ? 0xC000009A : 0;
}
break;
}
LABEL_74:
if( (v14 & 1) != 0 )
{
KeUnstackDetachProcess(&ApcState);
v14 &= ~1u;
}
if( v16 >= 0 )
*a2 = v41 / v64;
v47 = Pa;
v48 = a3;
while( v47 )
{
v49 = (unsigned __int64)v47->ByteCount >> 12;
for( i = 0i64; i < v49; i += v64 )
*v48++ = *((_QWORD *)&v47[1].Next + i);
v47 = v47->Next;
}
for( j = Pa; j; j = Next )
{
Next = j->Next;
ExFreePoolWithTag(j, 0);
}
v12 = v62 - v57;
CurrentThread = Thread;
goto LABEL_89;
}
}
else
{
v21 = P;
v22 = CurrentThread;
}
UNLOCK_ADDRESS_SPACE_SHARED(v22, v21);
v16 = -1073741523;
}
}
}
else
{
v16 = -1073741727;
}
LABEL_89:
if( v12 )
{
if( (v14 & 2) != 0 )
{
LOCK_ADDRESS_SPACE_SHARED(CurrentThread, v15);
MiReturnProcessCommitment(v15, v12);
UNLOCK_ADDRESS_SPACE_SHARED(CurrentThread, v15);
}
if( (v14 & 4) != 0 )
{
_InterlockedExchangeAdd64((volatile signed __int64 *)&v15->VadPhysicalPages, -(__int64)v12);
v15 = PROCESS;
}
}
if( (v14 & 1) != 0 )
KeUnstackDetachProcess(&ApcState);
if( (v14 & 8) == 0 )
ObfDereferenceObjectWithTag(v15, 0x68506D4Dui64);
return v16;
}
}
return result;
}Referenced by:
NtAllocateUserPhysicalPages
NtAllocateUserPhysicalPagesEx