VmpConvertPortionVpnRangeToGpnRange

unsigned __int64 __fastcall VmpConvertPortionVpnRangeToGpnRange(
        __int64 a1,
        unsigned __int64 *a2,
        unsigned __int64 a3,
        __int64 a4,
        _QWORD *a5){
  unsigned __int64 v5; 
  _QWORD *v6; 
  unsigned __int64 v8; 
  _QWORD *v9; 
  unsigned __int64 v10; 
  unsigned __int64 v14; 
  _QWORD *v15; 
  __int64 v16; 
  bool v17; 
  unsigned __int64 v18; 
  int v19; 
  unsigned __int64 v20; 
  _QWORD *v21; 
  unsigned __int64 v22; 
  unsigned __int64 v23; 
  unsigned __int64 v24; 
  unsigned __int64 v25; 
  int v26; 
  unsigned __int64 v27; 
  unsigned __int64 v28; 
  __int128 v30; 

  v5 = *a2;
  v6 = 0i64;
  v8 = a2[1] - 1;
  v9 = *(_QWORD **)a4;
  v10 = v5 + v8;
  v30 = 0ui64;
  a5[1] = 0i64;
  v14 = v5;
  if( !v9 )
    goto LABEL_61;
  v15 = *(_QWORD **)(a4 + 8);
  if( v15 )
  {
    *(_QWORD *)(a4 + 8) = 0i64;
    v6 = v15;
    v14 = *(_QWORD *)(a4 + 16);
    *(_QWORD *)(a4 + 16) = 0i64;
  }
  else if( v5 < v9[3] || v5 > v9[4] )
  {
    v9 = 0i64;
  }
  if( !v9 )
  {
LABEL_61:
    v16 = a1 + 24;
    v17 = (*(_BYTE *)(a1 + 32) & 1) == 0;
    v18 = *(_QWORD *)(a1 + 24);
    if( !v17 && v18 )
      v18 ^= v16;
    v19 = *(_BYTE *)(v16 + 8) & 1;
    v9 = 0i64;
    while( v18 )
    {
      if( v14 > *(_QWORD *)(v18 + 32) )
      {
        v20 = *(_QWORD *)(v18 + 8);
      }
      else
      {
        v9 = (_QWORD *)v18;
        v20 = *(_QWORD *)v18;
        if( v14 >= *(_QWORD *)(v18 + 24) )
        {
          if( v19 && v20 )
            v20 ^= v18;
          v21 = 0i64;
          if( v20 )
          {
            do
            {
              if( v14 > *(_QWORD *)(v20 + 32) )
              {
                v22 = *(_QWORD *)(v20 + 8);
              }
              else
              {
                v22 = *(_QWORD *)v20;
                if( v14 >= *(_QWORD *)(v20 + 24) )
                  v21 = (_QWORD *)v20;
              }
              if( v19 && v22 )
                v20 ^= v22;
              else
                v20 = v22;
            }
            while( v20 );
            if( v21 )
              v9 = v21;
          }
          break;
        }
      }
      if( v19 && v20 )
        v18 ^= v20;
      else
        v18 = v20;
    }
    if( !v9 )
      goto LABEL_54;
  }
  v23 = v9[3];
  if( v14 < v23 )
  {
    if( v10 < v23 )
    {
LABEL_54:
      *(_OWORD *)a2 = v30;
      return v14;
    }
    v14 = v9[3];
  }
  *(_QWORD *)a4 = v9;
  if( !v6 )
    v6 = (_QWORD *)v9[5];
  *a5 = v14 + v6[6] - v23;
  if( v10 - v14 + 1 <= a3 )
    v24 = v10;
  else
    v24 = v14 + a3 - 1;
  v25 = v9[4];
  v26 = 0;
  if( v24 >= v25 )
  {
    a5[1] = v25 - v14 + 1;
    v27 = v25 + 1;
    *(_QWORD *)&v30 = v25 + 1;
LABEL_48:
    v26 = 1;
    goto LABEL_50;
  }
  a5[1] = v24 - v14 + 1;
  v27 = v24 + 1;
  *(_QWORD *)&v30 = v24 + 1;
  if( v24 == v10 )
    goto LABEL_48;
  *(_QWORD *)(a4 + 8) = v6;
  *(_QWORD *)(a4 + 16) = v27;
LABEL_50:
  v28 = v10 - v27;
  *((_QWORD *)&v30 + 1) = v28 + 1;
  if( v26 )
  {
    if( (_QWORD *)*v6 == v9 + 5 )
    {
      if( v28 != -1i64 )
        *(_QWORD *)a4 = VmpVaMemoryRangeGetNext(a1, v9);
      goto LABEL_54;
    }
    *(_QWORD *)(a4 + 8) = *v6;
    if( v5 <= v23 )
      v5 = v23;
    *(_QWORD *)(a4 + 16) = v5;
  }
  return v14;
}

Referenced by:

VmpFillGpnRanges
VmpFlushTbVaRange
VmpQueryAccessedState