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

Zebediah Figura zfigura at codeweavers.com
Wed Nov 10 18:56:20 CST 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>
---
v6: rebase on top of current git.

 configure.ac                   |  3 +++
 dlls/ntdll/Makefile.in         |  1 +
 dlls/ntdll/loader.c            | 10 ++++++++--
 dlls/ntdll/unix/env.c          |  1 +
 dlls/ntdll/unix/loader.c       |  3 +++
 dlls/ntdll/unix/unix_private.h |  1 +
 6 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index f86a5decb07..d4c16e2c3d2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -99,6 +99,7 @@ AC_ARG_WITH(xshm,      AS_HELP_STRING([--without-xshm],[do not use XShm (shared
 AC_ARG_WITH(xxf86vm,   AS_HELP_STRING([--without-xxf86vm],[do not use XFree video mode extension]),
             [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_xf86vmode_h=no; ac_cv_header_X11_extensions_xf86vmproto_h=no; fi])
 
+AC_ARG_WITH(system-dlldir, AS_HELP_STRING([--with-system-dlldir=DIR],[load external PE dependencies from directory DIR]))
 AC_ARG_WITH(wine-tools,AS_HELP_STRING([--with-wine-tools=DIR],[use Wine tools from directory DIR]))
 AC_ARG_WITH(wine64,    AS_HELP_STRING([--with-wine64=DIR],[use the 64-bit Wine in DIR for a Wow64 build]))
 
@@ -266,6 +267,8 @@ then
     TARGETFLAGS="-b $host_alias $TARGETFLAGS"
 fi
 
+AC_SUBST(system_dlldir,"$with_system_dlldir")
+
 dnl Check for flex
 AC_CHECK_PROGS(FLEX,flex,none)
 if test "$FLEX" = "none"
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index d3be1fad0bc..bce141bc14b 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -72,5 +72,6 @@ EXTRA_OBJS = unix/version.o
 
 unix_loader_EXTRADEFS = \
 	-DBINDIR=\"${bindir}\" \
+	-DSYSTEMDLLDIR=\"${system_dlldir}\" \
 	-DDLL_TO_BINDIR=\"`${MAKEDEP} -R ${dlldir} ${bindir}`\" \
 	-DBIN_TO_DATADIR=\"`${MAKEDEP} -R ${bindir} ${datadir}/wine`\"
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 255d5afef79..a9578ae86bf 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 24f4fa5a588..f9e6e625cbb 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 99226d472da..8464637e7e3 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -386,6 +386,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;
@@ -617,6 +618,8 @@ static void init_paths( char *argv[] )
         data_dir = build_path( bin_dir, BIN_TO_DATADIR );
     }
 
+    if (strlen(SYSTEMDLLDIR)) system_dll_path = SYSTEMDLLDIR;
+
     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 641de0c465f..de7b66123c1 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -126,6 +126,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