IommuMapDevice

NTSTATUS __stdcall IommuMapDevice(INT64 a1, INT64 a2, INT64 a3, INT64 *a4){
  bool v5; 
  UINT8 *v7; 
  UINT8 *v8; 
  __int64 v9; 
  NTSTATUS DeviceCapabilities; 
  void *v11; 
  INT64 v12; 
  int v13; 
  _HALP_ALLOC_CONTEXT *v14; 
  UINT8 *v15; 
  UINT8 *v16; 
  unsigned int v17; 
  _HALP_ALLOC_CONTEXT *v18; 
  UINT8 *v19; 
  _HALP_ALLOC_CONTEXT *v20; 
  INT64 v21; 
  UINT8 *v22; 
  UINT8 *v23; 
  unsigned __int8 CurrentIrql; 
  __int64 v25; 
  __int64 v26; 
  __int64 v27; 
  UINT8 *v28; 
  __int64 v29; 
  UINT8 *v30; 
  UINT8 *v31; 
  UINT8 **v32; 
  __int64 v33; 
  _HALP_ALLOC_CONTEXT *v34; 
  VOID *v35; 
  INT64 v37; 
  void *v38; 
  __int64 v39[2]; 

  v5 = byte_140C49B2C == 0;
  *a4 = 0i64;
  v37 = 0i64;
  v7 = 0i64;
  v8 = 0i64;
  v38 = 0i64;
  v39[0] = 0i64;
  if( v5 )
  {
    DeviceCapabilities = HalpIommuLocateFromDevice(a2, &v37, (INT64)v39);
    if( DeviceCapabilities < 0 )
      return DeviceCapabilities;
    v11 = (void *)v39[0];
    LOBYTE(v9) = 1;
    v12 = v37;
    v38 = (void *)v39[0];
    v13 = (*(__int64(__fastcall **)(_QWORD, __int64, __int64))(v37 + 200))(*(_QWORD *)(v37 + 16), v39[0], v9);
  }
  else
  {
    DeviceCapabilities = IommupHvGetDeviceCapabilities(a2, &v38, &v37);
    if( DeviceCapabilities < 0 )
      return DeviceCapabilities;
    v12 = v37;
    v11 = v38;
    v13 = ((__int64(__fastcall *)(_QWORD, _QWORD, _QWORD, _QWORD))qword_140C4A240)(
            (unsigned int)v38,
            *(unsigned int *)(*(_QWORD *)a1 + 16i64),
            *(unsigned int *)v37,
            *(_DWORD *)(a3 + 4) & 0x1F | (4 * (*(_DWORD *)(a3 + 4) & 0x100)) | (*(_DWORD *)(a3 + 4) >> 4) & 0x3E0u);
  }
  DeviceCapabilities = v13;
  if( v13 < 0 )
    return DeviceCapabilities;
  v15 = HalpMmAllocCtxAlloc(v14, 0x68ui64);
  v16 = v15;
  if( v15 )
  {
    memset(v15, 0i64, 0x68u);
    *((_QWORD *)v16 + 3) = v12;
    *((_QWORD *)v16 + 5) = v11;
    ExInitializePushLock((PULONG_PTR)v16 + 6);
    v17 = *(_DWORD *)(a3 + 4);
    *((_QWORD *)v16 + 2) = 0i64;
    *((_DWORD *)v16 + 14) = (v17 >> 9) & 0x1F;
    *((_QWORD *)v16 + 12) = v16 + 88;
    *((_QWORD *)v16 + 11) = v16 + 88;
    v19 = HalpMmAllocCtxAlloc(v18, 0x3048ui64);
    v7 = v19;
    if( v19 )
    {
      memset(v19, 0i64, 0x3048u);
      if( byte_140C49B2C )
      {
        v21 = v12 + 24;
        v22 = HalpMmAllocCtxAlloc(v20, (unsigned int)(*(_DWORD *)(v12 + 44) << 9));
        *((_QWORD *)v7 + 1544) = v22;
        if( !v22 )
          goto LABEL_23;
      }
      else
      {
        v21 = v12 + 384;
      }
      *((_QWORD *)v7 + 5) = v16;
      v7[32] = 0;
      *((_DWORD *)v7 + 15) = *(_DWORD *)(v21 + 16);
      v23 = HalpMmAllocCtxAlloc(v20, 0x28ui64);
      v8 = v23;
      if( v23 )
      {
        *((_QWORD *)v23 + 2) = v12;
        *((_QWORD *)v23 + 4) = v23 + 24;
        *((_QWORD *)v23 + 3) = v23 + 24;
        CurrentIrql = KeGetCurrentIrql();
        __writecr8(0xFui64);
        KxAcquireSpinLock((UINT64 *)(*(_QWORD *)a1 + 24i64));
        v25 = *(_QWORD *)a1 + 48i64;
        v26 = *(_QWORD *)v25;
        if( *(_QWORD *)(*(_QWORD *)v25 + 8i64) != v25 )
          goto LABEL_22;
        *((_QWORD *)v16 + 1) = v25;
        *(_QWORD *)v16 = v26;
        *(_QWORD *)(v26 + 8) = v16;
        *(_QWORD *)v25 = v16;
        v27 = *(_QWORD *)a1 + 32i64;
        v28 = *(UINT8 **)v27;
        if( *(_QWORD *)v27 == v27 )
          goto LABEL_18;
        do
        {
          v29 = *((_QWORD *)v28 + 2);
          v30 = v28;
          if( v29 == v12 )
            goto LABEL_20;
          v28 = *(UINT8 **)v28;
        }
        while( v28 != (UINT8 *)v27 );
        if( v29 != v12 )
        {
LABEL_18:
          v31 = *(UINT8 **)v27;
          if( *(_QWORD *)(*(_QWORD *)v27 + 8i64) != v27 )
            goto LABEL_22;
          *(_QWORD *)v8 = v31;
          v30 = v8;
          *((_QWORD *)v8 + 1) = v27;
          *((_QWORD *)v31 + 1) = v8;
          *(_QWORD *)v27 = v8;
          v8 = 0i64;
        }
LABEL_20:
        v32 = (UINT8 **)(v30 + 24);
        v33 = *((_QWORD *)v30 + 3);
        if( *(UINT8 **)(v33 + 8) == v30 + 24 )
        {
          *(_QWORD *)v7 = v33;
          *((_QWORD *)v7 + 1) = v32;
          *(_QWORD *)(v33 + 8) = v7;
          *v32 = v7;
          v7 = 0i64;
          KxReleaseSpinLock((UINT64 *)(*(_QWORD *)a1 + 24i64));
          __writecr8(CurrentIrql);
          *a4 = (INT64)v16;
          goto LABEL_28;
        }
LABEL_22:
        __fastfail(3u);
      }
    }
  }
LABEL_23:
  if( byte_140C49B2C )
    IommupHvUnmapDevice(v11);
  else(*(void(__fastcall **)(_QWORD, void *, _QWORD))(v12 + 200))(*(_QWORD *)(v12 + 16), v11, 0i64);
  DeviceCapabilities = -1073741670;
  if( v16 )
  {
    HalpMmAllocCtxFree(v34, v16);
LABEL_28:
    if( v8 )
      HalpMmAllocCtxFree(v34, v8);
  }
  if( v7 )
  {
    v35 = (VOID *)*((_QWORD *)v7 + 1544);
    if( v35 )
      HalpMmAllocCtxFree(v34, v35);
    HalpMmAllocCtxFree(v34, v7);
  }
  return DeviceCapabilities;
}

Referenced by:

No references.