ntdll: Set the Wine paths environment variables from the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
36e55720b6
commit
438abad27c
163
dlls/ntdll/env.c
163
dlls/ntdll/env.c
|
@ -60,24 +60,6 @@ static inline SIZE_T get_env_length( const WCHAR *env )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* is_special_env_var
|
||||
*
|
||||
* Check if an environment variable needs to be handled specially when
|
||||
* passed through the Unix environment (i.e. prefixed with "WINE").
|
||||
*/
|
||||
static inline BOOL is_special_env_var( const char *var )
|
||||
{
|
||||
return (!strncmp( var, "PATH=", sizeof("PATH=")-1 ) ||
|
||||
!strncmp( var, "PWD=", sizeof("PWD=")-1 ) ||
|
||||
!strncmp( var, "HOME=", sizeof("HOME=")-1 ) ||
|
||||
!strncmp( var, "TEMP=", sizeof("TEMP=")-1 ) ||
|
||||
!strncmp( var, "TMP=", sizeof("TMP=")-1 ) ||
|
||||
!strncmp( var, "QT_", sizeof("QT_")-1 ) ||
|
||||
!strncmp( var, "VK_", sizeof("VK_")-1 ));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_env_var
|
||||
*/
|
||||
|
@ -86,8 +68,12 @@ static void set_env_var( WCHAR **env, const WCHAR *name, const WCHAR *val )
|
|||
UNICODE_STRING nameW, valW;
|
||||
|
||||
RtlInitUnicodeString( &nameW, name );
|
||||
RtlInitUnicodeString( &valW, val );
|
||||
RtlSetEnvironmentVariable( env, &nameW, &valW );
|
||||
if (val)
|
||||
{
|
||||
RtlInitUnicodeString( &valW, val );
|
||||
RtlSetEnvironmentVariable( env, &nameW, &valW );
|
||||
}
|
||||
else RtlSetEnvironmentVariable( env, &nameW, NULL );
|
||||
}
|
||||
|
||||
|
||||
|
@ -322,24 +308,6 @@ static void set_additional_environment( WCHAR **env )
|
|||
}
|
||||
|
||||
|
||||
/* set an environment variable for one of the wine path variables */
|
||||
static void set_wine_path_variable( WCHAR **env, const WCHAR *name, const char *unix_path )
|
||||
{
|
||||
UNICODE_STRING nt_name, var_name;
|
||||
ANSI_STRING unix_name;
|
||||
|
||||
RtlInitUnicodeString( &var_name, name );
|
||||
if (unix_path)
|
||||
{
|
||||
RtlInitAnsiString( &unix_name, unix_path );
|
||||
if (wine_unix_to_nt_file_name( &unix_name, &nt_name )) return;
|
||||
RtlSetEnvironmentVariable( env, &var_name, &nt_name );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
}
|
||||
else RtlSetEnvironmentVariable( env, &var_name, NULL );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_wow64_environment
|
||||
*
|
||||
|
@ -366,12 +334,6 @@ static void set_wow64_environment( WCHAR **env )
|
|||
static const WCHAR commonfilesW[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','F','i','l','e','s',0};
|
||||
static const WCHAR commonfiles86W[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','F','i','l','e','s','(','x','8','6',')',0};
|
||||
static const WCHAR commonw6432W[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','W','6','4','3','2',0};
|
||||
static const WCHAR winedlldirW[] = {'W','I','N','E','D','L','L','D','I','R','%','u',0};
|
||||
static const WCHAR winehomedirW[] = {'W','I','N','E','H','O','M','E','D','I','R',0};
|
||||
static const WCHAR winedatadirW[] = {'W','I','N','E','D','A','T','A','D','I','R',0};
|
||||
static const WCHAR winebuilddirW[] = {'W','I','N','E','B','U','I','L','D','D','I','R',0};
|
||||
static const WCHAR wineusernameW[] = {'W','I','N','E','U','S','E','R','N','A','M','E',0};
|
||||
static const WCHAR wineconfigdirW[] = {'W','I','N','E','C','O','N','F','I','G','D','I','R',0};
|
||||
|
||||
WCHAR buf[256];
|
||||
UNICODE_STRING arch_strW = { sizeof(archW) - sizeof(WCHAR), sizeof(archW), archW };
|
||||
|
@ -379,47 +341,23 @@ static void set_wow64_environment( WCHAR **env )
|
|||
UNICODE_STRING valW = { 0, sizeof(buf), buf };
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
const char *p;
|
||||
const char *home = getenv( "HOME" );
|
||||
const char *name = getenv( "USER" );
|
||||
const char **dll_paths;
|
||||
SIZE_T dll_path_maxlen;
|
||||
WCHAR *val;
|
||||
HANDLE hkey;
|
||||
DWORD i;
|
||||
SIZE_T size = 1024;
|
||||
WCHAR *ptr, *val, *p;
|
||||
|
||||
if (!home || !name)
|
||||
for (;;)
|
||||
{
|
||||
struct passwd *pwd = getpwuid( getuid() );
|
||||
if (pwd)
|
||||
{
|
||||
if (!home) home = pwd->pw_dir;
|
||||
if (!name) name = pwd->pw_name;
|
||||
}
|
||||
if (!(ptr = RtlAllocateHeap( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) break;
|
||||
if (!unix_funcs->get_dynamic_environment( ptr, &size )) break;
|
||||
RtlFreeHeap( GetProcessHeap(), 0, ptr );
|
||||
}
|
||||
|
||||
/* set the Wine paths */
|
||||
|
||||
set_wine_path_variable( env, winedatadirW, data_dir );
|
||||
set_wine_path_variable( env, winehomedirW, home );
|
||||
set_wine_path_variable( env, winebuilddirW, build_dir );
|
||||
set_wine_path_variable( env, wineconfigdirW, config_dir );
|
||||
unix_funcs->get_dll_path( &dll_paths, &dll_path_maxlen );
|
||||
for (i = 0; dll_paths[i]; i++)
|
||||
for (p = ptr; *p; p += wcslen(p) + 1)
|
||||
{
|
||||
NTDLL_swprintf( buf, winedlldirW, i );
|
||||
set_wine_path_variable( env, buf, dll_paths[i] );
|
||||
if ((val = wcschr( p, '=' ))) *val++ = 0;
|
||||
set_env_var( env, p, val );
|
||||
if (val) p = val;
|
||||
}
|
||||
NTDLL_swprintf( buf, winedlldirW, i );
|
||||
set_wine_path_variable( env, buf, NULL );
|
||||
|
||||
/* set user name */
|
||||
|
||||
if (!name) name = "wine";
|
||||
if ((p = strrchr( name, '/' ))) name = p + 1;
|
||||
if ((p = strrchr( name, '\\' ))) name = p + 1;
|
||||
ntdll_umbstowcs( name, strlen(name) + 1, buf, ARRAY_SIZE(buf) );
|
||||
set_env_var( env, wineusernameW, buf );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, ptr );
|
||||
|
||||
/* set the PROCESSOR_ARCHITECTURE variable */
|
||||
|
||||
|
@ -500,73 +438,6 @@ static WCHAR *build_initial_environment( WCHAR **wargv[] )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* build_envp
|
||||
*
|
||||
* Build the environment of a new child process.
|
||||
*/
|
||||
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;
|
||||
|
||||
lenW = get_env_length( envW );
|
||||
if (!(env = RtlAllocateHeap( GetProcessHeap(), 0, lenW * 3 ))) return NULL;
|
||||
length = ntdll_wcstoumbs( envW, lenW, env, lenW * 3, FALSE );
|
||||
|
||||
for (p = env; *p; p += strlen(p) + 1, count++)
|
||||
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 = RtlAllocateHeap( GetProcessHeap(), 0, 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 (!strncmp( p, "WINEPRELOADRESERVE=", sizeof("WINEPRELOADRESERVE=")-1 )) continue;
|
||||
if (!strncmp( p, "WINELOADERNOEXEC=", sizeof("WINELOADERNOEXEC=")-1 )) continue;
|
||||
if (!strncmp( p, "WINESERVERSOCKET=", sizeof("WINESERVERSOCKET=")-1 )) 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;
|
||||
}
|
||||
RtlFreeHeap( GetProcessHeap(), 0, env );
|
||||
return envp;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_current_directory
|
||||
*
|
||||
|
|
|
@ -70,13 +70,9 @@ extern void heap_set_debug_flags( HANDLE handle ) DECLSPEC_HIDDEN;
|
|||
extern void init_unix_codepage(void) DECLSPEC_HIDDEN;
|
||||
extern void init_locale( HMODULE module ) DECLSPEC_HIDDEN;
|
||||
extern void init_user_process_params( SIZE_T data_size ) DECLSPEC_HIDDEN;
|
||||
extern char **build_envp( const WCHAR *envW ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS restart_process( RTL_USER_PROCESS_PARAMETERS *params, NTSTATUS status ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* server support */
|
||||
extern const char *build_dir DECLSPEC_HIDDEN;
|
||||
extern const char *data_dir DECLSPEC_HIDDEN;
|
||||
extern const char *config_dir DECLSPEC_HIDDEN;
|
||||
extern BOOL is_wow64 DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret,
|
||||
data_size_t *ret_len ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -36,10 +36,6 @@
|
|||
#include "wine/debug.h"
|
||||
#include "ntdll_misc.h"
|
||||
|
||||
const char *build_dir = NULL;
|
||||
const char *data_dir = NULL;
|
||||
const char *config_dir = NULL;
|
||||
|
||||
BOOL is_wow64 = FALSE;
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -136,7 +136,6 @@ TEB *thread_init( SIZE_T *info_size )
|
|||
*/
|
||||
peb->SessionId = 1;
|
||||
|
||||
unix_funcs->get_paths( &build_dir, &data_dir, &config_dir );
|
||||
NtQueryInformationProcess( GetCurrentProcess(), ProcessWow64Information, &val, sizeof(val), NULL );
|
||||
is_wow64 = !!val;
|
||||
return teb;
|
||||
|
|
|
@ -841,6 +841,88 @@ NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *siz
|
|||
}
|
||||
|
||||
|
||||
/* append a variable to the environment */
|
||||
static void append_env( WCHAR *env, SIZE_T *pos, const char *name, const WCHAR *value )
|
||||
{
|
||||
SIZE_T i = *pos;
|
||||
|
||||
while (*name) env[i++] = (unsigned char)*name++;
|
||||
if (value)
|
||||
{
|
||||
env[i++] = '=';
|
||||
while (*value) env[i++] = *value++;
|
||||
}
|
||||
env[i++] = 0;
|
||||
*pos = i;
|
||||
}
|
||||
|
||||
/* set an environment variable for one of the wine path variables */
|
||||
static void add_path_var( WCHAR *env, SIZE_T *pos, const char *name, const char *path )
|
||||
{
|
||||
UNICODE_STRING nt_name;
|
||||
ANSI_STRING unix_name;
|
||||
|
||||
if (!path) append_env( env, pos, name, NULL );
|
||||
else
|
||||
{
|
||||
RtlInitAnsiString( &unix_name, path );
|
||||
if (unix_to_nt_file_name( &unix_name, &nt_name )) return;
|
||||
append_env( env, pos, name, nt_name.Buffer );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* get_dynamic_environment
|
||||
*
|
||||
* Get the environment variables that can differ between processes.
|
||||
*/
|
||||
NTSTATUS CDECL get_dynamic_environment( WCHAR *env, SIZE_T *size )
|
||||
{
|
||||
SIZE_T alloc, pos = 0;
|
||||
WCHAR *buffer;
|
||||
DWORD i;
|
||||
WCHAR buf[256];
|
||||
char dlldir[22];
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
||||
alloc = 20 * 6; /* 6 variable names */
|
||||
if (data_dir) alloc += strlen( data_dir ) + 9;
|
||||
if (home_dir) alloc += strlen( home_dir ) + 9;
|
||||
if (build_dir) alloc += strlen( build_dir ) + 9;
|
||||
if (config_dir) alloc += strlen( config_dir ) + 9;
|
||||
if (user_name) alloc += strlen( user_name );
|
||||
for (i = 0; dll_paths[i]; i++) alloc += 20 + strlen( dll_paths[i] ) + 9;
|
||||
|
||||
if (!(buffer = malloc( alloc * sizeof(WCHAR) ))) return STATUS_NO_MEMORY;
|
||||
pos = 0;
|
||||
add_path_var( buffer, &pos, "WINEDATADIR", data_dir );
|
||||
add_path_var( buffer, &pos, "WINEHOMEDIR", home_dir );
|
||||
add_path_var( buffer, &pos, "WINEBUILDDIR", build_dir );
|
||||
add_path_var( buffer, &pos, "WINECONFIGDIR", config_dir );
|
||||
for (i = 0; dll_paths[i]; i++)
|
||||
{
|
||||
sprintf( dlldir, "WINEDLLDIR%u", i );
|
||||
add_path_var( buffer, &pos, dlldir, dll_paths[i] );
|
||||
}
|
||||
sprintf( dlldir, "WINEDLLDIR%u", i );
|
||||
append_env( buffer, &pos, dlldir, NULL );
|
||||
ntdll_umbstowcs( user_name, strlen(user_name) + 1, buf, ARRAY_SIZE(buf) );
|
||||
append_env( buffer, &pos, "WINEUSERNAME", buf );
|
||||
assert( pos <= alloc );
|
||||
|
||||
if (pos < *size)
|
||||
{
|
||||
memcpy( env, buffer, pos * sizeof(WCHAR) );
|
||||
env[pos] = 0;
|
||||
}
|
||||
else status = STATUS_BUFFER_TOO_SMALL;
|
||||
*size = pos + 1;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* get_initial_directory
|
||||
*
|
||||
|
|
|
@ -120,13 +120,13 @@ static const BOOL is_win64 = (sizeof(void *) > sizeof(int));
|
|||
static char *argv0;
|
||||
static const char *bin_dir;
|
||||
static const char *dll_dir;
|
||||
static const char **dll_paths;
|
||||
static SIZE_T dll_path_maxlen;
|
||||
|
||||
const char *home_dir = NULL;
|
||||
const char *data_dir = NULL;
|
||||
const char *build_dir = NULL;
|
||||
const char *config_dir = NULL;
|
||||
const char **dll_paths = NULL;
|
||||
const char *user_name = NULL;
|
||||
HMODULE ntdll_module = NULL;
|
||||
|
||||
|
@ -400,31 +400,6 @@ void CDECL get_host_version( const char **sysname, const char **release )
|
|||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* get_paths
|
||||
*
|
||||
* Return the various configuration paths.
|
||||
*/
|
||||
static void CDECL get_paths( const char **builddir, const char **datadir, const char **configdir )
|
||||
{
|
||||
*builddir = build_dir;
|
||||
*datadir = data_dir;
|
||||
*configdir = config_dir;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* get_dll_path
|
||||
*
|
||||
* Return the various configuration paths.
|
||||
*/
|
||||
static void CDECL get_dll_path( const char ***paths, SIZE_T *maxlen )
|
||||
{
|
||||
*paths = dll_paths;
|
||||
*maxlen = dll_path_maxlen;
|
||||
}
|
||||
|
||||
|
||||
static void preloader_exec( char **argv )
|
||||
{
|
||||
if (use_preloader)
|
||||
|
@ -1491,9 +1466,8 @@ static struct unix_funcs unix_funcs =
|
|||
fast_RtlSleepConditionVariableCS,
|
||||
fast_RtlWakeConditionVariable,
|
||||
get_initial_environment,
|
||||
get_dynamic_environment,
|
||||
get_initial_directory,
|
||||
get_paths,
|
||||
get_dll_path,
|
||||
get_unix_codepage,
|
||||
get_locales,
|
||||
get_version,
|
||||
|
|
|
@ -96,6 +96,7 @@ int CDECL mmap_is_in_reserved_area( void *addr, SIZE_T size ) DECLSPEC_HIDDEN;
|
|||
int CDECL mmap_enum_reserved_areas( int (CDECL *enum_func)(void *base, SIZE_T size, void *arg), void *arg,
|
||||
int top_down ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *size ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL get_dynamic_environment( WCHAR *env, SIZE_T *size ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_initial_directory( UNICODE_STRING *dir ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_unix_codepage( CPTABLEINFO *table ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_locales( WCHAR *sys, WCHAR *user ) DECLSPEC_HIDDEN;
|
||||
|
@ -129,6 +130,7 @@ extern const char *data_dir DECLSPEC_HIDDEN;
|
|||
extern const char *build_dir DECLSPEC_HIDDEN;
|
||||
extern const char *config_dir DECLSPEC_HIDDEN;
|
||||
extern const char *user_name DECLSPEC_HIDDEN;
|
||||
extern const char **dll_paths DECLSPEC_HIDDEN;
|
||||
extern HMODULE ntdll_module DECLSPEC_HIDDEN;
|
||||
extern USHORT *uctable DECLSPEC_HIDDEN;
|
||||
extern USHORT *lctable DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -28,7 +28,7 @@ struct ldt_copy;
|
|||
struct msghdr;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 60
|
||||
#define NTDLL_UNIXLIB_VERSION 61
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -285,9 +285,8 @@ struct unix_funcs
|
|||
|
||||
/* environment functions */
|
||||
NTSTATUS (CDECL *get_initial_environment)( WCHAR **wargv[], WCHAR *env, SIZE_T *size );
|
||||
NTSTATUS (CDECL *get_dynamic_environment)( WCHAR *env, SIZE_T *size );
|
||||
void (CDECL *get_initial_directory)( UNICODE_STRING *dir );
|
||||
void (CDECL *get_paths)( const char **builddir, const char **datadir, const char **configdir );
|
||||
void (CDECL *get_dll_path)( const char ***paths, SIZE_T *maxlen );
|
||||
void (CDECL *get_unix_codepage)( CPTABLEINFO *table );
|
||||
void (CDECL *get_locales)( WCHAR *sys, WCHAR *user );
|
||||
const char * (CDECL *get_version)(void);
|
||||
|
|
Loading…
Reference in New Issue