MiCreatePagingFileMap

NTSTATUS __stdcall MiCreatePagingFileMap(
        _SEGMENT **Segment,
        UINT64 *MaximumSize,
        UINT64 ProtectionMask,
        UINT64 AllocationAttributes,
        UINT64 PreferredNode){
  int v5; 
  _SEGMENT **v6; 
  char v8; 
  unsigned __int64 v9; 
  __int64 v10; 
  unsigned __int64 v11; 
  int v12; 
  _ETHREAD *CurrentThread; 
  char v14; 
  _MI_PARTITION **v15; 
  _MI_PARTITION *v16; 
  int v17; 
  UINT64 NodeColor; 
  unsigned int *v19; 
  unsigned int *v20; 
  _MI_LARGEPAGE_MEMORY_INFO *LargeZeroPages; 
  INT64 v22; 
  __int64 v23; 
  INT64 v24; 
  unsigned __int64 v25; 
  unsigned __int64 v26; 
  _SEGMENT *v27; 
  _EX_PUSH_LOCK *v28; 
  _EX_PUSH_LOCK *v29; 
  __int16 v30; 
  int v31; 
  int v32; 
  __int16 v33; 
  __int16 v34; 
  __int64 v35; 
  unsigned __int64 v36; 
  char *v37; 
  char *i; 
  unsigned __int64 v39; 
  unsigned __int64 v40; 
  __int16 v41; 
  unsigned __int8 v42; 
  VOID *v43; 
  INT64 v44; 
  VOID *v45; 
  __int64 v46; 
  char *v47; 
  char *v48; 
  int v49; 
  __int64 v50; 
  INT64 v51; 
  unsigned __int64 v52; 
  char *v53; 
  VOID *v54; 
  INT64 v55; 
  __int64 v56; 
  UINT64 ZeroFillNeeded; 
  UINT64 ZeroFillNeededa; 
  unsigned __int64 v59; 
  __int64 v60; 
  __int64 v61; 
  char *v62; 
  unsigned __int64 v63; 
  __int64 v64; 
  _EX_PUSH_LOCK *v65; 
  __int64 NumberOfBytes; 
  char *v67; 
  char *Pool; 
  INT64 v69[2]; 
  __int128 v70; 
  unsigned int v72; 
  __int64 v73; 
  char v74; 
  char v75; 
  unsigned __int64 v76; 
  PVOID P; 

  v5 = *((_DWORD *)Segment + 4);
  v6 = Segment;
  *(_OWORD *)v69 = 0i64;
  v70 = 0i64;
  if( (v5 & 0x1000000) != 0 )
    return -1073741792;
  v8 = *((_BYTE *)Segment + 192);
  v75 = v8;
  if( v8 )
  {
    if( (v5 & 0x2BF7FFFF) != 0
      || (v5 & 0x4000000) == 0
      || (v5 & 0x8000000) != 0
      || (v5 & 0x80080000) == -2146959360
      || (v5 & 0x50000000) == 1342177280 )
    {
      return -1073741811;
    }
    if( (*((_DWORD *)Segment + 7) & 7) != 4 )
      return -1073741755;
    if( ((_DWORD)Segment[4] & 7) != 4 )
      return -1073741811;
  }
  else
  {
    if( v5 >= 0 )
      goto LABEL_18;
    if( (v5 & 0x8000000) == 0 )
      return -1073741580;
  }
  if( !SeSinglePrivilegeCheck(*(_QWORD *)&SeLockMemoryPrivilege, *((_BYTE *)Segment + 72)) )
    return -1073741727;
LABEL_18:
  v9 = (unsigned __int64)v6[19];
  v10 = 1i64;
  if( v8 )
  {
    if( v9 )
      return -1073741582;
    v11 = 1i64;
    v12 = v5 & 0x8000000;
  }
  else
  {
    if( !v9 )
      return -1073741582;
    v12 = v5 & 0x8000000;
    if( v9 > (-(__int64)((v5 & 0x8000000) != 0) & 0xFFFFF001000ui64) - 4096 )
      return -1073741760;
    v11 = (v9 + 4095) >> 12;
  }
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v14 = 0;
  v15 = (_MI_PARTITION **)v6[22];
  v60 = 0i64;
  v74 = 0;
  v64 = (__int64)CurrentThread;
  if( v15 )
    v16 = *v15;
  else
    v16 = &Irp;
  if( !v12 )
    goto LABEL_49;
  if( (v5 & 0x80000) != 0 && (v11 & 0xF) != 0 || v5 < 0 && (v11 & 0x1FF) != 0 )
    return -1073741582;
  if( !MiChargeCommit(v16, v11, 0i64) )
    return -1073741523;
  if( v5 >= 0 )
  {
    v10 = 1i64;
  }
  else
  {
    if( MiChargeResident((ULONG_PTR *)&v16->Core.PartitionId, v11, 0i64) == MiChargeFailed )
    {
LABEL_104:
      if( v12 )
      {
        MiFreeLargeZeroPages((UINT64)v16, (_MMPFN **)v69, 0i64);
        if( v14 )
          MiReturnResident((INT64)v16, v11);
        MiReturnCommit(v16, v11);
      }
      return -1073741670;
    }
    v17 = *((_DWORD *)v6 + 43);
    v74 = 1;
    if( v17 )
      NodeColor = (unsigned int)(v17 - 1);
    else
      NodeColor = (*(&KiProcessorBlock + CurrentThread->Tcb.IdealProcessor))->NodeColor;
    v19 = (unsigned int *)(*(&stru_140C4DB30 + 21) + 4i64 * (unsigned int)NodeColor * (unsigned __int16)KeNumberNodes);
    v20 = &v19[(unsigned __int16)KeNumberNodes];
    LODWORD(ZeroFillNeeded) = *((_DWORD *)v6 + 8);
    LargeZeroPages = MiAllocateLargeZeroPages((UINT64)v16, v11, 0x200ui64, NodeColor, ZeroFillNeeded);
    if( LargeZeroPages != (_MI_LARGEPAGE_MEMORY_INFO *)v11 )
    {
      do
      {
        if( ++v19 == v20 )
          break;
        LODWORD(ZeroFillNeededa) = *((_DWORD *)v6 + 8);
        LargeZeroPages = (_MI_LARGEPAGE_MEMORY_INFO *)((char *)LargeZeroPages
                                                     + (_QWORD)MiAllocateLargeZeroPages(
                                                                 (UINT64)v16,
                                                                 v11 - (_QWORD)LargeZeroPages,
                                                                 0x200ui64,
                                                                 *v19,
                                                                 ZeroFillNeededa));
      }
      while( LargeZeroPages != (_MI_LARGEPAGE_MEMORY_INFO *)v11 );
      if( LargeZeroPages != (_MI_LARGEPAGE_MEMORY_INFO *)v11 )
      {
LABEL_103:
        v14 = v74;
        goto LABEL_104;
      }
    }
    v22 = v69[0];
    v10 = 1i64;
    if( v69[0] )
    {
      v23 = 0i64;
      do
      {
        v23 += v10;
        LODWORD(v24) = MiGetPfnLink(v22);
        v22 = v24;
      }
      while( v24 );
      v60 = v23;
      v6 = Segment;
    }
  }
LABEL_49:
  P = 0i64;
  if( (v5 & 0x88000000) == 0x8000000 )
  {
    v59 = v11;
    v25 = v10;
  }
  else
  {
    v26 = (unsigned __int64)(((v5 >> 31) & 0x100000u) + 0x100000) >> 3;
    v59 = v26;
    v25 = v11 / v26;
    if( v11 % v26 )
      v25 += v10;
  }
  Pool = (char *)MiAllocatePool(64i64, 88 * v25 + 128, 0x61436D4Dui64);
  v27 = (_SEGMENT *)Pool;
  if( !Pool )
    goto LABEL_103;
  v28 = (_EX_PUSH_LOCK *)MiAllocatePool(256i64, 0x50ui64, 0x6765534Dui64);
  v65 = v28;
  v29 = v28;
  if( !v28 )
    goto LABEL_94;
  v28[9]._bf_0 = 0i64;
  v30 = (*((_WORD *)Pool + 30) ^ v16->Core.PartitionId) & 0x3FF;
  *((_DWORD *)Pool + 24) = v25;
  *((_WORD *)Pool + 30) ^= v30;
  *((_QWORD *)Pool + 2) = Pool + 8;
  *((_QWORD *)Pool + 1) = Pool + 8;
  v31 = *((_DWORD *)Pool + 14);
  *((_QWORD *)Pool + 14) = 1i64;
  *((_QWORD *)Pool + 3) = 1i64;
  *((_QWORD *)Pool + 6) = 1i64;
  *(_QWORD *)Pool = v28;
  if( (v5 & 0x200000) != 0 )
  {
    v31 |= 0x40u;
    *((_DWORD *)Pool + 14) = v31;
  }
  if( (v5 & 0x4000000) != 0 )
  {
    v31 |= 0x1000u;
    *((_DWORD *)Pool + 14) = v31;
  }
  if( v12 )
  {
    v31 |= 0x2000u;
    *((_DWORD *)Pool + 14) = v31;
  }
  if( (v5 & 0x80000) != 0 )
  {
    v31 |= 0x80000000;
    *((_DWORD *)Pool + 14) = v31;
  }
  v32 = *((_DWORD *)v6 + 43);
  *((_QWORD *)Pool + 13) = 0i64;
  *((_DWORD *)Pool + 14) = v31 ^ (v31 ^ (v32 << 20)) & 0x3F00000;
  memset(v29, 0i64, 0x48u);
  if( (v5 & 0x10000000) != 0 )
  {
    v33 = 0x8000;
LABEL_67:
    WORD2(v29[1].Ptr) |= v33;
    goto LABEL_68;
  }
  if( (v5 & 0x40000000) != 0 )
  {
    v33 = 0x4000;
    goto LABEL_67;
  }
LABEL_68:
  BYTE6(v29[1].Ptr) ^= (BYTE6(v29[1].Ptr) ^ (2 * *((_BYTE *)v6 + 32))) & 0x3E;
  LODWORD(v29[6]._bf_0) = KeGetCurrentThread()->ApcState.Process->UniqueProcessId;
  v29[3]._bf_0 = v11 << 12;
  v34 = (WORD2(v29[1].Ptr) ^ WORD2(v11)) & 0x3FF;
  v29->_bf_0 = (__int64)Pool;
  WORD2(v29[1].Ptr) ^= v34;
  LODWORD(v29[1]._bf_0) = v11;
  if( v75 && MiAllocateAweInfo((WCHAR *)Pool) < 0 )
  {
LABEL_94:
    v52 = 0i64;
    if( v25 )
    {
      v72 = v5 & 0x88000000;
      v53 = Pool + 136;
      do
      {
        v54 = *(VOID **)v53;
        if( !*(_QWORD *)v53 )
          break;
        if( v72 == -2013265920 )
        {
          MmReturnChargesToLockPagedPool(v54, 8i64 * *((unsigned int *)v53 + 9));
          v54 = *(VOID **)v53;
        }
        ExFreePoolWithTag(v54, 0);
        v53 += 88;
        ++v52;
      }
      while( v52 < v25 );
      v29 = v65;
    }
    ExFreePoolWithTag(Pool, 0);
    if( v29 )
      ExFreePoolWithTag(v29, 0);
    goto LABEL_103;
  }
  v76 = v11;
  v35 = 0i64;
  v62 = Pool + 128;
  v36 = 0i64;
  v61 = 0i64;
  v63 = 0i64;
  v37 = Pool + 128;
  for( i = Pool + 128; v36 < v25; v63 = v36 )
  {
    i = v37;
    v39 = v59;
    v40 = *((_QWORD *)v37 + 10) & 0xFFFFFFFFFFFFFFF8ui64 | 1;
    *(_QWORD *)v37 = Pool;
    *((_QWORD *)v37 + 10) = v40;
    v41 = *((_WORD *)v6 + 16);
    v67 = v37;
    if( v76 <= v59 )
      v39 = v76;
    *((_DWORD *)v37 + 9) = v35;
    v42 = *((_WORD *)v37 + 16) & 1;
    v76 -= v39;
    *((_DWORD *)v37 + 11) = v39;
    *((_WORD *)v37 + 16) = (WORD2(v35) << 6) | (v42 | (unsigned __int8)(2 * v41)) & 0x3F;
    NumberOfBytes = 8 * v39;
    if( v12 )
    {
      v43 = MiAllocatePool(274i64, 8 * v39, 0x74536D4Dui64);
      P = v43;
      if( !v43 )
        goto LABEL_94;
      if( v5 < 0 )
      {
        if( !MmObtainChargesToLockPagedPool(v43, NumberOfBytes, v44, v45) )
        {
          ExFreePoolWithTag(P, 0);
          goto LABEL_94;
        }
        v43 = P;
      }
      v37 = v62;
      i = v67;
      v36 = v63;
      v35 = v61;
      LODWORD(v39) = *((_DWORD *)v62 + 11);
      *((_QWORD *)v62 + 1) = v43;
    }
    v37 += 88;
    v35 += (unsigned int)v39;
    v62 = v37;
    ++v36;
    v61 = v35;
    *((_QWORD *)i + 2) = v37;
  }
  *((_QWORD *)i + 2) = 0i64;
  v29[8]._bf_0 = (__int64)P;
  if( v12 )
  {
    --*(_WORD *)(v64 + 486);
    ExAcquirePushLockExclusiveEx(v29 + 5, 0i64);
    MiUpdateControlAreaCommitCount((INT64)Pool, v11);
    if( (_InterlockedExchangeAdd64(&v29[5]._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(v29 + 5);
    KeAbPostRelease(&v29[5]);
    KiLeaveGuardedRegionUnsafe(v64);
    if( v5 >= 0 )
    {
      MiInitializePrototypePtes(*((VOID **)Pool + 17), v11, (_SUBSECTION *)(Pool + 128), 1ui64);
      MiUpdateSystemProtoPtesTree((_RTL_BALANCED_NODE *)(Pool + 184), 1i64);
    }
    else
    {
      WORD2(v29[1].Ptr) |= 0x1000u;
      *((_DWORD *)Pool + 23) |= 0x10000u;
      if( v25 )
      {
        v46 = v60;
        v47 = Pool + 176;
        do
        {
          v48 = (char *)*((_QWORD *)v47 - 5);
          MmLockPreChargedPagedPool((UINT64)v48);
          v49 = *(_DWORD *)v47 & 0x3FFFFFFF | 0x40000000;
          *(_DWORD *)v47 = v49;
          if( v46 )
          {
            --v46;
            *(_DWORD *)v47 = v49 & 0x3FFFFFFF | 0x80000000;
          }
          memset(v48, 0, 8i64 * *((unsigned int *)v47 - 1));
          MiUpdateSystemProtoPtesTree((_RTL_BALANCED_NODE *)(v47 + 8), 1i64);
          v73 = 0i64;
          if( *((_DWORD *)v47 - 1) )
          {
            do
            {
              v50 = 0i64;
              while( 1 )
              {
                v51 = v69[v50];
                if( v51 )
                  break;
                if( (unsigned __int64)++v50 >= 4 )
                  goto LABEL_110;
              }
              LODWORD(v55) = MiGetPfnLink(v51);
              v69[v50] = v55;
LABEL_110:
              v56 = MiLargePageSizes[(unsigned int)v50];
              MiUpdateLargePageSectionPfns(v51, (INT64)v48, *((unsigned int *)v6 + 8));
              v48 += 8 * v56;
              v73 += v56;
            }
            while( v73 != *((_DWORD *)v47 - 1) );
          }
          v47 += 88;
          --v25;
        }
        while( v25 );
        v27 = (_SEGMENT *)Pool;
        v29 = v65;
      }
    }
  }
  v6[8] = v27;
  _InterlockedAdd64(&v16->Segments.PfControlAreaCount, 1ui64);
  *(_DWORD *)v6 |= 4u;
  v6[16] = (_SEGMENT *)_InterlockedCompareExchange64(&v29[3]._bf_0, -1i64, -1i64);
  return 0;
}

Referenced by:

MiCreateSection