Index: /trunk/include/iprt/env.h
===================================================================
--- /trunk/include/iprt/env.h	(revision 50407)
+++ /trunk/include/iprt/env.h	(revision 50408)
@@ -90,4 +90,6 @@
  *
  * @param   Env     Environment block handle.
+ * @todo    This needs to change to return a copy of the env vars like
+ *          RTEnvQueryUtf16Block does!
  */
 RTDECL(char const * const *) RTEnvGetExecEnvP(RTENV Env);
@@ -121,4 +123,6 @@
  */
 RTDECL(bool) RTEnvExist(const char *pszVar);
+RTDECL(bool) RTEnvExistsBad(const char *pszVar);
+RTDECL(bool) RTEnvExistsUtf8(const char *pszVar);
 
 /**
@@ -146,4 +150,6 @@
  */
 RTDECL(const char *) RTEnvGet(const char *pszVar);
+RTDECL(const char *) RTEnvGetBad(const char *pszVar);
+RTDECL(int) RTEnvGetUtf8(const char *pszVar, char *pszValue, size_t cbValue, size_t *pcchActual);
 
 /**
@@ -174,4 +180,6 @@
  */
 RTDECL(int) RTEnvPut(const char *pszVarEqualValue);
+RTDECL(int) RTEnvPutBad(const char *pszVarEqualValue);
+RTDECL(int) RTEnvPutUtf8(const char *pszVarEqualValue);
 
 /**
@@ -198,4 +206,6 @@
  */
 RTDECL(int) RTEnvSet(const char *pszVar, const char *pszValue);
+RTDECL(int) RTEnvSetBad(const char *pszVar, const char *pszValue);
+RTDECL(int) RTEnvSetUtf8(const char *pszVar, const char *pszValue);
 
 /**
@@ -222,4 +232,6 @@
  */
 RTDECL(int) RTEnvUnset(const char *pszVar);
+RTDECL(int) RTEnvUnsetBad(const char *pszVar);
+RTDECL(int) RTEnvUnsetUtf8(const char *pszVar);
 
 /**
Index: /trunk/include/iprt/mangling.h
===================================================================
--- /trunk/include/iprt/mangling.h	(revision 50407)
+++ /trunk/include/iprt/mangling.h	(revision 50408)
@@ -495,15 +495,25 @@
 # define RTEnvDupEx                                     RT_MANGLER(RTEnvDupEx)
 # define RTEnvExist                                     RT_MANGLER(RTEnvExist)
+# define RTEnvExistsBad                                 RT_MANGLER(RTEnvExistsBad)
+# define RTEnvExistsUtf8                                RT_MANGLER(RTEnvExistsUtf8)
 # define RTEnvExistEx                                   RT_MANGLER(RTEnvExistEx)
 # define RTEnvFreeUtf16Block                            RT_MANGLER(RTEnvFreeUtf16Block)
 # define RTEnvGet                                       RT_MANGLER(RTEnvGet)
+# define RTEnvGetBad                                    RT_MANGLER(RTEnvGetBad)
+# define RTEnvGetUtf8                                   RT_MANGLER(RTEnvGetUtf8)
 # define RTEnvGetEx                                     RT_MANGLER(RTEnvGetEx)
 # define RTEnvGetExecEnvP                               RT_MANGLER(RTEnvGetExecEnvP)
 # define RTEnvPut                                       RT_MANGLER(RTEnvPut)
+# define RTEnvPutBad                                    RT_MANGLER(RTEnvPutBad)
+# define RTEnvPutUtf8                                   RT_MANGLER(RTEnvPutUtf8)
 # define RTEnvPutEx                                     RT_MANGLER(RTEnvPutEx)
 # define RTEnvQueryUtf16Block                           RT_MANGLER(RTEnvQueryUtf16Block)
 # define RTEnvSet                                       RT_MANGLER(RTEnvSet)
+# define RTEnvSetBad                                    RT_MANGLER(RTEnvSetBad)
+# define RTEnvSetUtf8                                   RT_MANGLER(RTEnvSetUtf8)
 # define RTEnvSetEx                                     RT_MANGLER(RTEnvSetEx)
 # define RTEnvUnset                                     RT_MANGLER(RTEnvUnset)
+# define RTEnvUnsetBad                                  RT_MANGLER(RTEnvUnsetBad)
+# define RTEnvUnsetUtf8                                 RT_MANGLER(RTEnvUnsetUtf8)
 # define RTEnvUnsetEx                                   RT_MANGLER(RTEnvUnsetEx)
 # define RTErrCOMGet                                    RT_MANGLER(RTErrCOMGet)
Index: /trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/Makefile.kmk	(revision 50407)
+++ /trunk/src/VBox/Runtime/Makefile.kmk	(revision 50408)
@@ -604,5 +604,5 @@
  	r3/nt/fs-nt.cpp \
  	r3/nt/pathint-nt.cpp \
-	r3/posix/env-posix.cpp \
+	r3/win/env-win.cpp \
 	r3/win/RTHandleGetStandard-win.cpp \
 	r3/win/RTSystemQueryOSInfo-win.cpp \
Index: /trunk/src/VBox/Runtime/generic/env-generic.cpp
===================================================================
--- /trunk/src/VBox/Runtime/generic/env-generic.cpp	(revision 50407)
+++ /trunk/src/VBox/Runtime/generic/env-generic.cpp	(revision 50408)
@@ -57,8 +57,24 @@
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
+/** The allocation granularity of the RTENVINTERNAL::papszEnv memory. */
+#define RTENV_GROW_SIZE     16
+
 /** Macro that unlocks the specified environment block. */
 #define RTENV_LOCK(pEnvInt)     do { } while (0)
 /** Macro that unlocks the specified environment block. */
 #define RTENV_UNLOCK(pEnvInt)   do { } while (0)
