1#pragma once
 2
 3#ifdef _WIN32
 4#   define WIN32_LEAN_AND_MEAN
 5#   ifndef NOMINMAX
 6#       define NOMINMAX
 7#   endif
 8#   include <windows.h>
 9#   include <winevt.h>
10#else
11#    include <dlfcn.h>
12#    include <unistd.h>
13#endif
14#include <filesystem>
15
16namespace fs = std::filesystem;
17
18#ifdef _WIN32
19
20using dl_handle = std::remove_pointer_t<HMODULE>;
21
22struct dl_handle_deleter {
23    void operator()(HMODULE handle) {
24        FreeLibrary(handle);
25    }
26};
27
28static inline dl_handle * dl_load_library(const fs::path & path) {
29    // suppress error dialogs for missing DLLs
30    DWORD old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
31    SetErrorMode(old_mode | SEM_FAILCRITICALERRORS);
32
33    HMODULE handle = LoadLibraryW(path.wstring().c_str());
34
35    SetErrorMode(old_mode);
36
37    return handle;
38}
39
40static inline void * dl_get_sym(dl_handle * handle, const char * name) {
41    DWORD old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
42    SetErrorMode(old_mode | SEM_FAILCRITICALERRORS);
43
44    void * p = (void *) GetProcAddress(handle, name);
45
46    SetErrorMode(old_mode);
47
48    return p;
49}
50
51static inline const char * dl_error() {
52    return "";
53}
54
55#else
56
57using dl_handle = void;
58
59struct dl_handle_deleter {
60    void operator()(void * handle) {
61        dlclose(handle);
62    }
63};
64
65static inline dl_handle * dl_load_library(const fs::path & path) {
66    dl_handle * handle = dlopen(path.string().c_str(), RTLD_NOW | RTLD_LOCAL);
67    return handle;
68}
69
70static inline void * dl_get_sym(dl_handle * handle, const char * name) {
71    return dlsym(handle, name);
72}
73
74static inline const char * dl_error() {
75    const char *rslt = dlerror();
76    return rslt != nullptr ? rslt : "";
77}
78
79#endif