HalpDmaAllocateNewTranslationBuffer

_HALP_DMA_TRANSLATION_BUFFER *__stdcall HalpDmaAllocateNewTranslationBuffer(
        _HALP_DMA_ADAPTER_OBJECT *Adapter,
        UINT64 EntriesNeeded){
  unsigned int v2; 
  _HALP_DMA_MASTER_ADAPTER_OBJECT *v3; 
  _HALP_ALLOC_CONTEXT *v4; 
  _HALP_DMA_TRANSLATION_BUFFER *v5; 
  char v6; 
  unsigned int v7; 
  unsigned int v8; 
  unsigned __int64 v9; 
  UINT8 *v10; 
  _HALP_DMA_TRANSLATION_ENTRY *v11; 
  unsigned int v12; 
  _QWORD *p_Next; 
  _LARGE_INTEGER *v14; 
  _LARGE_INTEGER v15; 
  unsigned __int64 v16; 
  unsigned __int64 v17; 
  unsigned int v18; 
  __int64 v19; 
  union {void *VirtualAddress;struct {unsigned __int64 BoundToMaster : 1;unsigned __int64 BoundToScatterPool : 1;unsigned __int64 OwnedByMaster : 1;unsigned __int64 OwnedByScatterPool : 1;unsigned __int64 TemporaryMapping : 1;unsigned __int64 ZeroBuffer : 1;unsigned __int64 Address : 58;} Flags;} v20; 
  _HALP_DMA_TRANSLATION_ENTRY *Next; 
  UINT64 PagesAllocated; 
  _LARGE_INTEGER *v24; 

  LODWORD(PagesAllocated) = 0;
  v2 = EntriesNeeded;
  v3 = (_HALP_DMA_MASTER_ADAPTER_OBJECT *)Adapter;
  if( !Adapter->IsMasterAdapter )
    v3 = *(_HALP_DMA_MASTER_ADAPTER_OBJECT **)&Adapter[1].DmaHeader.Version;
  v5 = (_HALP_DMA_TRANSLATION_BUFFER *)HalpMmAllocCtxAlloc((_HALP_ALLOC_CONTEXT *)Adapter, 0x18ui64);
  if( v5 )
  {
    v6 = 1;
    v7 = 72 * v2;
    if( 72 * v2 >= 0x1000 )
      v8 = (v7 + 4095) & 0xFFFFF000;
    else
      v8 = 4096;
    v9 = v8;
    v10 = HalpMmAllocCtxAlloc(v4, v8);
    if( v10 || v7 < 0x1000 && (v9 = v7, (v10 = HalpMmAllocCtxAlloc(v4, v7)) != 0i64) )
    {
      v5->Entries = (_HALP_DMA_TRANSLATION_ENTRY *)v10;
      v5->Next = 0i64;
      v5->EntryCount = v9 / 0x48;
      return v5;
    }
  }
  else
  {
    v6 = 0;
  }
  v11 = 0i64;
  v24 = 0i64;
  v12 = 0;
  p_Next = 0i64;
  while( v2 )
  {
    v14 = (_LARGE_INTEGER *)HalpDmaAllocateScatterPagesFromScatterPool(
                              (_ADAPTER_OBJECT *)v4,
                              &v3->AdapterObject,
                              1ui64,
                              1u,
                              0,
                              &PagesAllocated);
    if( !v14 )
    {
      v14 = (_LARGE_INTEGER *)HalpDmaAllocateScatterPagesFromContiguousPool(
                                (_ADAPTER_OBJECT *)v4,
                                &v3->AdapterObject,
                                1ui64,
                                1u,
                                0,
                                &PagesAllocated);
      if( !v14 )
      {
LABEL_31:
        if( v12 )
        {
          v19 = v12;
          do
          {
            v20.VirtualAddress = (void *)v11->u;
            if( ((__int64)v20.VirtualAddress & 0x10) != 0 )
            {
              MmUnmapIoSpace((VOID *)((unsigned __int64)v20.VirtualAddress & 0xFFFFFFFFFFFFF000ui64), 0x1000ui64);
              v11->u.VirtualAddress = (void *)((__int64)v11->u.VirtualAddress & 0xFEF);
            }
            Next = v11->Next;
            HalpDmaReturnPageToOwner(0i64, v3, v11);
            v11 = Next;
            --v19;
          }
          while( v19 );
        }
        if( v6 )
          HalpMmAllocCtxFree(v4, v5);
        return 0i64;
      }
    }
    if( v11 )
      v24[1].QuadPart = (LONGLONG)v14;
    else
      v11 = (_HALP_DMA_TRANSLATION_ENTRY *)v14;
    v15 = v14[6];
    ++v12;
    v24 = v14;
    v16 = v15.QuadPart & 0xFFFFFFFFFFFFF000ui64;
    if( !v16 )
    {
      v17 = (unsigned __int64)MmMapIoSpaceEx(*v14, 0x1000ui64, 4ui64);
      v16 = v17;
      if( !v17 )
        goto LABEL_31;
      v14[6].QuadPart |= 0x10ui64;
      v4 = (_HALP_ALLOC_CONTEXT *)(v17 | v14[6].anonymous_0.LowPart & 0xFFF);
      v14[6].QuadPart = (LONGLONG)v4;
    }
    if( v12 == 1 && v6 )
    {
      v5->Next = 0i64;
      p_Next = &v5->Next;
      v5->Entries = (_HALP_DMA_TRANSLATION_ENTRY *)v16;
      v5->EntryCount = 56;
    }
    else
    {
      if( v5 )
        *p_Next = v16;
      else
        v5 = (_HALP_DMA_TRANSLATION_BUFFER *)v16;
      *(_QWORD *)v16 = 0i64;
      *(_QWORD *)(v16 + 16) = v16 + 24;
      p_Next = (_QWORD *)v16;
      *(_DWORD *)(v16 + 8) = 56;
    }
    v18 = v2;
    v2 -= 56;
    if( v18 <= 0x38 )
      v2 = 0;
  }
  return v5;
}

Referenced by:

HalpDmaGetTranslationEntries