+
+/** @def RTENV_HAVE_WENVIRON
+ * Indicates that we have a _wenviron variable with UTF-16 strings that we
+ * better use instead of the current-cp strings in environ. */
+#if defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
+# define RTENV_HAVE_WENVIRON 1
+#endif
+
+/** @def RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API
+ * Indicates the RTEnv*Utf8 APIs are implemented. */
+#if defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
+# define RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API 1
+#endif
 
 
@@ -85,8 +101,8 @@
      * This get (re-)constructed when RTEnvGetExecEnvP method is called. */
     char      **papszEnvOtherCP;
+
+    /** The compare function we're using. */
+    DECLCALLBACKMEMBER(int, pfnCompare)(const char *psz1, const char *psz2, size_t cchMax);
 } RTENVINTERNAL, *PRTENVINTERNAL;
-
-/** The allocation granularity of the RTENVINTERNAL::papszEnv memory. */
-#define RTENV_GROW_SIZE     16
 
 
@@ -112,8 +128,10 @@
  *
  * @returns IPRT status code.
- * @param   ppIntEnv    Where to store the result.
- * @param   cAllocated  The initial array size.
+ * @param   ppIntEnv        Where to store the result.
+ * @param   cAllocated      The initial array size.
+ * @param   fCaseSensitive  Whether the environment block is case sensitive or
+ *                          not.
  */
-static int rtEnvCreate(PRTENVINTERNAL *ppIntEnv, size_t cAllocated)
+static int rtEnvCreate(PRTENVINTERNAL *ppIntEnv, size_t cAllocated, bool fCaseSensitive)
 {
     /*
@@ -127,4 +145,5 @@
          */
         pIntEnv->u32Magic = RTENV_MAGIC;
+        pIntEnv->pfnCompare = fCaseSensitive ? RTStrNCmp : RTStrNICmp;
         pIntEnv->papszEnvOtherCP = NULL;
         pIntEnv->cVars = 0;
@@ -147,5 +166,5 @@
 {
     AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
-    return rtEnvCreate(pEnv, RTENV_GROW_SIZE);
+    return rtEnvCreate(pEnv, RTENV_GROW_SIZE, false /*fCaseSensitive*/);
 }
 RT_EXPORT_SYMBOL(RTEnvCreate);
@@ -201,16 +220,34 @@
      * Validate input and figure out how many variable to clone and where to get them.
      */
+    bool fCaseSensitive = true;
     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)
