HalMapTransferEx

__int64 __fastcall HalMapTransferEx(
        INT64 a1,
        _MDL *Mdl,
        VOID *MapRegisterBase,
        unsigned __int64 a4,
        int a5,
        __int64 arg28,
        INT64 arg30,
        INT64 a8,
        int a9,
        INT64 a10,
        INT64 a11){
  unsigned int v11; 
  bool v13; 
  _QWORD *v14; 
  _MDL *v15; 
  _DWORD *v17; 
  __int64 v18; 
  unsigned __int64 ByteCount; 
  INT64 v20; 
  unsigned int v21; 
  unsigned int v22; 
  unsigned __int64 v23; 
  UINT64 v24; 
  unsigned int *v25; 
  unsigned int v26; 
  int v27; 
  __int64 v28; 
  unsigned int v29; 
  __int64 ByteOffset; 
  unsigned int v31; 
  char *v32; 
  unsigned int v33; 
  UINT64 v34; 
  unsigned int v35; 
  __int64 v36; 
  __int64 v37; 
  __int64 v38; 
  __int64 v39; 
  _DWORD *v40; 
  CHAR v41; 
  INT64 v43; 
  unsigned int MaxFragments; 
  unsigned int v45; 
  int v46; 
  char *v47; 
  unsigned int v48; 
  _LARGE_INTEGER v49; 
  unsigned int v50; 
  _LARGE_INTEGER v51; 
  __int64 v52; 
  INT64 v53; 
  __int64 v54; 
  __int64 v55; 
  _MDL *v56; 
  _MDL *Next; 
  INT64 DeferFlushing; 
  INT64 a6; 
  int v60; 
  UINT8 v61[4]; 
  unsigned int v62; 
  unsigned int v63; 
  char *v64; 
  __int64 v65; 
  unsigned int v66; 
  unsigned __int64 v67; 
  __int64 v68; 
  PVOID BugCheckParameter4; 
  CHAR a7; 
  _QWORD *v71; 

  v71 = MapRegisterBase;
  v11 = 0;
  v13 = *(_DWORD *)(a1 + 512) == 2;
  v14 = MapRegisterBase;
  v15 = Mdl;
  a7 = 0;
  BugCheckParameter4 = 0i64;
  if( v13 && !MapRegisterBase )
    return 3221225485i64;
  v68 = *(_QWORD *)(a1 + 504);
  v17 = (_DWORD *)arg28;
  *(_BYTE *)(a1 + 516) = 1;
  if( !*v17 )
  {
    v43 = a8;
    if( a8 && (unsigned int)a9 >= 0x10 )
    {
      *(_DWORD *)a8 = 0;
      *(_QWORD *)(v43 + 8) = 0i64;
    }
    else if( *(_BYTE *)(a1 + 433) )
    {
      return 3221225485i64;
    }
    return 0i64;
  }
  if( KeGetCurrentIrql() != 15 )
  {
    v18 = *(_QWORD *)(a1 + 352);
    if( v18 )
    {
      if( (*(_DWORD *)(v18 + 12) & 1) != 0 )
        return 3221225760i64;
    }
  }
  if( !Mdl )
    return 3221225485i64;
  do
  {
    ByteCount = v15->ByteCount;
    if( a4 < ByteCount )
      break;
    v15 = v15->Next;
    a4 -= ByteCount;
  }
  while( v15 );
  if( !v15 )
    return 3221225485i64;
  v20 = a8;
  if( !a8 )
  {
    if( !*(_BYTE *)(a1 + 433) )
    {
      v21 = *(_DWORD *)(a1 + 620);
      v20 = a1 + 624;
      goto LABEL_10;
    }
    return 3221225485i64;
  }
  v21 = a9;
  if( (unsigned int)a9 < 0x28 )
    return 3221225485i64;
LABEL_10:
  v22 = 0;
  *(_QWORD *)(v20 + 8) = 0i64;
  v23 = ((unsigned __int64)v21 - 16) / 0x18;
  v67 = v23;
  if( !*(_BYTE *)(a1 + 433) )
  {
    MaxFragments = HalpDmaControllerQueryMaxFragments(*(_QWORD *)(a1 + 360), a1, (unsigned int)v23);
    if( MaxFragments < (unsigned int)v23 )
      v23 = MaxFragments;
    v67 = v23;
  }
  HalpDmaCheckMdlAccessibility(
    a1,
    (INT64 *)v15,
    (unsigned int)a4,
    *(unsigned int *)arg28,
    &a7,
    (_MDL **)&BugCheckParameter4);
  v13 = *(_DWORD *)(a1 + 512) == 2;
  v24 = 0i64;
  v25 = (unsigned int *)arg28;
  v65 = 0i64;
  if( v13 )
  {
    v45 = *(_DWORD *)(a1 + 244);
    if( *(_DWORD *)arg28 > v45 )
      *(_DWORD *)arg28 = v45;
    v24 = v14[3];
    v14[4] = 0i64;
  }
  v26 = *v25;
  v27 = 0;
  v60 = 0;
  if( v14 )
  {
    do
    {
      if( !v26 )
        break;
      v46 = v26;
      v47 = (char *)v15->StartVa + v15->ByteOffset + a4;
      v48 = v15->ByteCount - a4;
      v64 = v47;
      if( v48 <= v26 )
        v46 = v48;
      v26 -= v46;
      v62 = v46;
      v63 = v26;
      if( v46 )
      {
        while( v22 < (unsigned int)v67 )
        {
          LOBYTE(a6) = arg30;
          *(_DWORD *)v61 = v46;
          v49 = IoMapTransferInternal((_ADAPTER_OBJECT *)a1, v15, v14, v47, (UINT8)v61, a6, a7);
          v50 = *(_DWORD *)v61;
          v51 = v49;
          if( !*(_DWORD *)v61 )
          {
            v14 = v71;
            v27 = v60;
            break;
          }
          if( *(_DWORD *)(a1 + 512) == 2 )
          {
            if( ((LOWORD(v49.anonymous_0.LowPart) | (unsigned __int16)v24) & 0xFFF) != 0 || !v65 )
            {
              if( (v24 & 0xFFF) != 0 )
                v24 = v24 + 4096 - ((v24 + 4096) & 0xFFF);
              v52 = v20 + 8 * (v22 + 2 * (v22 + 1i64));
              v65 = v52;
              *(_QWORD *)v52 = v24 + ((unsigned __int16)v64 & 0xFFF);
              *(_QWORD *)(v52 + 16) = v15;
              *(_DWORD *)(v52 + 8) = v50;
            }
            else
            {
              --v22;
              *(_DWORD *)(v65 + 8) += *(_DWORD *)v61;
            }
            v53 = v50 + (v49.anonymous_0.LowPart & 0xFFF);
            HalpIommuDomainMapLogicalRange(*(_QWORD *)(v68 + 40), 3i64, v49.QuadPart, v53, v24);
            v24 += v53;
            v50 = *(_DWORD *)v61;
          }
          else
          {
            v54 = 3i64 * v22;
            *(_QWORD *)(v20 + 8 * v54 + 32) = v15;
            *(_DWORD *)(v20 + 8 * v54 + 24) = v50;
            *(_LARGE_INTEGER *)(v20 + 8 * v54 + 16) = v49;
          }
          if( *(_DWORD *)(a1 + 512) == 3 )
            HalpIommuDomainMapLogicalRange(
              *(_QWORD *)(v68 + 40),
              3i64,
              v51.QuadPart,
              v50 + (v51.anonymous_0.LowPart & 0xFFF),
              v51.QuadPart);
          ++v22;
          v27 = v50 + v60;
          v46 = v62 - v50;
          v55 = v50;
          v14 = v71;
          v47 = &v64[v55];
          v64 += v55;
          v60 = v27;
          v62 = v46;
          if( !v46 )
          {
            v26 = v63;
            goto LABEL_84;
          }
        }
        v26 = 0;
      }
LABEL_84:
      v15 = v15->Next;
      a4 = 0i64;
    }
    while( v15 );
  }
  else
  {
    v28 = 0i64;
    v65 = 0i64;
    do
    {
      if( !v26 )
        break;
      v29 = v26;
      ByteOffset = v15->ByteOffset;
      if( v15->ByteCount - (int)a4 <= v26 )
        v29 = v15->ByteCount - a4;
      *(_DWORD *)v61 = v29;
      v26 -= v29;
      v31 = ((_WORD)ByteOffset + (_WORD)a4) & 0xFFF;
      v63 = v26;
      v62 = v31;
      v32 = (char *)(&v15[1].Next + ((unsigned __int64)(unsigned int)(ByteOffset + a4) >> 12));
      v64 = v32;
      if( !*(_BYTE *)(a1 + 437) )
      {
        LOBYTE(a6) = a7;
        LOBYTE(DeferFlushing) = arg30;
        HalpDmaFlushBuffer(v29, v15, (char *)v15->StartVa + ByteOffset + a4, v29, DeferFlushing, a6);
        v26 = v63;
        v29 = *(_DWORD *)v61;
        v27 = v60;
        v28 = v65;
        v32 = v64;
        v31 = v62;
      }
      if( v29 )
      {
        while( 1 )
        {
          v33 = v29;
          v34 = v31 + (*(_QWORD *)v32 << 12);
          v35 = 4096 - v31;
          v31 = 0;
          if( v35 <= v29 )
            v33 = v35;
          v66 = v33;
          if( v34 == v28 + 1 && ((v34 ^ v28) & 0x100000000i64) == 0 && v22 )
          {
            *(_DWORD *)(v20 + 24 * (v22 - 1 + 1i64)) += v33;
          }
          else
          {
            if( v22 >= (unsigned int)v67 )
            {
              v26 = 0;
              break;
            }
            v36 = v22++;
            v37 = 3 * v36;
            *(_QWORD *)(v20 + 8 * v37 + 16) = v34;
            *(_DWORD *)(v20 + 8 * v37 + 24) = v33;
          }
          v13 = *(_DWORD *)(a1 + 512) == 3;
          v38 = v33;
          v65 = v33;
          if( v13 )
          {
            HalpIommuDomainMapLogicalRange(*(_QWORD *)(v68 + 40), 3i64, v34, v33, v34);
            v33 = v66;
            v31 = 0;
            v27 = v60;
            v38 = v65;
          }
          v39 = v38 - 1;
          v29 = *(_DWORD *)v61 - v33;
          v32 = v64 + 8;
          *(_DWORD *)v61 = v29;
          v27 += v33;
          v64 += 8;
          v28 = v34 + v39;
          v60 = v27;
          v65 = v28;
          if( !v29 )
          {
            v26 = v63;
            break;
          }
        }
      }
      v15 = v15->Next;
      a4 = 0i64;
    }
    while( v15 );
  }
  if( !v15 && v26 && v22 )
  {
    *(_DWORD *)(v20 + 24 * (v22 - 1 + 1i64)) += v26;
    v27 += v26;
  }
  if( *(_DWORD *)(a1 + 512) == 2 )
    v14[4] = v24 - v14[3];
  v40 = (_DWORD *)arg28;
  *(_DWORD *)v20 = v22;
  *v40 = v27;
  if( v14 )
    *((_DWORD *)v14 + 4) = v27;
  v41 = arg30;
  if( a7 )
  {
    v56 = (_MDL *)BugCheckParameter4;
    HalpDmaFlushDriverMdl(BugCheckParameter4);
    if( v56 )
    {
      do
      {
        Next = v56->Next;
        IoFreeMdl(v56);
        v56 = Next;
      }
      while( Next );
      v41 = arg30;
    }
  }
  if( !*(_BYTE *)(a1 + 433) )
    return(unsigned int)HalpDmaControllerProgramChannel(
                           *(_QWORD *)(a1 + 360),
                           a1,
                           a10,
                           a11,
                           v20,
                           *(_QWORD *)(a1 + 448) + (unsigned int)a5,
                           v41);
  return v11;
}

Referenced by:

HalpAllocateAdapterCallbackV3