mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-01-18 20:39:33 +08:00
* 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:
parent
2599a694a6
commit
1dd75c50d5
@ -1,3 +1,15 @@
|
|||||||
|
2014-10-14 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2014-10-14 Corinna Vinschen <corinna@vinschen.de>
|
2014-10-14 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_socket.cc (fhandler_socket::connect): Init connect_state to
|
* fhandler_socket.cc (fhandler_socket::connect): Init connect_state to
|
||||||
|
@ -170,7 +170,6 @@ init_cygheap::init_installation_root ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
installation_root[1] = L'?';
|
installation_root[1] = L'?';
|
||||||
|
|
||||||
RtlInitEmptyUnicodeString (&installation_key, installation_key_buf,
|
RtlInitEmptyUnicodeString (&installation_key, installation_key_buf,
|
||||||
sizeof installation_key_buf);
|
sizeof installation_key_buf);
|
||||||
RtlInt64ToHexUnicodeString (hash_path_name (0, installation_root),
|
RtlInt64ToHexUnicodeString (hash_path_name (0, installation_root),
|
||||||
@ -185,6 +184,15 @@ init_cygheap::init_installation_root ()
|
|||||||
if (!w)
|
if (!w)
|
||||||
api_fatal ("Can't initialize Cygwin installation root dir.\n"
|
api_fatal ("Can't initialize Cygwin installation root dir.\n"
|
||||||
"Invalid DLL path");
|
"Invalid DLL path");
|
||||||
|
|
||||||
|
/* Remove "." from DLL search path and install our /bin dir instead.
|
||||||
|
Note that this change is propagated to child processes so we don't
|
||||||
|
have to call SetDllDirectory in each process. */
|
||||||
|
installation_root[1] = L'\\';
|
||||||
|
if (!SetDllDirectoryW (installation_root))
|
||||||
|
debug_printf ("Couldn't set %W as DLL directory, %E", installation_root);
|
||||||
|
installation_root[1] = L'?';
|
||||||
|
|
||||||
/* If w < p, the Cygwin DLL resides in the root dir of a drive or network
|
/* If w < p, the Cygwin DLL resides in the root dir of a drive or network
|
||||||
path. In that case, if we strip off yet another backslash, the path
|
path. In that case, if we strip off yet another backslash, the path
|
||||||
becomes invalid. We avoid that here so that the DLL also works in this
|
becomes invalid. We avoid that here so that the DLL also works in this
|
||||||
|
@ -308,14 +308,23 @@ private:
|
|||||||
available in shared memory avoids to test for the version every time
|
available in shared memory avoids to test for the version every time
|
||||||
around. Default to new version. */
|
around. Default to new version. */
|
||||||
fcwd_version_t fast_cwd_version;
|
fcwd_version_t fast_cwd_version;
|
||||||
void override_win32_cwd (bool, ULONG);
|
void override_win32_cwd (bool init, ULONG old_dismount_count);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UNICODE_STRING win32;
|
UNICODE_STRING win32;
|
||||||
static muto cwd_lock;
|
static muto cwd_lock;
|
||||||
const char *get_posix () const { return posix; };
|
const char *get_posix () const { return posix; };
|
||||||
void reset_posix (wchar_t *);
|
void reset_posix (wchar_t *w_cwd);
|
||||||
char *get (char *, int = 1, int = 0, unsigned = NT_MAX_PATH);
|
char *get (char *buf, int need_posix = 1, int with_chroot = 0,
|
||||||
|
unsigned ulen = NT_MAX_PATH);
|
||||||
|
PWCHAR get (PWCHAR buf, unsigned buflen = NT_MAX_PATH)
|
||||||
|
{
|
||||||
|
cwd_lock.acquire ();
|
||||||
|
buf[0] = L'\0';
|
||||||
|
wcsncat (buf, win32.Buffer, buflen - 1);
|
||||||
|
cwd_lock.release ();
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
HANDLE get_handle () { return dir; }
|
HANDLE get_handle () { return dir; }
|
||||||
DWORD get_drive (char * dst)
|
DWORD get_drive (char * dst)
|
||||||
{
|
{
|
||||||
|
@ -13,7 +13,11 @@ details. */
|
|||||||
#include <psapi.h>
|
#include <psapi.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <wctype.h>
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
#include "fhandler.h"
|
||||||
|
#include "dtable.h"
|
||||||
|
#include "cygheap.h"
|
||||||
#include "perprocess.h"
|
#include "perprocess.h"
|
||||||
#include "dlfcn.h"
|
#include "dlfcn.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
@ -156,7 +160,34 @@ dlopen (const char *name, int flags)
|
|||||||
if (flags & RTLD_NOLOAD)
|
if (flags & RTLD_NOLOAD)
|
||||||
GetModuleHandleExW (0, path, (HMODULE *) &ret);
|
GetModuleHandleExW (0, path, (HMODULE *) &ret);
|
||||||
else
|
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))
|
if (ret && (flags & RTLD_NODELETE))
|
||||||
GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_PIN, path,
|
GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_PIN, path,
|
||||||
(HMODULE *) &ret);
|
(HMODULE *) &ret);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user