HalpDmaAllocateChildAdapterV3

_ADAPTER_OBJECT *__stdcall HalpDmaAllocateChildAdapterV3(
        UINT64 NumberOfMapRegisters,
        UINT64 DmaAddressWidth,
        INT64 ScatterGather,
        INT64 MasterDevice,
        UINT8 CanCross64K,
        UINT8 CacheCoherent,
        UINT64 ScatterGatherLimit,
        _LARGE_INTEGER DeviceAddress,
        UINT64 *AllocatedMapRegistersOut){
  _ADAPTER_OBJECT *v9; 
  char *v10; 
  NTSTATUS SecurityPolicy; 
  size_t v12; 
  ULONG v13; 
  PVOID v14; 
  int v15; 
  __int64 v16; 
  _HALP_DMA_MASTER_ADAPTER_OBJECT *v17; 
  unsigned __int64 v18; 
  NTSTATUS LocalScatterPool; 
  int v21; 
  __int64 v22; 
  int v23; 
  _EX_PUSH_LOCK *AdapterByDeviceId; 
  char v25; 
  INT64 v26; 
  VOID *v27; 
  NTSTATUS Device; 
  char v29; 
  VOID *v30; 
  UINT64 v31; 
  UINT64 ObjectBodySize; 
  PVOID *Handle; 
  UINT64 v34; 
  __int16 v35; 
  PVOID Object; 
  PVOID v37; 
  _OBJECT_ATTRIBUTES ObjectAttributes; 
  _INTERFACE Interface[4]; 
  unsigned int NumberOfMapRegistersa; 
  int v41; 
  unsigned int v42; 
  char v43; 
  int v44; 
  PVOID InterfaceSpecificData; 
  _DWORD *v46; 

  v43 = MasterDevice;
  v42 = ScatterGather;
  v41 = DmaAddressWidth;
  NumberOfMapRegistersa = NumberOfMapRegisters;
  *(_QWORD *)&ObjectAttributes.Length = 48i64;
  v37 = 0i64;
  *(_QWORD *)&ObjectAttributes.Attributes = 528i64;
  v9 = 0i64;
  v35 = 0;
  v10 = 0i64;
  Object = 0i64;
  memset(Interface, 0i64, 0x50u);
  SecurityPolicy = HalpIommuGetSecurityPolicy();
  ObjectAttributes.RootDirectory = 0i64;
  v12 = 640;
  ObjectAttributes.ObjectName = 0i64;
  v13 = 0;
  *(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
  if( !CanCross64K )
  {
    v13 = 24 * (DeviceAddress.anonymous_0.LowPart + 1);
    v12 = v13 + 640;
  }
  v14 = InterfaceSpecificData;
  v15 = v44;
  if( InterfaceSpecificData || !v44 || SecurityPolicy != 1 )
  {
    InterfaceSpecificData = 0i64;
    if( v14 && v44 )
    {
      if( HalpDmaGetIommuInterface(v14, Interface) < 0 )
      {
        if( SecurityPolicy == 1 )
          return(_ADAPTER_OBJECT *)v10;
      }
      else
      {
        HIBYTE(v35) = 1;
        if( (*(unsigned int(__fastcall **)(void *, _QWORD, _QWORD, PVOID *))&Interface[2].Size)(
               Interface[0].Context,
               0i64,
               0i64,
               &InterfaceSpecificData) == -1073741789
          && InterfaceSpecificData )
        {
          v12 += (unsigned int)InterfaceSpecificData;
        }
        else
        {
          if( SecurityPolicy == 1 )
            goto LABEL_27;
          InterfaceSpecificData = 0i64;
        }
      }
    }
    LODWORD(v34) = 0;
    LODWORD(Handle) = 0;
    LODWORD(ObjectBodySize) = v12;
    if( ObCreateObjectEx(
           0i64,
           HalpDmaAdapterObjectType,
           &ObjectAttributes,
           0i64,
           v30,
           ObjectBodySize,
           (UINT64)Handle,
           v34,
           &Object,
           0i64) < 0 )
      goto LABEL_25;
    v10 = (char *)Object;
    memset(Object, 0i64, v12);
    if( ObReferenceObjectByPointer(v10, 0x20000ui64, HalpDmaAdapterObjectType, 0) < 0 )
      goto LABEL_25;
    LODWORD(v31) = 0;
    if( ObInsertObjectEx(v10, 0i64, 0x20000ui64, 0i64, v31, 0i64, &v37) < 0 )
      goto LABEL_25;
    ZwClose((_HANDLE)v37);
    v16 = 0i64;
    *((_QWORD *)v10 + 1) = &HalpDmaOperationsV3;
    v17 = &stru_140C4BA20;
    v10[145] = CacheCoherent;
    *(_DWORD *)v10 = 41943041;
    if( v42 >= 0x20 )
      v17 = &stru_140C4BB00;
    *((_QWORD *)v10 + 15) = 0i64;
    *((_QWORD *)v10 + 16) = 0i64;
    v10[144] = 0;
    *((_QWORD *)v10 + 19) = v17;
    if( v42 < 0x40 )
      v18 = (1i64 << v42) - 1;
    else
      v18 = -1i64;
    *((_QWORD *)v10 + 17) = v18;
    if( v18 < v17->AdapterObject.MaximumPhysicalAddress.QuadPart )
    {
LABEL_24:
      HalPutDmaAdapter((PADAPTER_OBJECT)v10);
LABEL_25:
      v10 = 0i64;
      goto LABEL_26;
    }
    *((_QWORD *)v10 + 39) = 0i64;
    v10[338] = 0;
    *((_QWORD *)v10 + 24) = v10 + 184;
    *((_QWORD *)v10 + 23) = v10 + 184;
    *((_QWORD *)v10 + 22) = 0i64;
    v10[216] = 0;
    *((_DWORD *)v10 + 56) = NumberOfMapRegistersa;
    v10[434] = v43;
    v10[437] = ScatterGatherLimit;
    *((_QWORD *)v10 + 56) = AllocatedMapRegistersOut;
    v10[433] = CanCross64K;
    *((_DWORD *)v10 + 94) = -1;
    *((_DWORD *)v10 + 110) = v42;
    *((_DWORD *)v10 + 155) = v13;
    *((_DWORD *)v10 + 37) = 3;
    *((_DWORD *)v10 + 154) = 0;
    *((_QWORD *)v10 + 70) = 0i64;
    *((_QWORD *)v10 + 72) = v10 + 568;
    *((_QWORD *)v10 + 71) = v10 + 568;
    v10[584] = 0;
    *((_DWORD *)v10 + 152) = 0;
    *((_QWORD *)v10 + 61) = IoFreeAdapterChannelV3Passive;
    *((_QWORD *)v10 + 62) = v10;
    *((_QWORD *)v10 + 59) = 0i64;
    if( NumberOfMapRegistersa )
    {
      if( v43 )
        LocalScatterPool = HalpDmaAllocateLocalScatterPool((_ADAPTER_OBJECT *)v10, NumberOfMapRegistersa);
      else
        LocalScatterPool = HalpDmaAllocateLocalContiguousPool((_HALP_DMA_ADAPTER_OBJECT *)v10, NumberOfMapRegistersa);
      v16 = 0i64;
      if( LocalScatterPool < 0 )
        goto LABEL_24;
      v21 = *((_DWORD *)v10 + 56);
      v10[337] = 0;
    }
    else
    {
      *((_DWORD *)v10 + 56) = 0;
      v21 = 0;
      v10[337] = 1;
    }
    *v46 = v21;
    *((_DWORD *)v10 + 61) = v41;
    *((_DWORD *)v10 + 128) = 0;
    *((_QWORD *)v10 + 65) = v14;
    if( InterfaceSpecificData && HIBYTE(v35) )
    {
      v22 = (__int64)&v10[v13 + 640];
      *((_QWORD *)v10 + 66) = v22;
      v23 = (*(__int64(__fastcall **)(void *, PVOID, __int64, _QWORD))&Interface[2].Size)(
              Interface[0].Context,
              InterfaceSpecificData,
              v22,
              0i64);
      v16 = 0i64;
      if( v23 >= 0 )
      {
        AdapterByDeviceId = (_EX_PUSH_LOCK *)HalpDmaFindAdapterByDeviceId(*((_QWORD *)v10 + 66));
        v16 = 0i64;
        v9 = (_ADAPTER_OBJECT *)AdapterByDeviceId;
        if( AdapterByDeviceId )
        {
          if( AdapterByDeviceId[65].Ptr != v14 )
          {
            ExAcquirePushLockExclusiveEx(AdapterByDeviceId + 39, 0i64);
            LOBYTE(v35) = 1;
          }
          HalPutDmaAdapter(v9);
          v16 = 0i64;
        }
        if( v44 == 2 )
        {
          v25 = ((__int64(__fastcall *)(_QWORD, _QWORD))off_140C00A38[0])(*((_QWORD *)v10 + 66), 0i64);
          v16 = 0i64;
          if( v25 )
            goto LABEL_52;
          v15 = 0;
        }
      }
      else
      {
        *((_QWORD *)v10 + 66) = 0i64;
        if( SecurityPolicy == 1 )
          goto LABEL_61;
      }
    }
    if( !v15 )
    {
LABEL_56:
      *((_QWORD *)v10 + 63) = v16;
      if( HalJoinDmaDomain((_ADAPTER_OBJECT *)v10, (VOID *)0xFFFFFFFFFFFFFFFFi64) >= 0
        || SecurityPolicy != 1
        && *((_DWORD *)v10 + 128)
        && (*((_DWORD *)v10 + 128) = 0, HalJoinDmaDomain((_ADAPTER_OBJECT *)v10, (VOID *)0xFFFFFFFFFFFFFFFFi64) >= 0) )
      {
        v29 = v35;
        if( v9 )
          v9->ExpiredFlag = v35;
        *(_QWORD *)(*((_QWORD *)v10 + 63) + 72i64) = v10;
        goto LABEL_67;
      }
      HalpIommuDeleteDevice((UINT64 *)v10 + 67);
LABEL_61:
      HalPutDmaAdapter((PADAPTER_OBJECT)v10);
      v29 = v35;
      v10 = 0i64;
      Object = 0i64;
LABEL_67:
      if( v29 )
      {
        if( (_InterlockedExchangeAdd64(&v9->ExpiredLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
          ExfTryToWakePushLock(&v9->ExpiredLock);
        KeAbPostRelease(&v9->ExpiredLock);
        v10 = (char *)Object;
      }
LABEL_26:
      if( !HIBYTE(v35) )
      {
LABEL_28:
        if( v10 && HalpDmaIsThinApiCapable((INT64)v10) )
          *((_QWORD *)v10 + 1) = &HalpDmaOperationsThin;
        return(_ADAPTER_OBJECT *)v10;
      }
LABEL_27:
      Interface[0].InterfaceDereference(Interface[0].Context);
      goto LABEL_28;
    }
LABEL_52:
    v26 = *((_QWORD *)v10 + 66);
    if( v26 && !HalpIommuCheckExceptionList(v26) )
    {
      Device = HalpIommuCreateDevice(v27);
      v16 = 0i64;
      if( Device < 0 )
      {
        if( SecurityPolicy == 1 )
          goto LABEL_61;
      }
      else
      {
        *((_DWORD *)v10 + 128) = v15;
      }
    }
    goto LABEL_56;
  }
  return(_ADAPTER_OBJECT *)v10;
}

Referenced by:

HalGetAdapterV3