NtMapUserPhysicalPagesScatter

NTSTATUS __stdcall NtMapUserPhysicalPagesScatter(PVOID *VirtualAddresses, UINT64 NumberOfPages, UINT64 *UserPfnArray){
  _ETHREAD *CurrentThread; 
  UINT64 *v8; 
  INT64 v9; 
  char *p_Destination; 
  UINT64 *v11; 
  UINT64 *v12; 
  NTSTATUS v13; 
  UINT64 v14; 
  MMPTE *AweNode; 
  INT64 v16; 
  INT64 v17; 
  __int64 v18; 
  int v19; 
  unsigned __int64 v20; 
  unsigned __int64 v21; 
  __int64 v22; 
  MMPTE *v23; 
  int v24; 
  int v25; 
  ULONG_PTR v26; 
  INT64 *v27; 
  __int64 v28; 
  INT64 v29; 
  ULONG_PTR v30; 
  INT64 v31[2]; 
  char P[4096]; 
  char Destination; 
  memset((INT64)P, 0i64);
  *(_OWORD *)v31 = 0i64;
  if( NumberOfPages > 0xFFFFFFFFFFFFFi64 )
    return -1073741584;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v8 = (UINT64 *)P;
  v9 = 0i64;
  p_Destination = 0i64;
  if( NumberOfPages > 0x200 )
  {
    LODWORD(v11) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
    v8 = v11;
    if( !v11 )
      return -1073741670;
  }
  v12 = v8;
  v13 = MiCaptureUlongPtrArray(v8, VirtualAddresses, NumberOfPages);
  if( v13 >= 0 )
  {
    if( !NumberOfPages )
      return 0;
    if( !UserPfnArray )
      goto LABEL_13;
    p_Destination = &Destination;
    if( NumberOfPages > 0x200 )
      p_Destination = (char *)&v8[NumberOfPages];
    v13 = MiCaptureUlongPtrArray(p_Destination, UserPfnArray, NumberOfPages);
    if( v13 >= 0 )
    {
LABEL_13:
      v14 = *v8;
      v13 = 0;
      v30 = MiLockAweVadsShared((__int64)CurrentThread);
      AweNode = MiGetAweNode(v14);
      if( !AweNode || (*((_DWORD *)AweNode + 10) & 3) != 0 )
      {
        v13 = -1073741585;
      }
      else
      {
        v16 = *((_QWORD *)AweNode + 4);
        v29 = (INT64)AweNode;
        v17 = ExGetCallBackBlockRoutine(v16);
        v19 = -1073741585;
        do
        {
          v20 = *v12;
          if( v17 == 1 )
          {
            v21 = *v12;
          }
          else
          {
            v22 = (v17 << 12) - 1;
            if( (v22 & v20) != 0 )
              goto LABEL_38;
            v21 = v22 + v20;
          }
          if( v20 < (*(unsigned int *)(v18 + 24) | ((unsigned __int64)*(unsigned __int8 *)(v18 + 32) << 32)) << 12
            || v21 > (((*(unsigned int *)(v18 + 28) | ((unsigned __int64)*(unsigned __int8 *)(v18 + 33) << 32)) << 12) | 0xFFF) )
          {
            v23 = MiGetAweNode(*v12);
            if( !v23 || (*((_DWORD *)v23 + 10) & 3) != 0 || *((_QWORD *)v23 + 4) != v16 )
            {
LABEL_38:
              v9 = v29;
              v13 = v19;
              goto LABEL_39;
            }
            v18 = *((_QWORD *)v23 + 3);
            v25 = *(_DWORD *)(v18 + 48) & 0x1100000;
            if( v24 == 17825792 )
            {
              if( v25 != 17825792 )
                v13 = v19;
            }
            else if( v25 == 17825792 )
            {
              v13 = v19;
            }
          }
          ++v12;
        }
        while( v12 < &v8[NumberOfPages] );
        v26 = MiLockAwePagesShared(v16, (INT64)CurrentThread);
        if( p_Destination
          && (v13 = MiReferenceIncomingPhysicalPages(
                      v16,
                      (INT64)p_Destination,
                      NumberOfPages,
                      (INT64)v8,
                      v31,
                      v29,
                      0i64),
              v13 < 0) )
        {
          v9 = v29;
        }
        else
        {
          v9 = v29;
          v31[1] = MiWriteAwePtes(v29, (INT64)p_Destination, NumberOfPages, (INT64)v8, 0i64, 1);
        }
        if( v26 )
          MiUnlockAweVadsShared((__int64)CurrentThread, v26);
      }
LABEL_39:
      if( v30 )
        MiUnlockAweVadsShared((__int64)CurrentThread, v30);
    }
  }
  v27 = v31;
  v28 = 2i64;
  do
  {
    if( *v27 )
      MiFreePhysicalPageChain(v9, *v27, 0i64);
    ++v27;
    --v28;
  }
  while( v28 );
  if( v8 != (UINT64 *)P )
    ExFreePoolWithTag(v8, 0);
  return v13;
}

Referenced by:

No references.