RTR3DECL(int)   RTProcQueryUsernameA(RTPROCESS hProcess, char **ppszUser)
{
    /*
     * Validation.
     */
    AssertPtrReturn(ppszUser, VERR_INVALID_POINTER);

    int rc = VINF_SUCCESS;
    size_t cbUser = 0;

    rc = RTProcQueryUsername(hProcess, NULL, cbUser, &cbUser);
    if (rc == VERR_BUFFER_OVERFLOW)
    {
        char *pszUser = (char *)RTStrAlloc(cbUser);
        if (pszUser)
        {
            rc = RTProcQueryUsername(hProcess, pszUser, cbUser, NULL);
            Assert(rc != VERR_BUFFER_OVERFLOW);
            if (RT_SUCCESS(rc))
                *ppszUser = pszUser;
            else
                RTStrFree(pszUser);
        }
        else
            rc = VERR_NO_STR_MEMORY;
    }

    return rc;
}
/**
 * Connects to VBoxTray IPC under the behalf of the user running
 * in the current thread context.
 *
 * @return  IPRT status code.
 * @param   phSession               Where to store the IPC session.
 */
static int vboxConnectToVBoxTray(RTLOCALIPCSESSION *phSession)
{
    char szPipeName[512 + sizeof(VBOXTRAY_IPC_PIPE_PREFIX)];
    memcpy(szPipeName, VBOXTRAY_IPC_PIPE_PREFIX, sizeof(VBOXTRAY_IPC_PIPE_PREFIX));
    int rc = RTProcQueryUsername(NIL_RTPROCESS,
                                 &szPipeName[sizeof(VBOXTRAY_IPC_PIPE_PREFIX) - 1],
                                 sizeof(szPipeName) - sizeof(VBOXTRAY_IPC_PIPE_PREFIX) + 1,
                                 NULL /*pcbUser*/);
    if (RT_SUCCESS(rc))
        rc = RTLocalIpcSessionConnect(phSession, szPipeName, RTLOCALIPC_FLAGS_NATIVE_NAME);
    return rc;
}
static void tstRTProcQueryUsername(void)
{
    RTTestISub("Basics");

    size_t  cbUser;
    char    szUser[1024];
    memset(szUser, '-', sizeof(szUser));

    /* negative stuff that may assert: */
    bool fMayPanic = RTAssertSetMayPanic(false);
    bool fQuiet    = RTAssertSetQuiet(true);

    RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), NULL, 8, &cbUser), VERR_INVALID_PARAMETER);
    RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), szUser, 0, &cbUser), VERR_INVALID_PARAMETER);
    RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), NULL, 0, NULL), VERR_INVALID_PARAMETER);
    RTTESTI_CHECK_RC(RTProcQueryUsernameA(RTProcSelf(), NULL), VERR_INVALID_POINTER);

    RTAssertSetMayPanic(fMayPanic);
    RTAssertSetQuiet(fQuiet);

    RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), NULL, 0, &cbUser), VERR_BUFFER_OVERFLOW);
    memset(szUser, '-', sizeof(szUser));
    RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), szUser, cbUser - 1, &cbUser), VERR_BUFFER_OVERFLOW);
    memset(szUser, '-', sizeof(szUser));
    RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), szUser, sizeof(szUser), &cbUser), VINF_SUCCESS);
    RTTestPrintf(NULL, RTTESTLVL_ALWAYS, "Username: %s\n", szUser); /* */

    char *pszUser = NULL;
    RTTESTI_CHECK_RC(RTProcQueryUsernameA(RTProcSelf(), &pszUser), VINF_SUCCESS);
    RTTestPrintf(NULL, RTTESTLVL_ALWAYS, "Username: %s\n", pszUser);
    RTTESTI_CHECK(strcmp(pszUser, szUser) == 0);
    RTStrFree(pszUser);
}