IopAddPageToPageMap

__int64 __fastcall IopAddPageToPageMap(
        __int64 a1,
        _RTL_BITMAP_EX *a2,
        UINT64 *a3,
        UINT64 a4,
        UINT64 a5,
        char a6,
        unsigned int a7){
  UINT64 v9; 
  unsigned __int64 SizeOfBitMap; 
  unsigned __int64 *Buffer; 
  UINT64 v15; 
  _DWORD *v16; 
  _DWORD *v17; 
  UINT64 v18; 
  UINT64 v19; 
  _DWORD *v20; 
  unsigned __int64 i; 

  v9 = a5;
  if( !a5 )
    return 0i64;
  SizeOfBitMap = a2->SizeOfBitMap;
  if( a4 < a2->SizeOfBitMap )
  {
    if( a4 + a5 - 1 >= SizeOfBitMap )
    {
      if( !a6 )
        return 3221225793i64;
      v9 = SizeOfBitMap - a4;
    }
    if( !v9 )
      return 0i64;
    if( !a3 )
    {
      IopAddPageRangeToPageMaps(a1, a2, a4, v9, a7);
      return 0i64;
    }
    Buffer = a2->Buffer;
    v15 = a4 + v9;
    while( 1 )
    {
      if( v15 <= a4 )
        return 0i64;
      v16 = (_DWORD *)Buffer + ((v15 - 1) >> 5);
      v17 = (_DWORD *)Buffer + (a4 >> 5);
      if( v17 != v16 && (*v17 | *((_DWORD *)qword_140011CE0 + (a4 & 0x1F))) == -1 )
      {
        a4 = (a4 & 0xFFFFFFFFFFFFFFE0ui64) + 32;
        for( ++v17; v17 < v16 && *v17 == -1; ++v17 )
          a4 += 32i64;
      }
      while( a4 < v15 && _bittest64((const signed __int64 *)Buffer, a4) )
        ++a4;
      v18 = 0i64;
      if( v17 != v16 )
      {
        v19 = a4 & 0x1F;
        if( (~*((_DWORD *)qword_140011CE0 + v19) & *v17) == 0 )
        {
          v18 = 32 - v19;
          if( v19 == 33 )
            goto LABEL_36;
          v20 = v17 + 1;
          while( v20 < v16 && !*v20 )
          {
            ++v20;
            v18 += 32i64;
            if( v18 == -1i64 )
              goto LABEL_36;
          }
        }
      }
      for( i = v18 + a4; i < v15 && !_bittest64((const signed __int64 *)Buffer, i) && v18 != -1i64; ++i )
        ++v18;
LABEL_36:
      if( !v18 )
        return 0i64;
      if( v18 > *a3 )
      {
        IopAddPageRangeToPageMaps(a1, a2, a4, *a3, a7);
        *a3 = 0i64;
        return 3221225507i64;
      }
      IopAddPageRangeToPageMaps(a1, a2, a4, v18, a7);
      *a3 -= v18;
      a4 += v18;
      if( a4 >= v15 )
        return 0i64;
    }
  }
  if( a6 )
    return 0i64;
  return 3221225793i64;
}

Referenced by:

IoSetDumpRange