MiCopyToCfgBitMap

NTSTATUS __stdcall MiCopyToCfgBitMap(
        VOID *DestinationVa,
        _MMVAD *DestinationVad,
        VOID *RvaList,
        _MI_RVA_LIST_TYPE ListType,
        UINT64 ImageStartRva,
        _MI_CFG_COPY_TO_BITMAP_ITERATOR *CopyIterator,
        UINT64 NumberOfBytes,
        _MI_CFG_COPY_TO_BITMAP_OPTION CopyOption,
        UINT64 AlignedBits){
  _DWORD *v9; 
  unsigned int *v10; 
  _MMVAD *v11; 
  unsigned int v12; 
  unsigned int v13; 
  int v14; 
  char *Pool; 
  char *v16; 
  unsigned __int64 v17; 
  UINT64 v18; 
  NTSTATUS v19; 
  int v20; 
  __int64 v21; 
  unsigned int v22; 
  UINT64 v23; 
  int v24; 
  VOID *v25; 
  int v26; 
  __int64 v28; 
  unsigned __int64 v29; 
  unsigned __int64 v30; 
  __int64 v31; 
  unsigned int v32; 
  unsigned int v33; 
  unsigned int i; 
  __int64 v35; 
  unsigned __int64 v36; 
  unsigned __int64 v37; 
  unsigned int v38; 
  unsigned int v39; 
  __int64 v40; 
  int v41; 
  int v42; 
  unsigned int v43; 
  int v44; 
  __int64 v45; 
  bool v46; 
  unsigned int v47; 
  unsigned __int64 v48; 
  unsigned __int64 v49; 
  unsigned int v50; 
  unsigned int v51; 
  __int64 v52; 
  unsigned __int8 *v53; 
  __int64 v54; 
  unsigned int v55; 
  __int64 v56; 
  unsigned int Right; 
  int *v58; 
  void *v59; 
  char v60; 
  unsigned int v61; 
  int v62; 
  unsigned __int64 v63; 
  VOID *Va; 
  unsigned int v65; 
  unsigned __int64 v66; 
  __int64 v67; 
  char *v68; 
  UINT64 v69; 
  _MI_RVA_LIST_TYPE v70; 
  unsigned int v71; 
  _MMVAD *v72; 
  _RTL_BITMAP_EX BitMapHeader; 
  _DWORD *v74; 
  _MMVAD *v75; 
  _MMVAD *v76; 

  v70 = ListType;
  v66 = (unsigned __int64)DestinationVad;
  v9 = DestinationVa;
  v74 = DestinationVa;
  BitMapHeader = 0i64;
  v10 = *(unsigned int **)&CopyOption;
  if( (unsigned __int64)DestinationVad > 1 && **(_DWORD **)&CopyOption == -1 )
  {
    DestinationVad = (_MMVAD *)1;
    v66 = 1i64;
  }
  v11 = DestinationVad;
  v75 = DestinationVad;
  v76 = DestinationVad;
  v72 = DestinationVad;
  v12 = 0;
  v61 = 0;
  v13 = NumberOfBytes;
  v67 = (unsigned int)NumberOfBytes;
  v62 = 0;
  v14 = 4096;
  v63 = 4096i64;
  if( (unsigned __int64)DestinationVad <= 1 )
  {
    Pool = (char *)*(&stru_140C4DB30 + 499);
    if( !DestinationVad )
      Pool = (char *)*(&stru_140C4DB30 + 500);
    goto LABEL_42;
  }
  Pool = (char *)MiAllocatePool(64i64, 0x1000ui64, 0x6554694Dui64);
  v68 = Pool;
  DestinationVad = (_MMVAD *)v66;
  v12 = v61;
  if( !Pool )
  {
    v14 = 256;
    v63 = 256i64;
    v59 = alloca(256i64);
    Pool = &v60;
LABEL_42:
    v68 = Pool;
    goto LABEL_7;
  }
  v62 = 1;
  v14 = v63;
LABEL_7:
  v16 = (char *)ImageStartRva;
  Va = (VOID *)ImageStartRva;
  v17 = AlignedBits;
  v18 = (AlignedBits >> 12) + (((AlignedBits & 0xFFF) + (unsigned int)(ImageStartRva & 0xFFF) + 4095) >> 12);
  v69 = v18;
  v19 = 0;
  while( 1 )
  {
    if( !v17 )
    {
      v25 = Va;
      goto LABEL_19;
    }
    v20 = v14 - 1;
    v21 = (unsigned int)v16 & v20;
    v22 = v63 - v21;
    if( v63 - v21 >= v17 )
      v22 = v17;
    v71 = v22;
    v23 = v22;
    if( (unsigned __int64)DestinationVad > 1 )
    {
      if( v70 == MiRvaListAllTypes )
      {
        if( v12 >= LODWORD(v72->Core.NextVad) )
        {
          v29 = v63;
        }
        else
        {
          v28 = *((_QWORD *)v72->Core.ExtraCreateInfo + 2 * v12) - v67;
          v29 = v63;
          v30 = (2 * ((v28 & ~(v63 - 1)) >> 4)) >> 3;
          if( v30 >= v63 )
          {
            v67 += v28 & ~(v63 - 1);
            v16 += v30;
            Va = v16;
            v17 -= v30;
            AlignedBits = v17;
          }
        }
        v31 = (unsigned int)v16 & v20;
        if( v29 - v31 < v17 )
          v23 = (unsigned int)(v29 - v31);
        else
          v23 = (unsigned int)v17;
        memmove(Pool, v16, v23);
        BitMapHeader.Buffer = (unsigned __int64 *)Pool;
        BitMapHeader.SizeOfBitMap = (unsigned int)(8 * v23);
        v32 = (unsigned int)v23 >> 1;
        v33 = (unsigned int)v23 >> 1 << 7;
        for( i = v61; i < LODWORD(v72->Core.NextVad); i = ++v61 )
        {
          v35 = (__int64)v72->Core.ExtraCreateInfo + 16 * i;
          v36 = (unsigned int)(*(_DWORD *)v35 - v67);
          v33 = v32 << 7;
          if( (unsigned int)v36 >= v32 << 7 )
            break;
          v37 = 2 * (v36 >> 4);
          if( (*(_BYTE *)(v35 + 8) & 5) != 0 )
          {
            _bittestandreset64((signed __int64 *)Pool, v37 + 1);
            _bittestandset64((signed __int64 *)Pool, v37);
          }
          else
          {
            RtlClearBitsEx(&BitMapHeader, v37, 2ui64);
          }
        }
        v67 += v33;
        goto LABEL_34;
      }
      v23 = v22;
      if( v70 == MiRvaListDefault )
      {
        BitMapHeader.Buffer = (unsigned __int64 *)Pool;
        BitMapHeader.SizeOfBitMap = 8 * v22;
        RtlClearAllBitsEx(&BitMapHeader);
        v38 = v13 + (v22 >> 1 << 7);
        v65 = v38;
        v39 = *v10;
        if( !*v10 )
        {
          v39 = RtlEnumRvaListFirst((INT64)v11, v10 + 2, v10 + 1);
          *v10 = v39;
          goto LABEL_58;
        }
        while( 1 )
        {
          if( v39 >= v13 )
          {
            if( v39 >= v38 )
            {
              v46 = v39 == 0;
LABEL_77:
              if( v46 )
                v39 = -1;
              v13 = v38;
              *v10 = v39;
              v23 = v71;
LABEL_34:
              v16 = (char *)Va;
              break;
            }
            v47 = v10[1];
            if( (v47 & 1) != 0 )
            {
              v48 = 2 * ((unsigned __int64)(v39 - v13) >> 4);
              if( (v39 & 0xF) == v9[6] )
              {
                v49 = v48 + 1;
                if( (v47 & 4) != 0 )
                {
                  _bittestandreset64((signed __int64 *)Pool, v48);
                  _bittestandset64((signed __int64 *)Pool, v49);
                }
                else
                {
                  _bittestandset64((signed __int64 *)Pool, v48);
                  _bittestandreset64((signed __int64 *)Pool, v49);
                }
              }
              else
              {
                RtlSetBitsEx(&BitMapHeader, v48, 2ui64);
              }
            }
          }
          v50 = ++v10[3];
          v51 = v10[2];
          v52 = v10[4];
          v53 = (unsigned __int8 *)(v52 + v11->Core.VadNode.ParentValue);
          v54 = *(_QWORD *)&v11->Core.StartingVpn - v52;
          if( v54 )
          {
            while( 1 )
            {
              v55 = *v53++;
              --v54;
              v56 = v55 >> 6;
              v51 += (v55 & 0x3F) * *((_DWORD *)RtlpRvaCompressionTableScales + v56);
              if( (_DWORD)v56 == 3 )
                break;
              if( !v54 )
                KeBugCheckEx(0x1Au, (PVOID)0x43666720, v11, v10 + 2, (PVOID)v51);
            }
            v10[2] = v51;
            v10[4] = (_DWORD)v53 - *(_DWORD *)&v11->Core.VadNode._bf_0;
            if( v10 != (unsigned int *)-4i64 )
            {
              v42 = 0;
              Right = (unsigned int)v11->Core.VadNode.Right;
              if( Right <= 1 )
              {
                if( Right == 1 )
                {
                  v58 = *(int **)&v11->Core.u.LongFlags;
                  if( v58 )
                    v42 = *v58;
                  else
                    v42 = 1;
                }
              }
              else
              {
                v43 = 0;
                v44 = 1;
                v45 = 0i64;
                do
                {
                  if( _bittest64((const signed __int64 *)v76->Core.PushLock._bf_0, v50 * Right + v43) )
                  {
                    v40 = *(_QWORD *)&v11->Core.u.LongFlags;
                    if( v40 )
                      v41 = *(_DWORD *)(v45 + v40);
                    else
                      v41 = v44;
                    v42 |= v41;
                  }
                  ++v43;
                  v44 = __ROL4__(v44, 1);
                  v45 += 4i64;
                }
                while( v43 < Right );
              }
              v10[1] = v42;
            }
            v39 = v10[2];
            v10 = *(unsigned int **)&CopyOption;
            v9 = v74;
          }
          else
          {
            v39 = 0;
            v10 = *(unsigned int **)&CopyOption;
            v9 = v74;
          }
LABEL_58:
          v38 = v65;
          v46 = v39 == 0;
          if( !v39 )
            goto LABEL_77;
        }
      }
    }
    MiSplitPrivatePage(v16, (_MMVAD *)CopyIterator);
    v19 = v24;
    if( v24 < 0 )
      break;
    v25 = Va;
    MiCopyToUserVa(Va, (_MMVAD *)CopyIterator, Pool, v23);
    v19 = v26;
    if( v26 < 0 )
      goto LABEL_88;
    v12 = v61;
    DestinationVad = (_MMVAD *)v66;
    v10 = *(unsigned int **)&CopyOption;
    if( v61 )
    {
      *(_DWORD *)v72->Core.VadNode.ParentValue = v61;
LABEL_16:
      v14 = v63;
      goto LABEL_17;
    }
    if( v66 <= 1 || **(_DWORD **)&CopyOption != -1 )
      goto LABEL_16;
    if( v62 )
    {
      ExFreePoolWithTag(Pool, 0);
      v62 = 0;
      v12 = v61;
    }
    DestinationVad = (_MMVAD *)1;
    v66 = 1i64;
    v14 = 4096;
    v63 = 4096i64;
    Pool = (char *)*(&stru_140C4DB30 + 499);
    v68 = (char *)*(&stru_140C4DB30 + 499);
LABEL_17:
    v16 = (char *)Va + v23;
    Va = (char *)Va + v23;
    v17 = AlignedBits - v23;
    AlignedBits -= v23;
    v18 = v69;
  }
  v25 = Va;
LABEL_88:
  v18 = v69;
LABEL_19:
  if( v62 )
    ExFreePoolWithTag(Pool, 0);
  if( v11 )
  {
    if( v19 >= 0 )
      goto LABEL_23;
    if( v25 != (VOID *)ImageStartRva && v19 != -1073741818 )
    {
      v18 = ((unsigned __int64)v25 - (ImageStartRva & 0xFFFFFFFFFFFFF000ui64)) >> 12;
LABEL_23:
      MiEliminateZeroPages(
        &KeGetCurrentThread()->ApcState.Process->Vm.Instance,
        (VOID *)(ImageStartRva & 0xFFFFFFFFFFFFF000ui64),
        v18 << 12);
    }
  }
  return v19;
}

Referenced by:

MiMarkSharedImageCfgBits
MiPopulateCfgBitMap