예제 #1
0
/**
 * Adjust the profile environment after forking the child process and changing
 * the UID.
 *
 * @returns IRPT status code.
 * @param   hEnvToUse       The environment we're going to use with execve.
 * @param   fFlags          The process creation flags.
 * @param   hEnv            The environment passed in by the user.
 */
static int rtProcPosixAdjustProfileEnvFromChild(RTENV hEnvToUse, uint32_t fFlags, RTENV hEnv)
{
    int rc = VINF_SUCCESS;
#ifdef RT_OS_DARWIN
    if (   RT_SUCCESS(rc)
        && (!(fFlags & RTPROC_FLAGS_ENV_CHANGE_RECORD) || RTEnvExistEx(hEnv, "TMPDIR")) )
    {
        char szValue[_4K];
        size_t cbNeeded = confstr(_CS_DARWIN_USER_TEMP_DIR, szValue, sizeof(szValue));
        if (cbNeeded > 0 && cbNeeded < sizeof(szValue))
        {
            char *pszTmp;
            rc = RTStrCurrentCPToUtf8(&pszTmp, szValue);
            if (RT_SUCCESS(rc))
            {
                rc = RTEnvSetEx(hEnvToUse, "TMPDIR", pszTmp);
                RTStrFree(pszTmp);
            }
        }
        else
            rc = VERR_BUFFER_OVERFLOW;
    }
#endif
    return rc;
}
예제 #2
0
/**
 * Internal worker which initializes or re-initializes the
 * program path, name and directory globals.
 *
 * @returns IPRT status code.
 * @param   fFlags          Flags, see RTR3INIT_XXX.
 * @param   cArgs           Pointer to the argument count.
 * @param   ppapszArgs      Pointer to the argument vector pointer. NULL
 *                          allowed if @a cArgs is 0.
 */
static int rtR3InitArgv(uint32_t fFlags, int cArgs, char ***ppapszArgs)
{
    NOREF(fFlags);
    if (cArgs)
    {
        AssertPtr(ppapszArgs);
        AssertPtr(*ppapszArgs);
        char **papszOrgArgs = *ppapszArgs;

        /*
         * Normally we should only be asked to convert arguments once.  If we
         * are though, it should be the already convered arguments.
         */
        if (g_crtArgs != -1)
        {
            AssertReturn(   g_crtArgs == cArgs
                         && g_papszrtArgs == papszOrgArgs,
                         VERR_WRONG_ORDER); /* only init once! */
            return VINF_SUCCESS;
        }

        /*
         * Convert the arguments.
         */
        char **papszArgs = (char **)RTMemAllocZ((cArgs + 1) * sizeof(char *));
        if (!papszArgs)
            return VERR_NO_MEMORY;

        for (int i = 0; i < cArgs; i++)
        {
            int rc = RTStrCurrentCPToUtf8(&papszArgs[i], papszOrgArgs[i]);
            if (RT_FAILURE(rc))
            {
                while (i--)
                    RTStrFree(papszArgs[i]);
                RTMemFree(papszArgs);
                return rc;
            }
        }
        papszArgs[cArgs] = NULL;

        g_papszrtOrgArgs = papszOrgArgs;
        g_papszrtArgs    = papszArgs;
        g_crtArgs        = cArgs;

        *ppapszArgs = papszArgs;
    }

    return VINF_SUCCESS;
}
예제 #3
0
RTR3DECL(int) RTProcQueryUsernameA(RTPROCESS hProcess, char **ppszUser)
{
    AssertPtrReturn(ppszUser, VERR_INVALID_POINTER);

    int rc;
    if (   hProcess == NIL_RTPROCESS
            || hProcess == RTProcSelf())
    {
        /*
         * Figure a good buffer estimate.
         */
        int32_t cbPwdMax = sysconf(_SC_GETPW_R_SIZE_MAX);
        if (cbPwdMax <= _1K)
            cbPwdMax = _1K;
        else
            AssertStmt(cbPwdMax <= 32*_1M, cbPwdMax = 32*_1M);
        char *pchBuf = (char *)RTMemTmpAllocZ(cbPwdMax);
        if (pchBuf)
        {
            /*
             * Get the password file entry.
             */
            struct passwd  Pwd;
            struct passwd *pPwd = NULL;
            rc = getpwuid_r(geteuid(), &Pwd, pchBuf, cbPwdMax, &pPwd);
            if (!rc)
            {
                /*
                 * Convert the name to UTF-8, assuming that we're getting it in the local codeset.
                 */
                rc = RTStrCurrentCPToUtf8(ppszUser, pPwd->pw_name);
            }
            else
                rc = RTErrConvertFromErrno(rc);
            RTMemFree(pchBuf);
        }
        else
            rc = VERR_NO_TMP_MEMORY;
    }
    else
        rc = VERR_NOT_SUPPORTED;
    return rc;
}
예제 #4
0
/**
 * Create a very very basic environment for a user.
 *
 * @returns IPRT status code.
 * @param   phEnvToUse  Where to return the created environment.
 * @param   pszUser     The user name for the profile.
 */
