HalGetAdapterV3

_HALP_DMA_CONTROLLER *__stdcall HalGetAdapterV3(
        const _UNICODE_STRING *DeviceDescriptor,
        _DEVICE_OBJECT *pNumberOfMapRegisters,
        UINT64 *er8){
  _DWORD *v3; 
  bool v5; 
  bool v6; 
  unsigned int v7; 
  unsigned int Buffer; 
  wchar_t *AllocatedMapRegistersOut; 
  _HALP_DMA_CONTROLLER *AdapterByRequestLine; 
  _HALP_DMA_CONTROLLER *v11; 
  char v12; 
  unsigned int v13; 
  _BOOL8 v14; 
  unsigned __int64 v15; 
  char v16; 
  unsigned int v17; 
  unsigned int v18; 
  _HALP_DMA_CONTROLLER *v19; 
  _LIST_ENTRY *AdapterByDeviceObject; 
  INT64 v21; 
  bool v22; 
  _ADAPTER_OBJECT *ChildAdapterV3; 
  char v24; 
  NTSTATUS AdapterVersion; 
  unsigned int v27; 
  _HALP_DMA_CONTROLLER *DmaControllerByRequestLine; 
  unsigned int v29; 
  unsigned int v30; 
  unsigned int MapBufferSize; 
  unsigned int v32; 
  _HALP_DMA_CONTROLLER *v33; 
  UINT64 ScatterGatherLimit; 
  _LARGE_INTEGER DeviceAddress; 
  char v36; 
  UINT8 CacheCoherent; 
  char v38; 
  bool v39; 
  unsigned int v40; 
  unsigned int RequestLine; 
  unsigned int RequestLine_4; 
  _HALP_DMA_CONTROLLER *Controller; 
  _MDL *Mdl; 
  char MasterDevice; 
  _DEVICE_OBJECT *DeviceObject; 
  int v47; 
  _DWORD *v48; 

  v48 = v3;
  v47 = (int)er8;
  DeviceObject = pNumberOfMapRegisters;
  v5 = *(_DWORD *)&DeviceDescriptor->Length < 3u;
  v6 = *(_DWORD *)&DeviceDescriptor->Length == 3;
  v36 = 0;
  Mdl = 0i64;
  v7 = 64;
  v39 = 0;
  if( v6 )
  {
    Buffer = (unsigned int)DeviceDescriptor[2].Buffer;
  }
  else
  {
    if( !v5 || (_DWORD)er8 != 2 || !*((_BYTE *)&DeviceDescriptor->MaximumLength + 2) )
      return 0i64;
    if( BYTE3(DeviceDescriptor->Buffer) )
    {
      Buffer = 64;
    }
    else if( LOBYTE(DeviceDescriptor->Buffer) || (Buffer = 24, *((_BYTE *)&DeviceDescriptor->MaximumLength + 3)) )
    {
      Buffer = 32;
    }
  }
  if( !pNumberOfMapRegisters )
    return 0i64;
  AllocatedMapRegistersOut = 0i64;
  RequestLine = 0;
  AdapterByRequestLine = 0i64;
  if( *((_BYTE *)&DeviceDescriptor->MaximumLength + 2) )
  {
    v38 = 0;
    v11 = 0i64;
    Controller = 0i64;
  }
  else
  {
    v27 = *(_DWORD *)&DeviceDescriptor[3].Length;
    AllocatedMapRegistersOut = DeviceDescriptor[3].Buffer;
    v38 = 1;
    RequestLine = v27;
    DmaControllerByRequestLine = HalpFindDmaControllerByRequestLine(v27);
    Controller = DmaControllerByRequestLine;
    v11 = DmaControllerByRequestLine;
    if( !DmaControllerByRequestLine )
      return 0i64;
    AdapterByRequestLine = HalpFindAdapterByRequestLine(DmaControllerByRequestLine, v27);
    if( !AdapterByRequestLine
      && !(unsigned __int8)HalpDmaControllerValidateRequestLineBinding(v11, (_DEVICE_DESCRIPTION *)DeviceDescriptor) )
    {
      return 0i64;
    }
    pNumberOfMapRegisters = DeviceObject;
  }
  v12 = *((_BYTE *)&DeviceDescriptor->MaximumLength + 2);
  v13 = ((*(_DWORD *)&DeviceDescriptor[2].Length & 0x7FFFFFFF) + 4095) & 0xFFFFF000;
  if( v12 )
  {
    MasterDevice = *((_BYTE *)&DeviceDescriptor->MaximumLength + 3);
    RequestLine_4 = 0;
  }
  else
  {
    v29 = v11->ScatterGatherLimit;
    Buffer = v11->DmaAddressWidth;
    MasterDevice = 1;
    if( v29 > 8 )
      v29 = 8;
    RequestLine_4 = v29;
  }
  if( Buffer >= 0x20 || (LODWORD(v14) = 0, v12) )
  {
    CacheCoherent = 1;
    v14 = Buffer >= 0x20;
  }
  else
  {
    CacheCoherent = 0;
  }
  HalpGetCacheCoherency((INT64)v11, pNumberOfMapRegisters, &v36);
  if( Buffer < 0x40 )
    v15 = (1i64 << Buffer) - 1;
  else
    v15 = -1i64;
  if( v15 < qword_140C4BA18 )
  {
    v16 = 0;
  }
  else
  {
    v16 = 1;
    if( v36 && MasterDevice && !v47 )
    {
      v17 = 0;
      v40 = 0;
      v18 = 0;
      goto LABEL_17;
    }
  }
  if( v14 )
  {
    if( MasterDevice && (v36 || !v16) )
      v7 = 512;
  }
  else
  {
    v7 = 16;
  }
  v17 = (v13 >> 12) + 1;
  v40 = v17;
  v30 = v17;
  if( v17 > v7 )
  {
    v17 = v7;
    v40 = v7;
    v30 = v7;
  }
  MapBufferSize = stru_140C4BB00.MapBufferSize;
  v18 = v30;
  if( !v14 )
    MapBufferSize = stru_140C4BA20.MapBufferSize;
  if( !CacheCoherent )
  {
    v32 = MapBufferSize >> 13;
    if( v30 > v32 )
    {
      v17 = v32;
      v40 = v32;
      v18 = v32;
    }
  }
LABEL_17:
  if( !v36 )
  {
    Mdl = IoAllocateMdl(0i64, v18 << 12, 0, 0, 0i64);
    if( !Mdl )
      return 0i64;
  }
  if( AdapterByRequestLine )
  {
    if( v18 > LODWORD(AdapterByRequestLine[1].Controllers.Flink) )
      LODWORD(AdapterByRequestLine[1].Controllers.Flink) = v17;
    AdapterByRequestLine[2].Controllers.Flink = (_LIST_ENTRY *)DeviceDescriptor[3].Buffer;
    ObReferenceObjectByPointer(AdapterByRequestLine, 0x20000ui64, HalpDmaAdapterObjectType, 0);
    goto LABEL_29;
  }
  KeWaitForSingleObject((UINT64)&word_140C49B80, 7, 0, 0, 0i64);
  v19 = Controller;
  if( v38 )
  {
    v33 = HalpFindAdapterByRequestLine(Controller, RequestLine);
    AdapterByRequestLine = v33;
    if( v33 )
    {
      if( v18 > LODWORD(v33[1].Controllers.Flink) )
        LODWORD(v33[1].Controllers.Flink) = v17;
      v33[2].Controllers.Flink = (_LIST_ENTRY *)DeviceDescriptor[3].Buffer;
      ObReferenceObjectByPointer(v33, 0x20000ui64, HalpDmaAdapterObjectType, 0);
      goto LABEL_28;
    }
  }
  AdapterByDeviceObject = HalpDmaFindAdapterByDeviceObject(DeviceObject);
  AdapterByRequestLine = (_HALP_DMA_CONTROLLER *)AdapterByDeviceObject;
  if( !AdapterByDeviceObject )
  {
    v22 = v39;
    goto LABEL_22;
  }
  AdapterVersion = HalpDmaGetAdapterVersion((_ADAPTER_OBJECT *)AdapterByDeviceObject);
  if( AdapterVersion != 3 )
  {
    HalPutDmaAdapter((PADAPTER_OBJECT)AdapterByRequestLine);
    AdapterByRequestLine = 0i64;
  }
  v22 = AdapterVersion != 3;
  if( !AdapterByRequestLine )
  {
LABEL_22:
    LOBYTE(v21) = MasterDevice;
    DeviceAddress.anonymous_0.LowPart = RequestLine_4;
    LOBYTE(ScatterGatherLimit) = v36;
    ChildAdapterV3 = HalpDmaAllocateChildAdapterV3(
                       v17,
                       v13,
                       Buffer,
                       v21,
                       *((_BYTE *)&DeviceDescriptor->MaximumLength + 2),
                       CacheCoherent,
                       ScatterGatherLimit,
                       DeviceAddress,
                       (UINT64 *)AllocatedMapRegistersOut);
    AdapterByRequestLine = (_HALP_DMA_CONTROLLER *)ChildAdapterV3;
    if( ChildAdapterV3 )
    {
      v6 = v38 == 0;
      ChildAdapterV3->AdapterInUse = v22;
      if( v6 )
      {
        ChildAdapterV3->DeviceObject = DeviceObject;
        HalpAddAdapterToList(ChildAdapterV3);
      }
      else
      {
        HalpAddAdapterToSystemList(v19, ChildAdapterV3);
        LODWORD(AdapterByRequestLine[1].Operations.CancelTransfer) = RequestLine;
        HIDWORD(AdapterByRequestLine[1].Operations.ReportCommonBuffer) = *(_DWORD *)&DeviceDescriptor[1].Length;
        AdapterByRequestLine[1].Operations.ReadDmaCounter = (unsigned int(__fastcall *)(void *, unsigned int))v19;
        *((_DWORD *)&AdapterByRequestLine[1].PowerActive + 1) = DeviceDescriptor[1].Buffer;
        ObReferenceObjectByPointer(AdapterByRequestLine, 0x20000ui64, HalpDmaAdapterObjectType, 0);
      }
      v24 = v40;
      if( v40 )
      {
        LODWORD(AdapterByRequestLine[1].Controllers.Flink) = v40;
        v24 = 1;
      }
      else
      {
        LODWORD(AdapterByRequestLine[1].Controllers.Flink) = (v13 >> 12) + 1;
      }
      LOBYTE(AdapterByRequestLine[1].PowerHandle) = v24;
      AdapterByRequestLine[1].Operations.InitializeController = 0i64;
      goto LABEL_28;
    }
    goto LABEL_87;
  }
  if( !*((_BYTE *)&DeviceDescriptor->MaximumLength + 2)
    || *((_BYTE *)&DeviceDescriptor->MaximumLength + 3) != BYTE2(AdapterByRequestLine[1].PowerHandle)
    || BYTE1(DeviceDescriptor->Buffer) != BYTE4(AdapterByRequestLine[1].PowerHandle)
    || Buffer != *(_DWORD *)&AdapterByRequestLine[1].PowerActive )
  {
    if( !HalpDmaIsAutomaticDomain(AdapterByRequestLine[2].Channels)
      || LODWORD(AdapterByRequestLine[2].ExtensionData) == 2
      || v47 == 2 )
    {
      HalPutDmaAdapter((PADAPTER_OBJECT)AdapterByRequestLine);
LABEL_87:
      KeSetEvent((PRKEVENT)&word_140C49B80, 0, 0);
      return 0i64;
    }
    BYTE4(AdapterByRequestLine[2].ExtensionData) = 1;
    HalPutDmaAdapter((PADAPTER_OBJECT)AdapterByRequestLine);
    v22 = 1;
    goto LABEL_22;
  }
LABEL_28:
  KeSetEvent((PRKEVENT)&word_140C49B80, 0, 0);
LABEL_29:
  BYTE3(AdapterByRequestLine[1].PowerHandle) = *((_BYTE *)&DeviceDescriptor->MaximumLength + 5);
  BYTE4(AdapterByRequestLine[1].PowerHandle) = 0;
  if( *(_DWORD *)&DeviceDescriptor->Length )
    BYTE4(AdapterByRequestLine[1].PowerHandle) = BYTE1(DeviceDescriptor->Buffer);
  *v48 = AdapterByRequestLine[1].Controllers.Flink;
  *(_QWORD *)&AdapterByRequestLine[1].CacheCoherent = Mdl;
  return AdapterByRequestLine;
}

Referenced by:

HalpGetAdapter