Index: /trunk/include/iprt/env.h
===================================================================
--- /trunk/include/iprt/env.h	(revision 55561)
+++ /trunk/include/iprt/env.h	(revision 55562)
@@ -158,6 +158,8 @@
  * @returns IPRT status code.
  * @retval  VERR_ENV_VAR_NOT_FOUND if the variable was not found.
- *
- * @param   Env         The environment handle.
+ * @retval  VERR_ENV_VAR_UNSET if @a hEnv is an environment change record and
+ *          the variable has been recorded as unset.
+ *
+ * @param   hEnv        The environment handle.
  * @param   pszVar      The environment variable name.
  * @param   pszValue    Where to put the buffer.
@@ -165,5 +167,5 @@
  * @param   pcchActual  Returns the actual value string length. Optional.
  */
-RTDECL(int) RTEnvGetEx(RTENV Env, const char *pszVar, char *pszValue, size_t cbValue, size_t *pcchActual);
+RTDECL(int) RTEnvGetEx(RTENV hEnv, const char *pszVar, char *pszValue, size_t cbValue, size_t *pcchActual);
 
 /**
@@ -276,4 +278,6 @@
  * @retval  VERR_BUFFER_OVERFLOW if one of the buffers are too small.  We'll
  *          fill it with as much we can in RTStrCopy fashion.
+ * @retval  VINF_ENV_VAR_UNSET if @a hEnv is an environment change record and
+ *          the variable at @a iVar is recorded as being unset.
  *
  * @param   hEnv        The environment handle.
@@ -285,5 +289,67 @@
  * @param   cbValue     The size of the value buffer.
  */
-RTDECL(uint32_t) RTEnvGetByIndexEx(RTENV hEnv, uint32_t iVar, char *pszVar, size_t cbVar, char *pszValue, size_t cbValue);
+RTDECL(int) RTEnvGetByIndexEx(RTENV hEnv, uint32_t iVar, char *pszVar, size_t cbVar, char *pszValue, size_t cbValue);
+
+/**
+ * Leaner and meaner version of RTEnvGetByIndexEx.
+ *
+ * This can be used together with RTEnvCount to enumerate the environment block.
+ *
+ * Use with caution as the returned pointer may change by the next call using
+ * the environment handle.  Please only use this API in cases where there is no
+ * chance of races.
+ *
+ * @returns Pointer to the internal environment variable=value string on
+ *          success.  If @a hEnv is an environment change recordthe string may
+ *          also be on the "variable" form, representing an unset operation. Do
+ *          NOT change this string, it is read only!
+ *
+ *          If the index is out of range on the environment handle is invalid,
+ *          NULL is returned.
+ *
+ * @param   hEnv        The environment handle.
+ *                      RTENV_DEFAULT is currently not accepted.
+ * @param   iVar        The variable index.
+ */
+RTDECL(const char *) RTEnvGetByIndexRawEx(RTENV hEnv, uint32_t iVar);
+
+
+/**
+ * Creates an empty environment change record.
+ *
+ * This is a special environment for use with RTEnvApplyChanges and similar
+ * purposes.  The
+ *
+ * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
+ *
+ * @param   phEnv       Where to store the handle of the new environment block.
+ */
+RTDECL(int) RTEnvCreateChangeRecord(PRTENV phEnv);
+
+/**
+ * Checks if @a hEnv is an environment change record.
+ *
+ * @returns true if it is, false if it's not or if the handle is invalid.
+ * @param   hEnv         The environment handle.
+ * @sa      RTEnvCreateChangeRecord.
+ */
+RTDECL(bool) RTEnvIsChangeRecord(RTENV hEnv);
+
+/**
+ * Applies changes from one environment onto another.
+ *
+ * If @a hEnvChanges is a normal environment, its content is just added to @a
+ * hEnvDst, where variables in the destination can only be overwritten. However
+ * if @a hEnvChanges is a change record environment, variables in the
+ * destination can also be removed.
+ *
+ * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
+ * @param   hEnvDst     The destination environment.
+ * @param   hEnvChanges Handle to the environment containig the changes to
+ *                      apply.  As said, especially useful if it's a environment
+ *                      change record.  RTENV_DEFAULT is not supported here.
+ */
+RTDECL(int) RTEnvApplyChanges(RTENV hEnvDst, RTENV hEnvChanges);
+
 
 #endif /* IN_RING3 */
