Alexandre Julliard : ntdll: Avoid using wine_get_config_dir() from libwine.

Alexandre Julliard julliard at winehq.org
Mon Apr 27 15:19:29 CDT 2020


Module: wine
Branch: master
Commit: e5030a4ac0a303d6788ae79ffdcd88e66cf78bd2
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=e5030a4ac0a303d6788ae79ffdcd88e66cf78bd2

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Apr 27 12:34:07 2020 +0200

ntdll: Avoid using wine_get_config_dir() from libwine.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/directory.c  |   7 +---
 dlls/ntdll/env.c        |   2 +-
 dlls/ntdll/ntdll_misc.h |   1 +
 dlls/ntdll/server.c     | 101 +++++++++++++++++++++++++++++++++---------------
 4 files changed, 72 insertions(+), 39 deletions(-)

diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index b8cfe507ed..1adc0c9b0d 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -106,7 +106,6 @@
 #include "ntdll_misc.h"
 #include "wine/server.h"
 #include "wine/list.h"
-#include "wine/library.h"
 #include "wine/debug.h"
 #include "wine/exception.h"
 
@@ -564,7 +563,6 @@ unsigned int DIR_get_drives_info( struct drive_info info[MAX_DOS_DRIVES] )
     RtlEnterCriticalSection( &dir_section );
     if (now != last_update)
     {
-        const char *config_dir = wine_get_config_dir();
         char *buffer, *p;
         struct stat st;
         unsigned int i;
@@ -1261,7 +1259,7 @@ static DWORD WINAPI init_options( RTL_RUN_ONCE *once, void *param, void **contex
     NtClose( root );
 
     /* a couple of directories that we don't want to return in directory searches */
-    ignore_file( wine_get_config_dir() );
+    ignore_file( config_dir );
     ignore_file( "/dev" );
     ignore_file( "/proc" );
 #ifdef linux
@@ -2219,7 +2217,6 @@ static unsigned int nb_redirects;
 static void init_redirects(void)
 {
     static const char windows_dir[] = "/dosdevices/c:/windows";
-    const char *config_dir = wine_get_config_dir();
     char *dir;
     struct stat st;
 
@@ -2322,7 +2319,6 @@ void init_directories(void)
  */
 static NTSTATUS get_dos_device( const WCHAR *name, UINT name_len, ANSI_STRING *unix_name_ret )
 {
-    const char *config_dir = wine_get_config_dir();
     struct stat st;
     char *unix_name, *new_name, *dev;
     unsigned int i;
@@ -2747,7 +2743,6 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRI
     static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, 0 };
 
     NTSTATUS status = STATUS_SUCCESS;
-    const char *config_dir = wine_get_config_dir();
     const WCHAR *name, *p;
     struct stat st;
     char *unix_name;
diff --git a/dlls/ntdll/env.c b/dlls/ntdll/env.c
index 6670786def..efb5270a2c 100644
--- a/dlls/ntdll/env.c
+++ b/dlls/ntdll/env.c
@@ -396,7 +396,7 @@ static void set_wow64_environment( WCHAR **env )
     set_wine_path_variable( env, winedatadirW, wine_get_data_dir() );
     set_wine_path_variable( env, winehomedirW, getenv("HOME") );
     set_wine_path_variable( env, winebuilddirW, wine_get_build_dir() );
-    set_wine_path_variable( env, wineconfigdirW, wine_get_config_dir() );
+    set_wine_path_variable( env, wineconfigdirW, config_dir );
     for (i = 0; (p = wine_dll_enum_load_path( i )); i++)
     {
         NTDLL_swprintf( buf, winedlldirW, i );
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 7dca506aad..11ff0d7bb3 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -104,6 +104,7 @@ extern char **__wine_main_argv;
 extern WCHAR **__wine_main_wargv;
 
 /* server support */
+extern const char *config_dir DECLSPEC_HIDDEN;
 extern timeout_t server_start_time DECLSPEC_HIDDEN;
 extern unsigned int server_cpus DECLSPEC_HIDDEN;
 extern BOOL is_wow64 DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index c0dd0f35fc..4beee9e6e1 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -34,6 +34,9 @@
 #ifdef HAVE_PTHREAD_NP_H
 # include <pthread_np.h>
 #endif
+#ifdef HAVE_PWD_H
+# include <pwd.h>
+#endif
 #include <signal.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -110,6 +113,8 @@ static const enum cpu_type client_cpu = CPU_ARM64;
 #error Unsupported CPU
 #endif
 
+const char *config_dir = NULL;
+
 unsigned int server_cpus = 0;
 BOOL is_wow64 = FALSE;
 
@@ -171,6 +176,17 @@ static void fatal_perror( const char *err, ... )
     exit(1);
 }
 
+/* build a path from the specified dir and name */
+static char *build_path( const char *dir, const char *name )
+{
+    size_t len = strlen( dir );
+    char *ret = malloc( len + strlen( name ) + 2 );
+
+    memcpy( ret, dir, len );
+    if (len && ret[len - 1] != '/') ret[len++] = '/';
+    strcpy( ret + len, name );
+    return ret;
+}
 
 /***********************************************************************
  *           server_protocol_error
@@ -1199,6 +1215,37 @@ static void start_server(void)
 }
 
 
+/***********************************************************************
+ *           init_config_dir
+ */
+static const char *init_config_dir(void)
+{
+    char *p, *dir;
+    const char *prefix = getenv( "WINEPREFIX" );
+
+    if (prefix)
+    {
+        if (prefix[0] != '/')
+            fatal_error( "invalid directory %s in WINEPREFIX: not an absolute path\n", prefix );
+        dir = strdup( prefix );
+        for (p = dir + strlen(dir) - 1; p > dir && *p == '/'; p--) *p = 0;
+    }
+    else
+    {
+        const char *home = getenv( "HOME" );
+        if (!home)
+        {
+            struct passwd *pwd = getpwuid( getuid() );
+            if (pwd) home = pwd->pw_dir;
+        }
+        if (!home) fatal_error( "could not determine your home directory\n" );
+        if (home[0] != '/') fatal_error( "your home directory %s is not an absolute path\n", home );
+        dir = build_path( home, ".wine" );
+    }
+    return dir;
+}
+
+
 /***********************************************************************
  *           setup_config_dir
  *
@@ -1206,46 +1253,38 @@ static void start_server(void)
  */
 static int setup_config_dir(void)
 {
-    const char *p, *config_dir = wine_get_config_dir();
+    char *p;
+    struct stat st;
     int fd_cwd = open( ".", O_RDONLY );
 
     if (chdir( config_dir ) == -1)
     {
-        if (errno != ENOENT) fatal_perror( "chdir to %s", config_dir );
-
+        if (errno != ENOENT) fatal_perror( "cannot use directory %s", config_dir );
         if ((p = strrchr( config_dir, '/' )) && p != config_dir)
         {
-            struct stat st;
-            char *tmp_dir;
-
-            if (!(tmp_dir = malloc( p + 1 - config_dir ))) fatal_error( "out of memory\n" );
-            memcpy( tmp_dir, config_dir, p - config_dir );
-            tmp_dir[p - config_dir] = 0;
-            if (!stat( tmp_dir, &st ) && st.st_uid != getuid())
+            while (p > config_dir + 1 && p[-1] == '/') p--;
+            *p = 0;
+            if (!stat( config_dir, &st ) && st.st_uid != getuid())
                 fatal_error( "'%s' is not owned by you, refusing to create a configuration directory there\n",
-                             tmp_dir );
-            free( tmp_dir );
+                             config_dir );
+            *p = '/';
         }
-
         mkdir( config_dir, 0777 );
         if (chdir( config_dir ) == -1) fatal_perror( "chdir to %s", config_dir );
-
         MESSAGE( "wine: created the configuration directory '%s'\n", config_dir );
     }
 
-    if (mkdir( "dosdevices", 0777 ) == -1)
+    if (stat( ".", &st ) == -1) fatal_perror( "stat %s", config_dir );
+    if (st.st_uid != getuid()) fatal_error( "'%s' is not owned by you\n", config_dir );
+
+    if (!mkdir( "dosdevices", 0777 ))
     {
-        if (errno == EEXIST) goto done;
-        fatal_perror( "cannot create %s/dosdevices", config_dir );
+        mkdir( "drive_c", 0777 );
+        symlink( "../drive_c", "dosdevices/c:" );
+        symlink( "/", "dosdevices/z:" );
     }
+    else if (errno != EEXIST) fatal_perror( "cannot create %s/dosdevices", config_dir );
 
-    /* create the drive symlinks */
-
-    mkdir( "drive_c", 0777 );
-    symlink( "../drive_c", "dosdevices/c:" );
-    symlink( "/", "dosdevices/z:" );
-
-done:
     if (fd_cwd == -1) fd_cwd = open( "dosdevices/c:", O_RDONLY );
     fcntl( fd_cwd, F_SETFD, FD_CLOEXEC );
     return fd_cwd;
@@ -1452,6 +1491,8 @@ void server_init_process(void)
     obj_handle_t version;
     const char *env_socket = getenv( "WINESERVERSOCKET" );
 
+    config_dir = init_config_dir();
+
     server_pid = -1;
     if (env_socket)
     {
@@ -1610,19 +1651,15 @@ size_t server_init_thread( void *entry_point, BOOL *suspend )
         if (arch)
         {
             if (!strcmp( arch, "win32" ) && (is_win64 || is_wow64))
-                fatal_error( "WINEARCH set to win32 but '%s' is a 64-bit installation.\n",
-                             wine_get_config_dir() );
+                fatal_error( "WINEARCH set to win32 but '%s' is a 64-bit installation.\n", config_dir );
             if (!strcmp( arch, "win64" ) && !is_win64 && !is_wow64)
-                fatal_error( "WINEARCH set to win64 but '%s' is a 32-bit installation.\n",
-                             wine_get_config_dir() );
+                fatal_error( "WINEARCH set to win64 but '%s' is a 32-bit installation.\n", config_dir );
         }
         return info_size;
     case STATUS_INVALID_IMAGE_WIN_64:
-        fatal_error( "'%s' is a 32-bit installation, it cannot support 64-bit applications.\n",
-                     wine_get_config_dir() );
+        fatal_error( "'%s' is a 32-bit installation, it cannot support 64-bit applications.\n", config_dir );
     case STATUS_NOT_SUPPORTED:
-        fatal_error( "'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.\n",
-                     wine_get_config_dir() );
+        fatal_error( "'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.\n", config_dir );
     case STATUS_INVALID_IMAGE_FORMAT:
         fatal_error( "wineserver doesn't support the %s architecture\n", cpu_names[client_cpu] );
     default:




More information about the wine-cvs mailing list