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