VirtualBox

Changeset 96587 in vbox for trunk/src/VBox/Runtime/r3/win


Ignore:
Timestamp:
Sep 3, 2022 2:37:15 AM (2 years ago)
Author:
vboxsync
Message:

IPRT/env-win.cpp: GetEnvironmentVariableW doesn't set ERROR_ENVVAR_NOT_FOUND on older windows versions (pre NT4?), added workaround for that. bugref:10261

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/win/env-win.cpp

    r96407 r96587  
    7272int rtEnvSetUtf8Worker(const char *pchVar, size_t cchVar, const char *pszValue);
    7373
     74
     75#if defined(RT_ARCH_X86) && defined(RT_OS_WINDOWS)
     76/**
     77 * This is a workaround for NT 3.x not setting the last error.
     78 */
     79static DWORD rtEnvNt31CheckEmpty(PCRTUTF16 pwszVar)
     80{
     81    /* Check the version first: */
     82    DWORD dwVersion = GetVersion();
     83    if (RT_BYTE1(dwVersion) != 3)
     84        return 0;
     85
     86    /* When called with an empty buffer, we should get 1 if empty value
     87       and 0 if not found:  */
     88    DWORD cwcNeeded = GetEnvironmentVariableW(pwszVar, NULL, 0);
     89    return cwcNeeded == 0 ? ERROR_ENVVAR_NOT_FOUND : NO_ERROR;
     90}
     91#endif
    7492
    7593
     
    173191    for (unsigned iTry = 0;; iTry++)
    174192    {
    175         /* This API is weird, it didn't always set ERROR_BUFFER_OVERFLOW.
     193        /* This API is weird, it didn't always set ERROR_BUFFER_OVERFLOW nor ERROR_ENVVAR_NOT_FOUND.
    176194           Note! Assume that the CRT transparently updates the process
    177195                 environment and that we don't need to use _wgetenv_s here. */
    178196        SetLastError(NO_ERROR);
    179197        DWORD const cwcValueRet = GetEnvironmentVariableW(pwszVar, pwszValue, cwcValueBuf);
    180         DWORD const dwErr       = GetLastError();
     198        DWORD       dwErr       = GetLastError();
    181199
    182200        if (cwcValueRet < cwcValueBuf)
    183201        {
     202#ifdef RT_ARCH_X86
     203            if (cwcValueRet == 0 && dwErr == NO_ERROR)
     204                dwErr = rtEnvNt31CheckEmpty(pwszVar);
     205#endif
    184206            if (cwcValueRet > 0 || dwErr == NO_ERROR) /* In case of empty values we have to see if last error was set or not. */
    185207            {
     
    241263    for (unsigned iTry = 0;; iTry++)
    242264    {
    243         /* This API is weird, it didn't always set ERROR_BUFFER_OVERFLOW.
     265        /* This API is weird, it didn't always set ERROR_BUFFER_OVERFLOW nor ERROR_ENVVAR_NOT_FOUND.
    244266           Note! Assume that the CRT transparently updates the process
    245267                 environment and that we don't need to use _wgetenv_s here. */
    246268        SetLastError(NO_ERROR);
    247269        DWORD const cwcValueRet = GetEnvironmentVariableW(pwszVar, pwszValue, cwcValueBuf);
    248         DWORD const dwErr       = GetLastError();
     270        DWORD       dwErr       = GetLastError();
    249271
    250272        if (cwcValueRet < cwcValueBuf)
    251273        {
     274#ifdef RT_ARCH_X86
     275            if (cwcValueRet == 0 && dwErr == NO_ERROR)
     276                dwErr = rtEnvNt31CheckEmpty(pwszVar);
     277#endif
    252278            if (cwcValueRet > 0 || dwErr == NO_ERROR) /* In case of empty values we have to see if last error was set or not. */
    253279            {
Note: See TracChangeset for help on using the changeset viewer.

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