NtMapUserPhysicalPagesScatter
NTSTATUS __stdcall NtMapUserPhysicalPagesScatter(VOID **VirtualAddresses, UINT64 NumberOfPages, UINT64 *UserPfnArray){
INT64 v6;
_ETHREAD *CurrentThread;
UINT64 *Pool;
INT64 v10;
char *v11;
UINT64 *v12;
int v13;
INT64 v14;
UINT64 v15;
_MMPTE *AweNode;
_EX_CALLBACK_ROUTINE_BLOCK *Long;
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;} v18;
__int64 v19;
__int64 v20;
int v21;
unsigned __int64 v22;
unsigned __int64 v23;
__int64 v24;
_MMPTE *v25;
int v26;
int v27;
VOID *v28;
VOID *v29;
INT64 v30;
INT64 *v31;
__int64 v32;
INT64 a5;
INT64 a5a;
INT64 a6;
INT64 a6a;
INT64 v37;
INT64 v38;
INT64 v39;
INT64 v40;
INT64 v41;
VOID *LockHandle;
INT64 v43[2];
char Destination[4096];
char v45;
memset(Destination, 0i64, sizeof(Destination));
*(_OWORD *)v43 = 0i64;
if( NumberOfPages > 0xFFFFFFFFFFFFFi64 )
return -1073741584;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Pool = (UINT64 *)Destination;
v10 = 0i64;
v11 = 0i64;
if( NumberOfPages > 0x200 )
{
Pool = (UINT64 *)MiAllocatePool(
64i64,
NumberOfPages * ((((unsigned __int128)-(__int128)(unsigned __int64)UserPfnArray >> 64) & 8) + 8),
0x77526D4Dui64);
if( !Pool )
return -1073741670;
}
v12 = Pool;
v13 = MiCaptureUlongPtrArray(Pool, VirtualAddresses, NumberOfPages, v6, a5, a6, v37, v39);
if( v13 >= 0 )
{
if( !NumberOfPages )
return 0;
if( !UserPfnArray )
goto LABEL_13;
v11 = &v45;
if( NumberOfPages > 0x200 )
v11 = (char *)&Pool[NumberOfPages];
v13 = MiCaptureUlongPtrArray(v11, UserPfnArray, NumberOfPages, v14, a5a, a6a, v38, v40);
if( v13 >= 0 )
{
LABEL_13:
v15 = *Pool;
v13 = 0;
LockHandle = MiLockAweVadsShared(&CurrentThread->Tcb);
AweNode = MiGetAweNode(v15);
if( !AweNode || (AweNode[5].u.Long & 3) != 0 )
{
v13 = -1073741585;
}
else
{
Long = (_EX_CALLBACK_ROUTINE_BLOCK *)AweNode[4].u.Long;
v41 = (INT64)AweNode;
ExGetCallBackBlockRoutine(Long);
v20 = v19;
v21 = -1073741585;
do
{
v22 = *v12;
if( v20 == 1 )
{
v23 = *v12;
}
else
{
v24 = (v20 << 12) - 1;
if( (v24 & v22) != 0 )
goto LABEL_38;
v23 = v24 + v22;
}
if( v22 < (*(unsigned int *)(v18.Long + 24) | ((unsigned __int64)*(unsigned __int8 *)(v18.Long + 32) << 32)) << 12
|| v23 > (((*(unsigned int *)(v18.Long + 28) | ((unsigned __int64)*(unsigned __int8 *)(v18.Long + 33) << 32)) << 12) | 0xFFF) )
{
v25 = MiGetAweNode(*v12);
if( !v25 || (v25[5].u.Long & 3) != 0 || (_EX_CALLBACK_ROUTINE_BLOCK *)v25[4].u.Long != Long )
{
LABEL_38:
v10 = v41;
v13 = v21;
goto LABEL_39;
}
v18.Long = (unsigned __int64)v25[3].u;
v27 = *(_DWORD *)(v18.Long + 48) & 0x1100000;
if( v26 == 17825792 )
{
if( v27 != 17825792 )
v13 = v21;
}
else if( v27 == 17825792 )
{
v13 = v21;
}
}
++v12;
}
while( v12 < &Pool[NumberOfPages] );
LODWORD(v28) = MiLockAwePagesShared((INT64)Long, (INT64)CurrentThread);
v29 = v28;
if( v11
&& (v13 = MiReferenceIncomingPhysicalPages(
Long,
(INT64)v11,
NumberOfPages,
(INT64)Pool,
(INT64)v43,
v41,
0i64),
v13 < 0) )
{
v10 = v41;
}
else
{
v10 = v41;
LODWORD(v30) = MiWriteAwePtes(v41, (INT64)v11, NumberOfPages, (INT64)Pool, 0i64, 1);
v43[1] = v30;
}
if( v29 )
MiUnlockAweVadsShared(&CurrentThread->Tcb, v29);
}
LABEL_39:
if( LockHandle )
MiUnlockAweVadsShared(&CurrentThread->Tcb, LockHandle);
}
}
v31 = v43;
v32 = 2i64;
do
{
if( *v31 )
MiFreePhysicalPageChain(v10, *v31, 0i64);
++v31;
--v32;
}
while( v32 );
if( Pool != (UINT64 *)Destination )
ExFreePoolWithTag(Pool, 0);
return v13;
}Referenced by:
No references.