HalpDmaAllocateLocalContiguousPool

NTSTATUS __fastcall HalpDmaAllocateLocalContiguousPool(_HALP_DMA_ADAPTER_OBJECT *AdapterObject, UINT64 PageCount){
  unsigned int v2; 
  unsigned int v3; 
  _RTL_BITMAP *v5; 
  _RTL_BITMAP *v6; 
  char v8; 
  _HALP_ALLOC_CONTEXT *v9; 
  __int64 v10; 
  bool v11; 
  int v12; 
  UINT8 *v13; 
  _HALP_ALLOC_CONTEXT *v14; 
  _HALP_DMA_TRANSLATION_ENTRY *v15; 
  _HALP_DMA_TRANSLATION_BUFFER *v16; 
  UINT8 *v17; 
  _HALP_ALLOC_CONTEXT *v18; 
  UINT8 *v19; 
  UINT64 v20; 
  _HALP_ALLOC_CONTEXT *v21; 
  _MDL *v22; 
  UINT8 *v23; 
  _HALP_DMA_TRANSLATION_ENTRY *v24; 
  unsigned int v25; 
  _HALP_DMA_TRANSLATION_ENTRY *v26; 
  _QWORD *v27; 
  _HALP_DMA_TRANSLATION_ENTRY *v28; 
  UINT8 *v29; 
  _HALP_DMA_TRANSLATION_BUFFER *ContiguousTranslations; 
  _HALP_DMA_TRANSLATION_BUFFER *Next; 
  _HALP_DMA_TRANSLATION_ENTRY *v32; 
  _MDL **MdlOut; 
  VOID *VirtualAddressOut; 
  UINT64 PhysicalAddress; 
  unsigned int v36; 
  unsigned int v37; 
  UINT64 NumberToClear; 
  _MDL *MemoryDescriptorList; 
  UINT64 PhysicalAddressOut; 

  VirtualAddressOut = 0i64;
  PhysicalAddressOut = 0i64;
  v2 = PageCount;
  MemoryDescriptorList = 0i64;
  v3 = (PageCount + 31) & 0xFFFFFFE0;
  v5 = (_RTL_BITMAP *)HalpMmAllocCtxAlloc((_HALP_ALLOC_CONTEXT *)AdapterObject, ((unsigned __int64)v3 >> 3) + 16);
  v6 = v5;
  if( !v5 )
    return -1073741670;
  v5->SizeOfBitMap = v3;
  v5->Buffer = &v5[1].SizeOfBitMap;
  RtlSetAllBits(v5);
  AdapterObject->ContiguousMapRegisters = v6;
  v8 = 1;
LABEL_4:
  LODWORD(v10) = HalpDmaAllocateContiguousMemory(
                   AdapterObject,
                   v2,
                   &VirtualAddressOut,
                   &PhysicalAddressOut,
                   &MemoryDescriptorList);
  LODWORD(NumberToClear) = v10;
  if( !(_DWORD)v10 )
    goto LABEL_18;
  v11 = AdapterObject->DmaCanCross64K == 0;
  PhysicalAddress = PhysicalAddressOut;
  if( v11 )
  {
    v9 = (_HALP_ALLOC_CONTEXT *)(PhysicalAddressOut >> 16);
    v12 = ((((unsigned __int64)(unsigned int)v10 << 12) + PhysicalAddressOut - 1) >> 16) - (PhysicalAddressOut >> 16);
  }
  else
  {
    v12 = 0;
  }
  v13 = HalpMmAllocCtxAlloc(v9, 0x18ui64);
  v15 = (_HALP_DMA_TRANSLATION_ENTRY *)VirtualAddressOut;
  v16 = (_HALP_DMA_TRANSLATION_BUFFER *)v13;
  if( !v13 )
  {
LABEL_13:
    v22 = MemoryDescriptorList;
    if( MemoryDescriptorList )
    {
      if( v15 )
        MmUnmapLockedPages(v15, MemoryDescriptorList);
      MmFreePagesFromMdl(v22);
      ExFreePoolWithTag(v22, 0);
    }
    else
    {
      MmFreeContiguousMemory(v15);
    }
LABEL_18:
    LOBYTE(MdlOut) = 1;
    v24 = HalpDmaAllocateContiguousPagesFromContiguousPool(
            (_ADAPTER_OBJECT *)AdapterObject,
            *(_HALP_DMA_ADAPTER_OBJECT **)&AdapterObject[1].DmaHeader.Version,
            v2,
            0i64,
            (INT64)MdlOut,
            &NumberToClear);
    if( !v24 )
      goto LABEL_19;
    v10 = (unsigned int)NumberToClear;
    v25 = 0;
    v26 = 0i64;
    v27 = 0i64;
    v23 = 0i64;
    v28 = v24;
    while( 1 )
    {
      v37 = v25;
      if( v25 >= (unsigned int)v10 )
      {
        RtlClearBits(AdapterObject->ContiguousMapRegisters, 0, v10);
        goto LABEL_43;
      }
      if( v24 == v28 || v26 != &v24[-1] )
      {
        v29 = HalpMmAllocCtxAlloc((_HALP_ALLOC_CONTEXT *)v23, 0x18ui64);
        v23 = v29;
        if( !v29 )
        {
          if( v27 )
          {
            ContiguousTranslations = AdapterObject->ContiguousTranslations;
            if( ContiguousTranslations )
            {
              do
              {
                Next = ContiguousTranslations->Next;
                HalpMmAllocCtxFree((_HALP_ALLOC_CONTEXT *)v23, ContiguousTranslations);
                ContiguousTranslations = Next;
              }
              while( Next );
            }
          }
          if( (_DWORD)v10 )
          {
            do
            {
              v32 = v28->Next;
              HalpDmaReturnPageToSource(AdapterObject, v28);
              v28 = v32;
              --v10;
            }
            while( v10 );
          }
LABEL_19:
          if( v2 <= 1 )
          {
            HalpMmAllocCtxFree((_HALP_ALLOC_CONTEXT *)v23, AdapterObject->ContiguousMapRegisters);
            return -1073741670;
          }
          v2 >>= 1;
          goto LABEL_4;
        }
        if( v27 )
          *v27 = v29;
        else
          AdapterObject->ContiguousTranslations = (_HALP_DMA_TRANSLATION_BUFFER *)v29;
        *(_QWORD *)v29 = 0i64;
        v27 = v29;
        *((_QWORD *)v29 + 1) = 0i64;
        *((_QWORD *)v29 + 2) = v24;
      }
      ++*((_DWORD *)v23 + 2);
      v26 = v24;
      v24->u.VirtualAddress = (void *)((unsigned __int64)v24->u.VirtualAddress & 0xFFFFFFFFFFFFFFF3ui64);
      v24 = v24->Next;
      v25 = v37 + 1;
    }
  }
  v36 = v12 + v10;
  v17 = HalpMmAllocCtxAlloc(v14, 72i64 * (unsigned int)(v12 + v10));
  v19 = v17;
  if( !v17 )
  {
LABEL_12:
    HalpMmAllocCtxFree(v18, v16);
    goto LABEL_13;
  }
  v16->Next = 0i64;
  *(&v16->EntryCount + 1) = 0;
  memset(v17, 0i64, 72 * v10);
  v20 = PhysicalAddress;
  v16->EntryCount = v36;
  v16->Entries = (_HALP_DMA_TRANSLATION_ENTRY *)v19;
  AdapterObject->ContiguousTranslationEnd.Offset = 0;
  AdapterObject->ContiguousTranslations = v16;
  AdapterObject->ContiguousTranslationEnd.Buffer = v16;
  if( !HalpDmaCommitContiguousMapBuffers(AdapterObject, v15, v20, (unsigned int)v10) )
  {
    HalpMmAllocCtxFree(v21, AdapterObject->ContiguousTranslations->Entries);
    goto LABEL_12;
  }
  if( MemoryDescriptorList )
  {
    AdapterObject[2].ContiguousMapRegisters = (_RTL_BITMAP *)MemoryDescriptorList;
    AdapterObject[2].ScatterBufferListHead = v15;
  }
  else
  {
    AdapterObject[2].ContiguousMapRegisters = (_RTL_BITMAP *)v15;
    v8 = 0;
  }
  LOBYTE(AdapterObject[2].NumberOfFreeScatterBuffers) = v8;
LABEL_43:
  LODWORD(AdapterObject[1].ScatterTranslationEnd.Buffer) = v10;
  return 0;
}

Referenced by:

HalpDmaAllocateChildAdapterV2
HalpDmaAllocateChildAdapterV3