HalpBuildScatterGatherList

INT64 __fastcall HalpBuildScatterGatherList(
        INT64 a1,
        DEVICE_OBJECT *DeviceObject,
        INT64 a3,
        INT64 a4,
        INT64 a5,
        INT64 a6,
        CHAR a7,
        INT64 a8,
        INT64 a9,
        CHAR a10,
        INT64 a11,
        INT64 a12,
        INT64 a13,
        INT64 a14,
        INT64 a15){
  INT64 v15; 
  unsigned __int64 v19; 
  INT64 result; 
  unsigned int v21; 
  INT64 v22; 
  INT64 v23; 
  _QWORD *v24; 
  VOID *PoolWithTag; 
  int v26; 
  int AdapterChannel; 
  int v28; 
  int v29; 
  __int128 v30; 
  v15 = a4;
  v30 = 0i64;
  if( !a4 )
    return 3221225485i64;
  if( a15 )
    *(_QWORD *)a15 = 0i64;
  do
  {
    v19 = *(unsigned int *)(v15 + 40);
    if( a5 < v19 )
      break;
    v15 = *(_QWORD *)v15;
    a5 -= v19;
  }
  while( v15 );
  if( !v15 )
    return 3221225485i64;
  v29 = 2;
  result = HalGetDmaTransferInfoInternal(a1, (__int64 *)v15, a5, a6, v28, &v29);
  if( (int)result >= 0 )
  {
    v21 = v30;
    if( a11 )
    {
      if( (unsigned int)a12 < DWORD2(v30) )
        return 3221225507i64;
      v22 = a11 + 40 + 24i64 * DWORD1(v30);
      *(_DWORD *)v22 |= 1u;
      *(_QWORD *)(v22 + 160) = a11;
      *(_DWORD *)(v22 + 156) = a12;
    }
    else
    {
      PoolWithTag = ExAllocatePoolWithTag(NonPagedPoolNx, DWORD2(v30), 0x206C6148ui64);
      if( !PoolWithTag )
        return 3221225626i64;
      v26 = DWORD2(v30);
      v22 = (INT64)PoolWithTag + 16 * DWORD1(v30) + 8 * DWORD1(v30) + 40;
      *(_DWORD *)v22 = 0;
      *(_QWORD *)(v22 + 160) = PoolWithTag;
      *(_DWORD *)(v22 + 156) = v26;
    }
    if( a15 )
      *(_QWORD *)a15 = *(_QWORD *)(v22 + 160);
    *(_DWORD *)(v22 + 156) -= 168;
    *(_QWORD *)(v22 + 8) = v15;
    *(_QWORD *)(v22 + 16) = 0i64;
    v23 = a5 + *(_QWORD *)(v15 + 32) + *(unsigned int *)(v15 + 44);
    *(_QWORD *)(v22 + 120) = a8;
    *(_QWORD *)(v22 + 32) = v23;
    *(_DWORD *)(v22 + 40) = a6;
    *(_QWORD *)(v22 + 128) = a9;
    *(_QWORD *)(v22 + 144) = a1;
    *(_BYTE *)(v22 + 152) = a10;
    *(_DWORD *)(v22 + 44) = v21;
    *(_QWORD *)(v22 + 24) = 0i64;
    if( a3 )
    {
      v24 = (_QWORD *)(a3 + 16);
      *(_QWORD *)(a3 + 88) = v22;
      *(_DWORD *)(a3 + 36) |= 2u;
    }
    else
    {
      v24 = (_QWORD *)(v22 + 48);
      *(_DWORD *)(v22 + 68) &= ~2u;
    }
    v24[4] = v22;
    v24[6] = DeviceObject;
    v24[7] = *((_QWORD *)DeviceObject + 4);
    if( !*(_BYTE *)(a1 + 432) && *(_DWORD *)(a1 + 512) != 2 && (*(_BYTE *)(a1 + 437) || a10) )
    {
      HalpAllocateAdapterCallbackV3(DeviceObject, *((IRP **)DeviceObject + 4), 0i64, (PVOID)v22);
      return 0i64;
    }
    else
    {
      if( !v21 )
        v21 = 1;
      *(_DWORD *)(v22 + 44) = v21;
      if( a8 )
      {
        AdapterChannel = HalpAllocateAdapterChannel(
                           a1,
                           (INT64)v24,
                           v21,
                           HIDWORD(v30),
                           a7,
                           (INT64)HalpAllocateAdapterCallbackV3);
      }
      else
      {
        AdapterChannel = HalpAllocateAdapterChannel(a1, (INT64)v24, v21, HIDWORD(v30), a7, 0i64);
        if( !AdapterChannel )
          HalpAllocateAdapterCallbackV3(DeviceObject, *((IRP **)DeviceObject + 4), *(PVOID *)(a1 + 232), (PVOID)v22);
      }
      if( AdapterChannel < 0 && !a11 )
        ExFreePoolWithTag(*(PVOID *)(v22 + 160), 0);
      return(unsigned int)AdapterChannel;
    }
  }
  return result;
}

Referenced by:

HalBuildScatterGatherListEx
HalBuildScatterGatherListV3
HalGetScatterGatherList
HalGetScatterGatherListEx