MiAllocateUserPhysicalPages

INT64 __fastcall MiAllocateUserPhysicalPages(MDL *a1, UINT64 *rdx0, VOID *a3, INT64 *a4, UINT64 arg20){
  char v7; 
  _ETHREAD *CurrentThread; 
  INT8 v9; 
  VOID *v10; 
  INT64 result; 
  unsigned __int64 v12; 
  UINT64 v13; 
  __int64 v14; 
  _DWORD *v15; 
  __int64 v16; 
  INT64 v17; 
  signed int v18; 
  unsigned __int64 v19; 
  __int64 v20; 
  _EPROCESS *v21; 
  __int64 v22; 
  __int64 v23; 
  int v24; 
  INT64 AweInfoPartition; 
  unsigned __int64 v26; 
  __int64 v27; 
  __int16 v28; 
  unsigned __int64 v29; 
  unsigned int v30; 
  UINT16 IdealNode; 
  int v32; 
  _LARGE_INTEGER v33; 
  _LARGE_INTEGER v34; 
  __int64 v35; 
  _MDL *PagesForMdl; 
  unsigned __int64 v37; 
  __int64 v38; 
  INT64 v39; 
  INT64 v40; 
  ULONG_PTR v41; 
  ULONG_PTR v42; 
  unsigned __int64 v43; 
  __int64 v44; 
  unsigned __int64 v45; 
  __int64 v46; 
  _MDL *v47; 
  __int64 v48; 
  __int64 v49; 
  __int64 v50; 
  unsigned __int64 v51; 
  _MDL *v52; 
  _QWORD *v53; 
  unsigned __int64 v54; 
  unsigned __int64 i; 
  _MDL *j; 
  _MDL *Next; 
  _SECTION *v58; 
  UINT64 Flags; 
  INT8 PreviousMode; 
  MDL *P; 
  _EPROCESS *PROCESS; 
  __int64 v63; 
  _EPROCESS *v64; 
  _MDL *v65; 
  unsigned __int64 v66; 
  int v67; 
  _DWORD *a2; 
  _SECTION *Section; 
  __int64 v70; 
  INT64 v71; 
  unsigned __int64 v72; 
  __int64 v73; 
  _MDL *v74; 
  HANDLE Handle; 
  unsigned __int64 v76; 
  INT64 v77; 
  _LARGE_INTEGER v78; 
  unsigned __int64 v79; 
  volatile void *Address; 
  unsigned __int64 v81; 
  __int64 v82; 
  UINT64 *v83; 
  unsigned __int64 v84; 
  char v85[32]; 
  unsigned int v86; 
  char v87; 
  __int64 v88; 
  struct _KAPC_STATE ApcState; 
  v83 = rdx0;
  Handle = a1;
  Address = a3;
  memset(&ApcState, 0, sizeof(ApcState));
  Section = 0i64;
  memset((INT64)v85, 0i64);
  v7 = 0;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v71 = (INT64)CurrentThread;
  v64 = (_EPROCESS *)*((_QWORD *)CurrentThread + 23);
  v9 = *((_BYTE *)CurrentThread + 562);
  PreviousMode = v9;
  LOBYTE(v10) = v9;
  result = MiCaptureAllocateMapExtendedParameters(a4, (unsigned int)arg20, v10);
  if( (int)result >= 0 )
  {
    if( (v88 & 0xFFFFFFFFFFFFFFF5ui64) != 0 || (v88 & 0xA) == 10 )
      return 3221225485i64;
    v12 = (v88 & 2) != 0 ? 16i64 : (unsigned __int64)(v88 & 8) << 6;
    v72 = v12;
    if( v86 > (unsigned __int16)KeNumberNodes )
      return 3221225485i64;
    if( v9 )
    {
      v14 = (__int64)rdx0;
      if( (unsigned __int64)rdx0 >= 0x7FFFFFFF0000i64 )
        v14 = 0x7FFFFFFF0000i64;
      *(_QWORD *)v14 = *(_QWORD *)v14;
      v13 = *rdx0;
      v70 = v13;
      v73 = v13;
      if( !v13 )
        return 0i64;
      if( v13 > 0x1FFFFFFFFFFFFFFFi64 )
        return 3221225712i64;
      ProbeForWrite((VOID *)Address, 8 * v13, 8ui64);
    }
    else
    {
      v13 = *rdx0;
      v70 = v13;
      v73 = v13;
      if( !v13 )
        return 0i64;
    }
    v15 = 0i64;
    a2 = 0i64;
    result = MiReferenceAweHandle(Handle, 2i64);
    if( (int)result >= 0 )
    {
      if( Section )
      {
        v15 = (_DWORD *)*((_QWORD *)MiSectionControlArea(Section) + 1);
        a2 = v15;
      }
      else
      {
        v7 = 8;
      }
      v16 = (__int64)v64;
      PROCESS = v64;
      if( !SeSinglePrivilegeCheck(*(_QWORD *)&SeLockMemoryPrivilege, PreviousMode) )
      {
        v18 = -1073741727;
LABEL_101:
        if( v13 )
        {
          if( (v7 & 2) != 0 )
          {
            LOCK_ADDRESS_SPACE_SHARED(CurrentThread, (_EPROCESS *)v16);
            MiReturnProcessCommitment(v16, v13);
            UNLOCK_ADDRESS_SPACE_SHARED((__int64)CurrentThread, v16);
          }
          if( (v7 & 4) != 0 )
          {
            _InterlockedExchangeAdd64((volatile signed __int64 *)(v16 + 2032), -(__int64)v13);
            v16 = (__int64)PROCESS;
          }
        }
        if( (v7 & 1) != 0 )
          KeUnstackDetachProcess(&ApcState);
        if( (v7 & 8) == 0 )
        {
          v58 = Section;
          if( !Section )
            v58 = (_SECTION *)v16;
          ObfDereferenceObjectWithTag(v58, 0x68506D4Dui64);
        }
        return(unsigned int)v18;
      }
      v63 = 0i64;
      if( !v15 )
      {
        LOBYTE(v17) = PreviousMode;
        v18 = MiCreateProcessDefaultAweInfo(v17, &a2);
        if( v18 < 0 )
          goto LABEL_101;
        v15 = a2;
      }
      v19 = ExGetCallBackBlockRoutine((INT64)v15);
      v76 = v19;
      if( v12 )
      {
        if( v12 <= v19 || v12 % v19 || ((v12 - 1) & v12) != 0 )
        {
          v18 = -1073741811;
          goto LABEL_101;
        }
      }
      else
      {
        v12 = v19;
        v72 = v19;
      }
      if( v12 > 1 )
      {
        v20 = v12 * v13;
        if( v13 >= v12 * v13 )
        {
          v18 = -1073741584;
          goto LABEL_101;
        }
        v13 *= v12;
        v70 = v20;
        v73 = v20;
      }
      if( !Section )
      {
        LOCK_ADDRESS_SPACE_SHARED(CurrentThread, v64);
        if( (*((_DWORD *)v64 + 281) & 0x20) != 0 )
        {
          UNLOCK_ADDRESS_SPACE_SHARED((__int64)CurrentThread, (__int64)v64);
          v18 = -1073741558;
          goto LABEL_101;
        }
        if( !(unsigned int)MiChargeProcessPhysicalPages((__int64)v64, v13) )
        {
          v22 = (__int64)v64;
          v23 = (__int64)CurrentThread;
LABEL_41:
          UNLOCK_ADDRESS_SPACE_SHARED(v23, v22);
          v18 = -1073741523;
          goto LABEL_101;
        }
        v7 |= 4u;
        v24 = MiChargeProcessCommitment(v21, v13);
        v22 = (__int64)v64;
        v23 = (__int64)CurrentThread;
        if( !v24 )
          goto LABEL_41;
        UNLOCK_ADDRESS_SPACE_SHARED((__int64)CurrentThread, (__int64)v64);
        v7 |= 2u;
      }
      AweInfoPartition = MiGetAweInfoPartition((INT64)v15);
      v77 = AweInfoPartition;
      v26 = *(_QWORD *)(AweInfoPartition + 6920) + 1i64;
      v65 = 0i64;
      Handle = 0i64;
      v27 = *(_QWORD *)(v16 + 1408);
      if( v27 )
      {
        v28 = *(_WORD *)(v27 + 8);
        if( (v28 == 332 || v28 == 452) && v26 > 0x100000000i64 )
          v26 = 0x100000000i64;
      }
      v29 = v26 << 12;
      v30 = 0x80000000;
      if( v86 )
      {
        IdealNode = v86 - 1;
        if( v87 == 1 )
          v30 = -2147483646;
      }
      else
      {
        IdealNode = *(_WORD *)(*((_QWORD *)*(&KiProcessorBlock + *((unsigned int *)CurrentThread + 147)) + 24) + 146i64);
      }
      v32 = v30 | 1;
      if( (*v15 & 4) == 0 )
        v32 = v30;
      v33.QuadPart = v12 << 12;
      v34.QuadPart = 0i64;
      if( v72 != 1 )
        v34 = v33;
      v78 = v34;
      if( v72 != 1 )
        v32 |= 0x30u;
      v67 = v32;
      v35 = v70;
      while( 2 )
      {
        PagesForMdl = 0i64;
        P = 0i64;
        v37 = v35 - v63;
        if( (unsigned __int64)(v35 - v63) > 0xC0000 )
          v37 = 786432i64;
        v66 = v37;
        if( v37 >= 0x10 && (v7 & 0x10) == 0 )
        {
          LODWORD(Flags) = v32 | 0x42;
          PagesForMdl = MiAllocatePagesForMdl(
                          (_MI_PARTITION *)AweInfoPartition,
                          0i64,
                          (_LARGE_INTEGER)(v29 - 4096),
                          v33,
                          v37 << 12,
                          (_MI_PFN_CACHE_ATTRIBUTE)a2[18],
                          IdealNode,
                          Flags);
          P = PagesForMdl;
          v37 = v66;
          AweInfoPartition = v77;
          v32 = v67;
          v34 = v78;
          if( !PagesForMdl )
            v7 |= 0x10u;
        }
        if( PagesForMdl
          || (LODWORD(Flags) = v32,
              PagesForMdl = MiAllocatePagesForMdl(
                              (_MI_PARTITION *)AweInfoPartition,
                              0i64,
                              (_LARGE_INTEGER)(v29 - 4096),
                              v34,
                              v37 << 12,
                              (_MI_PFN_CACHE_ATTRIBUTE)a2[18],
                              IdealNode,
                              Flags),
              (P = PagesForMdl) != 0i64) )
        {
          MiSortMdlFrames((INT64)PagesForMdl);
          v74 = PagesForMdl + 1;
          v79 = (unsigned __int64)PagesForMdl->ByteCount >> 12;
          v82 = (__int64)&PagesForMdl[1] + 8 * v79;
          v81 = *(_QWORD *)(v82 - 8) / v76;
          while( 1 )
          {
            v38 = v71;
            if( !Section )
            {
              LOCK_ADDRESS_SPACE_SHARED((_ETHREAD *)v71, (_EPROCESS *)v16);
              if( (*(_DWORD *)(v16 + 1124) & 0x20) != 0 )
              {
                UNLOCK_ADDRESS_SPACE_SHARED(v38, v16);
                MiFreePagesFromMdl(P, 0i64);
                ExFreePoolWithTag(P, 0);
                v18 = -1073741558;
                v43 = v63;
                goto LABEL_86;
              }
            }
            v39 = v38;
            v40 = (INT64)a2;
            v41 = MiLockAwePagesShared((INT64)a2, v39);
            v42 = v41;
            if( v81 < *(_QWORD *)(v40 + 16) )
              break;
            MiUnlockAweVadsShared(v71, v41);
            if( !Section )
              UNLOCK_ADDRESS_SPACE_SHARED(v71, v16);
            v18 = MiResizeAweBitMap(v40);
            if( v18 < 0 && v81 >= *((_QWORD *)a2 + 2) )
            {
              MiFreePagesFromMdl(P, 0i64);
              ExFreePoolWithTag(P, 0);
              v43 = v63;
              goto LABEL_86;
            }
          }
          v44 = *(_QWORD *)(v40 + 24);
          v45 = v76;
          v46 = 8 * v76;
          v47 = v74;
          v48 = v82;
          do
          {
            _InterlockedOr(
              (volatile signed __int32 *)(v44 + 4 * (((unsigned __int64)v47->Next / v45) >> 5)),
              1 << (((unsigned __int64)v47->Next / v45) & 0x1F));
            v47 = (_MDL *)((char *)v74 + v46);
            v74 = v47;
            v45 = v76;
          }
          while( v47 != (_MDL *)v48 );
          v49 = v71;
          MiUnlockAweVadsShared(v71, v42);
          if( !Section )
            UNLOCK_ADDRESS_SPACE_SHARED(v49, (__int64)PROCESS);
          P->Next = v65;
          v65 = P;
          Handle = P;
          AweInfoPartition = v77;
          _InterlockedExchangeAdd64((volatile signed __int64 *)(v77 + 7608), v79);
          v50 = v79 + v63;
          v63 = v50;
          v18 = 0;
          v35 = v73;
          v70 = v73;
          v16 = (__int64)PROCESS;
          if( v50 != v73 )
          {
            v32 = v67;
            v34 = v78;
            continue;
          }
          v43 = v50;
        }
        else
        {
          v43 = v63;
          v18 = v63 == 0 ? 0xC000009A : 0;
        }
        break;
      }
LABEL_86:
      if( (v7 & 1) != 0 )
      {
        KeUnstackDetachProcess(&ApcState);
        v7 &= ~1u;
      }
      v51 = v72;
      if( v18 >= 0 )
        *v83 = v43 / v72;
      v52 = v65;
      v53 = Address;
      while( v52 )
      {
        v74 = v52 + 1;
        v54 = (unsigned __int64)v52->ByteCount >> 12;
        v79 = v54;
        for( i = 0i64; ; i += v51 )
        {
          v84 = i;
          if( i >= v54 )
            break;
          *v53++ = *((_QWORD *)&v52[1].Next + i);
          Address = v53;
        }
        v52 = v52->Next;
      }
      for( j = v65; j; j = Next )
      {
        Next = j->Next;
        ExFreePoolWithTag(j, 0);
      }
      v13 = v70 - v63;
      v73 = v70 - v63;
      CurrentThread = (_ETHREAD *)v71;
      goto LABEL_101;
    }
  }
  return result;
}

Referenced by:

NtAllocateUserPhysicalPages
NtAllocateUserPhysicalPagesEx