Merge pull request #658 from mfleisz/master

Extended plugin system to be able to link/load plugins statically, credit goes to Mike McDonald from Quest Software
This commit is contained in:
Marc-André Moreau 2012-07-22 09:45:04 -07:00
commit c198576345
3 changed files with 83 additions and 1 deletions

View File

@ -29,5 +29,7 @@ FREERDP_API boolean freerdp_close_library(void* library);
FREERDP_API void* freerdp_load_library_symbol(const char* file, const char* name);
FREERDP_API void* freerdp_load_plugin(const char* name, const char* entry_name);
FREERDP_API void* freerdp_load_channel_plugin(rdpSettings* settings, const char* name, const char* entry_name);
FREERDP_API boolean freerdp_register_static_plugin(const char* name, const char* entry_name, void* entry_addr);
FREERDP_API void* freerdp_load_static_plugin(const char* name, const char* entry_name);
#endif /* __LOAD_PLUGIN_UTILS_H */

View File

@ -60,9 +60,15 @@ FREERDP_API int svc_plugin_send_event(rdpSvcPlugin* plugin, RDP_EVENT* event);
#define DEBUG_SVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
#ifdef WITH_STATIC_PLUGINS
#define DEFINE_SVC_PLUGIN_ENTRY(_prefix) int _prefix##_entry(PCHANNEL_ENTRY_POINTS pEntryPoints)
#else
#define DEFINE_SVC_PLUGIN_ENTRY(_prefix) int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
#endif
#define DEFINE_SVC_PLUGIN(_prefix, _name, _options) \
\
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) \
DEFINE_SVC_PLUGIN_ENTRY(_prefix) \
{ \
_prefix##Plugin* _p; \
\

View File

@ -46,6 +46,21 @@
#endif
#define MAX_STATIC_PLUGINS 50
struct static_plugin
{
const char* name;
const char* entry_name;
void* entry_addr;
};
typedef struct static_plugin staticPlugin;
static staticPlugin g_static_plugins[MAX_STATIC_PLUGINS];
static int g_static_plugins_count;
/**
* UNUSED
* This function opens a handle on the specified library in order to load symbols from it.
@ -185,6 +200,10 @@ void* freerdp_load_plugin(const char* name, const char* entry_name)
void* entry;
char* suffixed_name;
/* first attempt to load a static plugin */
entry = freerdp_load_static_plugin(name, entry_name);
if (entry != NULL) return entry;
suffixed_name = freerdp_append_shared_library_suffix((char*) name);
if (!freerdp_path_contains_separator(suffixed_name))
@ -276,3 +295,58 @@ void* freerdp_load_channel_plugin(rdpSettings* settings, const char* name, const
return entry;
}
/**
* This function is used to register a static plugin so that it can be loaded later on using freerdp_load_plugin.
*
* @param name [IN] - name of the library to load
* @param entry_name [IN] - name of the symbol to register for later loading
* @param entry [IN] - function pointer to the entry function
*
* @return true on success, otherwise false.
*/
boolean freerdp_register_static_plugin(const char* name, const char* entry_name, void* entry_addr)
{
staticPlugin* plugin;
if (g_static_plugins_count >= MAX_STATIC_PLUGINS)
{
printf("freerdp_register_static_plugin: cannot register %s/%s", name, entry_name);
return false;
}
/* add the static plugin to the vector */
plugin = &g_static_plugins[g_static_plugins_count++];
plugin->name = name;
plugin->entry_name = entry_name;
plugin->entry_addr = entry_addr;
return true;
}
/**
* This is a helper function, used by freerdp_load_plugin to return a function pointer from the static plugin table
*
* @param name [IN] - name of the library to load
* @param entry_name [IN] - name of the symbol to register for later loading
*
* @return Pointer to the entry function, NULL if no matching plugin could be found
*/
void* freerdp_load_static_plugin(const char* name, const char* entry_name)
{
staticPlugin* plugin;
int i;
for (i = 0; i < g_static_plugins_count; i++)
{
plugin = &g_static_plugins[i];
if (!strcmp(plugin->name, name) && !strcmp(plugin->entry_name, entry_name))
{
return plugin->entry_addr;
}
}
return NULL;
}