diff options
author | John Högberg <[email protected]> | 2017-11-29 12:54:21 +0100 |
---|---|---|
committer | John Högberg <[email protected]> | 2018-01-03 08:14:28 +0100 |
commit | 65df0ce5cec5fdee60c80409f322a58092526537 (patch) | |
tree | 69b9c97dc5fe9ca253a4d3154da7cc0209e718a9 /erts/emulator/sys | |
parent | c2d70945dce9cb09d5d7120d6e9ddf7faac8d230 (diff) | |
download | otp-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/emulator/sys')
-rw-r--r-- | erts/emulator/sys/win32/erl_win32_sys_ddll.c | 13 |
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); |