* cygheap.cc (init_cygheap::init_installation_root): Install Cygwin's

installation dir as DLL search path, instead of ".".
	* cygheap.h (class cwdstuff): Add parameter names in function
	declarations for readability.
	(cwdstuff::get): Ad inline implementation fetching the CWD as wide char
	string.
	* dlfcn.cc (dlopen): Add searching for dependent DLLs in DLL
	installation dir or CWD, if all else failed.
	Add comment to explain scenarios this is accommodating.
This commit is contained in:
Corinna Vinschen
2014-10-14 19:14:33 +00:00
parent 2599a694a6
commit 1dd75c50d5
4 changed files with 65 additions and 5 deletions

View File

@@ -13,7 +13,11 @@ details. */
#include <psapi.h>
#include <stdlib.h>
#include <ctype.h>
#include <wctype.h>
#include "path.h"
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
#include "perprocess.h"
#include "dlfcn.h"
#include "cygtls.h"
@@ -156,7 +160,34 @@ dlopen (const char *name, int flags)
if (flags & RTLD_NOLOAD)
GetModuleHandleExW (0, path, (HMODULE *) &ret);
else
ret = (void *) LoadLibraryW (path);
{
ret = (void *) LoadLibraryW (path);
if (!ret && GetLastError () == ERROR_MOD_NOT_FOUND)
{
/* This may indicate that a dependent DLL could not be loaded.
Typically this occurs because we removed the CWD from the
DLL search path via SetDllDirectory
(see init_cygheap::init_installation_root), and the load
mechanism expects that dlopening a DLL from the CWD allows
to load dependent DLLs from the same dir.
To continue supporting this scenario, call LoadLibraryEx
with the LOAD_WITH_ALTERED_SEARCH_PATH flag. This flag
replaces the application path with the DLL path in the DLL
search order. This functionality needs the full path to
the loaded DLL. */
if (!strchr (name, '/'))
{
wchar_t *path_full = tp.w_get ();
cygheap->cwd.get (path_full);
wcscat (path_full, L"\\");
wcscat (path_full, path);
path = path_full;
}
ret = (void *) LoadLibraryExW (path, NULL,
LOAD_WITH_ALTERED_SEARCH_PATH);
}
}
if (ret && (flags & RTLD_NODELETE))
GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_PIN, path,
(HMODULE *) &ret);