HalBuildScatterGatherListV2
NTSTATUS __stdcall HalBuildScatterGatherListV2(
PADAPTER_OBJECT AdapterObject,
INT64 a2,
UINT64 a3,
INT64 a4,
INT64 a5,
INT64 arg28,
INT64 a7,
CHAR a8,
PVOID P,
INT64 a10){
int v14;
NTSTATUS result;
PVOID v16;
char *PoolWithTag;
char *v18;
__int64 v19;
unsigned int v20;
unsigned int ByteOffset;
char *v22;
unsigned int ByteCount;
_MDL *v24;
_MDL *v25;
_MDL *Next;
unsigned int v27;
unsigned int v28;
unsigned int v29;
bool v30;
unsigned int v31;
__int64 v32;
CHAR v33;
unsigned int v34;
char *v35;
_QWORD *v36;
int AdapterChannel;
VOID **v38;
INT64 DeferFlushing;
INT64 a6;
unsigned int v41;
PDRIVER_CONTROL ExecutionRoutine;
UINT64 NumberOfBytes;
INT64 v45;
v45 = a4;
LODWORD(ExecutionRoutine) = 0;
v41 = 0;
LODWORD(NumberOfBytes) = 0;
if( !a3 )
return -1073741811;
v14 = a5;
result = HalpCalculateScatterGatherListSize(
AdapterObject,
(_MDL *)a3,
(VOID *)a4,
(unsigned int)a5,
&NumberOfBytes,
(UINT64 *)&ExecutionRoutine,
(UINT64 *)&v41);
if( result >= 0 )
{
if( AdapterObject->NeedsMapRegisters )
{
v34 = v41;
v33 = a8;
}
else if( AdapterObject->CacheCoherent || (v33 = a8) != 0 || (v34 = v41) == 0 )
{
v16 = P;
if( P )
{
if( (unsigned int)a10 >= (unsigned int)NumberOfBytes )
{
PoolWithTag = (char *)P;
LABEL_8:
v18 = PoolWithTag + 16;
v19 = *(_QWORD *)(a3 + 32) + *(unsigned int *)(a3 + 44);
v20 = a5;
*((_QWORD *)PoolWithTag + 1) = 0i64;
ByteOffset = a4 & 0xFFF;
v22 = PoolWithTag + 16;
ByteCount = v19 + *(_DWORD *)(a3 + 40) - a4;
v24 = (_MDL *)(a3 + 8 * (((a4 - (v19 & 0xFFFFFFFFFFFFF000ui64)) >> 12) + 6));
if( v20 )
{
v25 = (_MDL *)a3;
do
{
Next = v25->Next;
v27 = v20;
v28 = v20;
if( ByteCount <= v20 )
v27 = ByteCount;
if( Next )
v28 = v27;
v29 = v20 - v27;
v20 = 0;
if( Next )
v20 = v29;
v30 = AdapterObject->CacheCoherent == 0;
LODWORD(a5) = v20;
if( v30 )
{
if( v25 == (_MDL *)a3 )
v35 = (char *)v45;
else
v35 = (char *)v25->StartVa + ByteOffset;
LOBYTE(a6) = 0;
LOBYTE(DeferFlushing) = a8;
HalpDmaFlushBuffer((_DOUBLE)Next, v25, v35, v28, DeferFlushing, a6);
v20 = a5;
v18 = PoolWithTag + 16;
}
if( v28 )
{
do
{
v31 = 4096 - ByteOffset;
v32 = ByteOffset + ((__int64)v24->Next << 12);
*((_DWORD *)v22 + 2) = 4096 - ByteOffset;
*(_QWORD *)v22 = v32;
if( 4096 - ByteOffset > v28 )
{
*((_DWORD *)v22 + 2) = v28;
v31 = v28;
}
v28 -= v31;
if( v22 != v18 )
{
if( v32 == *((_QWORD *)v22 - 3) + *((unsigned int *)v22 - 4)
&& (((__int64)v24->Next ^ ((__int64)&v24->Next[-1].ByteOffset + 3)) & 0xFFFFFFFFFFF00000ui64) == 0 )
{
*((_DWORD *)v22 - 4) += v31;
v22 -= 24;
}
v18 = PoolWithTag + 16;
}
ByteOffset = 0;
v22 += 24;
v24 = (_MDL *)((char *)v24 + 8);
}
while( v28 );
v20 = a5;
}
v25 = v25->Next;
if( !v25 )
break;
ByteOffset = v25->ByteOffset;
v24 = v25 + 1;
ByteCount = v25->ByteCount;
}
while( v20 );
v16 = P;
}
*(_DWORD *)PoolWithTag = (v22 - PoolWithTag - 16) / 24;
if( v16 )
*((_QWORD *)PoolWithTag + 1) = 1i64;
((void(__fastcall *)(INT64, _QWORD, char *, INT64))arg28)(a2, *(_QWORD *)(a2 + 32), PoolWithTag, a7);
return 0;
}
return -1073741789;
}
PoolWithTag = (char *)ExAllocatePoolWithTag(0x200ui64, (unsigned int)NumberOfBytes, 543973704i64);
if( PoolWithTag )
goto LABEL_8;
return -1073741670;
}
v36 = P;
if( P )
{
if( (unsigned int)a10 < (unsigned int)NumberOfBytes )
return -1073741789;
*(_DWORD *)P |= 1u;
}
else
{
v38 = ExAllocatePoolWithTag(0x200ui64, (unsigned int)NumberOfBytes, 543973704i64);
v36 = v38;
if( !v38 )
return -1073741670;
*(_DWORD *)v38 = 0;
}
v36[4] = v45;
v36[15] = arg28;
v36[16] = a7;
v36[1] = a3;
v36[2] = 0i64;
*((_DWORD *)v36 + 10) = v14;
v36[18] = AdapterObject;
*((_BYTE *)v36 + 152) = v33;
v30 = AdapterObject->NeedsMapRegisters == 0;
v36[10] = v36;
if( !v30 )
v34 = (unsigned int)ExecutionRoutine;
*((_DWORD *)v36 + 11) = v34;
v36[12] = a2;
v36[13] = *(_QWORD *)(a2 + 32);
AdapterChannel = HalAllocateAdapterChannel(
(INT64)AdapterObject,
(INT64)(v36 + 6),
v34,
(INT64)HalpAllocateAdapterCallbackV2);
if( AdapterChannel < 0 )
ExFreePoolWithTag(v36, 0);
return AdapterChannel;
}
return result;
}Referenced by:
HalGetScatterGatherList