Because WINENV is limited (32767 bytes), and HOSTENV can be much larger, a whitelisting approach is used to keep WINENV as small as possible. Currently, only the following envvars are propagated from the host env to WINENV WINEPATH, WINEPWD, WINEHOME, WINETEMP, WINETMP, WINEQT_, WINEVK_, WINEXDG_SESSION_TYPE
Moreover, the NIXENV (env for running wine processes - not applications) on the host system is not produced from WINENV anymore, but the global ENV is propagated to all wine processes and threads.
This might be an alternative approach to MR!5231, MR!6140, bug #56941 and should provide a more deterministic behaviour of wine, because unrelated envvars do have no influence on the env for running windows applications.
Initial tests (winemine, notepad, cmd, etc) seem to run fine, but some envvars might need additional consideration. XVDK_* was mentioned, WINE*, MESA_*, VK_*, QT_*, LIBGL_* are other suspects.
Moreover, this is my first merge request, so your feedback is highly appreciated.
-- v23: ntdll: main_envp has been replaced by environ ntdll: remove is_dynamic_env_var(...) because it is not needed anymore ntdll: remove unused vars ntdll: remove dead code ntdll: conversion from HOSTENV to WINENV is now using whitelisting instead of blacklisting of envvars currently only envvars "WINE"<special_var> (as defined in is_special_env_var() ) are whitelisted. ntdll: separate env for windows applications (WINENV) from env for wine processes (NIXENV) WINENV is typically limited to 32767 WCHAR, the host environment where wine processes are running can be much larger. Keeping the two envs separate enables a more granula handling of envvars. (see also MR!5231, MR!6140, bug #56941)
From: Alois SCHLOEGL alois.schloegl@gmail.com
--- dlls/ntdll/unix/env.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index 7193cceb87e..04d6fda5100 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -489,6 +489,8 @@ const char *ntdll_get_data_dir(void) * build_envp * * Build the environment of a new child process. + * converts WINENV (WCHAR*) to NIXENV (char*) + * Use HOSTENV stored in global var main_envp */ char **build_envp( const WCHAR *envW ) { @@ -498,6 +500,12 @@ char **build_envp( const WCHAR *envW ) int count = 1, length, lenW; unsigned int i;
+#if 1 + /* to not convert from WINENV but use HOSTENV */ + return main_envp; +#else + + /* convert WINENV to NIXENV */ lenW = get_env_length( envW ); if (!(env = malloc( lenW * 3 ))) return NULL; length = ntdll_wcstoumbs( envW, lenW, env, lenW * 3, FALSE ); @@ -550,6 +558,7 @@ char **build_envp( const WCHAR *envW ) } free( env ); return envp; +#endif }
From: Alois SCHLOEGL alois.schloegl@gmail.com
--- dlls/ntdll/unix/env.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index 04d6fda5100..8015e983afd 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -936,6 +936,13 @@ static const char overrides_help_message[] = * get_initial_environment * * Return the initial environment. + * converts HOSTENV (char*) to WINENV (WCHAR*) + * HOSTENV is stored in global var main_envp + * WINENV is returned in *env. + * pos: returns size [in WCHAR] of win environment + * size: returns size [in bytes] of host environment + * return value is host env converted to win env + with special and dynamic envvars beeing ignored */ static WCHAR *get_initial_environment( SIZE_T *pos, SIZE_T *size ) { @@ -965,6 +972,12 @@ static WCHAR *get_initial_environment( SIZE_T *pos, SIZE_T *size ) } else if (is_special_env_var( str )) continue; /* skip it */
+#if 1 + // do whitelisting instead of blacklisting of envvars + // prevents propagating nixenv to winenv, except "WINE"+special-env-var + else continue; +#endif + if (is_dynamic_env_var( str )) continue; ptr += ntdll_umbstowcs( str, strlen(str) + 1, ptr, end - ptr ); }
From: Alois Schlögl alois.schloegl@gmail.com
--- dlls/ntdll/unix/env.c | 72 +++---------------------------------------- 1 file changed, 4 insertions(+), 68 deletions(-)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index 8015e983afd..b4ab2cf6eb2 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -500,65 +500,8 @@ char **build_envp( const WCHAR *envW ) int count = 1, length, lenW; unsigned int i;
-#if 1 /* to not convert from WINENV but use HOSTENV */ return main_envp; -#else - - /* convert WINENV to NIXENV */ - lenW = get_env_length( envW ); - if (!(env = malloc( lenW * 3 ))) return NULL; - length = ntdll_wcstoumbs( envW, lenW, env, lenW * 3, FALSE ); - - for (p = env; *p; p += strlen(p) + 1, count++) - { - if (is_dynamic_env_var( p )) continue; - if (is_special_env_var( p )) length += 4; /* prefix it with "WINE" */ - } - - for (i = 0; i < ARRAY_SIZE( unix_vars ); i++) - { - if (!(p = getenv(unix_vars[i]))) continue; - length += strlen(unix_vars[i]) + strlen(p) + 2; - count++; - } - - if ((envp = malloc( count * sizeof(*envp) + length ))) - { - char **envptr = envp; - char *dst = (char *)(envp + count); - - /* some variables must not be modified, so we get them directly from the unix env */ - for (i = 0; i < ARRAY_SIZE( unix_vars ); i++) - { - if (!(p = getenv( unix_vars[i] ))) continue; - *envptr++ = strcpy( dst, unix_vars[i] ); - strcat( dst, "=" ); - strcat( dst, p ); - dst += strlen(dst) + 1; - } - - /* now put the Windows environment strings */ - for (p = env; *p; p += strlen(p) + 1) - { - if (*p == '=') continue; /* skip drive curdirs, this crashes some unix apps */ - if (is_dynamic_env_var( p )) continue; - if (is_special_env_var( p )) /* prefix it with "WINE" */ - { - *envptr++ = strcpy( dst, "WINE" ); - strcat( dst, p ); - } - else - { - *envptr++ = strcpy( dst, p ); - } - dst += strlen(dst) + 1; - } - *envptr = 0; - } - free( env ); - return envp; -#endif }
@@ -963,23 +906,16 @@ static WCHAR *get_initial_environment( SIZE_T *pos, SIZE_T *size ) /* skip Unix special variables and use the Wine variants instead */ if (!strncmp( str, "WINE", 4 )) { - if (is_special_env_var( str + 4 )) str += 4; + if (is_special_env_var( str + 4 )) { + str += 4; + ptr += ntdll_umbstowcs( str, strlen(str) + 1, ptr, end - ptr ); + } else if (!strcmp( str, "WINEDLLOVERRIDES=help" )) { MESSAGE( overrides_help_message ); exit(0); } } - else if (is_special_env_var( str )) continue; /* skip it */ - -#if 1 - // do whitelisting instead of blacklisting of envvars - // prevents propagating nixenv to winenv, except "WINE"+special-env-var - else continue; -#endif - - if (is_dynamic_env_var( str )) continue; - ptr += ntdll_umbstowcs( str, strlen(str) + 1, ptr, end - ptr ); } *pos = ptr - env; return env;
From: Alois Schlögl alois.schloegl@gmail.com
--- dlls/ntdll/unix/env.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index b4ab2cf6eb2..dc1a9fd2e62 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -494,12 +494,6 @@ const char *ntdll_get_data_dir(void) */ char **build_envp( const WCHAR *envW ) { - static const char * const unix_vars[] = { "PATH", "TEMP", "TMP", "HOME" }; - char **envp; - char *env, *p; - int count = 1, length, lenW; - unsigned int i; - /* to not convert from WINENV but use HOSTENV */ return main_envp; }
From: Alois Schlögl alois.schloegl@gmail.com
--- dlls/ntdll/unix/env.c | 18 ------------------ 1 file changed, 18 deletions(-)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index dc1a9fd2e62..7ca4f48c625 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -349,24 +349,6 @@ static BOOL is_special_env_var( const char *var ) STARTS_WITH( var, "XDG_SESSION_TYPE=" )); }
-/* check if an environment variable changes dynamically in every new process */ -static BOOL is_dynamic_env_var( const char *var ) -{ - return (STARTS_WITH( var, "WINEDLLOVERRIDES=" ) || - STARTS_WITH( var, "WINEDATADIR=" ) || - STARTS_WITH( var, "WINEHOMEDIR=" ) || - STARTS_WITH( var, "WINEBUILDDIR=" ) || - STARTS_WITH( var, "WINECONFIGDIR=" ) || - STARTS_WITH( var, "WINELOADER=" ) || - STARTS_WITH( var, "WINEDLLDIR" ) || - STARTS_WITH( var, "WINEUNIXCP=" ) || - STARTS_WITH( var, "WINEUSERLOCALE=" ) || - STARTS_WITH( var, "WINEUSERNAME=" ) || - STARTS_WITH( var, "WINEPRELOADRESERVE=" ) || - STARTS_WITH( var, "WINELOADERNOEXEC=" ) || - STARTS_WITH( var, "WINESERVERSOCKET=" )); -} - /****************************************************************** * ntdll_umbstowcs (ntdll.so) *
From: Alois Schlögl alois.schloegl@gmail.com
--- dlls/ntdll/unix/env.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index 7ca4f48c625..91a4789b913 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -472,12 +472,12 @@ const char *ntdll_get_data_dir(void) * * Build the environment of a new child process. * converts WINENV (WCHAR*) to NIXENV (char*) - * Use HOSTENV stored in global var main_envp + * Use HOSTENV stored in global var environ */ char **build_envp( const WCHAR *envW ) { /* to not convert from WINENV but use HOSTENV */ - return main_envp; + return environ; }
@@ -856,7 +856,7 @@ static const char overrides_help_message[] = * * Return the initial environment. * converts HOSTENV (char*) to WINENV (WCHAR*) - * HOSTENV is stored in global var main_envp + * HOSTENV is stored in global var environ * WINENV is returned in *env. * pos: returns size [in WCHAR] of win environment * size: returns size [in bytes] of host environment