HalpDmaAllocateMapRegisters

__int64 __fastcall HalpDmaAllocateMapRegisters(__int64 a1, unsigned int a2, __int64 a3, __int64 a4){
  __int64 v4; 
  unsigned int v5; 
  __int64 v8; 
  __int64 result; 
  __int64 v10; 
  __int64 v11; 
  __int64 ScatterPagesFromScatterPool; 
  __int64 v13; 
  __int64 v14; 
  __int64 ScatterPagesFromContiguousPool; 
  __int64 v16; 
  unsigned int v17; 
  PVOID v18; 
  __int64 v19; 
  MDL *v20; 
  unsigned int v21; 
  __int64 v22; 
  __int64 v23; 
  __int64 v24; 
  __int64 v25; 
  _QWORD *v26; 
  void *v27; 
  _HALP_DMA_TRANSLATION_ENTRY *TranslationEntries; 
  __int64 *v29; 
  __int64 v30; 
  __int64 v31; 
  __int64 v32; 
  _QWORD *v33; 
  PVOID *v34; 
  __int64 v35; 
  unsigned __int64 v36; 
  __int64 v37; 
  __int64 v38; 
  PVOID BaseAddress; 
  PMDL MemoryDescriptorList; 
  struct _KLOCK_QUEUE_HANDLE LockHandle; 
  unsigned int v42; 
  int v43; 
  PHYSICAL_ADDRESS v44; 
  LODWORD(v4) = 0;
  v5 = 0;
  v42 = 0;
  v43 = 0;
  v8 = 0i64;
  BaseAddress = 0i64;
  v44.QuadPart = 0i64;
  MemoryDescriptorList = 0i64;
  memset(&LockHandle, 0, sizeof(LockHandle));
  if( !*(_BYTE *)(a1 + 337) )
  {
    if( *(_BYTE *)(a1 + 434) )
    {
      result = HalpDmaAllocateScatterPagesFromScatterPool(a1, a1, a2, 0i64, 0, &v42);
      v5 = v42;
      v8 = result;
      if( v42 == a2 )
        return result;
    }
    else
    {
      LOBYTE(a4) = 1;
      result = HalpDmaAllocateContiguousPagesFromContiguousPool(a1, a1, a2, a4, 0, &v42);
      v8 = result;
      if( result )
        return result;
      v5 = v42;
    }
  }
  v10 = *(_QWORD *)(a1 + 152);
  if( *(_BYTE *)(a1 + 434) )
  {
    ScatterPagesFromScatterPool = HalpDmaAllocateScatterPagesFromScatterPool(
                                    a1,
                                    v10,
                                    a2 - v5,
                                    0i64,
                                    0,
                                    (unsigned int *)&v43);
    if( ScatterPagesFromScatterPool )
    {
      v14 = HalpDmaPrependTranslations(ScatterPagesFromScatterPool, v43, v8);
      v5 += v43;
      v8 = v14;
      v42 = v5;
    }
    if( v5 == a2 )
      return v8;
    ScatterPagesFromContiguousPool = HalpDmaAllocateScatterPagesFromContiguousPool(
                                       v13,
                                       *(_QWORD *)(a1 + 152),
                                       a2 - v5,
                                       0i64,
                                       0,
                                       (ULONG *)&v43);
    if( ScatterPagesFromContiguousPool )
    {
      v16 = HalpDmaPrependTranslations(ScatterPagesFromContiguousPool, v43, v8);
      v5 += v43;
      v8 = v16;
      v42 = v5;
    }
    if( v5 == a2 )
      return v8;
  }
  else
  {
    LOBYTE(a4) = 1;
    result = HalpDmaAllocateContiguousPagesFromContiguousPool(a1, v10, a2, a4, 0, &v42);
    v8 = result;
    if( result )
      return result;
    v5 = v42;
  }
  if( !*(_BYTE *)(a1 + 434) )
  {
    v17 = HalpDmaAllocateContiguousMemory(a1, a2, &BaseAddress, &v44, &MemoryDescriptorList);
    v42 = v17;
    if( v17 )
    {
      v18 = BaseAddress;
      if( HalpDmaCommitContiguousMapBuffers(*(_QWORD *)(a1 + 152), (__int64)BaseAddress, v44.QuadPart, v17) )
      {
        LOBYTE(v19) = 1;
        result = HalpDmaAllocateContiguousPagesFromContiguousPool(a1, *(_QWORD *)(a1 + 152), a2, v19, 0, &v42);
        if( result )
          return result;
      }
      else
      {
        v20 = MemoryDescriptorList;
        if( MemoryDescriptorList )
        {
          if( v18 )
            MmUnmapLockedPages(v18, MemoryDescriptorList);
          MiFreePagesFromMdl(v20, 0i64);
          ExFreePoolWithTag(v20, 0);
        }
        else
        {
          MmFreeContiguousMemory(v18);
        }
      }
    }
    return 0i64;
  }
  v21 = a2 - v5;
  v22 = v21;
  v23 = HalpMmAllocCtxAlloc(v11, 8i64 * v21);
  v25 = v23;
  if( !v23 )
  {
LABEL_38:
    if( v5 )
    {
      v30 = v5;
      do
      {
        v31 = *(_QWORD *)(v8 + 8);
        HalpDmaReturnPageToOwner(a1, *(_QWORD *)(a1 + 152), v8);
        v8 = v31;
        --v30;
      }
      while( v30 );
    }
    return 0i64;
  }
  if( v21 )
  {
    v26 = (_QWORD *)v23;
    while( 1 )
    {
      v27 = (void *)HalpMmAllocCtxAlloc(v24, 4096i64);
      *v26 = v27;
      if( !v27 || MmGetPhysicalAddress(v27).HighPart )
        goto LABEL_34;
      LODWORD(v4) = v4 + 1;
      ++v26;
      if( (unsigned int)v4 >= v21 )
      {
        v22 = v21;
        break;
      }
    }
  }
  TranslationEntries = HalpDmaGetTranslationEntries(
                         *(_HALP_DMA_ADAPTER_OBJECT **)(a1 + 152),
                         HalpDmaNonContiguousMapBuffer,
                         v21);
  if( !TranslationEntries )
  {
LABEL_34:
    if( (_DWORD)v4 )
    {
      v29 = (__int64 *)v25;
      v4 = (unsigned int)v4;
      do
      {
        HalpMmAllocCtxFree(v24, *v29++);
        --v4;
      }
      while( v4 );
    }
    HalpMmAllocCtxFree(v24, v25);
    goto LABEL_38;
  }
  v32 = HalpDmaPrependTranslations((__int64)TranslationEntries, v21, v8);
  v33 = (_QWORD *)v32;
  if( v21 )
  {
    v34 = (PVOID *)v25;
    do
    {
      *v33 = MmGetPhysicalAddress(*v34).LowPart;
      v35 = 1i64;
      v36 = (unsigned __int64)*v34;
      v37 = 2i64;
      do
      {
        v36 |= v35++;
        --v37;
      }
      while( v37 );
      ++v34;
      v33[6] = v36 | 0xC;
      v33 = (_QWORD *)v33[1];
      --v22;
    }
    while( v22 );
  }
  KeAcquireInStackQueuedSpinLock((UINT64 *)(*(_QWORD *)(a1 + 152) + 120i64), &LockHandle);
  *(_DWORD *)(*(_QWORD *)(a1 + 152) + 208i64) += v21;
  KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
  __writecr8(LockHandle.OldIrql);
  HalpMmAllocCtxFree(v38, v25);
  return v32;
}

Referenced by:

HalAllocateAdapterChannelV2
HalDmaAllocateCrashDumpRegistersEx
HalpAllocateDmaResourcesInternal
HalpAllocateMapRegisters
HalpDmaProcessMapRegisterQueueV2
IoFreeAdapterChannelV2