HalGetAdapterV3
_HALP_DMA_CONTROLLER *__stdcall HalGetAdapterV3(
const _UNICODE_STRING *DeviceDescriptor,
_DEVICE_OBJECT *pNumberOfMapRegisters,
UINT64 *er8){
_DWORD *v3;
bool v5;
bool v6;
unsigned int v7;
unsigned int Buffer;
wchar_t *AllocatedMapRegistersOut;
_HALP_DMA_CONTROLLER *AdapterByRequestLine;
_HALP_DMA_CONTROLLER *v11;
char v12;
unsigned int v13;
_BOOL8 v14;
unsigned __int64 v15;
char v16;
unsigned int v17;
unsigned int v18;
_HALP_DMA_CONTROLLER *v19;
_LIST_ENTRY *AdapterByDeviceObject;
INT64 v21;
bool v22;
_ADAPTER_OBJECT *ChildAdapterV3;
char v24;
NTSTATUS AdapterVersion;
unsigned int v27;
_HALP_DMA_CONTROLLER *DmaControllerByRequestLine;
unsigned int v29;
unsigned int v30;
unsigned int MapBufferSize;
unsigned int v32;
_HALP_DMA_CONTROLLER *v33;
UINT64 ScatterGatherLimit;
_LARGE_INTEGER DeviceAddress;
char v36;
UINT8 CacheCoherent;
char v38;
bool v39;
unsigned int v40;
unsigned int RequestLine;
unsigned int RequestLine_4;
_HALP_DMA_CONTROLLER *Controller;
_MDL *Mdl;
char MasterDevice;
_DEVICE_OBJECT *DeviceObject;
int v47;
_DWORD *v48;
v48 = v3;
v47 = (int)er8;
DeviceObject = pNumberOfMapRegisters;
v5 = *(_DWORD *)&DeviceDescriptor->Length < 3u;
v6 = *(_DWORD *)&DeviceDescriptor->Length == 3;
v36 = 0;
Mdl = 0i64;
v7 = 64;
v39 = 0;
if( v6 )
{
Buffer = (unsigned int)DeviceDescriptor[2].Buffer;
}
else
{
if( !v5 || (_DWORD)er8 != 2 || !*((_BYTE *)&DeviceDescriptor->MaximumLength + 2) )
return 0i64;
if( BYTE3(DeviceDescriptor->Buffer) )
{
Buffer = 64;
}
else if( LOBYTE(DeviceDescriptor->Buffer) || (Buffer = 24, *((_BYTE *)&DeviceDescriptor->MaximumLength + 3)) )
{
Buffer = 32;
}
}
if( !pNumberOfMapRegisters )
return 0i64;
AllocatedMapRegistersOut = 0i64;
RequestLine = 0;
AdapterByRequestLine = 0i64;
if( *((_BYTE *)&DeviceDescriptor->MaximumLength + 2) )
{
v38 = 0;
v11 = 0i64;
Controller = 0i64;
}
else
{
v27 = *(_DWORD *)&DeviceDescriptor[3].Length;
AllocatedMapRegistersOut = DeviceDescriptor[3].Buffer;
v38 = 1;
RequestLine = v27;
DmaControllerByRequestLine = HalpFindDmaControllerByRequestLine(v27);
Controller = DmaControllerByRequestLine;
v11 = DmaControllerByRequestLine;
if( !DmaControllerByRequestLine )
return 0i64;
AdapterByRequestLine = HalpFindAdapterByRequestLine(DmaControllerByRequestLine, v27);
if( !AdapterByRequestLine
&& !(unsigned __int8)HalpDmaControllerValidateRequestLineBinding(v11, (_DEVICE_DESCRIPTION *)DeviceDescriptor) )
{
return 0i64;
}
pNumberOfMapRegisters = DeviceObject;
}
v12 = *((_BYTE *)&DeviceDescriptor->MaximumLength + 2);
v13 = ((*(_DWORD *)&DeviceDescriptor[2].Length & 0x7FFFFFFF) + 4095) & 0xFFFFF000;
if( v12 )
{
MasterDevice = *((_BYTE *)&DeviceDescriptor->MaximumLength + 3);
RequestLine_4 = 0;
}
else
{
v29 = v11->ScatterGatherLimit;
Buffer = v11->DmaAddressWidth;
MasterDevice = 1;
if( v29 > 8 )
v29 = 8;
RequestLine_4 = v29;
}
if( Buffer >= 0x20 || (LODWORD(v14) = 0, v12) )
{
CacheCoherent = 1;
v14 = Buffer >= 0x20;
}
else
{
CacheCoherent = 0;
}
HalpGetCacheCoherency((INT64)v11, pNumberOfMapRegisters, &v36);
if( Buffer < 0x40 )
v15 = (1i64 << Buffer) - 1;
else
v15 = -1i64;
if( v15 < qword_140C4BA18 )
{
v16 = 0;
}
else
{
v16 = 1;
if( v36 && MasterDevice && !v47 )
{
v17 = 0;
v40 = 0;
v18 = 0;
goto LABEL_17;
}
}
if( v14 )
{
if( MasterDevice && (v36 || !v16) )
v7 = 512;
}
else
{
v7 = 16;
}
v17 = (v13 >> 12) + 1;
v40 = v17;
v30 = v17;
if( v17 > v7 )
{
v17 = v7;
v40 = v7;
v30 = v7;
}
MapBufferSize = stru_140C4BB00.MapBufferSize;
v18 = v30;
if( !v14 )
MapBufferSize = stru_140C4BA20.MapBufferSize;
if( !CacheCoherent )
{
v32 = MapBufferSize >> 13;
if( v30 > v32 )
{
v17 = v32;
v40 = v32;
v18 = v32;
}
}
LABEL_17:
if( !v36 )
{
Mdl = IoAllocateMdl(0i64, v18 << 12, 0, 0, 0i64);
if( !Mdl )
return 0i64;
}
if( AdapterByRequestLine )
{
if( v18 > LODWORD(AdapterByRequestLine[1].Controllers.Flink) )
LODWORD(AdapterByRequestLine[1].Controllers.Flink) = v17;
AdapterByRequestLine[2].Controllers.Flink = (_LIST_ENTRY *)DeviceDescriptor[3].Buffer;
ObReferenceObjectByPointer(AdapterByRequestLine, 0x20000ui64, HalpDmaAdapterObjectType, 0);
goto LABEL_29;
}
KeWaitForSingleObject((UINT64)&word_140C49B80, 7, 0, 0, 0i64);
v19 = Controller;
if( v38 )
{
v33 = HalpFindAdapterByRequestLine(Controller, RequestLine);
AdapterByRequestLine = v33;
if( v33 )
{
if( v18 > LODWORD(v33[1].Controllers.Flink) )
LODWORD(v33[1].Controllers.Flink) = v17;
v33[2].Controllers.Flink = (_LIST_ENTRY *)DeviceDescriptor[3].Buffer;
ObReferenceObjectByPointer(v33, 0x20000ui64, HalpDmaAdapterObjectType, 0);
goto LABEL_28;
}
}
AdapterByDeviceObject = HalpDmaFindAdapterByDeviceObject(DeviceObject);
AdapterByRequestLine = (_HALP_DMA_CONTROLLER *)AdapterByDeviceObject;
if( !AdapterByDeviceObject )
{
v22 = v39;
goto LABEL_22;
}
AdapterVersion = HalpDmaGetAdapterVersion((_ADAPTER_OBJECT *)AdapterByDeviceObject);
if( AdapterVersion != 3 )
{
HalPutDmaAdapter((PADAPTER_OBJECT)AdapterByRequestLine);
AdapterByRequestLine = 0i64;
}
v22 = AdapterVersion != 3;
if( !AdapterByRequestLine )
{
LABEL_22:
LOBYTE(v21) = MasterDevice;
DeviceAddress.anonymous_0.LowPart = RequestLine_4;
LOBYTE(ScatterGatherLimit) = v36;
ChildAdapterV3 = HalpDmaAllocateChildAdapterV3(
v17,
v13,
Buffer,
v21,
*((_BYTE *)&DeviceDescriptor->MaximumLength + 2),
CacheCoherent,
ScatterGatherLimit,
DeviceAddress,
(UINT64 *)AllocatedMapRegistersOut);
AdapterByRequestLine = (_HALP_DMA_CONTROLLER *)ChildAdapterV3;
if( ChildAdapterV3 )
{
v6 = v38 == 0;
ChildAdapterV3->AdapterInUse = v22;
if( v6 )
{
ChildAdapterV3->DeviceObject = DeviceObject;
HalpAddAdapterToList(ChildAdapterV3);
}
else
{
HalpAddAdapterToSystemList(v19, ChildAdapterV3);
LODWORD(AdapterByRequestLine[1].Operations.CancelTransfer) = RequestLine;
HIDWORD(AdapterByRequestLine[1].Operations.ReportCommonBuffer) = *(_DWORD *)&DeviceDescriptor[1].Length;
AdapterByRequestLine[1].Operations.ReadDmaCounter = (unsigned int(__fastcall *)(void *, unsigned int))v19;
*((_DWORD *)&AdapterByRequestLine[1].PowerActive + 1) = DeviceDescriptor[1].Buffer;
ObReferenceObjectByPointer(AdapterByRequestLine, 0x20000ui64, HalpDmaAdapterObjectType, 0);
}
v24 = v40;
if( v40 )
{
LODWORD(AdapterByRequestLine[1].Controllers.Flink) = v40;
v24 = 1;
}
else
{
LODWORD(AdapterByRequestLine[1].Controllers.Flink) = (v13 >> 12) + 1;
}
LOBYTE(AdapterByRequestLine[1].PowerHandle) = v24;
AdapterByRequestLine[1].Operations.InitializeController = 0i64;
goto LABEL_28;
}
goto LABEL_87;
}
if( !*((_BYTE *)&DeviceDescriptor->MaximumLength + 2)
|| *((_BYTE *)&DeviceDescriptor->MaximumLength + 3) != BYTE2(AdapterByRequestLine[1].PowerHandle)
|| BYTE1(DeviceDescriptor->Buffer) != BYTE4(AdapterByRequestLine[1].PowerHandle)
|| Buffer != *(_DWORD *)&AdapterByRequestLine[1].PowerActive )
{
if( !HalpDmaIsAutomaticDomain(AdapterByRequestLine[2].Channels)
|| LODWORD(AdapterByRequestLine[2].ExtensionData) == 2
|| v47 == 2 )
{
HalPutDmaAdapter((PADAPTER_OBJECT)AdapterByRequestLine);
LABEL_87:
KeSetEvent((PRKEVENT)&word_140C49B80, 0, 0);
return 0i64;
}
BYTE4(AdapterByRequestLine[2].ExtensionData) = 1;
HalPutDmaAdapter((PADAPTER_OBJECT)AdapterByRequestLine);
v22 = 1;
goto LABEL_22;
}
LABEL_28:
KeSetEvent((PRKEVENT)&word_140C49B80, 0, 0);
LABEL_29:
BYTE3(AdapterByRequestLine[1].PowerHandle) = *((_BYTE *)&DeviceDescriptor->MaximumLength + 5);
BYTE4(AdapterByRequestLine[1].PowerHandle) = 0;
if( *(_DWORD *)&DeviceDescriptor->Length )
BYTE4(AdapterByRequestLine[1].PowerHandle) = BYTE1(DeviceDescriptor->Buffer);
*v48 = AdapterByRequestLine[1].Controllers.Flink;
*(_QWORD *)&AdapterByRequestLine[1].CacheCoherent = Mdl;
return AdapterByRequestLine;
}Referenced by:
HalpGetAdapter