Index: /trunk/include/iprt/err.h
===================================================================
--- /trunk/include/iprt/err.h	(revision 55561)
+++ /trunk/include/iprt/err.h	(revision 55562)
@@ -1600,4 +1600,10 @@
  * codeset issues (LANG / LC_ALL / LC_CTYPE). */
 #define VWRN_ENV_NOT_FULLY_TRANSLATED           (751)
+/** Invalid environment variable name. */
+#define VERR_ENV_INVALID_VAR_NAME               (-752)
+/** The environment variable is an unset record. */
+#define VINF_ENV_VAR_UNSET                      (753)
+/** The environment variable has been recorded as being unset. */
+#define VERR_ENV_VAR_UNSET                      (-753)
 /** @} */
 
Index: /trunk/include/iprt/mangling.h
===================================================================
--- /trunk/include/iprt/mangling.h	(revision 55561)
+++ /trunk/include/iprt/mangling.h	(revision 55562)
@@ -508,7 +508,9 @@
 # define RTDvmVolumeTypeGetDescr                        RT_MANGLER(RTDvmVolumeTypeGetDescr)
 # define RTDvmVolumeCreateVfsFile                       RT_MANGLER(RTDvmVolumeCreateVfsFile)
+# define RTEnvApplyChanges                              RT_MANGLER(RTEnvApplyChanges)
 # define RTEnvClone                                     RT_MANGLER(RTEnvClone)
 # define RTEnvCountEx                                   RT_MANGLER(RTEnvCountEx)
 # define RTEnvCreate                                    RT_MANGLER(RTEnvCreate)
+# define RTEnvCreateChangeRecord                        RT_MANGLER(RTEnvCreateChangeRecord)
 # define RTEnvDestroy                                   RT_MANGLER(RTEnvDestroy)
 # define RTEnvDupEx                                     RT_MANGLER(RTEnvDupEx)
@@ -521,7 +523,9 @@
 # define RTEnvGetBad                                    RT_MANGLER(RTEnvGetBad)
 # define RTEnvGetByIndexEx                              RT_MANGLER(RTEnvGetByIndexEx)
+# define RTEnvGetByIndexRawEx                           RT_MANGLER(RTEnvGetByIndexRawEx)
 # define RTEnvGetUtf8                                   RT_MANGLER(RTEnvGetUtf8)
 # define RTEnvGetEx                                     RT_MANGLER(RTEnvGetEx)
 # define RTEnvGetExecEnvP                               RT_MANGLER(RTEnvGetExecEnvP)
+# define RTEnvIsChangeRecord                            RT_MANGLER(RTEnvIsChangeRecord)
 # define RTEnvPut                                       RT_MANGLER(RTEnvPut)
 # define RTEnvPutBad                                    RT_MANGLER(RTEnvPutBad)
Index: /trunk/src/VBox/Runtime/generic/env-generic.cpp
===================================================================
--- /trunk/src/VBox/Runtime/generic/env-generic.cpp	(revision 55561)
+++ /trunk/src/VBox/Runtime/generic/env-generic.cpp	(revision 55562)
@@ -89,4 +89,6 @@
     /** Magic value . */
     uint32_t    u32Magic;
+    /** Set if this is a record of environment changes, putenv style. */
+    bool        fPutEnvBlock;
     /** Number of variables in the array.
      * This does not include the terminating NULL entry. */
@@ -96,5 +98,8 @@
      * with the C library), so that c <= cCapacity - 1. */
     size_t      cAllocated;
-    /** Array of environment variables. */
+    /** Array of environment variables.
+     * These are always in "NAME=VALUE" form, where the value can be empty. If
+     * fPutEnvBlock is set though, there will be "NAME" entries too for variables
+     * that need to be removed when merged with another environment block. */
     char      **papszEnv;
     /** Array of environment variables in the process CP.
@@ -132,6 +137,10 @@
  * @param   fCaseSensitive  Whether the environment block is case sensitive or
  *                          not.
+ * @param   fPutEnvBlock    Indicates whether this is a special environment
+ *                          block that will be used to record change another
+ *                          block.  We will keep unsets in putenv format, i.e.
+ *                          just the variable name without any equal sign.
  */
