From 3752b1d7c4c878e2d4be67a88bfc30ebb0b439f0 Mon Sep 17 00:00:00 2001 From: Thilo Schulz Date: Fri, 29 Jul 2011 20:18:37 +0000 Subject: [PATCH] Change DLL search path order for external libraries that are linked at runtime, like libcurl or libopenal to: * system library paths * executable path * fs_basepath --- code/client/cl_curl.c | 23 +++++------------ code/client/qal.c | 17 +------------ code/qcommon/qcommon.h | 2 +- code/qcommon/vm.c | 2 +- code/sys/sys_loadlib.h | 2 ++ code/sys/sys_main.c | 57 +++++++++++++++++++++++++++++++++++++++--- 6 files changed, 64 insertions(+), 39 deletions(-) diff --git a/code/client/cl_curl.c b/code/client/cl_curl.c index 16a73b66..95029924 100644 --- a/code/client/cl_curl.c +++ b/code/client/cl_curl.c @@ -94,30 +94,19 @@ qboolean CL_cURL_Init() Com_Printf("Loading \"%s\"...", cl_cURLLib->string); - if( (cURLLib = Sys_LoadLibrary(cl_cURLLib->string)) == 0 ) + if(!(cURLLib = Sys_LoadDll(cl_cURLLib->string))) { #ifdef _WIN32 return qfalse; -#else - char fn[1024]; - Q_strncpyz( fn, Sys_Cwd( ), sizeof( fn ) ); - strncat(fn, "/", sizeof(fn)-strlen(fn)-1); - strncat(fn, cl_cURLLib->string, sizeof(fn)-strlen(fn)-1); - - if((cURLLib = Sys_LoadLibrary(fn)) == 0) - { -#ifdef ALTERNATE_CURL_LIB - // On some linux distributions there is no libcurl.so.3, but only libcurl.so.4. That one works too. - if( (cURLLib = Sys_LoadLibrary(ALTERNATE_CURL_LIB)) == 0 ) - { - return qfalse; - } +#elsif ALTERNATE_CURL_LIB + // On some linux distributions there is no libcurl.so.3, but only libcurl.so.4. That one works too. + if(!(cURLLib = Sys_LoadDll(ALTERNATE_CURL_LIB))) + return qfalse; #else + return qfalse; #endif - } -#endif /* _WIN32 */ } clc.cURLEnabled = qtrue; diff --git a/code/client/qal.c b/code/client/qal.c index 5ddd67f2..9b016038 100644 --- a/code/client/qal.c +++ b/code/client/qal.c @@ -144,23 +144,8 @@ qboolean QAL_Init(const char *libname) if(OpenALLib) return qtrue; - Com_Printf( "Loading \"%s\"...\n", libname); - if( (OpenALLib = Sys_LoadLibrary(libname)) == 0 ) - { -#ifdef _WIN32 + if(!(OpenALLib = Sys_LoadDll(libname))) return qfalse; -#else - char fn[1024]; - Q_strncpyz( fn, Sys_Cwd( ), sizeof( fn ) ); - strncat(fn, "/", sizeof(fn) - strlen(fn) - 1); - strncat(fn, libname, sizeof(fn) - strlen(fn) - 1); - - if( (OpenALLib = Sys_LoadLibrary(fn)) == 0 ) - { - return qfalse; - } -#endif - } alinit_fail = qfalse; diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index e08a0c81..4a6410d4 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -1071,7 +1071,7 @@ typedef enum { void Sys_Init (void); // general development dll loading for virtual machine testing -void * QDECL Sys_LoadDll( const char *name, intptr_t (QDECL **entryPoint)(int, ...), +void * QDECL Sys_LoadQVMDll( const char *name, intptr_t (QDECL **entryPoint)(int, ...), intptr_t (QDECL *systemcalls)(intptr_t, ...) ); void Sys_UnloadDll( void *dllHandle ); diff --git a/code/qcommon/vm.c b/code/qcommon/vm.c index a99e109d..6f0548d9 100644 --- a/code/qcommon/vm.c +++ b/code/qcommon/vm.c @@ -579,7 +579,7 @@ vm_t *VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *), { Com_Printf("Try loading dll file %s\n", filename); - vm->dllHandle = Sys_LoadDll(filename, &vm->entryPoint, VM_DllSyscall); + vm->dllHandle = Sys_LoadQVMDll(filename, &vm->entryPoint, VM_DllSyscall); if(vm->dllHandle) { diff --git a/code/sys/sys_loadlib.h b/code/sys/sys_loadlib.h index 994c5d3f..2c4ddd04 100644 --- a/code/sys/sys_loadlib.h +++ b/code/sys/sys_loadlib.h @@ -47,3 +47,5 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # define Sys_LoadFunction(h,fn) SDL_LoadFunction(h,fn) # define Sys_LibraryError() SDL_GetError() #endif + +void * QDECL Sys_LoadDll(const char *name); diff --git a/code/sys/sys_main.c b/code/sys/sys_main.c index cd6db6fc..5fbb6f8c 100644 --- a/code/sys/sys_main.c +++ b/code/sys/sys_main.c @@ -412,10 +412,59 @@ void Sys_UnloadDll( void *dllHandle ) ================= Sys_LoadDll +First try to load library name from system library path, +from executable path, then fs_basepath. +================= +*/ + +void *Sys_LoadDll(const char *name) +{ + void *dllhandle; + + Com_Printf("Try loading \"%s\"...\n", name); + if(!(dllhandle = Sys_LoadLibrary(name))) + { + const char *topDir; + char libPath[MAX_OSPATH]; + + topDir = Sys_BinaryPath(); + + if(!*topDir) + topDir = "."; + + Com_Printf("Try loading \"%s\" from \"%s\"...\n", name, topDir); + Com_sprintf(libPath, sizeof(libPath), "%s%c%s", topDir, PATH_SEP, name); + + if(!(dllhandle = Sys_LoadLibrary(libPath))) + { + const char *basePath = Cvar_VariableString("fs_basepath"); + + if(!basePath || !*basePath) + basePath = "."; + + if(FS_FilenameCompare(topDir, basePath)) + { + Com_Printf("Try loading \"%s\" from \"%s\"...\n", name, basePath); + Com_sprintf(libPath, sizeof(libPath), "%s%c%s", basePath, PATH_SEP, name); + dllhandle = Sys_LoadLibrary(libPath); + } + + if(!dllhandle) + Com_Printf("Loading \"%s\" failed\n", name); + } + } + + return dllhandle; +} + +/* +================= +Sys_LoadQVMDll + Used to load a development dll instead of a virtual machine ================= */ -void *Sys_LoadDll(const char *name, +void *Sys_LoadQVMDll(const char *name, intptr_t (QDECL **entryPoint)(int, ...), intptr_t (*systemcalls)(intptr_t, ...)) { @@ -429,7 +478,7 @@ void *Sys_LoadDll(const char *name, if(!libHandle) { - Com_Printf("Sys_LoadDll(%s) failed:\n\"%s\"\n", name, Sys_LibraryError()); + Com_Printf("Sys_LoadQVMDll(%s) failed:\n\"%s\"\n", name, Sys_LibraryError()); return NULL; } @@ -438,13 +487,13 @@ void *Sys_LoadDll(const char *name, if ( !*entryPoint || !dllEntry ) { - Com_Printf ( "Sys_LoadDll(%s) failed to find vmMain function:\n\"%s\" !\n", name, Sys_LibraryError( ) ); + Com_Printf ( "Sys_LoadQVMDll(%s) failed to find vmMain function:\n\"%s\" !\n", name, Sys_LibraryError( ) ); Sys_UnloadLibrary(libHandle); return NULL; } - Com_Printf ( "Sys_LoadDll(%s) found vmMain function at %p\n", name, *entryPoint ); + Com_Printf ( "Sys_LoadQVMDll(%s) found vmMain function at %p\n", name, *entryPoint ); dllEntry( systemcalls ); return libHandle;