static int rtProcPosixCreateProfileEnv(PRTENV phEnvToUse, const char *pszUser)
{
    struct passwd   Pwd;
    struct passwd  *pPwd = NULL;
    char            achBuf[_4K];
    int             rc;
    errno = 0;
    if (pszUser)
        rc = getpwnam_r(pszUser, &Pwd, achBuf, sizeof(achBuf), &pPwd);
    else
        rc = getpwuid_r(getuid(), &Pwd, achBuf, sizeof(achBuf), &pPwd);
    if (rc == 0 && pPwd)
    {
        char *pszDir;
        rc = RTStrCurrentCPToUtf8(&pszDir, pPwd->pw_dir);
        if (RT_SUCCESS(rc))
        {
            char *pszShell;
            rc = RTStrCurrentCPToUtf8(&pszShell, pPwd->pw_shell);
            if (RT_SUCCESS(rc))
            {
                char *pszUserFree = NULL;
                if (!pszUser)
                {
                    rc = RTStrCurrentCPToUtf8(&pszUserFree, pPwd->pw_name);
                    if (RT_SUCCESS(rc))
                        pszUser = pszUserFree;
                }
                if (RT_SUCCESS(rc))
                {
                    rc = RTEnvCreate(phEnvToUse);
                    if (RT_SUCCESS(rc))
                    {
                        RTENV hEnvToUse = *phEnvToUse;

                        rc = RTEnvSetEx(hEnvToUse, "HOME", pszDir);
                        if (RT_SUCCESS(rc))
                            rc = RTEnvSetEx(hEnvToUse, "SHELL", pszShell);
                        if (RT_SUCCESS(rc))
                            rc = RTEnvSetEx(hEnvToUse, "USER", pszUser);
                        if (RT_SUCCESS(rc))
                            rc = RTEnvSetEx(hEnvToUse, "LOGNAME", pszUser);

                        if (RT_SUCCESS(rc))
                            rc = RTEnvSetEx(hEnvToUse, "PATH", pPwd->pw_uid == 0 ? _PATH_STDPATH : _PATH_DEFPATH);

                        if (RT_SUCCESS(rc))
                        {
                            RTStrPrintf(achBuf, sizeof(achBuf), "%s/%s", _PATH_MAILDIR, pszUser);
                            rc = RTEnvSetEx(hEnvToUse, "MAIL", achBuf);
                        }

#ifdef RT_OS_DARWIN
                        if (RT_SUCCESS(rc) && !pszUserFree)
                        {
                            size_t cbNeeded = confstr(_CS_DARWIN_USER_TEMP_DIR, achBuf, sizeof(achBuf));
                            if (cbNeeded > 0 && cbNeeded < sizeof(achBuf))
                            {
                                char *pszTmp;
                                rc = RTStrCurrentCPToUtf8(&pszTmp, achBuf);
                                if (RT_SUCCESS(rc))
                                {
                                    rc = RTEnvSetEx(hEnvToUse, "TMPDIR", pszTmp);
                                    RTStrFree(pszTmp);
                                }
                            }
                            else
                                rc = VERR_BUFFER_OVERFLOW;
                        }
#endif

                        /** @todo load /etc/environment, /etc/profile.env and ~/.pam_environment? */

                        if (RT_FAILURE(rc))
                            RTEnvDestroy(hEnvToUse);
                    }
                    RTStrFree(pszUserFree);
                }
                RTStrFree(pszShell);
            }
            RTStrFree(pszDir);
        }
    }
    else
        rc = errno ? RTErrConvertFromErrno(errno) : VERR_ACCESS_DENIED;
    return rc;
}
예제 #5
0
STDMETHODIMP VBoxDnDDropTarget::Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
    RT_NOREF(pt);
    AssertPtrReturn(pDataObject, E_INVALIDARG);
    AssertPtrReturn(pdwEffect,   E_INVALIDARG);

    LogFlowFunc(("mFormatEtc.cfFormat=%RI16 (%s), pDataObject=0x%p, grfKeyState=0x%x, x=%ld, y=%ld\n",
                 mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat),
                 pDataObject, grfKeyState, pt.x, pt.y));

    HRESULT hr = S_OK;

    if (mFormatEtc.cfFormat) /* Did we get a supported format yet? */
    {
        /* Make sure the data object's data format is still valid. */
        hr = pDataObject->QueryGetData(&mFormatEtc);
        AssertMsg(SUCCEEDED(hr),
                  ("Data format changed to invalid between DragEnter() and Drop(), cfFormat=%RI16 (%s), hr=%Rhrc\n",
                  mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat), hr));
    }

    int rc = VINF_SUCCESS;

    if (SUCCEEDED(hr))
    {
        STGMEDIUM stgMed;
        hr = pDataObject->GetData(&mFormatEtc, &stgMed);
        if (SUCCEEDED(hr))
        {
            /*
             * First stage: Prepare the access to the storage medium.
             *              For now we only support HGLOBAL stuff.
             */
            PVOID pvData = NULL; /** @todo Put this in an own union? */

            switch (mFormatEtc.tymed)
            {
                case TYMED_HGLOBAL:
                    pvData = GlobalLock(stgMed.hGlobal);
                    if (!pvData)
                    {
                        LogFlowFunc(("Locking HGLOBAL storage failed with %Rrc\n",
                                     RTErrConvertFromWin32(GetLastError())));
                        rc = VERR_INVALID_HANDLE;
                        hr = E_INVALIDARG; /* Set special hr for OLE. */
                    }
                    break;

                default:
                    AssertMsgFailed(("Storage medium type %RI32 supported\n",
                                     mFormatEtc.tymed));
                    rc = VERR_NOT_SUPPORTED;
                    hr = DV_E_TYMED; /* Set special hr for OLE. */
                    break;
            }

            if (RT_SUCCESS(rc))
            {
                /*
                 * Second stage: Do the actual copying of the data object's data,
                 *               based on the storage medium type.
                 */
                switch (mFormatEtc.cfFormat)
                {
                    case CF_TEXT:
                    /* Fall through is intentional. */
                    case CF_UNICODETEXT:
                    {
                        AssertPtr(pvData);
                        size_t cbSize = GlobalSize(pvData);
                        LogFlowFunc(("CF_TEXT/CF_UNICODETEXT 0x%p got %zu bytes\n", pvData, cbSize));
                        if (cbSize)
                        {
                            char *pszText = NULL;

                            rc = mFormatEtc.cfFormat == CF_TEXT
                               /* ANSI codepage -> UTF-8 */
                               ? RTStrCurrentCPToUtf8(&pszText, (char *)pvData)
                               /* Unicode  -> UTF-8 */
                               : RTUtf16ToUtf8((PCRTUTF16)pvData, &pszText);

                            if (RT_SUCCESS(rc))
                            {
                                AssertPtr(pszText);

                                size_t cbText = strlen(pszText) + 1; /* Include termination. */

                                mpvData = RTMemDup((void *)pszText, cbText);
                                mcbData = cbText;

                                RTStrFree(pszText);
                                pszText = NULL;
                            }
                        }

                        break;
                    }

                    case CF_HDROP:
                    {
                        AssertPtr(pvData);

                        /* Convert to a string list, separated by \r\n. */
                        DROPFILES *pDropFiles = (DROPFILES *)pvData;
                        AssertPtr(pDropFiles);
                        bool fUnicode = RT_BOOL(pDropFiles->fWide);

                        /* Get the offset of the file list. */
                        Assert(pDropFiles->pFiles >= sizeof(DROPFILES));
                        /* Note: This is *not* pDropFiles->pFiles! DragQueryFile only
                         *       will work with the plain storage medium pointer! */
                        HDROP hDrop = (HDROP)(pvData);

                        /* First, get the file count. */
                        /** @todo Does this work on Windows 2000 / NT4? */
                        char *pszFiles = NULL;
                        uint32_t cchFiles = 0;
                        UINT cFiles = DragQueryFile(hDrop, UINT32_MAX /* iFile */,
                                                    NULL /* lpszFile */, 0 /* cchFile */);
                        LogFlowFunc(("CF_HDROP got %RU16 file(s)\n", cFiles));

                        for (UINT i = 0; i < cFiles; i++)
                        {
                            UINT cch = DragQueryFile(hDrop, i /* File index */,
                                                     NULL /* Query size first */,
                                                     0 /* cchFile */);
                            Assert(cch);

                            if (RT_FAILURE(rc))
                                break;

                            char *pszFile = NULL; /* UTF-8 version. */
                            UINT cchFile = 0;
                            if (fUnicode)
                            {
                                /* Allocate enough space (including terminator). */
                                WCHAR *pwszFile = (WCHAR *)RTMemAlloc((cch + 1) * sizeof(WCHAR));
                                if (pwszFile)
                                {
                                    cchFile = DragQueryFileW(hDrop, i /* File index */,
                                                             pwszFile, cch + 1 /* Include terminator */);
                                    AssertMsg(cchFile == cch, ("cchCopied (%RU16) does not match cchFile (%RU16)\n",
                                                               cchFile, cch));
                                    rc = RTUtf16ToUtf8(pwszFile, &pszFile);
                                    AssertRC(rc);

                                    RTMemFree(pwszFile);
                                }
                                else
                                    rc = VERR_NO_MEMORY;
                            }
                            else /* ANSI */
                            {
                                /* Allocate enough space (including terminator). */
                                pszFile = (char *)RTMemAlloc((cch + 1) * sizeof(char));
                                if (pszFile)
                                {
                                    cchFile = DragQueryFileA(hDrop, i /* File index */,
                                                             pszFile, cchFile + 1 /* Include terminator */);
                                    AssertMsg(cchFile == cch, ("cchCopied (%RU16) does not match cchFile (%RU16)\n",
                                                               cchFile, cch));
                                }
                                else
                                    rc = VERR_NO_MEMORY;
                            }

                            if (RT_SUCCESS(rc))
                            {
                                LogFlowFunc(("\tFile: %s (cchFile=%RU32)\n", pszFile, cchFile));
                                rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
                                                     pszFile, cchFile);
                                if (RT_SUCCESS(rc))
                                    cchFiles += cchFile;
                            }

                            if (pszFile)
                                RTStrFree(pszFile);

                            if (RT_FAILURE(rc))
                                break;

                            /* Add separation between filenames.
                             * Note: Also do this for the last element of the list. */
                            rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
                                                 "\r\n", 2 /* Bytes */);
                            if (RT_SUCCESS(rc))
                                cchFiles += 2; /* Include \r\n */
                        }

                        if (RT_SUCCESS(rc))
                        {
                            cchFiles += 1; /* Add string termination. */
                            uint32_t cbFiles = cchFiles * sizeof(char);

                            LogFlowFunc(("cFiles=%u, cchFiles=%RU32, cbFiles=%RU32, pszFiles=0x%p\n",
                                         cFiles, cchFiles, cbFiles, pszFiles));

                            /* Translate the list into URI elements. */
                            DnDURIList lstURI;
                            rc = lstURI.AppendNativePathsFromList(pszFiles, cbFiles,
                                                                  DNDURILIST_FLAGS_ABSOLUTE_PATHS);
                            if (RT_SUCCESS(rc))
                            {
                                RTCString strRoot = lstURI.RootToString();
                                size_t cbRoot = strRoot.length() + 1; /* Include termination */

                                mpvData = RTMemAlloc(cbRoot);
                                if (mpvData)
                                {
                                    memcpy(mpvData, strRoot.c_str(), cbRoot);
                                    mcbData = cbRoot;
                                }
                                else
                                    rc = VERR_NO_MEMORY;
                            }
                        }

                        LogFlowFunc(("Building CF_HDROP list rc=%Rrc, pszFiles=0x%p, cFiles=%RU16, cchFiles=%RU32\n",
                                     rc, pszFiles, cFiles, cchFiles));

                        if (pszFiles)
                            RTStrFree(pszFiles);
                        break;
                    }

                    default:
                        /* Note: Should not happen due to the checks done in DragEnter(). */
                        AssertMsgFailed(("Format of type %RI16 (%s) not supported\n",
                                         mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat)));
                        hr = DV_E_CLIPFORMAT; /* Set special hr for OLE. */
                        break;
                }

                /*
                 * Third stage: Unlock + release access to the storage medium again.
                 */
                switch (mFormatEtc.tymed)
                {
                    case TYMED_HGLOBAL:
                        GlobalUnlock(stgMed.hGlobal);
                        break;

                    default:
                        AssertMsgFailed(("Really should not happen -- see init stage!\n"));
                        break;
                }
            }

            /* Release storage medium again. */
            ReleaseStgMedium(&stgMed);

            /* Signal waiters. */
            mDroppedRc = rc;
            RTSemEventSignal(hEventDrop);
        }
    }

    if (RT_SUCCESS(rc))
    {
        /* Note: pt is not used since we don't need to differentiate within our
         *       proxy window. */
        *pdwEffect = VBoxDnDDropTarget::GetDropEffect(grfKeyState, *pdwEffect);
    }
    else
        *pdwEffect = DROPEFFECT_NONE;

    if (mpWndParent)
        mpWndParent->hide();

    LogFlowFunc(("Returning with hr=%Rhrc (%Rrc), mFormatEtc.cfFormat=%RI16 (%s), *pdwEffect=%RI32\n",
                 hr, rc, mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat),
                 *pdwEffect));

    return hr;
}
RTDECL(int) RTEnvGetEx(RTENV Env, const char *pszVar, char *pszValue, size_t cbValue, size_t *pcchActual)
{
    AssertPtrReturn(pszVar, VERR_INVALID_POINTER);
    AssertPtrNullReturn(pszValue, VERR_INVALID_POINTER);
    AssertPtrNullReturn(pcchActual, VERR_INVALID_POINTER);
    AssertReturn(pcchActual || (pszValue && cbValue), VERR_INVALID_PARAMETER);
    AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);

    if (pcchActual)
        *pcchActual = 0;
    int rc;
    if (Env == RTENV_DEFAULT)
    {
#ifdef RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API
        rc = RTEnvGetUtf8(pszVar, pszValue, cbValue, pcchActual);
#else
        /*
         * Since RTEnvGet isn't UTF-8 clean and actually expects the strings
         * to be in the current code page (codeset), we'll do the necessary
         * conversions here.
         */
        char *pszVarOtherCP;
        rc = RTStrUtf8ToCurrentCP(&pszVarOtherCP, pszVar);
        if (RT_SUCCESS(rc))
        {
            const char *pszValueOtherCP = RTEnvGet(pszVarOtherCP);
            RTStrFree(pszVarOtherCP);
            if (pszValueOtherCP)
            {
                char *pszValueUtf8;
                rc = RTStrCurrentCPToUtf8(&pszValueUtf8, pszValueOtherCP);
                if (RT_SUCCESS(rc))
                {
                    rc = VINF_SUCCESS;
                    size_t cch = strlen(pszValueUtf8);
                    if (pcchActual)
                        *pcchActual = cch;
                    if (pszValue && cbValue)
                    {
                        if (cch < cbValue)
                            memcpy(pszValue, pszValueUtf8, cch + 1);
                        else
                            rc = VERR_BUFFER_OVERFLOW;
                    }
                    RTStrFree(pszValueUtf8);
                }
            }
            else
                rc = VERR_ENV_VAR_NOT_FOUND;
        }
#endif
    }
    else
    {
        PRTENVINTERNAL pIntEnv = Env;
        AssertPtrReturn(pIntEnv, VERR_INVALID_HANDLE);
        AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);

        RTENV_LOCK(pIntEnv);

        /*
         * Locate the first variable and return it to the caller.
         */
        rc = VERR_ENV_VAR_NOT_FOUND;
        const size_t cchVar = strlen(pszVar);
        size_t iVar;
        for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
            if (!pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar))
            {
                if (pIntEnv->papszEnv[iVar][cchVar] == '=')
                {
                    rc = VINF_SUCCESS;
                    const char *pszValueOrg = pIntEnv->papszEnv[iVar] + cchVar + 1;
                    size_t cch = strlen(pszValueOrg);
                    if (pcchActual)
                        *pcchActual = cch;
                    if (pszValue && cbValue)
                    {
                        if (cch < cbValue)
                            memcpy(pszValue, pszValueOrg, cch + 1);
                        else
                            rc = VERR_BUFFER_OVERFLOW;
                    }
                    break;
                }
                if (pIntEnv->papszEnv[iVar][cchVar] == '\0')
                {
                    Assert(pIntEnv->fPutEnvBlock);
                    rc = VERR_ENV_VAR_UNSET;
                    break;
                }
            }

        RTENV_UNLOCK(pIntEnv);
    }
    return rc;
}
RTDECL(int) RTEnvClone(PRTENV pEnv, RTENV EnvToClone)
{
    /*
     * Validate input and figure out how many variable to clone and where to get them.
     */
    bool fCaseSensitive = true;
    bool fPutEnvBlock   = false;
    size_t cVars;
    const char * const *papszEnv;
#ifdef RTENV_HAVE_WENVIRON
    PCRTUTF16 const * papwszEnv;
#endif
    PRTENVINTERNAL pIntEnvToClone;
    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
    if (EnvToClone == RTENV_DEFAULT)
    {
        cVars = 0;
        pIntEnvToClone = NULL;
#ifdef RTENV_HAVE_WENVIRON
        papszEnv  = NULL;
        papwszEnv = (PCRTUTF16 * const)_wenviron;
        if (!papwszEnv)
        {
            _wgetenv(L"Path"); /* Force the CRT to initalize it. */
            papwszEnv = (PCRTUTF16 * const)_wenviron;
        }
        if (papwszEnv)
            while (papwszEnv[cVars])
                cVars++;
#else
        papszEnv = rtEnvDefault();
        if (papszEnv)
            while (papszEnv[cVars])
                cVars++;
#endif

#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
        /* DOS systems was case insensitive.  A prime example is the 'Path'
           variable on windows which turns into the 'PATH' variable. */
        fCaseSensitive = false;
#endif
    }
    else
    {
        pIntEnvToClone = EnvToClone;
        AssertPtrReturn(pIntEnvToClone, VERR_INVALID_HANDLE);
        AssertReturn(pIntEnvToClone->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
        RTENV_LOCK(pIntEnvToClone);

        fPutEnvBlock = pIntEnvToClone->fPutEnvBlock;
        papszEnv = pIntEnvToClone->papszEnv;
        cVars = pIntEnvToClone->cVars;
    }

    /*
     * Create the duplicate.
     */
    PRTENVINTERNAL pIntEnv;
    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, fCaseSensitive, fPutEnvBlock);
    if (RT_SUCCESS(rc))
    {
        pIntEnv->cVars = cVars;
        pIntEnv->papszEnv[pIntEnv->cVars] = NULL;
        if (EnvToClone == RTENV_DEFAULT)
        {
            /* ASSUMES the default environment is in the current codepage. */
            size_t  iDst = 0;
            for (size_t iSrc = 0; iSrc < cVars; iSrc++)
            {
#ifdef RTENV_HAVE_WENVIRON
                int rc2 = RTUtf16ToUtf8(papwszEnv[iSrc], &pIntEnv->papszEnv[iDst]);
#else
                int rc2 = RTStrCurrentCPToUtf8(&pIntEnv->papszEnv[iDst], papszEnv[iSrc]);
#endif
                if (RT_SUCCESS(rc2))
                {
                    /* Make sure it contains an '='. */
                    iDst++;
                    if (strchr(pIntEnv->papszEnv[iDst - 1], '='))
                        continue;
                    rc2 = RTStrAAppend(&pIntEnv->papszEnv[iDst - 1], "=");
                    if (RT_SUCCESS(rc2))
                        continue;
                }
                else if (rc2 == VERR_NO_TRANSLATION)
                {
                    rc = VWRN_ENV_NOT_FULLY_TRANSLATED;
                    continue;
                }

                /* failed fatally. */
                pIntEnv->cVars = iDst;
                RTEnvDestroy(pIntEnv);
                return rc2;
            }
            pIntEnv->cVars = iDst;
        }
        else
        {
            for (size_t iVar = 0; iVar < cVars; iVar++)
            {
                char *pszVar = RTStrDup(papszEnv[iVar]);
                if (RT_UNLIKELY(!pszVar))
                {
                    RTENV_UNLOCK(pIntEnvToClone);

                    pIntEnv->cVars = iVar;
                    RTEnvDestroy(pIntEnv);
                    return VERR_NO_STR_MEMORY;
                }
                pIntEnv->papszEnv[iVar] = pszVar;
            }
        }

        /* done */
        *pEnv = pIntEnv;
    }

    if (pIntEnvToClone)
        RTENV_UNLOCK(pIntEnvToClone);
    return rc;
}
예제 #8
0
void GetInterfaceNameByIID(const GUID &aIID, BSTR *aName)
{
    Assert(aName);
    if (!aName)
        return;

    *aName = NULL;

#if !defined(VBOX_WITH_XPCOM)

    LONG rc;
    LPOLESTR iidStr = NULL;
    if (StringFromIID(aIID, &iidStr) == S_OK)
    {
        HKEY ifaceKey;
        rc = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Interface",
                           0, KEY_QUERY_VALUE, &ifaceKey);
        if (rc == ERROR_SUCCESS)
        {
            HKEY iidKey;
            rc = RegOpenKeyExW(ifaceKey, iidStr, 0, KEY_QUERY_VALUE, &iidKey);
            if (rc == ERROR_SUCCESS)
            {
                /* determine the size and type */
                DWORD sz, type;
                rc = RegQueryValueExW(iidKey, NULL, NULL, &type, NULL, &sz);
                if (rc == ERROR_SUCCESS && type == REG_SZ)
                {
                    /* query the value to BSTR */
                    *aName = SysAllocStringLen(NULL, (sz + 1) / sizeof(TCHAR) + 1);
                    rc = RegQueryValueExW(iidKey, NULL, NULL, NULL, (LPBYTE) *aName, &sz);
                    if (rc != ERROR_SUCCESS)
                    {
                        SysFreeString(*aName);
                        aName = NULL;
                    }
                }
                RegCloseKey(iidKey);
            }
            RegCloseKey(ifaceKey);
        }
        CoTaskMemFree(iidStr);
    }

