you can use CreateProcessAsUserW for start process with not elevated user token. but here exisr several problems - you need SE_INCREASE_QUOTA_NAME and SE_ASSIGNPRIMARYTOKEN_NAME privilege for call this api, if hToken is a restricted version of the caller's primary token.
second how get user token ? you can use WTSQueryUserToken for this, but for call this api you need have SE_TCB_NAME privilege
so you need have/get 3 privilege SE_ASSIGNPRIMARYTOKEN_NAME , SE_TCB_NAME, and  SE_INCREASE_QUOTA_NAME. in general LocalSystem processes have it. we can open some of this process, if we have SE_DEBUG_PRIVILEGE.
so in general we need do next:
- get self 
SessionId (need for call WTSQueryUserToken) 
- enable 
SE_DEBUG_PRIVILEGE in process or thread token (elevated
token usually have this privilege) 
- search processes with token, which have required for as privilege
 
- impersonate with this token
 
- call 
WTSQueryUserToken 
- call 
CreateProcessAsUserW 
----- code: ---------------
inline ULONG BOOL_TO_ERROR(BOOL f)
{
    return f ? NOERROR : GetLastError();
}
// use in _alloca(guz) because _alloca(0) work incorrect
// return 0 pointer instead allocates a zero-length item
volatile UCHAR guz;
ULONG takePrivileges(HANDLE hToken, ::PTOKEN_PRIVILEGES ptp, ULONG cb, BOOL& bContinue)
{
    if (ULONG PrivilegeCount = ptp->PrivilegeCount)
    {
        int n = 3;
        BOOL fAdjust = FALSE;
        ::PLUID_AND_ATTRIBUTES Privileges = ptp->Privileges;
        do 
        {
            switch (Privileges->Luid.LowPart)
            {
            case SE_ASSIGNPRIMARYTOKEN_PRIVILEGE:
            case SE_INCREASE_QUOTA_PRIVILEGE:
            case SE_TCB_PRIVILEGE:
                if (!(Privileges->Attributes & SE_PRIVILEGE_ENABLED))
                {
                    Privileges->Attributes |= SE_PRIVILEGE_ENABLED;
                    fAdjust = TRUE;
                }
                if (!--n)
                {
                    bContinue = FALSE;
                    ULONG dwError = BOOL_TO_ERROR(DuplicateTokenEx(hToken, 
                        TOKEN_ADJUST_PRIVILEGES|TOKEN_IMPERSONATE, 
                        0, ::SecurityImpersonation, ::TokenImpersonation, 
                        &hToken));
                    if (dwError == NOERROR)
                    {
                        if (fAdjust)
                        {
                            AdjustTokenPrivileges(hToken, FALSE, ptp, cb, NULL, NULL);
                            dwError = GetLastError();
                        }
                        if (dwError == NOERROR)
                        {
                            dwError = BOOL_TO_ERROR(SetThreadToken(0, hToken));
                        }
                        CloseHandle(hToken);
                    }
                    return dwError;
                }
            }
        } while (Privileges++, --PrivilegeCount);
    }
    return ERROR_NOT_FOUND;
}
ULONG GetPrivileges()
{
    ULONG dwError;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot != INVALID_HANDLE_VALUE)
    {
        dwError = ERROR_NOT_FOUND;
        PROCESSENTRY32W pe = { sizeof(pe) };
        if (Process32FirstW(hSnapshot, &pe))
        {
            ULONG cb = 0, rcb = 0x100;
            PVOID stack = alloca(guz);
            union {
                PVOID buf;
                ::PTOKEN_PRIVILEGES ptp;
            };
            BOOL bContinue = TRUE;
            do 
            {
                if (HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pe.th32ProcessID))
                {
                    HANDLE hToken;
                    if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE, &hToken))
                    {
                        do 
                        {
                            if (cb < rcb)
                            {
                                cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
                            }
                            if (GetTokenInformation(hToken, ::TokenPrivileges, buf, cb, &rcb))
                            {
                                dwError = takePrivileges(hToken, ptp, rcb, bContinue);
                                break;
                            }
                        } while (GetLastError() == ERROR_INSUFFICIENT_BUFFER);
                        CloseHandle(hToken);
                    }
                    CloseHandle(hProcess);
                }
            } while (bContinue && Process32NextW(hSnapshot, &pe));
        }
        CloseHandle(hSnapshot);
    }
    else
    {
        dwError = GetLastError();
    }
    return dwError;
}
ULONG RunNotElevated(PCWSTR lpApplicationName, PWSTR lpCommandLine, PCWSTR lpCurrentDirectory)
{
    HANDLE hToken, hDupToken = 0;
    ULONG SessionId;
    ULONG dwError = BOOL_TO_ERROR(ProcessIdToSessionId(GetCurrentProcessId(), &SessionId));
    if (NOERROR == dwError && 
        (NOERROR == (dwError = BOOL_TO_ERROR(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &hToken)))))
    {
        dwError = BOOL_TO_ERROR(DuplicateTokenEx(hToken, 
            TOKEN_IMPERSONATE|TOKEN_ADJUST_PRIVILEGES, 0,
            ::SecurityImpersonation, ::TokenImpersonation, &hDupToken));
        CloseHandle(hToken);
        if (dwError == NOERROR)
        {
            // get SE_DEBUG_PRIVILEGE
            static ::TOKEN_PRIVILEGES tp = { 1, { { {SE_DEBUG_PRIVILEGE }, SE_PRIVILEGE_ENABLED } } };
            AdjustTokenPrivileges(hDupToken, FALSE, &tp, 0, 0, 0);
            if ((dwError = GetLastError()) == NOERROR)
            {
                dwError = BOOL_TO_ERROR(SetThreadToken(0, hDupToken));
            }
            CloseHandle(hDupToken);
            if (dwError == NOERROR)
            {
                if (NOERROR == (dwError = GetPrivileges()))
                {
                    STARTUPINFOW si = { sizeof(si) };
                    PROCESS_INFORMATION pi;
                    PVOID lpEnvironment;
                    if (WTSQueryUserToken(SessionId, &hToken))
                    {
                        dwError = BOOL_TO_ERROR(CreateEnvironmentBlock(&lpEnvironment, hToken, FALSE));
                        if (dwError == NOERROR)
                        {
                            dwError = BOOL_TO_ERROR(CreateProcessAsUserW(
                                hToken, lpApplicationName, lpCommandLine, 
                                NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT,
                                lpEnvironment, lpCurrentDirectory, &si, &pi));
                            DestroyEnvironmentBlock(lpEnvironment);
                        }
                        CloseHandle(hToken);
                        if (dwError == NOERROR)
                        {
                            CloseHandle(pi.hThread);
                            CloseHandle(pi.hProcess);
                        }
                    }
                }
                SetThreadToken(0, 0);
            }
        }
    }
    return dwError;
}
void test_r()
{
    WCHAR cmd[MAX_PATH];
    if (GetEnvironmentVariable(L"comspec", cmd, RTL_NUMBER_OF(cmd)))
    {
        RunNotElevated1(cmd, L"cmd /k whoami /all",0);
    }
}