HalGetAdapterV3

VOID __fastcall HalGetAdapterV3(GUID *a1){
  DEVICE_OBJECT *v1; 
  int v2; 
  _DWORD *v3; 
  bool v5; 
  bool v6; 
  unsigned int v7; 
  unsigned int v8; 
  __int64 v9; 
  _QWORD *AdapterByRequestLine; 
  INT64 v11; 
  char Data2; 
  unsigned int v13; 
  _BOOL8 v14; 
  unsigned __int64 v15; 
  char v16; 
  unsigned int v17; 
  unsigned int v18; 
  __int64 v19; 
  LIST_ENTRY *AdapterByDeviceObject; 
  char v21; 
  char *v22; 
  char v23; 
  int AdapterVersion; 
  int Data1; 
  __int64 DmaControllerByRequestLine; 
  char v27; 
  unsigned int v28; 
  unsigned int v29; 
  unsigned int v30; 
  unsigned int v31; 
  _QWORD *v32; 
  BYTE v33; 
  char v34; 
  char v35; 
  char v36; 
  unsigned int v37; 
  int v38; 
  int v39; 
  __int64 v40; 
  PMDL Mdl; 
  char Data2_high; 
  DEVICE_OBJECT *DeviceObject; 
  int v44; 
  _DWORD *v45; 
  v45 = v3;
  v44 = v2;
  DeviceObject = v1;
  v5 = a1->Data1 < 3;
  v6 = a1->Data1 == 3;
  v33 = 0;
  Mdl = 0i64;
  v7 = 64;
  v36 = 0;
  if( v6 )
  {
    v8 = *(_DWORD *)a1[2].Data4;
  }
  else
  {
    if( !v5 || v2 != 2 || !LOBYTE(a1->Data2) )
      return;
    if( a1->Data4[3] )
    {
      v8 = 64;
    }
    else if( a1->Data4[0] || (v8 = 24, HIBYTE(a1->Data2)) )
    {
      v8 = 32;
    }
  }
  if( !v1 )
    return;
  v9 = 0i64;
  v38 = 0;
  AdapterByRequestLine = 0i64;
  if( LOBYTE(a1->Data2) )
  {
    v35 = 0;
    v11 = 0i64;
    v40 = 0i64;
  }
  else
  {
    Data1 = a1[3].Data1;
    v9 = *(_QWORD *)a1[3].Data4;
    v35 = 1;
    v38 = Data1;
    DmaControllerByRequestLine = HalpFindDmaControllerByRequestLine(Data1);
    v40 = DmaControllerByRequestLine;
    v11 = DmaControllerByRequestLine;
    if( !DmaControllerByRequestLine )
      return;
    AdapterByRequestLine = HalpFindAdapterByRequestLine(DmaControllerByRequestLine, Data1);
    if( !AdapterByRequestLine )
    {
      HalpDmaControllerValidateRequestLineBinding((UINT64 *)v11, (UINT8 *)a1);
      if( !v27 )
        return;
    }
    v1 = DeviceObject;
  }
  Data2 = a1->Data2;
  v13 = ((a1[2].Data1 & 0x7FFFFFFF) + 4095) & 0xFFFFF000;
  if( Data2 )
  {
    Data2_high = HIBYTE(a1->Data2);
    v39 = 0;
  }
  else
  {
    v28 = *(_DWORD *)(v11 + 48);
    v8 = *(_DWORD *)(v11 + 76);
    Data2_high = 1;
    if( v28 > 8 )
      v28 = 8;
    v39 = v28;
  }
  if( v8 >= 0x20 || (LODWORD(v14) = 0, Data2) )
  {
    v34 = 1;
    v14 = v8 >= 0x20;
  }
  else
  {
    v34 = 0;
  }
  HalpGetCacheCoherency(v11, v1, &v33);
  if( v8 < 0x40 )
    v15 = (1i64 << v8) - 1;
  else
    v15 = -1i64;
  if( v15 < HalpMaximumPhysicalMemoryAddress )
  {
    v16 = 0;
  }
  else
  {
    v16 = 1;
    if( v33 && Data2_high && !v44 )
    {
      v17 = 0;
      v37 = 0;
      v18 = 0;
      goto LABEL_17;
    }
  }
  if( v14 )
  {
    if( Data2_high && (v33 || !v16) )
      v7 = 512;
  }
  else
  {
    v7 = 16;
  }
  v17 = (v13 >> 12) + 1;
  v37 = v17;
  v29 = v17;
  if( v17 > v7 )
  {
    v17 = v7;
    v37 = v7;
    v29 = v7;
  }
  v30 = dword_140C4BBB8;
  v18 = v29;
  if( !v14 )
    v30 = dword_140C4BAD8;
  if( !v34 )
  {
    v31 = v30 >> 13;
    if( v29 > v31 )
    {
      v17 = v31;
      v37 = v31;
      v18 = v31;
    }
  }
LABEL_17:
  if( !v33 )
  {
    Mdl = IoAllocateMdl(0i64, v18 << 12, 0, 0, 0i64);
    if( !Mdl )
      return;
  }
  if( AdapterByRequestLine )
  {
    if( v18 > *((_DWORD *)AdapterByRequestLine + 56) )
      *((_DWORD *)AdapterByRequestLine + 56) = v17;
    AdapterByRequestLine[56] = *(_QWORD *)a1[3].Data4;
    ObReferenceObjectByPointer(AdapterByRequestLine, 0x20000u, HalpDmaAdapterObjectType, 0);
    goto LABEL_29;
  }
  KeWaitForSingleObject(&HalpNewAdapter, WrExecutive, 0, 0, 0i64);
  v19 = v40;
  if( v35 )
  {
    v32 = HalpFindAdapterByRequestLine(v40, v38);
    AdapterByRequestLine = v32;
    if( v32 )
    {
      if( v18 > *((_DWORD *)v32 + 56) )
        *((_DWORD *)v32 + 56) = v17;
      v32[56] = *(_QWORD *)a1[3].Data4;
      ObReferenceObjectByPointer(v32, 0x20000u, HalpDmaAdapterObjectType, 0);
      goto LABEL_28;
    }
  }
  AdapterByDeviceObject = HalpDmaFindAdapterByDeviceObject(DeviceObject);
  AdapterByRequestLine = &AdapterByDeviceObject->Flink;
  if( !AdapterByDeviceObject )
  {
    v21 = v36;
    goto LABEL_22;
  }
  AdapterVersion = HalpDmaGetAdapterVersion((__int64)AdapterByDeviceObject);
  if( AdapterVersion != 3 )
  {
    HalPutDmaAdapter((PADAPTER_OBJECT)AdapterByRequestLine);
    AdapterByRequestLine = 0i64;
  }
  v21 = AdapterVersion != 3;
  if( !AdapterByRequestLine )
  {
LABEL_22:
    v22 = HalpDmaAllocateChildAdapterV3(v17, v13, v8, Data2_high, a1->Data2, v34, v33, v39, v9, v44, DeviceObject, &v37);
    AdapterByRequestLine = v22;
    if( v22 )
    {
      v6 = v35 == 0;
      v22[516] = v21;
      if( v6 )
      {
        *((_QWORD *)v22 + 65) = DeviceObject;
        HalpAddAdapterToList(v22);
      }
      else
      {
        HalpAddAdapterToSystemList(v19, (__int64)v22);
        *((_DWORD *)AdapterByRequestLine + 94) = v38;
        *((_DWORD *)AdapterByRequestLine + 93) = a1[1].Data1;
        AdapterByRequestLine[45] = v19;
        *((_DWORD *)AdapterByRequestLine + 111) = *(_DWORD *)a1[1].Data4;
        ObReferenceObjectByPointer(AdapterByRequestLine, 0x20000u, HalpDmaAdapterObjectType, 0);
      }
      v23 = v37;
      if( v37 )
      {
        *((_DWORD *)AdapterByRequestLine + 56) = v37;
        v23 = 1;
      }
      else
      {
        *((_DWORD *)AdapterByRequestLine + 56) = (v13 >> 12) + 1;
      }
      *((_BYTE *)AdapterByRequestLine + 432) = v23;
      AdapterByRequestLine[38] = 0i64;
      goto LABEL_28;
    }
LABEL_87:
    KeSetEvent(&HalpNewAdapter, 0);
    return;
  }
  if( !LOBYTE(a1->Data2)
    || HIBYTE(a1->Data2) != *((_BYTE *)AdapterByRequestLine + 434)
    || a1->Data4[1] != *((_BYTE *)AdapterByRequestLine + 436)
    || v8 != *((_DWORD *)AdapterByRequestLine + 110) )
  {
    if( !HalpDmaIsAutomaticDomain((PVOID)AdapterByRequestLine[63])
      || *((_DWORD *)AdapterByRequestLine + 128) == 2
      || v44 == 2 )
    {
      HalPutDmaAdapter((PADAPTER_OBJECT)AdapterByRequestLine);
      goto LABEL_87;
    }
    *((_BYTE *)AdapterByRequestLine + 516) = 1;
    HalPutDmaAdapter((PADAPTER_OBJECT)AdapterByRequestLine);
    v21 = 1;
    goto LABEL_22;
  }
LABEL_28:
  KeSetEvent(&HalpNewAdapter, 0);
LABEL_29:
  *((_BYTE *)AdapterByRequestLine + 435) = HIBYTE(a1->Data3);
  *((_BYTE *)AdapterByRequestLine + 436) = 0;
  if( a1->Data1 )
    *((_BYTE *)AdapterByRequestLine + 436) = a1->Data4[1];
  *v45 = *((_DWORD *)AdapterByRequestLine + 56);
  AdapterByRequestLine[37] = Mdl;
}

Referenced by:

HalpGetAdapter