MiAllocateUserPhysicalPages

NTSTATUS __stdcall MiAllocateUserPhysicalPages(_MDL *a1, UINT64 *a2, VOID *a3, INT64 *a4, UINT64 arg20){
  _ETHREAD *CurrentThread; 
  char v8; 
  VOID *v9; 
  NTSTATUS result; 
  unsigned __int64 v11; 
  UINT64 v12; 
  __int64 v13; 
  char v14; 
  _EPROCESS *v15; 
  signed int v16; 
  int v17; 
  unsigned __int64 v18; 
  UINT64 v19; 
  _EPROCESS *v20; 
  _EPROCESS *v21; 
  _ETHREAD *v22; 
  int v23; 
  _MI_PARTITION *v24; 
  _MI_PARTITION *v25; 
  unsigned __int64 v26; 
  _EWOW64PROCESS *WoW64Process; 
  unsigned __int16 Machine; 
  unsigned __int64 v29; 
  unsigned int v30; 
  UINT16 IdealNode; 
  int v32; 
  _LARGE_INTEGER v33; 
  _LARGE_INTEGER v34; 
  UINT64 v35; 
  _MDL *PagesForMdl; 
  unsigned __int64 v37; 
  VOID *v38; 
  VOID *v39; 
  UINT64 v40; 
  unsigned __int64 v41; 
  __int64 v42; 
  unsigned __int64 v43; 
  _MDL *v44; 
  __int64 v45; 
  UINT64 v46; 
  _MDL *v47; 
  _QWORD *v48; 
  unsigned __int64 v49; 
  unsigned __int64 i; 
  _MDL *j; 
  _MDL *Next; 
  UINT64 Flags; 
  CHAR PreviousMode; 
  _MDL *MemoryDescriptorList; 
  _EPROCESS *PROCESS; 
  __int64 v57; 
  _EPROCESS *P; 
  _MDL *Pa; 
  unsigned __int64 v60; 
  int v61; 
  UINT64 v62; 
  _ETHREAD *Thread; 
  unsigned __int64 v64; 
  UINT64 v65; 
  _MDL *v66; 
  _HANDLE Handle; 
  unsigned __int64 v68; 
  _MI_PARTITION *v69; 
  _LARGE_INTEGER v70; 
  unsigned __int64 v71; 
  unsigned __int64 v73; 
  _MDL *v74; 
  __int64 v76[9]; 
  _KAPC_STATE ApcState; 

  Handle = (int)a1;
  memset(&ApcState, 0, sizeof(ApcState));
  memset(v76, 0i64, sizeof(v76));
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  Thread = CurrentThread;
  P = CurrentThread->Tcb.ApcState.Process;
  v8 = CurrentThread->Tcb.PreviousMode;
  PreviousMode = v8;
  LOBYTE(v9) = v8;
  result = MiCaptureAllocateMapExtendedParameters(a4, (unsigned int)arg20, v9);
  if( result >= 0 )
  {
    if( (v76[7] & 0xFFFFFFFFFFFFFFF5ui64) != 0 || (v76[7] & 0xA) == 10 )
      return -1073741811;
    v11 = (v76[7] & 2) != 0 ? 16i64 : (unsigned __int64)(v76[7] & 8) << 6;
    v64 = v11;
    if( LODWORD(v76[4]) > (unsigned __int16)KeNumberNodes )
      return -1073741811;
    if( v8 )
    {
      v13 = (__int64)a2;
      if( (unsigned __int64)a2 >= 0x7FFFFFFF0000i64 )
        v13 = 0x7FFFFFFF0000i64;
      *(_QWORD *)v13 = *(_QWORD *)v13;
      v12 = *a2;
      v62 = *a2;
      v65 = *a2;
      if( !*a2 )
        return 0;
      if( v12 > 0x1FFFFFFFFFFFFFFFi64 )
        return -1073741584;
      ProbeForWrite((UINT64)a3, 8 * v12, 8i64);
    }
    else
    {
      v12 = *a2;
      v62 = *a2;
      v65 = *a2;
      if( !*a2 )
        return 0;
    }
    result = MiReferenceAweHandle(Handle, 2i64);
    if( result >= 0 )
    {
      v14 = 8;
      v15 = P;
      PROCESS = P;
      if( SeSinglePrivilegeCheck(*(_QWORD *)&SeLockMemoryPrivilege, PreviousMode) )
      {
        v57 = 0i64;
        MiCreateProcessDefaultAweInfo();
        v16 = v17;
        if( v17 >= 0 )
        {
          ExGetCallBackBlockRoutine(0i64);
          v68 = v18;
          if( v11 )
          {
            if( v11 <= v18 || v11 % v18 || ((v11 - 1) & v11) != 0 )
            {
              v16 = -1073741811;
              goto LABEL_89;
            }
          }
          else
          {
            v11 = v18;
            v64 = v18;
          }
          if( v11 > 1 )
          {
            v19 = v11 * v12;
            if( v12 >= v11 * v12 )
            {
              v16 = -1073741584;
              goto LABEL_89;
            }
            v12 *= v11;
            v62 = v19;
            v65 = v19;
          }
          LOCK_ADDRESS_SPACE_SHARED(CurrentThread, P);
          if( (P->Flags & 0x20) != 0 )
          {
            UNLOCK_ADDRESS_SPACE_SHARED(CurrentThread, P);
            v16 = -1073741558;
          }
          else
          {
            if( MiChargeProcessPhysicalPages(P, v12) )
            {
              v14 = 12;
              MiChargeProcessCommitment(v20, v12);
              v21 = P;
              v22 = CurrentThread;
              if( v23 )
              {
                UNLOCK_ADDRESS_SPACE_SHARED(CurrentThread, P);
                v14 = 14;
                LODWORD(v24) = MiGetAweInfoPartition(0i64);
                v25 = v24;
                v69 = v24;
                v26 = v24->Vp.HighestPhysicalPage + 1;
                Pa = 0i64;
                WoW64Process = v15->WoW64Process;
                if( WoW64Process )
                {
                  Machine = WoW64Process->Machine;
                  if( (Machine == 332 || Machine == 452) && v26 > 0x100000000i64 )
                    v26 = 0x100000000i64;
                }
                v29 = v26 << 12;
                v30 = 0x80000000;
                if( LODWORD(v76[4]) )
                {
                  IdealNode = LOWORD(v76[4]) - 1;
                  if( BYTE1(v76[6]) == 1 )
                    v30 = -2147483646;
                }
                else
                {
                  IdealNode = (*(&KiProcessorBlock + CurrentThread->Tcb.IdealProcessor))->ParentNode->Affinity.Reserved[0];
                }
                v32 = v30 | 1;
                if( (MEMORY[0] & 4) == 0 )
                  v32 = v30;
                v33.QuadPart = v11 << 12;
                v34.QuadPart = 0i64;
                if( v64 != 1 )
                  v34 = v33;
                v70 = v34;
                if( v64 != 1 )
                  v32 |= 0x30u;
                v61 = v32;
                v35 = v62;
                while( 2 )
                {
                  PagesForMdl = 0i64;
                  MemoryDescriptorList = 0i64;
                  v37 = v35 - v57;
                  if( v35 - v57 > 0xC0000 )
                    v37 = 786432i64;
                  v60 = v37;
                  if( v37 >= 0x10 && (v14 & 0x10) == 0 )
                  {
                    LODWORD(Flags) = v32 | 0x42;
                    PagesForMdl = MiAllocatePagesForMdl(
                                    v25,
                                    0i64,
                                    (_LARGE_INTEGER)(v29 - 4096),
                                    v33,
                                    v37 << 12,
                                    MEMORY[0x48],
                                    IdealNode,
                                    Flags);
                    MemoryDescriptorList = PagesForMdl;
                    v37 = v60;
                    v25 = v69;
                    v32 = v61;
                    v34 = v70;
                    if( !PagesForMdl )
                      v14 |= 0x10u;
                  }
                  if( PagesForMdl
                    || (LODWORD(Flags) = v32,
                        PagesForMdl = MiAllocatePagesForMdl(
                                        v25,
                                        0i64,
                                        (_LARGE_INTEGER)(v29 - 4096),
                                        v34,
                                        v37 << 12,
                                        MEMORY[0x48],
                                        IdealNode,
                                        Flags),
                        (MemoryDescriptorList = PagesForMdl) != 0i64) )
                  {
                    MiSortMdlFrames((INT64)PagesForMdl);
                    v66 = PagesForMdl + 1;
                    v71 = (unsigned __int64)PagesForMdl->ByteCount >> 12;
                    v74 = (_MDL *)((char *)PagesForMdl + 8 * v71 + 48);
                    v73 = *(_QWORD *)&v74[-1].ByteCount / v68;
                    while( 1 )
                    {
                      LOCK_ADDRESS_SPACE_SHARED(Thread, v15);
                      if( (v15->Flags & 0x20) != 0 )
                      {
                        UNLOCK_ADDRESS_SPACE_SHARED(Thread, v15);
                        MiFreePagesFromMdl(MemoryDescriptorList, 0i64, v46);
                        ExFreePoolWithTag(MemoryDescriptorList, 0);
                        v16 = -1073741558;
                        v41 = v57;
                        goto LABEL_74;
                      }
                      LODWORD(v38) = MiLockAwePagesShared(0i64, (INT64)Thread);
                      v39 = v38;
                      if( v73 < MEMORY[0x10] )
                        break;
                      MiUnlockAweVadsShared(&Thread->Tcb, v38);
                      UNLOCK_ADDRESS_SPACE_SHARED(Thread, v15);
                      v16 = MiResizeAweBitMap(0i64);
                      if( v16 < 0 && v73 >= MEMORY[0x10] )
                      {
                        MiFreePagesFromMdl(MemoryDescriptorList, 0i64, v40);
                        ExFreePoolWithTag(MemoryDescriptorList, 0);
                        v41 = v57;
                        goto LABEL_74;
                      }
                    }
                    v42 = MEMORY[0x18];
                    v43 = v68;
                    v44 = v66;
                    do
                    {
                      _InterlockedOr(
                        (volatile signed __int32 *)(v42 + 4 * (((unsigned __int64)v44->Next / v43) >> 5)),
                        1 << (((unsigned __int64)v44->Next / v43) & 0x1F));
                      v44 = (_MDL *)((char *)v66 + 8 * v68);
                      v66 = v44;
                      v43 = v68;
                    }
                    while( v44 != v74 );
                    MiUnlockAweVadsShared(&Thread->Tcb, v39);
                    UNLOCK_ADDRESS_SPACE_SHARED(Thread, PROCESS);
                    MemoryDescriptorList->Next = Pa;
                    Pa = MemoryDescriptorList;
                    v25 = v69;
                    _InterlockedExchangeAdd64((volatile signed __int64 *)&v69->Vp.VadPhysicalPages, v71);
                    v45 = v71 + v57;
                    v57 = v45;
                    v16 = 0;
                    v35 = v65;
                    v62 = v65;
                    v15 = PROCESS;
                    if( v45 != v65 )
                    {
                      v32 = v61;
                      v34 = v70;
                      continue;
                    }
                    v41 = v45;
                  }
                  else
                  {
                    v41 = v57;
                    v16 = v57 == 0 ? 0xC000009A : 0;
                  }
                  break;
                }
LABEL_74:
                if( (v14 & 1) != 0 )
                {
                  KeUnstackDetachProcess(&ApcState);
                  v14 &= ~1u;
                }
                if( v16 >= 0 )
                  *a2 = v41 / v64;
                v47 = Pa;
                v48 = a3;
                while( v47 )
                {
                  v49 = (unsigned __int64)v47->ByteCount >> 12;
                  for( i = 0i64; i < v49; i += v64 )
                    *v48++ = *((_QWORD *)&v47[1].Next + i);
                  v47 = v47->Next;
                }
                for( j = Pa; j; j = Next )
                {
                  Next = j->Next;
                  ExFreePoolWithTag(j, 0);
                }
                v12 = v62 - v57;
                CurrentThread = Thread;
                goto LABEL_89;
              }
            }
            else
            {
              v21 = P;
              v22 = CurrentThread;
            }
            UNLOCK_ADDRESS_SPACE_SHARED(v22, v21);
            v16 = -1073741523;
          }
        }
      }
      else
      {
        v16 = -1073741727;
      }
LABEL_89:
      if( v12 )
      {
        if( (v14 & 2) != 0 )
        {
          LOCK_ADDRESS_SPACE_SHARED(CurrentThread, v15);
          MiReturnProcessCommitment(v15, v12);
          UNLOCK_ADDRESS_SPACE_SHARED(CurrentThread, v15);
        }
        if( (v14 & 4) != 0 )
        {
          _InterlockedExchangeAdd64((volatile signed __int64 *)&v15->VadPhysicalPages, -(__int64)v12);
          v15 = PROCESS;
        }
      }
      if( (v14 & 1) != 0 )
        KeUnstackDetachProcess(&ApcState);
      if( (v14 & 8) == 0 )
        ObfDereferenceObjectWithTag(v15, 0x68506D4Dui64);
      return v16;
    }
  }
  return result;
}

Referenced by:

NtAllocateUserPhysicalPages
NtAllocateUserPhysicalPagesEx