HalGetAdapterV2

char *__fastcall HalGetAdapterV2(__int64 a1, _DEVICE_OBJECT *a2, _DWORD *a3){
  bool v4; 
  char v5; 
  char v6; 
  unsigned int v7; 
  int v8; 
  char v9; 
  char v10; 
  char v11; 
  unsigned int v12; 
  unsigned int v13; 
  __int64 v14; 
  __int64 v15; 
  LIST_ENTRY *AdapterByDeviceObject; 
  struct _DMA_ADAPTER *v17; 
  char *v18; 
  char *v19; 
  char v20; 
  unsigned int v22; 
  unsigned int v23; 
  unsigned int v24; 
  unsigned int v25; 
  int AdapterVersion; 
  bool IsAutomaticDomain; 
  __int64 v28; 
  char v29; 
  PMDL Mdl; 
  char v31; 
  _DEVICE_OBJECT *DeviceObject; 
  unsigned int v34; 
  DeviceObject = a2;
  v4 = *(_DWORD *)a1 <= 2u;
  LOBYTE(v34) = 0;
  Mdl = 0i64;
  if( !v4 )
    return 0i64;
  if( *(_BYTE *)(a1 + 4) && (*(_DWORD *)(a1 + 20) != 1 || *(_DWORD *)(a1 + 16) > 7u) )
  {
    v5 = 0;
    v31 = 0;
  }
  else
  {
    v5 = 1;
    v31 = 1;
    if( !(*(unsigned __int8(**)(void))(DmaDispatch + 8))() )
      return 0i64;
    a2 = DeviceObject;
  }
  v6 = *(_BYTE *)(a1 + 4);
  v7 = *(_DWORD *)(a1 + 32) & 0x7FFFFFFF;
  if( v6 && *(_BYTE *)(a1 + 5) )
    *(_BYTE *)(a1 + 8) = 1;
  if( *(_BYTE *)(a1 + 11) )
  {
    *(_BYTE *)(a1 + 8) = 1;
  }
  else if( !*(_BYTE *)(a1 + 8) )
  {
    v8 = 0;
    v9 = 0;
    if( !v6 )
      goto LABEL_12;
    goto LABEL_11;
  }
  v8 = 1;
LABEL_11:
  v9 = 1;
LABEL_12:
  v29 = v9;
  if( v5 || !a2 )
  {
    v10 = 1;
    goto LABEL_15;
  }
  HalpGetCacheCoherency(0i64, a2, (BYTE *)&v34);
  v10 = v34;
  if( !(_BYTE)v34 )
    return 0i64;
LABEL_15:
  v11 = *(_BYTE *)(a1 + 5);
  if( v11 && v10 && ((unsigned __int64)HalpMaximumPhysicalMemoryAddress < 0x100000000i64 || *(_BYTE *)(a1 + 11)) )
  {
    v12 = 0;
    v34 = 0;
    v13 = 0;
  }
  else
  {
    if( v8 )
    {
      v22 = 64;
      if( v11 )
        v22 = v10 != 0 ? 512 : 64;
    }
    else
    {
      v22 = 16;
    }
    v12 = (v7 >> 12) + ((v7 & 0xFFF) != 0) + 1;
    v34 = v12;
    v23 = v12;
    if( v12 > v22 )
    {
      v12 = v22;
      v34 = v22;
      v23 = v22;
    }
    v24 = dword_140C4B9F8;
    v13 = v23;
    if( !v8 )
      v24 = dword_140C4B918;
    if( !v9 )
    {
      v25 = v24 >> 13;
      if( v23 > v25 )
      {
        v12 = v25;
        v34 = v25;
        v13 = v25;
      }
    }
  }
  if( !v10 )
  {
    Mdl = IoAllocateMdl(0i64, v13 << 12, 0, 0, 0i64);
    if( !Mdl )
      return 0i64;
  }
  v14 = *(unsigned int *)(a1 + 16);
  v15 = v14;
  if( v31 )
  {
    v19 = *(char **)(HalpDmaAdapters + 8 * v14);
    if( v19 )
    {
      if( v13 > *((_DWORD *)v19 + 56) )
        *((_DWORD *)v19 + 56) = v12;
      ObReferenceObjectByPointer(v19, 0x20000u, HalpDmaAdapterObjectType, 0);
      goto LABEL_31;
    }
  }
  KeWaitForSingleObject(&HalpNewAdapter, WrExecutive, 0, 0, 0i64);
  if( v31 )
  {
    v19 = *(char **)(HalpDmaAdapters + 8 * v14);
    if( v19 )
    {
      if( v13 > *((_DWORD *)v19 + 56) )
        *((_DWORD *)v19 + 56) = v12;
      ObReferenceObjectByPointer(v19, 0x20000u, HalpDmaAdapterObjectType, 0);
      goto LABEL_30;
    }
  }
  if( DeviceObject )
  {
    AdapterByDeviceObject = HalpDmaFindAdapterByDeviceObject(DeviceObject);
    v17 = (struct _DMA_ADAPTER *)AdapterByDeviceObject;
    if( AdapterByDeviceObject )
    {
      AdapterVersion = HalpDmaGetAdapterVersion((__int64)AdapterByDeviceObject);
      IsAutomaticDomain = HalpDmaIsAutomaticDomain(v17[31].DmaOperations);
      HalPutDmaAdapter(v17);
      if( AdapterVersion != 2 && !IsAutomaticDomain )
        goto LABEL_72;
      LODWORD(v14) = v15;
    }
  }
  v18 = HalpDmaAllocateChildAdapterV2(
          v12,
          *(_BYTE *)(a1 + 8),
          *(_BYTE *)(a1 + 11),
          *(_BYTE *)(a1 + 5),
          *(_BYTE *)(a1 + 4),
          v29,
          v10,
          &v34);
  v19 = v18;
  if( !v18 )
  {
LABEL_72:
    KeSetEvent(&HalpNewAdapter, 0);
    return 0i64;
  }
  v18[516] = 1;
  if( v31 )
  {
    *(_QWORD *)(HalpDmaAdapters + 8 * v15) = v18;
    v28 = (*(__int64(__fastcall **)(__int64))(DmaDispatch + 24))(a1);
    if( v28 )
    {
      *((_QWORD *)v19 + 53) = v28;
      ObReferenceObjectByPointer(v19, 0x20000u, HalpDmaAdapterObjectType, 0);
      goto LABEL_27;
    }
    goto LABEL_72;
  }
LABEL_27:
  if( v34 )
  {
    *((_DWORD *)v19 + 56) = v34;
    v20 = 1;
  }
  else
  {
    *((_DWORD *)v19 + 56) = (v7 >> 12) + ((v7 & 0xFFF) != 0) + 1;
    v20 = 0;
  }
  v19[432] = v20;
  *((_QWORD *)v19 + 38) = 0i64;
LABEL_30:
  KeSetEvent(&HalpNewAdapter, 0);
LABEL_31:
  v19[436] = 0;
  if( *(_DWORD *)a1 )
    v19[436] = *(_BYTE *)(a1 + 9);
  *a3 = *((_DWORD *)v19 + 56);
  *((_QWORD *)v19 + 37) = Mdl;
  if( v31 )
  {
    *((_DWORD *)v19 + 93) = v14;
  }
  else
  {
    *((_QWORD *)v19 + 65) = DeviceObject;
    HalpAddAdapterToList(v19);
  }
  return v19;
}

Referenced by:

HalpGetAdapter