[PATCH v2 2/3] ntdll: Allow loading system DLLs from a path specified at configure time.

Zebediah Figura zfigura at codeweavers.com
Wed Nov 3 21:37:19 CDT 2021


Many distributions provide MinGW-compiled system DLLs which are currently
bundled with Wine. Unfortunately, while MinGW pkg-config can be used to detect
the linking path, there is no standardized runtime path, and many distributions
in fact use different paths.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
To be clear I don't necessarily think this is *clearly* the best option.
Obviously it'd be nice to establish some sort of standard along the lines of
ld.so's standardized search location, but this may be a length process.

An environment variable configurable at runtime would also be useful, as
LD_LIBRARY_PATH often is. I could see arguments for specifying it in addition
to, or in lieu of, a path supplied at configure time.

It's also possible that we should allow specifying multiple paths here.

Nevertheless, I believe we should allow some way to load DLLs from an external
path, rather than forcing the user to manually copy them into the prefix (or
forcing Wine to be built with bundled dependencies.) I readily welcome consensus
on any of the above questions, but in lieu thereof, since it is relatively easy
to effect incremental improvement here, I propose this solution for now.

 configure.ac                   |  4 ++++
 dlls/ntdll/loader.c            | 10 ++++++++--
 dlls/ntdll/unix/env.c          |  1 +
 dlls/ntdll/unix/loader.c       |  5 +++++
 dlls/ntdll/unix/unix_private.h |  1 +
 5 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 57383fb2e31..a00f2ebc11f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,6 +36,8 @@ AC_ARG_ENABLE(maintainer-mode, AS_HELP_STRING([--enable-maintainer-mode],[enable
 AC_ARG_ENABLE(silent-rules, AS_HELP_STRING([--enable-silent-rules],[use silent build rules (override: "make V=1")]))
 AC_ARG_ENABLE(werror, AS_HELP_STRING([--enable-werror],[treat compilation warnings as errors]))
 
+AC_ARG_VAR([SYSTEMDLLDIR], [path containing system dependency shared libraries])
+
 AC_ARG_WITH(alsa,      AS_HELP_STRING([--without-alsa],[do not use the Alsa sound support]))
 AC_ARG_WITH(capi,      AS_HELP_STRING([--without-capi],[do not use CAPI (ISDN support)]))
 AC_ARG_WITH(coreaudio, AS_HELP_STRING([--without-coreaudio],[do not use the CoreAudio sound support]),
@@ -108,6 +110,8 @@ AC_ARG_WITH(wine64,    AS_HELP_STRING([--with-wine64=DIR],[use the 64-bit Wine i
 
 AC_CANONICAL_HOST
 
+AS_VAR_IF([SYSTEMDLLDIR],[],[],[AC_DEFINE_UNQUOTED([SYSTEMDLLDIR],["$SYSTEMDLLDIR"],[Define to the path containing system dependency shared libraries.])])
+
 dnl **** Check for some programs ****
 
 AC_PROG_MAKE_SET
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 17c8d7f7485..c83f7980572 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -95,6 +95,7 @@ static int free_lib_count;   /* recursion depth of LdrUnloadDll calls */
 static ULONG path_safe_mode;  /* path mode set by RtlSetSearchPathMode */
 static ULONG dll_safe_mode = 1;  /* dll search mode */
 static UNICODE_STRING dll_directory;  /* extra path for LdrSetDllDirectory */
+static UNICODE_STRING system_dll_path; /* path to search for system dependency dlls */
 static DWORD default_search_flags;  /* default flags set by LdrSetDefaultDllDirectories */
 static WCHAR *default_load_path;    /* default dll search path */
 
@@ -2981,12 +2982,15 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
     struct file_id id;
     HANDLE mapping = 0;
     SECTION_IMAGE_INFORMATION image_info;
-    NTSTATUS nts;
+    NTSTATUS nts = STATUS_DLL_NOT_FOUND;
     ULONG64 prev;
 
     TRACE( "looking for %s in %s\n", debugstr_w(libname), debugstr_w(load_path) );
 
-    nts = find_dll_file( load_path, libname, default_ext, &nt_name, pwm, &mapping, &image_info, &id );
+    if (system_dll_path.Buffer)
+        nts = find_dll_file( system_dll_path.Buffer, libname, default_ext, &nt_name, pwm, &mapping, &image_info, &id );
+    if (nts)
+        nts = find_dll_file( load_path, libname, default_ext, &nt_name, pwm, &mapping, &image_info, &id );
 
     if (*pwm)  /* found already loaded module */
     {
@@ -3997,6 +4001,8 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
         load_global_options();
         version_init();
 
+        get_env_var( L"WINESYSTEMDLLDIR", 0, &system_dll_path );
+
         wm = build_main_module();
         wm->ldr.LoadCount = -1;
 
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c
index 43a34bf831b..1647603efa5 100644
--- a/dlls/ntdll/unix/env.c
+++ b/dlls/ntdll/unix/env.c
@@ -1296,6 +1296,7 @@ static void add_dynamic_environment( WCHAR **env, SIZE_T *pos, SIZE_T *size )
     add_path_var( env, pos, size, "WINEHOMEDIR", home_dir );
     add_path_var( env, pos, size, "WINEBUILDDIR", build_dir );
     add_path_var( env, pos, size, "WINECONFIGDIR", config_dir );
+    add_path_var( env, pos, size, "WINESYSTEMDLLDIR", system_dll_path );
     for (i = 0; dll_paths[i]; i++)
     {
         sprintf( str, "WINEDLLDIR%u", i );
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index 0ca4b1ea6dd..5dfe7191dbe 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -388,6 +388,7 @@ const char *data_dir = NULL;
 const char *build_dir = NULL;
 const char *config_dir = NULL;
 const char **dll_paths = NULL;
+const char *system_dll_path = NULL;
 const char *user_name = NULL;
 SECTION_IMAGE_INFORMATION main_image_info = { NULL };
 static HMODULE ntdll_module;
@@ -619,6 +620,10 @@ static void init_paths( char *argv[] )
         data_dir = build_path( bin_dir, BIN_TO_DATADIR );
     }
 
+#ifdef SYSTEMDLLDIR
+    system_dll_path = SYSTEMDLLDIR;
+#endif
+
     set_dll_path();
     set_home_dir();
     set_config_dir();
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 792cb33710d..01c7cc1c103 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -125,6 +125,7 @@ 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 const char *system_dll_path DECLSPEC_HIDDEN;
 extern PEB *peb DECLSPEC_HIDDEN;
 extern USHORT *uctable DECLSPEC_HIDDEN;
 extern USHORT *lctable DECLSPEC_HIDDEN;
-- 
2.33.0




More information about the wine-devel mailing list