diff options
author | Martin Sustrik <sustrik@250bpm.com> | 2012-04-10 19:18:12 +0200 |
---|---|---|
committer | Martin Sustrik <sustrik@250bpm.com> | 2012-04-16 13:22:34 +0200 |
commit | dd0411ec78a4f8fa99aa32a2f2a90dba5d7bf572 (patch) | |
tree | 9f164cc1a573aaa2c6db528dca6a45d8708b5386 | |
parent | 35d748dfa5f846916c32142fc641eae0b5d9b88d (diff) |
Automatic loading of plugins on Windows
Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
-rw-r--r-- | src/ctx.cpp | 66 | ||||
-rw-r--r-- | src/ctx.hpp | 6 | ||||
-rw-r--r-- | src/windows.hpp | 16 |
3 files changed, 76 insertions, 12 deletions
diff --git a/src/ctx.cpp b/src/ctx.cpp index 8bd3506..99a2b3c 100644 --- a/src/ctx.cpp +++ b/src/ctx.cpp @@ -53,6 +53,63 @@ xs::ctx_t::ctx_t () : // Plug in the standard plugins. rc = plug (prefix_filter); errno_assert (rc == 0); + + + // Now plug in all the extensions found in plugin directory. + +#if defined XS_HAVE_WINDOWS + + // Find out the path to the plugins. + char files_common [MAX_PATH]; + HRESULT hr = SHGetFolderPath (NULL, CSIDL_PROGRAM_FILES_COMMON, + NULL, SHGFP_TYPE_CURRENT, files_common); + xs_assert (hr == S_OK); + std::string path = files_common; + WIN32_FIND_DATA ffd; + HANDLE fh = FindFirstFile ((path + "\\xs\\plugins\\*").c_str (), &ffd); + if (fh == INVALID_HANDLE_VALUE) + return; + while (true) { + + // Ignore the files without .xsp extension. + std::string file = ffd.cFileName; + if (file.size () < 4) + goto next; + if (file.substr (file.size () - 4) != ".xsp") + goto next; + + // Load the library and locate the extension point. + HMODULE dl = LoadLibrary ((path + "\\xs\\" + ffd.cFileName).c_str ()); + if (!dl) + goto next; + file = std::string ("xsp_") + file.substr (0, file.size () - 4) + + "_init"; + void *(*initfn) (); + *(void**)(&initfn) = GetProcAddress (dl, file.c_str ()); + if (!initfn) + goto next; + + // Plug the extension into the context. + rc = plug (initfn ()); + if (rc != 0) { + FreeLibrary (dl); + goto next; + } + + // Store the library handle so that we can unload it + // when context is terminated. + opt_sync.lock (); + plugins.push_back (dl); + opt_sync.unlock (); + +next: + if (FindNextFile (fh, &ffd) == 0) + break; + } + BOOL brc = FindClose (fh); + win_assert (brc != 0); + +#endif } bool xs::ctx_t::check_tag () @@ -128,6 +185,15 @@ int xs::ctx_t::terminate () } slot_sync.unlock (); + // Unload any dynamically loaded extension libraries. + opt_sync.lock (); +#if defined XS_HAVE_WINDOWS + for (plugins_t::iterator it = plugins.begin (); + it != plugins.end (); ++it) + FreeLibrary (*it); +#endif + opt_sync.unlock (); + // Deallocate the resources. delete this; diff --git a/src/ctx.hpp b/src/ctx.hpp index 54144ad..75b36bd 100644 --- a/src/ctx.hpp +++ b/src/ctx.hpp @@ -169,6 +169,12 @@ namespace xs // Synchronisation of access to context options. mutex_t opt_sync; + // List of all dynamically loaded extension libraries. +#if defined XS_HAVE_WINDOWS + typedef std::vector <HMODULE> plugins_t; + plugins_t plugins; +#endif + // List of all filters plugged into the context. typedef std::map <int, xs_filter_t*> filters_t; filters_t filters; diff --git a/src/windows.hpp b/src/windows.hpp index 1b108ef..48fe437 100644 --- a/src/windows.hpp +++ b/src/windows.hpp @@ -37,9 +37,6 @@ #ifndef NOVIRTUALKEYCODES #define NOVIRTUALKEYCODES // VK_* #endif -#ifndef NOWINMESSAGES -#define NOWINMESSAGES // WM_*, EM_*, LB_*, CB_* -#endif #ifndef NOWINSTYLES #define NOWINSTYLES // WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_* #endif @@ -76,9 +73,6 @@ #ifndef NOCOLOR #define NOCOLOR // Screen colors #endif -#ifndef NOCTLMGR -#define NOCTLMGR // Control and Dialog routines -#endif #ifndef NODRAWTEXT #define NODRAWTEXT // DrawText() and DT_* #endif @@ -88,9 +82,6 @@ #ifndef NOKERNEL #define NOKERNEL // All KERNEL defines and routines #endif -#ifndef NOUSER -#define NOUSER // All USER defines and routines -#endif #ifndef NONLS #define NONLS // All NLS defines and routines #endif @@ -106,9 +97,6 @@ #ifndef NOMINMAX #define NOMINMAX // Macros min(a,b) and max(a,b) #endif -#ifndef NOMSG -#define NOMSG // typedef MSG and associated routines -#endif #ifndef NOOPENFILE #define NOOPENFILE // OpenFile(), OemToAnsi, AnsiToOem, and OF_* #endif @@ -176,4 +164,8 @@ #ifndef AI_NUMERICSERV #define AI_NUMERICSERV 0x0400 #endif + +#include <Shlobj.h> + #endif + |