HalpDmaAllocateChildAdapterV3
_ADAPTER_OBJECT *__stdcall HalpDmaAllocateChildAdapterV3(
UINT64 NumberOfMapRegisters,
UINT64 DmaAddressWidth,
INT64 ScatterGather,
INT64 MasterDevice,
UINT8 CanCross64K,
UINT8 CacheCoherent,
UINT64 ScatterGatherLimit,
_LARGE_INTEGER DeviceAddress,
UINT64 *AllocatedMapRegistersOut){
_ADAPTER_OBJECT *v9;
char *v10;
NTSTATUS SecurityPolicy;
size_t v12;
ULONG v13;
PVOID v14;
int v15;
__int64 v16;
_HALP_DMA_MASTER_ADAPTER_OBJECT *v17;
unsigned __int64 v18;
NTSTATUS LocalScatterPool;
int v21;
__int64 v22;
int v23;
_EX_PUSH_LOCK *AdapterByDeviceId;
char v25;
INT64 v26;
VOID *v27;
NTSTATUS Device;
char v29;
VOID *v30;
UINT64 v31;
UINT64 ObjectBodySize;
PVOID *Handle;
UINT64 v34;
__int16 v35;
PVOID Object;
PVOID v37;
_OBJECT_ATTRIBUTES ObjectAttributes;
_INTERFACE Interface[4];
unsigned int NumberOfMapRegistersa;
int v41;
unsigned int v42;
char v43;
int v44;
PVOID InterfaceSpecificData;
_DWORD *v46;
v43 = MasterDevice;
v42 = ScatterGather;
v41 = DmaAddressWidth;
NumberOfMapRegistersa = NumberOfMapRegisters;
*(_QWORD *)&ObjectAttributes.Length = 48i64;
v37 = 0i64;
*(_QWORD *)&ObjectAttributes.Attributes = 528i64;
v9 = 0i64;
v35 = 0;
v10 = 0i64;
Object = 0i64;
memset(Interface, 0i64, 0x50u);
SecurityPolicy = HalpIommuGetSecurityPolicy();
ObjectAttributes.RootDirectory = 0i64;
v12 = 640;
ObjectAttributes.ObjectName = 0i64;
v13 = 0;
*(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
if( !CanCross64K )
{
v13 = 24 * (DeviceAddress.anonymous_0.LowPart + 1);
v12 = v13 + 640;
}
v14 = InterfaceSpecificData;
v15 = v44;
if( InterfaceSpecificData || !v44 || SecurityPolicy != 1 )
{
InterfaceSpecificData = 0i64;
if( v14 && v44 )
{
if( HalpDmaGetIommuInterface(v14, Interface) < 0 )
{
if( SecurityPolicy == 1 )
return(_ADAPTER_OBJECT *)v10;
}
else
{
HIBYTE(v35) = 1;
if( (*(unsigned int(__fastcall **)(void *, _QWORD, _QWORD, PVOID *))&Interface[2].Size)(
Interface[0].Context,
0i64,
0i64,
&InterfaceSpecificData) == -1073741789
&& InterfaceSpecificData )
{
v12 += (unsigned int)InterfaceSpecificData;
}
else
{
if( SecurityPolicy == 1 )
goto LABEL_27;
InterfaceSpecificData = 0i64;
}
}
}
LODWORD(v34) = 0;
LODWORD(Handle) = 0;
LODWORD(ObjectBodySize) = v12;
if( ObCreateObjectEx(
0i64,
HalpDmaAdapterObjectType,
&ObjectAttributes,
0i64,
v30,
ObjectBodySize,
(UINT64)Handle,
v34,
&Object,
0i64) < 0 )
goto LABEL_25;
v10 = (char *)Object;
memset(Object, 0i64, v12);
if( ObReferenceObjectByPointer(v10, 0x20000ui64, HalpDmaAdapterObjectType, 0) < 0 )
goto LABEL_25;
LODWORD(v31) = 0;
if( ObInsertObjectEx(v10, 0i64, 0x20000ui64, 0i64, v31, 0i64, &v37) < 0 )
goto LABEL_25;
ZwClose((_HANDLE)v37);
v16 = 0i64;
*((_QWORD *)v10 + 1) = &HalpDmaOperationsV3;
v17 = &stru_140C4BA20;
v10[145] = CacheCoherent;
*(_DWORD *)v10 = 41943041;
if( v42 >= 0x20 )
v17 = &stru_140C4BB00;
*((_QWORD *)v10 + 15) = 0i64;
*((_QWORD *)v10 + 16) = 0i64;
v10[144] = 0;
*((_QWORD *)v10 + 19) = v17;
if( v42 < 0x40 )
v18 = (1i64 << v42) - 1;
else
v18 = -1i64;
*((_QWORD *)v10 + 17) = v18;
if( v18 < v17->AdapterObject.MaximumPhysicalAddress.QuadPart )
{
LABEL_24:
HalPutDmaAdapter((PADAPTER_OBJECT)v10);
LABEL_25:
v10 = 0i64;
goto LABEL_26;
}
*((_QWORD *)v10 + 39) = 0i64;
v10[338] = 0;
*((_QWORD *)v10 + 24) = v10 + 184;
*((_QWORD *)v10 + 23) = v10 + 184;
*((_QWORD *)v10 + 22) = 0i64;
v10[216] = 0;
*((_DWORD *)v10 + 56) = NumberOfMapRegistersa;
v10[434] = v43;
v10[437] = ScatterGatherLimit;
*((_QWORD *)v10 + 56) = AllocatedMapRegistersOut;
v10[433] = CanCross64K;
*((_DWORD *)v10 + 94) = -1;
*((_DWORD *)v10 + 110) = v42;
*((_DWORD *)v10 + 155) = v13;
*((_DWORD *)v10 + 37) = 3;
*((_DWORD *)v10 + 154) = 0;
*((_QWORD *)v10 + 70) = 0i64;
*((_QWORD *)v10 + 72) = v10 + 568;
*((_QWORD *)v10 + 71) = v10 + 568;
v10[584] = 0;
*((_DWORD *)v10 + 152) = 0;
*((_QWORD *)v10 + 61) = IoFreeAdapterChannelV3Passive;
*((_QWORD *)v10 + 62) = v10;
*((_QWORD *)v10 + 59) = 0i64;
if( NumberOfMapRegistersa )
{
if( v43 )
LocalScatterPool = HalpDmaAllocateLocalScatterPool((_ADAPTER_OBJECT *)v10, NumberOfMapRegistersa);
else
LocalScatterPool = HalpDmaAllocateLocalContiguousPool((_HALP_DMA_ADAPTER_OBJECT *)v10, NumberOfMapRegistersa);
v16 = 0i64;
if( LocalScatterPool < 0 )
goto LABEL_24;
v21 = *((_DWORD *)v10 + 56);
v10[337] = 0;
}
else
{
*((_DWORD *)v10 + 56) = 0;
v21 = 0;
v10[337] = 1;
}
*v46 = v21;
*((_DWORD *)v10 + 61) = v41;
*((_DWORD *)v10 + 128) = 0;
*((_QWORD *)v10 + 65) = v14;
if( InterfaceSpecificData && HIBYTE(v35) )
{
v22 = (__int64)&v10[v13 + 640];
*((_QWORD *)v10 + 66) = v22;
v23 = (*(__int64(__fastcall **)(void *, PVOID, __int64, _QWORD))&Interface[2].Size)(
Interface[0].Context,
InterfaceSpecificData,
v22,
0i64);
v16 = 0i64;
if( v23 >= 0 )
{
AdapterByDeviceId = (_EX_PUSH_LOCK *)HalpDmaFindAdapterByDeviceId(*((_QWORD *)v10 + 66));
v16 = 0i64;
v9 = (_ADAPTER_OBJECT *)AdapterByDeviceId;
if( AdapterByDeviceId )
{
if( AdapterByDeviceId[65].Ptr != v14 )
{
ExAcquirePushLockExclusiveEx(AdapterByDeviceId + 39, 0i64);
LOBYTE(v35) = 1;
}
HalPutDmaAdapter(v9);
v16 = 0i64;
}
if( v44 == 2 )
{
v25 = ((__int64(__fastcall *)(_QWORD, _QWORD))off_140C00A38[0])(*((_QWORD *)v10 + 66), 0i64);
v16 = 0i64;
if( v25 )
goto LABEL_52;
v15 = 0;
}
}
else
{
*((_QWORD *)v10 + 66) = 0i64;
if( SecurityPolicy == 1 )
goto LABEL_61;
}
}
if( !v15 )
{
LABEL_56:
*((_QWORD *)v10 + 63) = v16;
if( HalJoinDmaDomain((_ADAPTER_OBJECT *)v10, (VOID *)0xFFFFFFFFFFFFFFFFi64) >= 0
|| SecurityPolicy != 1
&& *((_DWORD *)v10 + 128)
&& (*((_DWORD *)v10 + 128) = 0, HalJoinDmaDomain((_ADAPTER_OBJECT *)v10, (VOID *)0xFFFFFFFFFFFFFFFFi64) >= 0) )
{
v29 = v35;
if( v9 )
v9->ExpiredFlag = v35;
*(_QWORD *)(*((_QWORD *)v10 + 63) + 72i64) = v10;
goto LABEL_67;
}
HalpIommuDeleteDevice((UINT64 *)v10 + 67);
LABEL_61:
HalPutDmaAdapter((PADAPTER_OBJECT)v10);
v29 = v35;
v10 = 0i64;
Object = 0i64;
LABEL_67:
if( v29 )
{
if( (_InterlockedExchangeAdd64(&v9->ExpiredLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(&v9->ExpiredLock);
KeAbPostRelease(&v9->ExpiredLock);
v10 = (char *)Object;
}
LABEL_26:
if( !HIBYTE(v35) )
{
LABEL_28:
if( v10 && HalpDmaIsThinApiCapable((INT64)v10) )
*((_QWORD *)v10 + 1) = &HalpDmaOperationsThin;
return(_ADAPTER_OBJECT *)v10;
}
LABEL_27:
Interface[0].InterfaceDereference(Interface[0].Context);
goto LABEL_28;
}
LABEL_52:
v26 = *((_QWORD *)v10 + 66);
if( v26 && !HalpIommuCheckExceptionList(v26) )
{
Device = HalpIommuCreateDevice(v27);
v16 = 0i64;
if( Device < 0 )
{
if( SecurityPolicy == 1 )
goto LABEL_61;
}
else
{
*((_DWORD *)v10 + 128) = v15;
}
}
goto LABEL_56;
}
return(_ADAPTER_OBJECT *)v10;
}Referenced by:
HalGetAdapterV3