PspSetupUserStack

NTSTATUS __stdcall PspSetupUserStack(
        ULONG_PTR Process,
        _CONTEXT *UserContext,
        PS_INITIAL_TEB *InitialTeb,
        PSP_STACK_ALLOCATION_STATE *StackAllocationState,
        UINT64 PreferredNode){
  char v5; 
  char v6; 
  INT64 v10; 
  unsigned __int64 v11; 
  int UserStack; 
  __int64 v13; 
  _INITIAL_TEB *v15; 
  UINT64 RegionSize; 
  VOID *BaseAddress; 
  _KAPC_STATE ApcState; 

  v5 = *(_BYTE *)StackAllocationState;
  v6 = 0;
  v10 = *(_QWORD *)&Process;
  memset(&ApcState, 0, sizeof(ApcState));
  if( (v5 & 1) != 0 )
    goto LABEL_9;
  v11 = 4096i64;
  if( (_DWORD)PreferredNode )
    v11 = ((unsigned __int64)(unsigned int)PreferredNode << 56) | 0x1000;
  KiStackAttachProcess(*(PVOID *)&Process, 0i64, &ApcState);
  UserStack = RtlCreateUserStack(
                *((_QWORD *)StackAllocationState + 2),
                *((_QWORD *)StackAllocationState + 3),
                *((_QWORD *)StackAllocationState + 1),
                v11,
                v15);
  if( UserStack < 0 )
    goto LABEL_13;
  if( (*(_DWORD *)(v10 + 2512) & 0x40) != 0 )
    v13 = 0i64;
  else
    v13 = 16 * (unsigned int)(ExGenRandom(ExGenRandomDomainUserVisible) & 0x7F);
  if( !*(_QWORD *)(v10 + 1408) || (UserStack = PspWow64SetupCpuArea((UINT64 *)InitialTeb + 2, v10), UserStack >= 0) )
  {
    UserContext->_Rsp = *((_QWORD *)InitialTeb + 2) - v13 - 40;
    KiUnstackDetachProcess(&ApcState, 0i64);
    v5 = *(_BYTE *)StackAllocationState;
    v6 = 2;
LABEL_9:
    *(_BYTE *)StackAllocationState = v6 | v5 & 0xFD;
    return 0;
  }
  BaseAddress = (VOID *)*((_QWORD *)InitialTeb + 4);
  RegionSize = 0i64;
  ZwFreeVirtualMemory((VOID *)0xFFFFFFFFFFFFFFFFi64, &BaseAddress, &RegionSize, 0x8000ui64);
LABEL_13:
  KiUnstackDetachProcess(&ApcState, 0i64);
  return UserStack;
}

Referenced by:

PspAllocateThread