#else /* !defined (VBOX_WITH_XPCOM) */

    nsresult rv;
    nsCOMPtr<nsIInterfaceInfoManager> iim =
        do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv);
    if (NS_SUCCEEDED(rv))
    {
        nsCOMPtr<nsIInterfaceInfo> iinfo;
        rv = iim->GetInfoForIID(&aIID, getter_AddRefs(iinfo));
        if (NS_SUCCEEDED(rv))
        {
            const char *iname = NULL;
            iinfo->GetNameShared(&iname);
            char *utf8IName = NULL;
            if (RT_SUCCESS(RTStrCurrentCPToUtf8(&utf8IName, iname)))
            {
                PRTUTF16 utf16IName = NULL;
                if (RT_SUCCESS(RTStrToUtf16(utf8IName, &utf16IName)))
                {
                    *aName = SysAllocString((OLECHAR *) utf16IName);
                    RTUtf16Free(utf16IName);
                }
                RTStrFree(utf8IName);
            }
        }
    }

#endif /* !defined (VBOX_WITH_XPCOM) */
}
예제 #9
0
RTR3DECL(int) RTProcQueryUsername(RTPROCESS hProcess, char *pszUser, size_t cbUser, size_t *pcbUser)
{
    AssertReturn(   (pszUser && cbUser > 0)
                    || (!pszUser && !cbUser), VERR_INVALID_PARAMETER);
    AssertReturn(pcbUser || pszUser, VERR_INVALID_PARAMETER);

    int rc;
    if (   hProcess == NIL_RTPROCESS
            || hProcess == RTProcSelf())
    {
        /*
         * Figure a good buffer estimate.
         */
        int32_t cbPwdMax = sysconf(_SC_GETPW_R_SIZE_MAX);
        if (cbPwdMax <= _1K)
            cbPwdMax = _1K;
        else
            AssertStmt(cbPwdMax <= 32*_1M, cbPwdMax = 32*_1M);
        char *pchBuf = (char *)RTMemTmpAllocZ(cbPwdMax);
        if (pchBuf)
        {
            /*
             * Get the password file entry.
             */
            struct passwd  Pwd;
            struct passwd *pPwd = NULL;
            rc = getpwuid_r(geteuid(), &Pwd, pchBuf, cbPwdMax, &pPwd);
            if (!rc)
            {
                /*
                 * Convert the name to UTF-8, assuming that we're getting it in the local codeset.
                 */
                /** @todo This isn't exactly optimal... the current codeset/page conversion
                 *        stuff never was.  Should optimize that for UTF-8 and ASCII one day.
                 *        And also optimize for avoiding heap. */
                char *pszTmp = NULL;
                rc = RTStrCurrentCPToUtf8(&pszTmp, pPwd->pw_name);
                if (RT_SUCCESS(rc))
                {
                    size_t cbTmp = strlen(pszTmp) + 1;
                    if (pcbUser)
                        *pcbUser = cbTmp;
                    if (cbTmp <= cbUser)
                    {
                        memcpy(pszUser, pszTmp, cbTmp);
                        rc = VINF_SUCCESS;
                    }
                    else
                        rc = VERR_BUFFER_OVERFLOW;
                    RTStrFree(pszTmp);
                }
            }
            else
                rc = RTErrConvertFromErrno(rc);
            RTMemFree(pchBuf);
        }
        else
            rc = VERR_NO_TMP_MEMORY;
    }
    else
        rc = VERR_NOT_SUPPORTED;
    return rc;
}
/**
 * Internal worker which initializes or re-initializes the
 * program path, name and directory globals.
 *
 * @returns IPRT status code.
 * @param   fFlags          Flags, see RTR3INIT_XXX.
 * @param   cArgs           Pointer to the argument count.
 * @param   ppapszArgs      Pointer to the argument vector pointer. NULL
 *                          allowed if @a cArgs is 0.
 */
