VirtualBox

忽略:
時間撮記:
2014-2-11 上午02:21:39 (11 年 以前)
作者:
vboxsync
訊息:

RTEnv: Use the unicode CRT APIs on windows to avoid lost-in-translation issues.

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Runtime/generic/env-generic.cpp

    r46035 r50408  
    5757*   Defined Constants And Macros                                               *
    5858*******************************************************************************/
     59/** The allocation granularity of the RTENVINTERNAL::papszEnv memory. */
     60#define RTENV_GROW_SIZE     16
     61
    5962/** Macro that unlocks the specified environment block. */
    6063#define RTENV_LOCK(pEnvInt)     do { } while (0)
    6164/** Macro that unlocks the specified environment block. */
    6265#define RTENV_UNLOCK(pEnvInt)   do { } while (0)
     66
     67/** @def RTENV_HAVE_WENVIRON
     68 * Indicates that we have a _wenviron variable with UTF-16 strings that we
     69 * better use instead of the current-cp strings in environ. */
     70#if defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
     71# define RTENV_HAVE_WENVIRON 1
     72#endif
     73
     74/** @def RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API
     75 * Indicates the RTEnv*Utf8 APIs are implemented. */
     76#if defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
     77# define RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API 1
     78#endif
    6379
    6480
     
    85101     * This get (re-)constructed when RTEnvGetExecEnvP method is called. */
    86102    char      **papszEnvOtherCP;
     103
     104    /** The compare function we're using. */
     105    DECLCALLBACKMEMBER(int, pfnCompare)(const char *psz1, const char *psz2, size_t cchMax);
    87106} RTENVINTERNAL, *PRTENVINTERNAL;
    88 
    89 /** The allocation granularity of the RTENVINTERNAL::papszEnv memory. */
    90 #define RTENV_GROW_SIZE     16
    91107
    92108
     
    112128 *
    113129 * @returns IPRT status code.
    114  * @param   ppIntEnv    Where to store the result.
    115  * @param   cAllocated  The initial array size.
     130 * @param   ppIntEnv        Where to store the result.
     131 * @param   cAllocated      The initial array size.
     132 * @param   fCaseSensitive  Whether the environment block is case sensitive or
     133 *                          not.
    116134 */
    117 static int rtEnvCreate(PRTENVINTERNAL *ppIntEnv, size_t cAllocated)
     135static int rtEnvCreate(PRTENVINTERNAL *ppIntEnv, size_t cAllocated, bool fCaseSensitive)
    118136{
    119137    /*
     
    127145         */
    128146        pIntEnv->u32Magic = RTENV_MAGIC;
     147        pIntEnv->pfnCompare = fCaseSensitive ? RTStrNCmp : RTStrNICmp;
    129148        pIntEnv->papszEnvOtherCP = NULL;
    130149        pIntEnv->cVars = 0;
     
    147166{
    148167    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
    149     return rtEnvCreate(pEnv, RTENV_GROW_SIZE);
     168    return rtEnvCreate(pEnv, RTENV_GROW_SIZE, false /*fCaseSensitive*/);
    150169}
    151170RT_EXPORT_SYMBOL(RTEnvCreate);
     
    201220     * Validate input and figure out how many variable to clone and where to get them.
    202221     */
     222    bool fCaseSensitive = true;
    203223    size_t cVars;
    204224    const char * const *papszEnv;
     225#ifdef RTENV_HAVE_WENVIRON
     226    PCRTUTF16 const * papwszEnv;
     227#endif
    205228    PRTENVINTERNAL pIntEnvToClone;
    206229    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
    207230    if (EnvToClone == RTENV_DEFAULT)
    208231    {
     232        cVars = 0;
    209233        pIntEnvToClone = NULL;
     234#ifdef RTENV_HAVE_WENVIRON
     235        papszEnv  = NULL;
     236        papwszEnv = (PCRTUTF16 * const )_wenviron;
     237        if (papwszEnv)
     238            while (papwszEnv[cVars])
     239                cVars++;
     240#else
    210241        papszEnv = rtEnvDefault();
    211         cVars = 0;
    212242        if (papszEnv)
    213243            while (papszEnv[cVars])
    214244                cVars++;
     245#endif
     246
     247#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
     248        /* DOS systems was case insensitive.  A prime example is the 'Path'
     249           variable on windows which turns into the 'PATH' variable. */
     250        fCaseSensitive = false;
     251#endif
    215252    }
    216253    else
     
    229266     */
    230267    PRTENVINTERNAL pIntEnv;
    231     int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */);
     268    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, fCaseSensitive);
    232269    if (RT_SUCCESS(rc))
    233270    {
     
    240277            for (size_t iSrc = 0; iSrc < cVars; iSrc++)
    241278            {
     279#ifdef RTENV_HAVE_WENVIRON
     280                int rc2 = RTUtf16ToUtf8(papwszEnv[iSrc], &pIntEnv->papszEnv[iDst]);
     281#else
    242282                int rc2 = RTStrCurrentCPToUtf8(&pIntEnv->papszEnv[iDst], papszEnv[iSrc]);
     283#endif
    243284                if (RT_SUCCESS(rc2))
    244285                    iDst++;
     
    319360    if (Env == RTENV_DEFAULT)
    320361    {
     362#ifdef RT_OS_WINDOWS
     363        rc = RTEnvSetUtf8(pszVar, pszValue);
     364#else
    321365        /*
    322366         * Since RTEnvPut isn't UTF-8 clean and actually expects the strings
     
    337381            RTStrFree(pszVarOtherCP);
    338382        }
     383#endif
    339384    }
    340385    else
     
    364409            size_t iVar;
    365410            for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
    366                 if (    !strncmp(pIntEnv->papszEnv[iVar], pszVar, cchVar)
     411                if (    !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
    367412                    &&  pIntEnv->papszEnv[iVar][cchVar] == '=')
    368413                    break;
     
    424469    if (Env == RTENV_DEFAULT)
    425470    {
     471#ifdef RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API
     472        rc = RTEnvUnsetUtf8(pszVar);
     473#else
    426474        /*
    427475         * Since RTEnvUnset isn't UTF-8 clean and actually expects the strings
     
    436484            RTStrFree(pszVarOtherCP);
    437485        }
     486#endif
    438487    }
    439488    else
     
    452501        size_t iVar;
    453502        for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
    454             if (    !strncmp(pIntEnv->papszEnv[iVar], pszVar, cchVar)
     503            if (    !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
    455504                &&  pIntEnv->papszEnv[iVar][cchVar] == '=')
    456505            {
     
    484533    if (Env == RTENV_DEFAULT)
    485534    {
     535#ifdef RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API
     536        rc = RTEnvGetUtf8(pszVar, pszValue, cbValue, pcchActual);
     537#else
    486538        /*
    487539         * Since RTEnvGet isn't UTF-8 clean and actually expects the strings
     
    518570                rc = VERR_ENV_VAR_NOT_FOUND;
    519571        }
     572#endif
    520573    }
    521574    else
     
    534587        size_t iVar;
    535588        for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
    536             if (    !strncmp(pIntEnv->papszEnv[iVar], pszVar, cchVar)
     589            if (    !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
    537590                &&  pIntEnv->papszEnv[iVar][cchVar] == '=')
    538591            {
     
    555608    }
    556609    return rc;
    557 
    558610}
    559611RT_EXPORT_SYMBOL(RTEnvGetEx);
     
    564616    AssertPtrReturn(pszVar, false);
    565617
    566     bool fExist = false;
     618    bool fExists = false;
    567619    if (Env == RTENV_DEFAULT)
    568620    {
     621#ifdef RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API
     622        fExists = RTEnvExistsUtf8(pszVar);
     623#else
    569624        /*
    570625         * Since RTEnvExist isn't UTF-8 clean and actually expects the strings
     
    576631        if (RT_SUCCESS(rc))
    577632        {
    578             fExist = RTEnvExist(pszVarOtherCP);
     633            fExists = RTEnvExist(pszVarOtherCP);
    579634            RTStrFree(pszVarOtherCP);
    580635        }
     636#endif
    581637    }
    582638    else
     
    593649        const size_t cchVar = strlen(pszVar);
    594650        for (size_t iVar = 0; iVar < pIntEnv->cVars; iVar++)
    595             if (    !strncmp(pIntEnv->papszEnv[iVar], pszVar, cchVar)
     651            if (    !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
    596652                &&  pIntEnv->papszEnv[iVar][cchVar] == '=')
    597653            {
    598                 fExist = true;
     654                fExists = true;
    599655                break;
    600656            }
     
    602658        RTENV_UNLOCK(pIntEnv);
    603659    }
    604     return fExist;
     660    return fExists;
    605661}
    606662RT_EXPORT_SYMBOL(RTEnvExistEx);
     
    612668    if (Env == RTENV_DEFAULT)
    613669    {
     670        /** @todo fix this API it's fundamentally wrong! */
    614671        papszRet = rtEnvDefault();
    615672        if (!papszRet)
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette