HalpIommuMapLogical
NTSTATUS __stdcall HalpIommuMapLogical(INT64 a1, INT64 a2, INT64 a3, INT64 a4, UINT64 a5, INT64 a6){
int v6;
unsigned __int64 v7;
unsigned int v8;
unsigned __int64 v9;
UINT64 v10;
int v11;
__int64 v12;
int v14;
__int64 v15;
unsigned int v16;
unsigned __int64 v17;
__int64 v18;
__int64 v19;
unsigned __int64 v20;
unsigned __int64 v21;
UINT64 v22;
__int64 v23;
VOID *v24;
unsigned int v25;
__int64 v26;
int v27;
VOID *v28;
unsigned int v29;
int v30;
INT64 v31;
__int64 v32;
unsigned int v34;
char v35;
unsigned int Length;
unsigned __int64 BaseAddress;
VOID *BaseAddressa;
UINT64 v39;
INT64 v40;
INT64 v41;
__int128 v42[3];
v6 = *(_DWORD *)(a2 + 28);
v7 = *(_QWORD *)(a2 + 16);
v8 = 0;
v9 = a6;
v10 = 0i64;
v40 = a4;
v35 = v6;
v11 = 1 << v6;
LODWORD(v12) = 0;
Length = 1 << v6;
v42[0] = v7;
memset(&v42[1], 0, 32);
v34 = 0;
v41 = a6;
v39 = 0i64;
if( !a5 )
return 0;
while( 1 )
{
v14 = *(_DWORD *)(a2 + 24);
if( (unsigned int)v12 < v14 - 1 )
{
v15 = (unsigned int)v12;
while( 1 )
{
v16 = *(_DWORD *)(a2 + 4 * v15 + 36);
v17 = v7 + (1 << v16 << v6);
if( v16 < 0x40 )
v18 = (1i64 << v16) - 1;
else
LODWORD(v18) = -1;
v19 = (unsigned int)v18 & (unsigned int)(v9 >> *(_DWORD *)(a2 + 4 * v15 + 60));
BaseAddress = (unsigned int)v19;
v20 = *(_QWORD *)(v17 + 8 * v19);
if( !v20 )
{
v21 = (unsigned __int8)KeAcquireSpinLockRaiseToDpc((UINT64 *)(a2 + 8));
if( !*(_QWORD *)(v17 + 8i64 * (unsigned int)v19) )
{
LODWORD(v22) = HalpIommuAllocateAndZeroPageTable(a2, (unsigned int)(v12 + 1), 0i64);
*(_QWORD *)(v17 + 8i64 * (unsigned int)v19) = v22;
if( !v22 )
{
KxReleaseSpinLock((UINT64 *)(a2 + 8));
__writecr8(v21);
return -1073741670;
}
LODWORD(v23) = MmGetPhysicalAddress(v22);
v24 = (VOID *)(v7 + (unsigned int)((_DWORD)v19 << v35));
(**(void(__fastcall ***)(VOID *, _QWORD, __int64))(a2 + 88))(
v24,
(unsigned int)(*(_DWORD *)(a2 + 24) - v12 - 1),
v23);
if( !byte_140C49BF1 )
KeInvalidateRangeAllCachesNoIpi(v24, Length);
}
KxReleaseSpinLock((UINT64 *)(a2 + 8));
__writecr8(v21);
v14 = *(_DWORD *)(a2 + 24);
LOBYTE(v6) = v35;
v20 = *(_QWORD *)(v17 + 8 * BaseAddress);
}
v9 = a6;
v12 = (unsigned int)(v12 + 1);
v7 = v20;
v15 = (unsigned int)v12;
*((_QWORD *)v42 + v12) = v20;
if( (unsigned int)v12 >= v14 - 1 )
{
v10 = v39;
v11 = Length;
v8 = v34;
break;
}
}
}
v25 = *(_DWORD *)(a2 + 4i64 * (unsigned int)v12 + 36);
if( v25 < 0x40 )
v26 = (1i64 << v25) - 1;
else
LODWORD(v26) = -1;
v27 = v26 & (v9 >> *(_DWORD *)(a2 + 4i64 * (unsigned int)v12 + 60));
v28 = (VOID *)(v7 + (unsigned int)(v27 << v6));
v29 = (1 << *(_DWORD *)(a2 + 4i64 * (unsigned int)(v14 - 1) + 36)) - v27;
BaseAddressa = v28;
if( (unsigned int)a5 - v8 <= v29 )
v29 = a5 - v8;
v30 = (*(__int64(__fastcall **)(VOID *, INT64, __int64, _QWORD))(*(_QWORD *)(a2 + 88) + 16i64))(
v28,
v40 + 8i64 * v8,
3i64,
v29);
v10 += (unsigned int)(v30 << 12);
v39 = v10;
if( v30 != v29 )
break;
if( !byte_140C49BF1 )
KeInvalidateRangeAllCachesNoIpi(BaseAddressa, v11 * v29);
v8 = v29 + v34;
v31 = v9 + ((unsigned __int64)v29 << 12);
v34 += v29;
if( (_DWORD)v12 )
{
do
{
v32 = (unsigned int)(v12 - 1);
if( ((1i64 << *(_DWORD *)(a2 + 4 * v32 + 60)) & v31) == (v9 & (1i64 << *(_DWORD *)(a2 + 4 * v32 + 60))) )
break;
LODWORD(v12) = v12 - 1;
}
while( (_DWORD)v32 );
}
v9 += (unsigned __int64)v29 << 12;
a6 = v31;
v7 = *((_QWORD *)v42 + (unsigned int)v12);
if( v8 >= a5 )
return 0;
LOBYTE(v6) = v35;
}
HalpIommuUnmapLogicalRange(a2, &v39, v41);
return -1073741811;
}Referenced by:
HalpIommuDomainMapLogical