-static int rtEnvCreate(PRTENVINTERNAL *ppIntEnv, size_t cAllocated, bool fCaseSensitive)
+static int rtEnvCreate(PRTENVINTERNAL *ppIntEnv, size_t cAllocated, bool fCaseSensitive, bool fPutEnvBlock)
 {
     /*
@@ -145,4 +154,5 @@
          */
         pIntEnv->u32Magic = RTENV_MAGIC;
+        pIntEnv->fPutEnvBlock = fPutEnvBlock;
         pIntEnv->pfnCompare = fCaseSensitive ? RTStrNCmp : RTStrNICmp;
         pIntEnv->papszEnvOtherCP = NULL;
@@ -166,5 +176,5 @@
 {
     AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
-    return rtEnvCreate(pEnv, RTENV_GROW_SIZE, false /*fCaseSensitive*/);
+    return rtEnvCreate(pEnv, RTENV_GROW_SIZE, false /*fCaseSensitive*/, false /*fPutEnvBlock*/);
 }
 RT_EXPORT_SYMBOL(RTEnvCreate);
@@ -221,4 +231,5 @@
      */
     bool fCaseSensitive = true;
+    bool fPutEnvBlock   = false;
     size_t cVars;
     const char * const *papszEnv;
@@ -263,4 +274,5 @@
         RTENV_LOCK(pIntEnvToClone);
 
+        fPutEnvBlock = pIntEnvToClone->fPutEnvBlock;
         papszEnv = pIntEnvToClone->papszEnv;
         cVars = pIntEnvToClone->cVars;
@@ -271,5 +283,5 @@
      */
     PRTENVINTERNAL pIntEnv;
-    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, fCaseSensitive);
+    int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, fCaseSensitive, fPutEnvBlock);
     if (RT_SUCCESS(rc))
     {
@@ -288,13 +300,23 @@
 #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;
-                else
-                {
-                    pIntEnv->cVars = iDst;
-                    RTEnvDestroy(pIntEnv);
-                    return rc2;
-                }
+                    continue;
+                }
+
+                /* failed fatally. */
+                pIntEnv->cVars = iDst;
+                RTEnvDestroy(pIntEnv);
+                return rc2;
             }
             pIntEnv->cVars = iDst;
@@ -361,4 +383,5 @@
     AssertReturn(*pszVar, VERR_INVALID_PARAMETER);
     AssertPtrReturn(pszValue, VERR_INVALID_POINTER);
+    AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);
 
     int rc;
@@ -415,5 +438,6 @@
             for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
                 if (    !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
-                    &&  pIntEnv->papszEnv[iVar][cchVar] == '=')
+                    &&  (   pIntEnv->papszEnv[iVar][cchVar] == '='
+                         || pIntEnv->papszEnv[iVar][cchVar] == '\0') )
                     break;
             if (iVar < pIntEnv->cVars)
@@ -470,4 +494,5 @@
     AssertPtrReturn(pszVar, VERR_INVALID_POINTER);
     AssertReturn(*pszVar, VERR_INVALID_PARAMETER);
+    AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);
 
     int rc;
@@ -507,11 +532,20 @@
         for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
             if (    !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
-                &&  pIntEnv->papszEnv[iVar][cchVar] == '=')
-            {
-                RTMemFree(pIntEnv->papszEnv[iVar]);
-                pIntEnv->cVars--;
-                if (pIntEnv->cVars > 0)
-                    pIntEnv->papszEnv[iVar] = pIntEnv->papszEnv[pIntEnv->cVars];
-                pIntEnv->papszEnv[pIntEnv->cVars] = NULL;
+                &&  (   pIntEnv->papszEnv[iVar][cchVar] == '='
+                     || pIntEnv->papszEnv[iVar][cchVar] == '\0') )
+            {
+                if (!pIntEnv->fPutEnvBlock)
+                {
+                    RTMemFree(pIntEnv->papszEnv[iVar]);
+                    pIntEnv->cVars--;
+                    if (pIntEnv->cVars > 0)
+                        pIntEnv->papszEnv[iVar] = pIntEnv->papszEnv[pIntEnv->cVars];
+                    pIntEnv->papszEnv[pIntEnv->cVars] = NULL;
+                }
+                else
+                {
+                    /* Record this unset by keeping the variable without any equal sign. */
+                    pIntEnv->papszEnv[iVar][cchVar] = '\0';
+                }
                 rc = VINF_SUCCESS;
                 /* no break, there could be more. */
@@ -532,4 +566,5 @@
     AssertPtrNullReturn(pcchActual, VERR_INVALID_POINTER);
     AssertReturn(pcchActual || (pszValue && cbValue), VERR_INVALID_PARAMETER);
+    AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);
 
     if (pcchActual)
@@ -592,20 +627,28 @@
         size_t iVar;
         for (iVar = 0; iVar < pIntEnv->cVars; iVar++)
-            if (    !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
-                &&  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->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;
+                }
             }
 