+            while (papwszEnv[cVars])
+                cVars++;
+#else
         papszEnv = rtEnvDefault();
-        cVars = 0;
         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
@@ -229,5 +266,5 @@
      */
     PRTENVINTERNAL pIntEnv;
-    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */);
+    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, fCaseSensitive);
     if (RT_SUCCESS(rc))
     {
@@ -240,5 +277,9 @@
             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))
                     iDst++;
@@ -319,4 +360,7 @@
     if (Env == RTENV_DEFAULT)
     {
+#ifdef RT_OS_WINDOWS
+        rc = RTEnvSetUtf8(pszVar, pszValue);
+#else
         /*
          * Since RTEnvPut isn't UTF-8 clean and actually expects the strings
@@ -337,4 +381,5 @@
             RTStrFree(pszVarOtherCP);
         }
+#endif
     }
     else
@@ -364,5 +409,5 @@
             size_t iVar;
             for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
-                if (    !strncmp(pIntEnv->papszEnv[iVar], pszVar, cchVar)
+                if (    !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
                     &&  pIntEnv->papszEnv[iVar][cchVar] == '=')
                     break;
@@ -424,4 +469,7 @@
     if (Env == RTENV_DEFAULT)
     {
+#ifdef RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API
+        rc = RTEnvUnsetUtf8(pszVar);
+#else
         /*
          * Since RTEnvUnset isn't UTF-8 clean and actually expects the strings
@@ -436,4 +484,5 @@
             RTStrFree(pszVarOtherCP);
         }
+#endif
     }
     else
@@ -452,5 +501,5 @@
         size_t iVar;
         for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
-            if (    !strncmp(pIntEnv->papszEnv[iVar], pszVar, cchVar)
+            if (    !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
                 &&  pIntEnv->papszEnv[iVar][cchVar] == '=')
             {
@@ -484,4 +533,7 @@
     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
@@ -518,4 +570,5 @@
                 rc = VERR_ENV_VAR_NOT_FOUND;
         }
+#endif
     }
     else
@@ -534,5 +587,5 @@
         size_t iVar;
         for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
-            if (    !strncmp(pIntEnv->papszEnv[iVar], pszVar, cchVar)
+            if (    !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
                 &&  pIntEnv->papszEnv[iVar][cchVar] == '=')
             {
@@ -555,5 +608,4 @@
     }
     return rc;
-
 }
 RT_EXPORT_SYMBOL(RTEnvGetEx);
@@ -564,7 +616,10 @@
     AssertPtrReturn(pszVar, false);
 
-    bool fExist = false;
+    bool fExists = false;
     if (Env == RTENV_DEFAULT)
     {
+#ifdef RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API
+        fExists = RTEnvExistsUtf8(pszVar);
+#else
         /*
          * Since RTEnvExist isn't UTF-8 clean and actually expects the strings
@@ -576,7 +631,8 @@
         if (RT_SUCCESS(rc))
         {
-            fExist = RTEnvExist(pszVarOtherCP);
+            fExists = RTEnvExist(pszVarOtherCP);
             RTStrFree(pszVarOtherCP);
         }
+#endif
     }
     else
@@ -593,8 +649,8 @@
         const size_t cchVar = strlen(pszVar);
         for (size_t iVar = 0; iVar < pIntEnv->cVars; iVar++)
-            if (    !strncmp(pIntEnv->papszEnv[iVar], pszVar, cchVar)
+            if (    !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
                 &&  pIntEnv->papszEnv[iVar][cchVar] == '=')
             {
-                fExist = true;
+                fExists = true;
                 break;
             }
@@ -602,5 +658,5 @@
         RTENV_UNLOCK(pIntEnv);
     }
-    return fExist;
+    return fExists;
 }
 RT_EXPORT_SYMBOL(RTEnvExistEx);
@@ -612,4 +668,5 @@
     if (Env == RTENV_DEFAULT)
     {
+        /** @todo fix this API it's fundamentally wrong! */
         papszRet = rtEnvDefault();
         if (!papszRet)
Index: /trunk/src/VBox/Runtime/r3/posix/env-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/env-posix.cpp	(revision 50407)
+++ /trunk/src/VBox/Runtime/r3/posix/env-posix.cpp	(revision 50408)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -47,11 +47,17 @@
 
 
-RTDECL(bool) RTEnvExist(const char *pszVar)
+RTDECL(bool) RTEnvExistsBad(const char *pszVar)
 {
-    return RTEnvGet(pszVar) != NULL;
+    return RTEnvGetBad(pszVar) != NULL;
 }
 
 
-RTDECL(const char *) RTEnvGet(const char *pszVar)
+RTDECL(bool) RTEnvExist(const char *pszVar)
+{
+    return RTEnvExistsBad(pszVar);
+}
+
+
+RTDECL(const char *) RTEnvGetBad(const char *pszVar)
 {
     IPRT_ALIGNMENT_CHECKS_DISABLE(); /* glibc causes trouble */
@@ -62,5 +68,11 @@
 
 
-RTDECL(int) RTEnvPut(const char *pszVarEqualValue)
+RTDECL(const char *) RTEnvGet(const char *pszVar)
+{
+    return RTEnvGetBad(pszVar);
+}
+
+
+RTDECL(int) RTEnvPutBad(const char *pszVarEqualValue)
 {
     /** @todo putenv is a source memory leaks. deal with this on a per system basis. */
@@ -70,5 +82,12 @@
 }
 
-RTDECL(int) RTEnvSet(const char *pszVar, const char *pszValue)
+
+RTDECL(int) RTEnvPut(const char *pszVarEqualValue)
+{
+    return RTEnvPutBad(pszVarEqualValue);
+}
+
+
+RTDECL(int) RTEnvSetBad(const char *pszVar, const char *pszValue)
 {
 #if defined(_MSC_VER)
@@ -99,5 +118,10 @@
 
 
-RTDECL(int) RTEnvUnset(const char *pszVar)
+RTDECL(int) RTEnvSet(const char *pszVar, const char *pszValue)
+{
+    return RTEnvSetBad(pszVar, pszValue);
+}
+
+RTDECL(int) RTEnvUnsetBad(const char *pszVar)
 {
     AssertReturn(!strchr(pszVar, '='), VERR_INVALID_PARAMETER);
@@ -132,2 +156,7 @@
 }
 
+RTDECL(int) RTEnvUnset(const char *pszVar)
+{
+    return RTEnvUnsetBad(pszVar);
+}
+
Index: /trunk/src/VBox/Runtime/r3/win/env-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/env-win.cpp	(revision 50408)
+++ /trunk/src/VBox/Runtime/r3/win/env-win.cpp	(revision 50408)
@@ -0,0 +1,268 @@
+/* $Id$ */
+/** @file
+ * IPRT - Environment, Posix.
+ */
+
+/*
+ * Copyright (C) 2006-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <iprt/env.h>
+
+#include <iprt/alloca.h>
+#include <iprt/assert.h>
+#include <iprt/string.h>
+#include <iprt/mem.h>
+
+#include <stdlib.h>
+#include <errno.h>
+
+
+RTDECL(bool) RTEnvExistsBad(const char *pszVar)
+{
+    return RTEnvGetBad(pszVar) != NULL;
+}
+
+
+RTDECL(bool) RTEnvExist(const char *pszVar)
+{
+    return RTEnvExistsBad(pszVar);
+}
+
+
+RTDECL(bool) RTEnvExistsUtf8(const char *pszVar)
+{
+    PRTUTF16 pwszVar;
+    int rc = RTStrToUtf16(pszVar, &pwszVar);
+    AssertRCReturn(rc, false);
+    bool fRet = _wgetenv(pwszVar) != NULL;
+    RTUtf16Free(pwszVar);
+    return fRet;
+}
+
+
+RTDECL(const char *) RTEnvGetBad(const char *pszVar)
+{
+    return getenv(pszVar);
+}
+
+
+RTDECL(const char *) RTEnvGet(const char *pszVar)
+{
+    return RTEnvGetBad(pszVar);
+}
+
+RTDECL(int) RTEnvGetUtf8(const char *pszVar, char *pszValue, size_t cbValue, size_t *pcchActual)
+{
+    AssertPtrReturn(pszVar, VERR_INVALID_POINTER);
+    AssertPtrNullReturn(pszValue, VERR_INVALID_POINTER);
+    AssertReturn(pszValue || !cbValue, VERR_INVALID_PARAMETER);
+    AssertPtrNullReturn(pcchActual, VERR_INVALID_POINTER);
+    AssertReturn(pcchActual || (pszValue && cbValue), VERR_INVALID_PARAMETER);
+
+    if (pcchActual)
+        *pcchActual = 0;
+
+    PRTUTF16 pwszVar;
+    int rc = RTStrToUtf16(pszVar, &pwszVar);
+    AssertRCReturn(rc, false);
+
+    /** @todo Consider _wgetenv_s or GetEnvironmentVariableW here to avoid the
+     *        potential race with a concurrent _wputenv/_putenv. */
+    PCRTUTF16 pwszValue = _wgetenv(pwszVar);
+    RTUtf16Free(pwszVar);
+    if (pwszValue)
+    {
+        if (cbValue)
+            rc = RTUtf16ToUtf8Ex(pwszValue, RTSTR_MAX, &pszValue, cbValue, pcchActual);
+        else
+            rc = RTUtf16CalcUtf8LenEx(pwszValue, RTSTR_MAX, pcchActual);
+    }
+    else
+        rc = VERR_ENV_VAR_NOT_FOUND;
+    return rc;
+}
+
+
+RTDECL(int) RTEnvPutBad(const char *pszVarEqualValue)
+{
+    /** @todo putenv is a source memory leaks. deal with this on a per system basis. */
+    if (!putenv((char *)pszVarEqualValue))
+        return 0;
+    return RTErrConvertFromErrno(errno);
+}
+
+
+RTDECL(int) RTEnvPut(const char *pszVarEqualValue)
+{
+    return RTEnvPutBad(pszVarEqualValue);
+}
+
+
+RTDECL(int) RTEnvPutUtf8(const char *pszVarEqualValue)
+{
+    PRTUTF16 pwszVarEqualValue;
+    int rc = RTStrToUtf16(pszVarEqualValue, &pwszVarEqualValue);
+    if (RT_SUCCESS(rc))
+    {
+        if (!_wputenv(pwszVarEqualValue))
+            rc = VINF_SUCCESS;
+        else
+            rc = RTErrConvertFromErrno(errno);
+        RTUtf16Free(pwszVarEqualValue);
+    }
+    return rc;
+}
+
+
+
+RTDECL(int) RTEnvSetBad(const char *pszVar, const char *pszValue)
+{
+    /* make a local copy and feed it to putenv. */
+    const size_t cchVar = strlen(pszVar);
+    const size_t cchValue = strlen(pszValue);
+    char *pszTmp = (char *)alloca(cchVar + cchValue + 2 + !*pszValue);
+    memcpy(pszTmp, pszVar, cchVar);
+    pszTmp[cchVar] = '=';
+    if (*pszValue)
+        memcpy(pszTmp + cchVar + 1, pszValue, cchValue + 1);
+    else
+    {
+        pszTmp[cchVar + 1] = ' '; /* wrong, but putenv will remove it otherwise. */
+        pszTmp[cchVar + 2] = '\0';
+    }
+
+    if (!putenv(pszTmp))
+        return 0;
+    return RTErrConvertFromErrno(errno);
+}
+
+
+RTDECL(int) RTEnvSet(const char *pszVar, const char *pszValue)
+{
+    return RTEnvSetBad(pszVar, pszValue);
+}
+
+RTDECL(int) RTEnvSetUtf8(const char *pszVar, const char *pszValue)
+{
+    size_t cwcVar;
+    int rc = RTStrCalcUtf16LenEx(pszVar, RTSTR_MAX, &cwcVar);
+    if (RT_SUCCESS(rc))
+    {
+        size_t cwcValue;
+        rc = RTStrCalcUtf16LenEx(pszVar, RTSTR_MAX, &cwcValue);
+        if (RT_SUCCESS(rc))
+        {
+            PRTUTF16 pwszTmp = (PRTUTF16)RTMemTmpAlloc((cwcVar + 1 + cwcValue + 1) * sizeof(RTUTF16));
+            if (pwszTmp)
+            {
+                rc = RTStrToUtf16Ex(pszVar, RTSTR_MAX, &pwszTmp, cwcVar + 1, NULL);
+                if (RT_SUCCESS(rc))
+                {
+                    PRTUTF16 pwszTmpValue = &pwszTmp[cwcVar];
+                    *pwszTmpValue++ = '=';
+                    rc = RTStrToUtf16Ex(pszValue, RTSTR_MAX, &pwszTmpValue, cwcValue + 1, NULL);
+                    if (RT_SUCCESS(rc))
+                    {
+                        if (!_wputenv(pwszTmp))
+                            rc = VINF_SUCCESS;
+                        else
+                            rc = RTErrConvertFromErrno(errno);
+                    }
+                }
+                RTMemTmpFree(pwszTmp);
+            }
+            else
+                rc = VERR_NO_TMP_MEMORY;
+        }
+    }
+    return rc;
+}
+
+
+RTDECL(int) RTEnvUnsetBad(const char *pszVar)
+{
+    AssertReturn(!strchr(pszVar, '='), VERR_INVALID_PARAMETER);
+
+    /*
+     * Check that it exists first.
+     */
+    if (!RTEnvExist(pszVar))
+        return VINF_ENV_VAR_NOT_FOUND;
+
+    /*
+     * Ok, try remove it.
+     */
+#ifdef RT_OS_WINDOWS
+    /* Use putenv(var=) since Windows does not have unsetenv(). */
+    size_t cchVar = strlen(pszVar);
+    char *pszBuf = (char *)alloca(cchVar + 2);
+    memcpy(pszBuf, pszVar, cchVar);
+    pszBuf[cchVar]     = '=';
+    pszBuf[cchVar + 1] = '\0';
+
+    if (!putenv(pszBuf))
+        return VINF_SUCCESS;
+
+#else
+    /* This is the preferred function as putenv() like used above does neither work on Solaris nor on Darwin. */
+    if (!unsetenv((char*)pszVar))
+        return VINF_SUCCESS;
+#endif
+
+    return RTErrConvertFromErrno(errno);
+}
+
+
+RTDECL(int) RTEnvUnset(const char *pszVar)
+{
+    return RTEnvUnsetBad(pszVar);
+}
+
+
+RTDECL(int) RTEnvUnsetUtf8(const char *pszVar)
+{
+    size_t cwcVar;
+    int rc = RTStrCalcUtf16LenEx(pszVar, RTSTR_MAX, &cwcVar);
+    if (RT_SUCCESS(rc))
+    {
+        PRTUTF16 pwszTmp = (PRTUTF16)RTMemTmpAlloc((cwcVar + 1 + 1) * sizeof(RTUTF16));
+        if (pwszTmp)
+        {
+            rc = RTStrToUtf16Ex(pszVar, RTSTR_MAX, &pwszTmp, cwcVar + 1, NULL);
+            if (RT_SUCCESS(rc))
+            {
+                pwszTmp[cwcVar] = '=';
+                pwszTmp[cwcVar + 1] = '\0';
+                if (!_wputenv(pwszTmp))
+                    rc = VINF_SUCCESS;
+                else
+                    rc = RTErrConvertFromErrno(errno);
+            }
+            RTMemTmpFree(pwszTmp);
+        }
+    }
+    return rc;
+}
+