static int rtR3InitArgv(uint32_t fFlags, int cArgs, char ***ppapszArgs)
{
    NOREF(fFlags);
    if (cArgs)
    {
        AssertPtr(ppapszArgs);
        AssertPtr(*ppapszArgs);
        char **papszOrgArgs = *ppapszArgs;

        /*
         * Normally we should only be asked to convert arguments once.  If we
         * are though, it should be the already convered arguments.
         */
        if (g_crtArgs != -1)
        {
            AssertReturn(   g_crtArgs == cArgs
                         && g_papszrtArgs == papszOrgArgs,
                         VERR_WRONG_ORDER); /* only init once! */
            return VINF_SUCCESS;
        }

        if (!(fFlags & RTR3INIT_FLAGS_UTF8_ARGV))
        {
            /*
             * Convert the arguments.
             */
            char **papszArgs = (char **)RTMemAllocZ((cArgs + 1) * sizeof(char *));
            if (!papszArgs)
                return VERR_NO_MEMORY;

#ifdef RT_OS_WINDOWS
            /* HACK ALERT! Try convert from unicode versions if possible.
               Unfortunately for us, __wargv is only initialized if we have a
               unicode main function.  So, we have to use CommandLineToArgvW to get
               something similar. It should do the same conversion... :-) */
            int    cArgsW     = -1;
            PWSTR *papwszArgs = NULL;
            if (   papszOrgArgs == __argv
                && cArgs        == __argc
                && (papwszArgs = CommandLineToArgvW(GetCommandLineW(), &cArgsW)) != NULL )
            {
                AssertMsg(cArgsW == cArgs, ("%d vs %d\n", cArgsW, cArgs));
                for (int i = 0; i < cArgs; i++)
                {
                    int rc = RTUtf16ToUtf8(papwszArgs[i], &papszArgs[i]);
                    if (RT_FAILURE(rc))
                    {
                        while (i--)
                            RTStrFree(papszArgs[i]);
                        RTMemFree(papszArgs);
                        LocalFree(papwszArgs);
                        return rc;
                    }
                }
                LocalFree(papwszArgs);
            }
            else
#endif
            {
                for (int i = 0; i < cArgs; i++)
                {
                    int rc = RTStrCurrentCPToUtf8(&papszArgs[i], papszOrgArgs[i]);
                    if (RT_FAILURE(rc))
                    {
                        while (i--)
                            RTStrFree(papszArgs[i]);
                        RTMemFree(papszArgs);
                        return rc;
                    }
                }
            }

            papszArgs[cArgs] = NULL;

            g_papszrtOrgArgs = papszOrgArgs;
            g_papszrtArgs    = papszArgs;
            g_crtArgs        = cArgs;

            *ppapszArgs = papszArgs;
        }
        else
        {
            /*
             * The arguments are already UTF-8, no conversion needed.
             */
            g_papszrtOrgArgs = papszOrgArgs;
            g_papszrtArgs    = papszOrgArgs;
            g_crtArgs        = cArgs;
        }
    }

    return VINF_SUCCESS;
}
예제 #11
0
RTDECL(int) RTEnvClone(PRTENV pEnv, RTENV EnvToClone)
{
    /*
     * Validate input and figure out how many variable to clone and where to get them.
     */
    size_t cVars;
    const char * const *papszEnv;
    PRTENVINTERNAL pIntEnvToClone;
    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
    if (EnvToClone == RTENV_DEFAULT)
    {
        pIntEnvToClone = NULL;
        papszEnv = rtEnvDefault();
        cVars = 0;
        if (papszEnv)
            while (papszEnv[cVars])
                cVars++;
    }
    else
    {
        pIntEnvToClone = EnvToClone;
        AssertPtrReturn(pIntEnvToClone, VERR_INVALID_HANDLE);
        AssertReturn(pIntEnvToClone->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
        RTENV_LOCK(pIntEnvToClone);

        papszEnv = pIntEnvToClone->papszEnv;
        cVars = pIntEnvToClone->cVars;
    }

    /*
     * Create the duplicate.
     */
    PRTENVINTERNAL pIntEnv;
    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */);
    if (RT_SUCCESS(rc))
    {
        pIntEnv->cVars = cVars;
        pIntEnv->papszEnv[pIntEnv->cVars] = NULL;
        if (EnvToClone == RTENV_DEFAULT)
        {
            /* ASSUMES the default environment is in the current codepage. */
            size_t  iDst = 0;
            for (size_t iSrc = 0; iSrc < cVars; iSrc++)
            {
                int rc2 = RTStrCurrentCPToUtf8(&pIntEnv->papszEnv[iDst], papszEnv[iSrc]);
                if (RT_SUCCESS(rc2))
                    iDst++;
                else if (rc2 == VERR_NO_TRANSLATION)
                    rc = VWRN_ENV_NOT_FULLY_TRANSLATED;
                else
                {
                    pIntEnv->cVars = iDst;
                    RTEnvDestroy(pIntEnv);
                    return rc2;
                }
            }
            pIntEnv->cVars = iDst;
        }
        else
        {
            for (size_t iVar = 0; iVar < cVars; iVar++)
            {
                char *pszVar = RTStrDup(papszEnv[iVar]);
                if (RT_UNLIKELY(!pszVar))
                {
                    RTENV_UNLOCK(pIntEnvToClone);

                    pIntEnv->cVars = iVar;
                    RTEnvDestroy(pIntEnv);
                    return VERR_NO_STR_MEMORY;
                }
                pIntEnv->papszEnv[iVar] = pszVar;
            }
        }

        /* done */
        *pEnv = pIntEnv;
    }

    if (pIntEnvToClone)
        RTENV_UNLOCK(pIntEnvToClone);
    return rc;
}