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