aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libstrongswan/utils/windows.c124
-rw-r--r--src/libstrongswan/utils/windows.h70
2 files changed, 136 insertions, 58 deletions
diff --git a/src/libstrongswan/utils/windows.c b/src/libstrongswan/utils/windows.c
index 4a6a35eff..feefcd497 100644
--- a/src/libstrongswan/utils/windows.c
+++ b/src/libstrongswan/utils/windows.c
@@ -49,6 +49,130 @@ int usleep(useconds_t usec)
return 0;
}
+/*
+ * See header.
+ */
+void *dlopen(const char *filename, int flag)
+{
+ return LoadLibrary(filename);
+}
+
+/**
+ * Load a symbol from known default libs (monolithic build)
+ */
+static void* dlsym_default(const char *name)
+{
+ const char *dlls[] = {
+ "libstrongswan-0.dll",
+ "libhydra-0.dll",
+ "libcharon-0.dll",
+ "libtnccs-0.dll",
+ NULL /* .exe */
+ };
+ HANDLE handle;
+ void *sym = NULL;
+ int i;
+
+ for (i = 0; i < countof(dlls); i++)
+ {
+ handle = GetModuleHandle(dlls[i]);
+ if (handle)
+ {
+ sym = GetProcAddress(handle, name);
+ if (sym)
+ {
+ break;
+ }
+ }
+ }
+ return sym;
+}
+
+/**
+ * Emulate RTLD_NEXT for some known symbols
+ */
+static void* dlsym_next(const char *name)
+{
+ struct {
+ const char *dll;
+ const char *syms[4];
+ } dlls[] = {
+ /* for leak detective */
+ { "msvcrt",
+ { "malloc", "calloc", "realloc", "free" }
+ },
+ };
+ HANDLE handle = NULL;
+ int i, j;
+
+ for (i = 0; i < countof(dlls); i++)
+ {
+ for (j = 0; j < countof(dlls[0].syms); j++)
+ {
+ if (dlls[i].syms[j] && streq(dlls[i].syms[j], name))
+ {
+ handle = GetModuleHandle(dlls[i].dll);
+ break;
+ }
+ }
+ }
+ if (handle)
+ {
+ return GetProcAddress(handle, name);
+ }
+ return handle;
+}
+
+/**
+ * See header.
+ */
+void* dlsym(void *handle, const char *symbol)
+{
+ if (handle == RTLD_DEFAULT)
+ {
+ return dlsym_default(symbol);
+ }
+ if (handle == RTLD_NEXT)
+ {
+ return dlsym_next(symbol);
+ }
+ return GetProcAddress((HMODULE)handle, symbol);
+}
+
+/**
+ * See header.
+ */
+char* dlerror(void)
+{
+ static char buf[128];
+ char *pos;
+ DWORD err;
+
+ err = GetLastError();
+ if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, err, 0, buf, sizeof(buf), NULL) > 0)
+ {
+ pos = strchr(buf, '\n');
+ if (pos)
+ {
+ *pos = '\0';
+ }
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "(%u)", err);
+ }
+ return buf;
+}
+
+/**
+ * See header.
+ */
+int dlclose(void *handle)
+{
+ return FreeLibrary((HMODULE)handle);
+}
+
/**
* See header
*/
diff --git a/src/libstrongswan/utils/windows.h b/src/libstrongswan/utils/windows.h
index 8e6fd80b1..e070a79a2 100644
--- a/src/libstrongswan/utils/windows.h
+++ b/src/libstrongswan/utils/windows.h
@@ -204,39 +204,11 @@ static inline int setenv(const char *name, const char *value, int overwrite)
}
/**
- * dlerror(3) from <dlfcn.h>, printing error to an alloca() buffer
- */
-#define dlerror() \
-({ \
- char buf[128], *out;\
- ssize_t len; \
- DWORD err; \
- err = GetLastError(); \
- len = FormatMessage(0, NULL, err, 0, buf, sizeof(buf), NULL); \
- if (len <= 0) \
- { \
- len = snprintf(buf, sizeof(buf), "(%u)", err); \
- } \
- len++; \
- out = alloca(len); \
- memcpy(out, buf, len); \
- out; \
-})
-
-/**
* Lazy binding, ignored on Windows
*/
#define RTLD_LAZY 1
/**
- * dlopen(3) from <dlfcn.h>
- */
-static inline void *dlopen(const char *filename, int flag)
-{
- return LoadLibrary(filename);
-}
-
-/**
* Default handle targeting .exe
*/
#define RTLD_DEFAULT (NULL)
@@ -247,42 +219,24 @@ static inline void *dlopen(const char *filename, int flag)
#define RTLD_NEXT ((void*)~(uintptr_t)0)
/**
+ * dlopen(3) from <dlfcn.h>
+ */
+void* dlopen(const char *filename, int flag);
+
+/**
* dlsym() from <dlfcn.h>
*/
-static inline void *dlsym(void *handle, const char *symbol)
-{
- if (handle == RTLD_DEFAULT)
- {
- handle = GetModuleHandle(NULL);
- }
- else if (handle == RTLD_NEXT)
- {
- if (strcmp(symbol, "malloc") == 0 ||
- strcmp(symbol, "realloc") == 0 ||
- strcmp(symbol, "free") == 0)
- {
- /* for leak-detective */
- handle = GetModuleHandle("msvcrt");
- }
- else
- {
- return NULL;
- }
- }
- if (handle)
- {
- return GetProcAddress((HMODULE)handle, symbol);
- }
- return NULL;
-}
+void* dlsym(void *handle, const char *symbol);
+
+/**
+ * dlerror(3) from <dlfcn.h>, currently not thread save
+ */
+char* dlerror(void);
/**
* dlclose() from <dlfcn.h>
*/
-static inline int dlclose(void *handle)
-{
- return FreeLibrary((HMODULE)handle);
-}
+int dlclose(void *handle);
/**
* socketpair(2) for SOCK_STREAM, uses TCP on loopback