summaryrefslogtreecommitdiffstats
path: root/Source/kwsys/DynamicLoader.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/kwsys/DynamicLoader.cxx')
-rw-r--r--Source/kwsys/DynamicLoader.cxx110
1 files changed, 82 insertions, 28 deletions
diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx
index a85690f..b93a215 100644
--- a/Source/kwsys/DynamicLoader.cxx
+++ b/Source/kwsys/DynamicLoader.cxx
@@ -1,9 +1,14 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
+#if defined(_WIN32)
+# define NOMINMAX // hide min,max to not conflict with <limits>
+#endif
+
#include "kwsysPrivate.h"
#include KWSYS_HEADER(DynamicLoader.hxx)
#include KWSYS_HEADER(Configure.hxx)
+#include KWSYS_HEADER(Encoding.hxx)
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
@@ -25,6 +30,28 @@
// Each part of the ifdef contains a complete implementation for
// the static methods of DynamicLoader.
+#define CHECK_OPEN_FLAGS(var, supported, ret) \
+ do { \
+ /* Check for unknown flags. */ \
+ if ((var & AllOpenFlags) != var) { \
+ return ret; \
+ } \
+ \
+ /* Check for unsupported flags. */ \
+ if ((var & (supported)) != var) { \
+ return ret; \
+ } \
+ } while (0)
+
+namespace KWSYS_NAMESPACE {
+
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
+ const std::string& libname)
+{
+ return DynamicLoader::OpenLibrary(libname, 0);
+}
+}
+
#if !KWSYS_SUPPORTS_SHARED_LIBS
// Implementation for environments without dynamic libs
# include <string.h> // for strerror()
@@ -32,7 +59,7 @@
namespace KWSYS_NAMESPACE {
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
- const std::string& libname)
+ const std::string& libname, int flags)
{
return 0;
}
@@ -67,8 +94,10 @@ const char* DynamicLoader::LastError()
namespace KWSYS_NAMESPACE {
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
- const std::string& libname)
+ const std::string& libname, int flags)
{
+ CHECK_OPEN_FLAGS(flags, 0, 0);
+
return shl_load(libname.c_str(), BIND_DEFERRED | DYNAMIC_PATH, 0L);
}
@@ -130,8 +159,10 @@ const char* DynamicLoader::LastError()
namespace KWSYS_NAMESPACE {
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
- const std::string& libname)
+ const std::string& libname, int flags)
{
+ CHECK_OPEN_FLAGS(flags, 0, 0);
+
NSObjectFileImageReturnCode rc;
NSObjectFileImage image = 0;
@@ -185,19 +216,22 @@ const char* DynamicLoader::LastError()
// Implementation for Windows win32 code but not cygwin
# include <windows.h>
+# include <stdio.h>
+
namespace KWSYS_NAMESPACE {
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
- const std::string& libname)
+ const std::string& libname, int flags)
{
- DynamicLoader::LibraryHandle lh;
- int length = MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, NULL, 0);
- wchar_t* wchars = new wchar_t[length + 1];
- wchars[0] = '\0';
- MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, wchars, length);
- lh = LoadLibraryW(wchars);
- delete[] wchars;
- return lh;
+ CHECK_OPEN_FLAGS(flags, SearchBesideLibrary, NULL);
+
+ DWORD llFlags = 0;
+ if (flags & SearchBesideLibrary) {
+ llFlags |= LOAD_WITH_ALTERED_SEARCH_PATH;
+ }
+
+ return LoadLibraryExW(Encoding::ToWindowsExtendedPath(libname).c_str(), NULL,
+ llFlags);
}
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
@@ -247,24 +281,38 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
# endif
}
+# define DYNLOAD_ERROR_BUFFER_SIZE 1024
+
const char* DynamicLoader::LastError()
{
- LPVOID lpMsgBuf = NULL;
-
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR)&lpMsgBuf, 0, NULL);
+ wchar_t lpMsgBuf[DYNLOAD_ERROR_BUFFER_SIZE + 1];
+
+ DWORD error = GetLastError();
+ DWORD length = FormatMessageW(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ lpMsgBuf, DYNLOAD_ERROR_BUFFER_SIZE, NULL);
+
+ static char str[DYNLOAD_ERROR_BUFFER_SIZE + 1];
+
+ if (length < 1) {
+ /* FormatMessage failed. Use a default message. */
+ _snprintf(str, DYNLOAD_ERROR_BUFFER_SIZE,
+ "DynamicLoader encountered error 0x%X. "
+ "FormatMessage failed with error 0x%X",
+ error, GetLastError());
+ return str;
+ }
- if (!lpMsgBuf) {
- return NULL;
+ if (!WideCharToMultiByte(CP_UTF8, 0, lpMsgBuf, -1, str,
+ DYNLOAD_ERROR_BUFFER_SIZE, NULL, NULL)) {
+ /* WideCharToMultiByte failed. Use a default message. */
+ _snprintf(str, DYNLOAD_ERROR_BUFFER_SIZE,
+ "DynamicLoader encountered error 0x%X. "
+ "WideCharToMultiByte failed with error 0x%X",
+ error, GetLastError());
}
- static char* str = 0;
- delete[] str;
- str = strcpy(new char[strlen((char*)lpMsgBuf) + 1], (char*)lpMsgBuf);
- // Free the buffer.
- LocalFree(lpMsgBuf);
return str;
}
@@ -282,8 +330,10 @@ namespace KWSYS_NAMESPACE {
static image_id last_dynamic_err = B_OK;
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
- const std::string& libname)
+ const std::string& libname, int flags)
{
+ CHECK_OPEN_FLAGS(flags, 0, 0);
+
// image_id's are integers, errors are negative. Add one just in case we
// get a valid image_id of zero (is that even possible?).
image_id rc = load_add_on(libname.c_str());
@@ -360,8 +410,10 @@ const char* DynamicLoader::LastError()
namespace KWSYS_NAMESPACE {
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
- const std::string& libname)
+ const std::string& libname, int flags)
{
+ CHECK_OPEN_FLAGS(flags, 0, NULL);
+
char* name = (char*)calloc(1, libname.size() + 1);
dld_init(program_invocation_name);
strncpy(name, libname.c_str(), libname.size());
@@ -404,8 +456,10 @@ const char* DynamicLoader::LastError()
namespace KWSYS_NAMESPACE {
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
- const std::string& libname)
+ const std::string& libname, int flags)
{
+ CHECK_OPEN_FLAGS(flags, 0, NULL);
+
return dlopen(libname.c_str(), RTLD_LAZY);
}