HalMapTransferEx

VOID __fastcall HalMapTransferEx(
        INT64 a1,
        MDL *Mdl,
        PVOID MapRegisterBase,
        UINT64 a4,
        INT64 a5,
        INT64 a6,
        UINT64 a7,
        INT64 a8,
        INT64 a9,
        INT64 a10){
  bool v11; 
  _QWORD *v12; 
  MDL *v13; 
  _DWORD *v15; 
  __int64 v16; 
  UINT64 ByteCount; 
  INT64 v18; 
  unsigned int v19; 
  unsigned int v20; 
  unsigned __int64 v21; 
  UINT64 v22; 
  unsigned int *v23; 
  unsigned int v24; 
  int v25; 
  __int64 v26; 
  __int64 v27; 
  __int64 ByteOffset; 
  unsigned int v29; 
  unsigned int v30; 
  _QWORD *v31; 
  unsigned int v32; 
  UINT64 v33; 
  unsigned int v34; 
  __int64 v35; 
  __int64 v36; 
  __int64 v37; 
  __int64 v38; 
  _DWORD *v39; 
  CHAR v40; 
  INT64 v41; 
  unsigned int MaxFragments; 
  unsigned int v43; 
  int v44; 
  __int64 v45; 
  unsigned int v46; 
  __int64 v47; 
  unsigned int v48; 
  UINT64 v49; 
  __int64 v50; 
  INT64 v51; 
  __int64 v52; 
  __int64 v53; 
  PMDL v54; 
  struct _MDL *Next; 
  int v56; 
  unsigned int v57; 
  unsigned int v58; 
  unsigned int v59; 
  __int64 v60; 
  __int64 v61; 
  unsigned int v62; 
  unsigned __int64 v63; 
  __int64 v64; 
  PMDL Mdla; 
  CHAR v66; 
  _QWORD *v67; 
  INT64 v68; 
  v67 = MapRegisterBase;
  v11 = *(_DWORD *)(a1 + 512) == 2;
  v12 = MapRegisterBase;
  v13 = Mdl;
  v66 = 0;
  Mdla = 0i64;
  if( !v11 || MapRegisterBase )
  {
    v64 = *(_QWORD *)(a1 + 504);
    v15 = (_DWORD *)a6;
    *(_BYTE *)(a1 + 516) = 1;
    if( *v15 )
    {
      if( KeGetCurrentIrql() == 15 || (v16 = *(_QWORD *)(a1 + 352)) == 0 || (*(_DWORD *)(v16 + 12) & 1) == 0 )
      {
        if( Mdl )
        {
          do
          {
            ByteCount = v13->ByteCount;
            if( a4 < ByteCount )
              break;
            v13 = v13->Next;
            a4 -= ByteCount;
          }
          while( v13 );
          if( v13 )
          {
            v18 = a8;
            if( a8 )
            {
              v19 = a9;
              if( (unsigned int)a9 < 0x28 )
                return;
            }
            else
            {
              if( *(_BYTE *)(a1 + 433) )
                return;
              v19 = *(_DWORD *)(a1 + 620);
              v18 = a1 + 624;
            }
            v20 = 0;
            *(_QWORD *)(v18 + 8) = 0i64;
            v21 = ((unsigned __int64)v19 - 16) / 0x18;
            v63 = v21;
            if( !*(_BYTE *)(a1 + 433) )
            {
              MaxFragments = HalpDmaControllerQueryMaxFragments(*(_QWORD *)(a1 + 360), a1, (unsigned int)v21);
              if( MaxFragments < (unsigned int)v21 )
                v21 = MaxFragments;
              v63 = v21;
            }
            HalpDmaCheckMdlAccessibility(a1, (INT64 *)v13, (unsigned int)a4, *(unsigned int *)a6, &v66, &Mdla);
            v11 = *(_DWORD *)(a1 + 512) == 2;
            v22 = 0i64;
            v23 = (unsigned int *)a6;
            v61 = 0i64;
            if( v11 )
            {
              v43 = *(_DWORD *)(a1 + 244);
              if( *(_DWORD *)a6 > v43 )
                *(_DWORD *)a6 = v43;
              v22 = v12[3];
              v12[4] = 0i64;
            }
            v24 = *v23;
            v25 = 0;
            v56 = 0;
            if( v12 )
            {
              do
              {
                if( !v24 )
                  break;
                v44 = v24;
                v45 = (__int64)v13->StartVa + v13->ByteOffset + a4;
                v46 = v13->ByteCount - a4;
                v60 = v45;
                if( v46 <= v24 )
                  v44 = v46;
                v24 -= v44;
                v58 = v44;
                v59 = v24;
                if( v44 )
                {
                  while( v20 < (unsigned int)v63 )
                  {
                    v57 = v44;
                    v47 = IoMapTransferInternal(a1, (__int64)v13, (__int64)v12, v45, &v57, a7, v66);
                    v48 = v57;
                    v49 = v47;
                    if( !v57 )
                    {
                      v12 = v67;
                      v25 = v56;
                      break;
                    }
                    if( *(_DWORD *)(a1 + 512) == 2 )
                    {
                      if( (((unsigned __int16)v47 | (unsigned __int16)v22) & 0xFFF) != 0 || !v61 )
                      {
                        if( (v22 & 0xFFF) != 0 )
                          v22 = v22 + 4096 - ((v22 + 4096) & 0xFFF);
                        v50 = v18 + 8 * (v20 + 2 * (v20 + 1i64));
                        v61 = v50;
                        *(_QWORD *)v50 = v22 + (v60 & 0xFFF);
                        *(_QWORD *)(v50 + 16) = v13;
                        *(_DWORD *)(v50 + 8) = v48;
                      }
                      else
                      {
                        --v20;
                        *(_DWORD *)(v61 + 8) += v57;
                      }
                      v51 = v48 + (v47 & 0xFFF);
                      HalpIommuDomainMapLogicalRange(*(_QWORD *)(v64 + 40), 3i64, v47, v51, v22);
                      v22 += v51;
                      v48 = v57;
                    }
                    else
                    {
                      v52 = 3i64 * v20;
                      *(_QWORD *)(v18 + 8 * v52 + 32) = v13;
                      *(_DWORD *)(v18 + 8 * v52 + 24) = v48;
                      *(_QWORD *)(v18 + 8 * v52 + 16) = v47;
                    }
                    if( *(_DWORD *)(a1 + 512) == 3 )
                      HalpIommuDomainMapLogicalRange(*(_QWORD *)(v64 + 40), 3i64, v49, v48 + (v49 & 0xFFF), v49);
                    ++v20;
                    v25 = v48 + v56;
                    v44 = v58 - v48;
                    v53 = v48;
                    v12 = v67;
                    v45 = v53 + v60;
                    v60 += v53;
                    v56 = v25;
                    v58 = v44;
                    if( !v44 )
                    {
                      v24 = v59;
                      goto LABEL_83;
                    }
                  }
                  v24 = 0;
                }
LABEL_83:
                v13 = v13->Next;
                a4 = 0i64;
              }
              while( v13 );
            }
            else
            {
              v26 = 0i64;
              v61 = 0i64;
              do
              {
                if( !v24 )
                  break;
                v27 = v24;
                ByteOffset = v13->ByteOffset;
                v29 = v13->ByteCount - a4;
                if( v29 <= v24 )
                  v27 = v29;
                v57 = v27;
                v24 -= v27;
                v30 = ((_WORD)ByteOffset + (_WORD)a4) & 0xFFF;
                v59 = v24;
                v58 = v30;
                v31 = &v13[1].Next + ((unsigned __int64)(unsigned int)(ByteOffset + a4) >> 12);
                v60 = (__int64)v31;
                if( !*(_BYTE *)(a1 + 437) )
                {
                  HalpDmaFlushBuffer(v27, (__int64)v13, (__int64)v13->StartVa + ByteOffset + a4, v27, a7, v66);
                  v24 = v59;
                  LODWORD(v27) = v57;
                  v25 = v56;
                  v26 = v61;
                  v31 = (_QWORD *)v60;
                  v30 = v58;
                }
                if( (_DWORD)v27 )
                {
                  while( 1 )
                  {
                    v32 = v27;
                    v33 = v30 + (*v31 << 12);
                    v34 = 4096 - v30;
                    v30 = 0;
                    if( v34 <= (unsigned int)v27 )
                      v32 = v34;
                    v62 = v32;
                    if( v33 == v26 + 1 && ((v33 ^ v26) & 0x100000000i64) == 0 && v20 )
                    {
                      *(_DWORD *)(v18 + 24 * (v20 - 1 + 1i64)) += v32;
                    }
                    else
                    {
                      if( v20 >= (unsigned int)v63 )
                      {
                        v24 = 0;
                        break;
                      }
                      v35 = v20++;
                      v36 = 3 * v35;
                      *(_QWORD *)(v18 + 8 * v36 + 16) = v33;
                      *(_DWORD *)(v18 + 8 * v36 + 24) = v32;
                    }
                    v11 = *(_DWORD *)(a1 + 512) == 3;
                    v37 = v32;
                    v61 = v32;
                    if( v11 )
                    {
                      HalpIommuDomainMapLogicalRange(*(_QWORD *)(v64 + 40), 3i64, v33, v32, v33);
                      v32 = v62;
                      v30 = 0;
                      v25 = v56;
                      v37 = v61;
                    }
                    v38 = v37 - 1;
                    LODWORD(v27) = v57 - v32;
                    v31 = (_QWORD *)(v60 + 8);
                    v57 = v27;
                    v25 += v32;
                    v60 += 8i64;
                    v26 = v33 + v38;
                    v56 = v25;
                    v61 = v26;
                    if( !(_DWORD)v27 )
                    {
                      v24 = v59;
                      break;
                    }
                  }
                }
                v13 = v13->Next;
                a4 = 0i64;
              }
              while( v13 );
            }
            if( !v13 && v24 && v20 )
            {
              *(_DWORD *)(v18 + 24 * (v20 - 1 + 1i64)) += v24;
              v25 += v24;
            }
            if( *(_DWORD *)(a1 + 512) == 2 )
              v12[4] = v22 - v12[3];
            v39 = (_DWORD *)a6;
            *(_DWORD *)v18 = v20;
            *v39 = v25;
            if( v12 )
              *((_DWORD *)v12 + 4) = v25;
            v40 = a7;
            if( v66 )
            {
              v54 = Mdla;
              HalpDmaFlushDriverMdl(Mdla);
              if( v54 )
              {
                do
                {
                  Next = v54->Next;
                  IoFreeMdl(v54);
                  v54 = Next;
                }
                while( Next );
                v40 = a7;
              }
            }
            if( !*(_BYTE *)(a1 + 433) )
              HalpDmaControllerProgramChannel(
                *(_QWORD *)(a1 + 360),
                a1,
                a10,
                v68,
                v18,
                *(_QWORD *)(a1 + 448) + (unsigned int)a5,
                v40);
          }
        }
      }
    }
    else
    {
      v41 = a8;
      if( a8 && (unsigned int)a9 >= 0x10 )
      {
        *(_DWORD *)a8 = 0;
        *(_QWORD *)(v41 + 8) = 0i64;
      }
    }
  }
}

Referenced by:

HalpAllocateAdapterCallbackV3