MiCopyToCfgBitMap

INT64 __fastcall MiCopyToCfgBitMap(
        INT64 a1,
        UINT64 a2,
        INT64 a3,
        INT64 a4,
        UINT64 Src,
        INT64 a6,
        UINT64 a7,
        UINT64 *a8,
        size_t Size){
  INT64 v9; 
  UINT64 *v10; 
  UINT64 v11; 
  unsigned int v12; 
  unsigned int v13; 
  int v14; 
  __int64 v15; 
  UINT8 *v16; 
  char *v17; 
  unsigned __int64 v18; 
  UINT64 v19; 
  int v20; 
  int v21; 
  __int64 v22; 
  unsigned int v23; 
  UINT64 v24; 
  VOID *v25; 
  __int64 v27; 
  unsigned __int64 v28; 
  unsigned __int64 v29; 
  __int64 v30; 
  unsigned int v31; 
  unsigned int v32; 
  unsigned int i; 
  __int64 v34; 
  unsigned __int64 v35; 
  unsigned __int64 v36; 
  unsigned int v37; 
  unsigned int v38; 
  __int64 v39; 
  int v40; 
  int v41; 
  unsigned int v42; 
  int v43; 
  __int64 v44; 
  bool v45; 
  int v46; 
  unsigned __int64 v47; 
  unsigned __int64 v48; 
  int v49; 
  unsigned int v50; 
  __int64 v51; 
  unsigned __int8 *v52; 
  __int64 v53; 
  unsigned int v54; 
  __int64 v55; 
  unsigned int v56; 
  int *v57; 
  void *v58; 
  char v59; 
  unsigned int v60; 
  int v61; 
  unsigned __int64 v62; 
  VOID *Va; 
  unsigned int v64; 
  unsigned __int64 v65; 
  __int64 v66; 
  __int64 v67; 
  UINT64 v68; 
  int v69; 
  unsigned int v70; 
  UINT64 v71; 
  _RTL_BITMAP_EX BitMapHeader; 
  INT64 v73; 
  UINT64 v74; 
  UINT64 v75; 
  v69 = a4;
  v65 = a2;
  v9 = a1;
  v73 = a1;
  BitMapHeader = 0i64;
  v10 = a8;
  if( a2 > 1 && *(_DWORD *)a8 == -1 )
  {
    a2 = 1i64;
    v65 = 1i64;
  }
  v11 = a2;
  v74 = a2;
  v75 = a2;
  v71 = a2;
  v12 = 0;
  v60 = 0;
  v13 = a7;
  v66 = (unsigned int)a7;
  v61 = 0;
  v14 = 4096;
  v62 = 4096i64;
  if( a2 <= 1 )
  {
    v16 = (UINT8 *)qword_140C4EAC8;
    if( !a2 )
      v16 = (UINT8 *)qword_140C4EAD0;
    goto LABEL_42;
  }
  LODWORD(v15) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
  v16 = (UINT8 *)v15;
  v67 = v15;
  a2 = v65;
  v12 = v60;
  if( !v15 )
  {
    v14 = 256;
    v62 = 256i64;
    v58 = alloca(256i64);
    v16 = (UINT8 *)&v59;
LABEL_42:
    v67 = (__int64)v16;
    goto LABEL_7;
  }
  v61 = 1;
  v14 = v62;
LABEL_7:
  v17 = (char *)Src;
  Va = (VOID *)Src;
  v18 = Size;
  v19 = (Size >> 12) + (((Size & 0xFFF) + (unsigned int)(Src & 0xFFF) + 4095) >> 12);
  v68 = v19;
  v20 = 0;
  while( 1 )
  {
    if( !v18 )
    {
      v25 = Va;
      goto LABEL_19;
    }
    v21 = v14 - 1;
    v22 = (unsigned int)v17 & v21;
    v23 = v62 - v22;
    if( v62 - v22 >= v18 )
      v23 = v18;
    v70 = v23;
    v24 = v23;
    if( a2 > 1 )
    {
      if( v69 == 1 )
      {
        if( v12 >= *(_DWORD *)v71 )
        {
          v28 = v62;
        }
        else
        {
          v27 = *(_QWORD *)(*(_QWORD *)(v71 + 8) + 16i64 * v12) - v66;
          v28 = v62;
          v29 = (2 * ((v27 & ~(v62 - 1)) >> 4)) >> 3;
          if( v29 >= v62 )
          {
            v66 += v27 & ~(v62 - 1);
            v17 += v29;
            Va = v17;
            v18 -= v29;
            Size = v18;
          }
        }
        v30 = (unsigned int)v17 & v21;
        if( v28 - v30 < v18 )
          v24 = (unsigned int)(v28 - v30);
        else
          v24 = (unsigned int)v18;
        memmove(v16, (UINT8 *)v17, (unsigned int)v24);
        BitMapHeader.Buffer = (unsigned __int64 *)v16;
        BitMapHeader.SizeOfBitMap = (unsigned int)(8 * v24);
        v31 = (unsigned int)v24 >> 1;
        v32 = (unsigned int)v24 >> 1 << 7;
        for( i = v60; i < *(_DWORD *)v71; i = ++v60 )
        {
          v34 = *(_QWORD *)(v71 + 8) + 16i64 * i;
          v35 = (unsigned int)(*(_DWORD *)v34 - v66);
          v32 = v31 << 7;
          if( (unsigned int)v35 >= v31 << 7 )
            break;
          v36 = 2 * (v35 >> 4);
          if( (*(_BYTE *)(v34 + 8) & 5) != 0 )
          {
            _bittestandreset64((signed __int64 *)v16, v36 + 1);
            _bittestandset64((signed __int64 *)v16, v36);
          }
          else
          {
            RtlClearBitsEx((INT64)&BitMapHeader, v36, 2ui64);
          }
        }
        v66 += v32;
        goto LABEL_34;
      }
      v24 = v23;
      if( !v69 )
      {
        BitMapHeader.Buffer = (unsigned __int64 *)v16;
        BitMapHeader.SizeOfBitMap = 8 * v23;
        RtlClearAllBitsEx(&BitMapHeader);
        v37 = v13 + (v23 >> 1 << 7);
        v64 = v37;
        v38 = *(_DWORD *)v10;
        if( !*(_DWORD *)v10 )
        {
          v38 = RtlEnumRvaListFirst(v11, v10 + 1, (_DWORD *)v10 + 1);
          *(_DWORD *)v10 = v38;
          goto LABEL_58;
        }
        while( 1 )
        {
          if( v38 >= v13 )
          {
            if( v38 >= v37 )
            {
              v45 = v38 == 0;
LABEL_77:
              if( v45 )
                v38 = -1;
              v13 = v37;
              *(_DWORD *)v10 = v38;
              v24 = v70;
LABEL_34:
              v17 = (char *)Va;
              break;
            }
            v46 = *((_DWORD *)v10 + 1);
            if( (v46 & 1) != 0 )
            {
              v47 = 2 * ((unsigned __int64)(v38 - v13) >> 4);
              if( (v38 & 0xF) == *(_DWORD *)(v9 + 24) )
              {
                v48 = v47 + 1;
                if( (v46 & 4) != 0 )
                {
                  _bittestandreset64((signed __int64 *)v16, v47);
                  _bittestandset64((signed __int64 *)v16, v48);
                }
                else
                {
                  _bittestandset64((signed __int64 *)v16, v47);
                  _bittestandreset64((signed __int64 *)v16, v48);
                }
              }
              else
              {
                RtlSetBitsEx((INT64)&BitMapHeader, v47, 2ui64);
              }
            }
          }
          v49 = ++*((_DWORD *)v10 + 3);
          v50 = *((_DWORD *)v10 + 2);
          v51 = *((unsigned int *)v10 + 4);
          v52 = (unsigned __int8 *)(v51 + *(_QWORD *)(v11 + 16));
          v53 = *(_QWORD *)(v11 + 24) - v51;
          if( v53 )
          {
            while( 1 )
            {
              v54 = *v52++;
              --v53;
              v55 = v54 >> 6;
              v50 += (v54 & 0x3F) * *((_DWORD *)RtlpRvaCompressionTableScales + v55);
              if( (_DWORD)v55 == 3 )
                break;
              if( !v53 )
                KeBugCheckEx(0x1Au, 0x43666720ui64, v11, (ULONG_PTR)(v10 + 1), v50);
            }
            *((_DWORD *)v10 + 2) = v50;
            *((_DWORD *)v10 + 4) = (_DWORD)v52 - *(_DWORD *)(v11 + 16);
            if( v10 != (UINT64 *)-4i64 )
            {
              v41 = 0;
              v56 = *(_DWORD *)(v11 + 8);
              if( v56 <= 1 )
              {
                if( v56 == 1 )
                {
                  v57 = *(int **)(v11 + 48);
                  if( v57 )
                    v41 = *v57;
                  else
                    v41 = 1;
                }
              }
              else
              {
                v42 = 0;
                v43 = 1;
                v44 = 0i64;
                do
                {
                  if( _bittest64(*(const signed __int64 **)(v75 + 40), v49 * v56 + v42) )
                  {
                    v39 = *(_QWORD *)(v11 + 48);
                    if( v39 )
                      v40 = *(_DWORD *)(v44 + v39);
                    else
                      v40 = v43;
                    v41 |= v40;
                  }
                  ++v42;
                  v43 = __ROL4__(v43, 1);
                  v44 += 4i64;
                }
                while( v42 < v56 );
              }
              *((_DWORD *)v10 + 1) = v41;
            }
            v38 = *((_DWORD *)v10 + 2);
            v10 = a8;
            v9 = v73;
          }
          else
          {
            v38 = 0;
            v10 = a8;
            v9 = v73;
          }
LABEL_58:
          v37 = v64;
          v45 = v38 == 0;
          if( !v38 )
            goto LABEL_77;
        }
      }
    }
    v20 = MiSplitPrivatePage((UINT64)v17, a6);
    if( v20 < 0 )
      break;
    v25 = Va;
    v20 = MiCopyToUserVa(Va, (_MMVAD *)a6, v16, v24);
    if( v20 < 0 )
      goto LABEL_88;
    v12 = v60;
    a2 = v65;
    v10 = a8;
    if( v60 )
    {
      **(_DWORD **)(v71 + 16) = v60;
LABEL_16:
      v14 = v62;
      goto LABEL_17;
    }
    if( v65 <= 1 || *(_DWORD *)a8 != -1 )
      goto LABEL_16;
    if( v61 )
    {
      ExFreePoolWithTag(v16, 0);
      v61 = 0;
      v12 = v60;
    }
    a2 = 1i64;
    v65 = 1i64;
    v14 = 4096;
    v62 = 4096i64;
    v16 = (UINT8 *)qword_140C4EAC8;
    v67 = qword_140C4EAC8;
LABEL_17:
    v17 = (char *)Va + v24;
    Va = (char *)Va + v24;
    v18 = Size - v24;
    Size -= v24;
    v19 = v68;
  }
  v25 = Va;
LABEL_88:
  v19 = v68;
LABEL_19:
  if( v61 )
    ExFreePoolWithTag(v16, 0);
  if( v11 )
  {
    if( v20 >= 0 )
      goto LABEL_23;
    if( v25 != (VOID *)Src && v20 != -1073741818 )
    {
      v19 = ((unsigned __int64)v25 - (Src & 0xFFFFFFFFFFFFF000ui64)) >> 12;
LABEL_23:
      MiEliminateZeroPages(*((_QWORD *)KeGetCurrentThread() + 23) + 1664i64, Src & 0xFFFFFFFFFFFFF000ui64, v19 << 12);
    }
  }
  return(unsigned int)v20;
}

Referenced by:

MiMarkSharedImageCfgBits
MiPopulateCfgBitMap