aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2017-11-29 12:54:21 +0100
committerJohn Högberg <[email protected]>2018-01-03 08:14:28 +0100
commit65df0ce5cec5fdee60c80409f322a58092526537 (patch)
tree69b9c97dc5fe9ca253a4d3154da7cc0209e718a9 /erts
parentc2d70945dce9cb09d5d7120d6e9ddf7faac8d230 (diff)
downloadotp-65df0ce5cec5fdee60c80409f322a58092526537.tar.gz
otp-65df0ce5cec5fdee60c80409f322a58092526537.tar.bz2
otp-65df0ce5cec5fdee60c80409f322a58092526537.zip
Alter erl_ddll:load dependency search path on Windows
The standard search order does not include the directory that the loaded DLL resides in, requiring dirty $PATH hacks to get things working, which is not an option now that os:putenv/2 is divorced from the OS environment.
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/sys/win32/erl_win32_sys_ddll.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/erts/emulator/sys/win32/erl_win32_sys_ddll.c b/erts/emulator/sys/win32/erl_win32_sys_ddll.c
index 274133a346..fc2179328f 100644
--- a/erts/emulator/sys/win32/erl_win32_sys_ddll.c
+++ b/erts/emulator/sys/win32/erl_win32_sys_ddll.c
@@ -46,9 +46,17 @@ static TWinDynDriverCallbacks wddc;
static TWinDynNifCallbacks nif_callbacks;
void erl_sys_ddll_init(void) {
+ WCHAR cwd_buffer[MAX_PATH];
+
tls_index = TlsAlloc();
ERL_INIT_CALLBACK_STRUCTURE(wddc);
+ /* LOAD_WITH_ALTERED_SEARCH_PATH removes the startup directory from the
+ * search path, so we add it separately to be backwards compatible. */
+ if (GetCurrentDirectoryW(sizeof(cwd_buffer), cwd_buffer)) {
+ SetDllDirectoryW(cwd_buffer);
+ }
+
#define ERL_NIF_API_FUNC_DECL(RET,NAME,ARGS) nif_callbacks.NAME = NAME
#include "erl_nif_api_funcs.h"
#undef ERL_NIF_API_FUNC_DECL
@@ -81,7 +89,10 @@ int erts_sys_ddll_open(const char *full_name, void **handle, ErtsSysDdllError* e
ERTS_ALC_T_TMP, &used, EXT_LEN);
wcscpy(&wcp[used/2 - 1], FILE_EXT_WCHAR);
- if ((hinstance = LoadLibraryW(wcp)) == NULL) {
+ /* LOAD_WITH_ALTERED_SEARCH_PATH adds the specified DLL's directory to the
+ * dependency search path. This also removes the directory we started in,
+ * but we've explicitly added that in in erl_sys_ddll_init. */
+ if ((hinstance = LoadLibraryExW(wcp, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) {
code = ERL_DE_DYNAMIC_ERROR_OFFSET - GetLastError();
if (err != NULL) {
err->str = erts_sys_ddll_error(code);