HalpIommuDeleteDevice

INT64 __fastcall HalpIommuDeleteDevice(UINT64 *Memory){
  unsigned int v2; 
  char v3; 
  __int64 v4; 
  __int64 i; 
  __int64 v6; 
  __int64 v8; 
  __int64 *v9; 
  __int64 v10; 
  __int64 v12; 
  __int64 v13; 
  __int64 v14; 
  v2 = 0;
  v3 = 0;
  v4 = 0i64;
  ExAcquirePushLockExclusiveEx((UINT64)&HalpIommuDeviceCreatedListPushLock, 0i64);
  for( i = HalpIommuDeviceCreatedList; (__int64 *)i != &HalpIommuDeviceCreatedList; i = *(_QWORD *)v6 )
  {
    v4 = i;
    if( IidAreIdsStrictlyEqual(*(INT64 **)(i + 16), Memory[4]) )
    {
      if( (*(_DWORD *)(v6 + 32))-- == 1 )
      {
        v8 = *(_QWORD *)v6;
        if( *(_QWORD *)(*(_QWORD *)v6 + 8i64) != v6 || (v9 = *(__int64 **)(v6 + 8), *v9 != v6) )
          __fastfail(3u);
        *v9 = v8;
        v3 = 1;
        *(_QWORD *)(v8 + 8) = v9;
        break;
      }
    }
  }
  if( (_InterlockedExchangeAdd64(
          (volatile signed __int64 *)&HalpIommuDeviceCreatedListPushLock,
          0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock((volatile INT64 *)&HalpIommuDeviceCreatedListPushLock);
  KeAbPostRelease(&HalpIommuDeviceCreatedListPushLock);
  if( !v3 )
    return 0i64;
  if( v4 )
  {
    v12 = *(_QWORD *)(v4 + 16);
    if( v12 )
      HalpMmAllocCtxFree(v10, v12);
    HalpMmAllocCtxFree(v10, v4);
  }
  if( HalpHvIommu )
    v2 = IommupHvUnregisterDeviceId();
  else(*(void(__fastcall **)(_QWORD, UINT64, _QWORD))(Memory[1] + 96))(*(_QWORD *)(Memory[1] + 16), *Memory, 0i64);
  v14 = Memory[4];
  if( v14 )
    HalpMmAllocCtxFree(v13, v14);
  HalpMmAllocCtxFree(v13, (__int64)Memory);
  return v2;
}

Referenced by:

HalpDmaAllocateChildAdapterV3
HalpDmaFreeChildAdapter
HalpIommuBlockDevice
HalpIommuUnblockDevice
IommuDomainDetachDevice