@@ -654,9 +697,13 @@
         const size_t cchVar = strlen(pszVar);
         for (size_t iVar = 0; iVar < pIntEnv->cVars; iVar++)
-            if (    !pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)
-                &&  pIntEnv->papszEnv[iVar][cchVar] == '=')
-            {
-                fExists = true;
-                break;
+            if (!pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar))
+            {
+                if (pIntEnv->papszEnv[iVar][cchVar] == '=')
+                {
+                    fExists = true;
+                    break;
+                }
+                if (pIntEnv->papszEnv[iVar][cchVar] == '\0')
+                    break;
             }
 
@@ -740,5 +787,5 @@
  * @param   pvUser              Ignored.
  */
-DECLCALLBACK(int) rtEnvSortCompare(const void *pvElement1, const void *pvElement2, void *pvUser)
+static DECLCALLBACK(int) rtEnvSortCompare(const void *pvElement1, const void *pvElement2, void *pvUser)
 {
     NOREF(pvUser);
@@ -863,5 +910,5 @@
 
 
-RTDECL(uint32_t) RTEnvGetByIndexEx(RTENV hEnv, uint32_t iVar, char *pszVar, size_t cbVar, char *pszValue, size_t cbValue)
+RTDECL(int) RTEnvGetByIndexEx(RTENV hEnv, uint32_t iVar, char *pszVar, size_t cbVar, char *pszValue, size_t cbValue)
 {
     PRTENVINTERNAL pIntEnv = hEnv;
@@ -882,10 +929,19 @@
         bool        fHasEqual   = pszSrcValue != NULL;
         if (pszSrcValue)
+        {
             pszSrcValue++;
+            rc = VINF_SUCCESS;
+        }
         else
+        {
             pszSrcValue = strchr(pszSrcVar, '\0');
-        rc = VINF_SUCCESS;
+            rc = VINF_ENV_VAR_UNSET;
+        }
         if (cbVar)
-            rc = RTStrCopyEx(pszVar, cbVar, pszSrcVar, pszSrcValue - pszSrcVar - fHasEqual);
+        {
+            int rc2 = RTStrCopyEx(pszVar, cbVar, pszSrcVar, pszSrcValue - pszSrcVar - fHasEqual);
+            if (RT_FAILURE(rc2))
+                rc = rc2;
+        }
         if (cbValue)
         {
@@ -904,2 +960,64 @@
 RT_EXPORT_SYMBOL(RTEnvGetByIndexEx);
 
+
+RTDECL(const char *) RTEnvGetByIndexRawEx(RTENV hEnv, uint32_t iVar)
+{
+    PRTENVINTERNAL pIntEnv = hEnv;
+    AssertPtrReturn(pIntEnv, NULL);
+    AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, NULL);
+
+    RTENV_LOCK(pIntEnv);
+
+    const char *pszRet;
+    if (iVar < pIntEnv->cVars)
+        pszRet = pIntEnv->papszEnv[iVar];
+    else
+        pszRet = NULL;
+
+    RTENV_UNLOCK(pIntEnv);
+
+    return pszRet;
+}
+RT_EXPORT_SYMBOL(RTEnvGetByIndexRawEx);
+
+
+RTDECL(int) RTEnvCreateChangeRecord(PRTENV phEnv)
+{
+    AssertPtrReturn(phEnv, VERR_INVALID_POINTER);
+    return rtEnvCreate(phEnv, RTENV_GROW_SIZE, false /*fCaseSensitive*/, true /*fPutEnvBlock*/);
+}
+RT_EXPORT_SYMBOL(RTEnvCreateChangeRecord);
+
+
+RTDECL(bool) RTEnvIsChangeRecord(RTENV hEnv)
+{
+    if (hEnv == RTENV_DEFAULT)
+        return false;
+
+    PRTENVINTERNAL pIntEnv = hEnv;
+    AssertPtrReturn(pIntEnv, false);
+    AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, false);
+    return pIntEnv->fPutEnvBlock;
+}
+RT_EXPORT_SYMBOL(RTEnvIsChangeRecord);
+
+
+RTDECL(int) RTEnvApplyChanges(RTENV hEnvDst, RTENV hEnvChanges)
+{
+    PRTENVINTERNAL pIntEnvChanges = hEnvChanges;
+    AssertPtrReturn(pIntEnvChanges, VERR_INVALID_HANDLE);
+    AssertReturn(pIntEnvChanges->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE);
+
+    /** @todo lock validator trouble ahead here! */
+    RTENV_LOCK(pIntEnvChanges);
+
+    int rc = VINF_SUCCESS;
+    for (uint32_t iChange = 0; iChange < pIntEnvChanges->cVars && RT_SUCCESS(rc); iChange++)
+        rc = RTEnvPutEx(hEnvDst, pIntEnvChanges->papszEnv[iChange]);
+
+    RTENV_UNLOCK(pIntEnvChanges);
+
+    return rc;
+}
+RT_EXPORT_SYMBOL(RTEnvApplyChanges);
+
Index: /trunk/src/VBox/Runtime/r3/posix/env-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/env-posix.cpp	(revision 55561)
+++ /trunk/src/VBox/Runtime/r3/posix/env-posix.cpp	(revision 55562)
@@ -49,4 +49,5 @@
 RTDECL(bool) RTEnvExistsBad(const char *pszVar)
 {
+    AssertReturn(strchr(pszVar, '=') == NULL, false);
     return RTEnvGetBad(pszVar) != NULL;
 }
@@ -61,4 +62,6 @@
 RTDECL(const char *) RTEnvGetBad(const char *pszVar)
 {
+    AssertReturn(strchr(pszVar, '=') == NULL, NULL);
+
     IPRT_ALIGNMENT_CHECKS_DISABLE(); /* glibc causes trouble */
     const char *pszValue = getenv(pszVar);
@@ -91,4 +94,6 @@
 RTDECL(int) RTEnvSetBad(const char *pszVar, const char *pszValue)
 {
+    AssertMsgReturn(strchr(pszVar, '=') == NULL, ("'%s'\n", pszVar), VERR_ENV_INVALID_VAR_NAME);
+
 #if defined(_MSC_VER)
     /* make a local copy and feed it to putenv. */
@@ -125,5 +130,5 @@
 RTDECL(int) RTEnvUnsetBad(const char *pszVar)
 {
-    AssertReturn(!strchr(pszVar, '='), VERR_INVALID_PARAMETER);
+    AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);
 
     /*
Index: /trunk/src/VBox/Runtime/r3/win/env-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/env-win.cpp	(revision 55561)
+++ /trunk/src/VBox/Runtime/r3/win/env-win.cpp	(revision 55562)
@@ -54,4 +54,6 @@
 RTDECL(bool) RTEnvExistsUtf8(const char *pszVar)
 {
+    AssertReturn(strchr(pszVar, '=') == NULL, false);
+
     PRTUTF16 pwszVar;
     int rc = RTStrToUtf16(pszVar, &pwszVar);
@@ -65,4 +67,5 @@
 RTDECL(const char *) RTEnvGetBad(const char *pszVar)
 {
+    AssertReturn(strchr(pszVar, '=') == NULL, NULL);
     return getenv(pszVar);
 }
@@ -81,4 +84,5 @@
     AssertPtrNullReturn(pcchActual, VERR_INVALID_POINTER);
     AssertReturn(pcchActual || (pszValue && cbValue), VERR_INVALID_PARAMETER);
+    AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);
 
     if (pcchActual)
@@ -87,5 +91,5 @@
     PRTUTF16 pwszVar;
     int rc = RTStrToUtf16(pszVar, &pwszVar);
-    AssertRCReturn(rc, false);
+    AssertRCReturn(rc, rc);
 
     /** @todo Consider _wgetenv_s or GetEnvironmentVariableW here to avoid the
@@ -140,4 +144,6 @@
 RTDECL(int) RTEnvSetBad(const char *pszVar, const char *pszValue)
 {
+    AssertMsgReturn(strchr(pszVar, '=') == NULL, ("'%s'\n", pszVar), VERR_ENV_INVALID_VAR_NAME);
+
     /* make a local copy and feed it to putenv. */
     const size_t cchVar = strlen(pszVar);
@@ -167,4 +173,6 @@
 RTDECL(int) RTEnvSetUtf8(const char *pszVar, const char *pszValue)
 {
+    AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);
+
     size_t cwcVar;
     int rc = RTStrCalcUtf16LenEx(pszVar, RTSTR_MAX, &cwcVar);
@@ -204,5 +212,5 @@
 RTDECL(int) RTEnvUnsetBad(const char *pszVar)
 {
-    AssertReturn(!strchr(pszVar, '='), VERR_INVALID_PARAMETER);
+    AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);
 
     /*
@@ -244,4 +252,6 @@
 RTDECL(int) RTEnvUnsetUtf8(const char *pszVar)
 {
+    AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME);
+
     size_t cwcVar;
     int rc = RTStrCalcUtf16LenEx(pszVar, RTSTR_MAX, &cwcVar);
