diff --git a/src/lib/arch/IArchPlugin.h b/src/lib/arch/IArchPlugin.h index e864bc4d..f6ae4637 100644 --- a/src/lib/arch/IArchPlugin.h +++ b/src/lib/arch/IArchPlugin.h @@ -70,7 +70,8 @@ public: */ virtual void* invoke(const char* plugin, const char* command, - void** args) = 0; + void** args, + void* library = NULL) = 0; //@} diff --git a/src/lib/arch/unix/ArchPluginUnix.cpp b/src/lib/arch/unix/ArchPluginUnix.cpp index e13e9472..ce81946f 100644 --- a/src/lib/arch/unix/ArchPluginUnix.cpp +++ b/src/lib/arch/unix/ArchPluginUnix.cpp @@ -83,21 +83,20 @@ ArchPluginUnix::load() } String filename = synergy::string::removeFileExt(*it); - m_pluginTable.insert(std::make_pair(filename, library)); - size_t pos = filename.find("lib"); String pluginName = filename.substr(pos + 3); - char* version = (char*)invoke(filename.c_str(), "version", NULL); + char* version = (char*)invoke(filename.c_str(), "version", NULL, library); String expectedVersion(pluginVersion(pluginName.c_str())); + if (version != NULL && expectedVersion.compare(version) == 0) { LOG((CLOG_DEBUG "loaded plugin: %s (%s)", (*it).c_str(), version)); + m_pluginTable.insert(std::make_pair(filename, library)); } else { LOG((CLOG_WARN "plugin version doesn't match")); LOG((CLOG_DEBUG "expected plugin version: %s actual plugin version: %s", expectedVersion.c_str(), version)); LOG((CLOG_WARN "skip plugin: %s", (*it).c_str())); - m_pluginTable.erase(filename); dlclose(library); } } @@ -166,26 +165,37 @@ void* ArchPluginUnix::invoke( const char* plugin, const char* command, - void** args) + void** args, + void* library) { - PluginTable::iterator it; - it = m_pluginTable.find(plugin); - if (it != m_pluginTable.end()) { - invokeFunc invokePlugin = (invokeFunc)dlsym(it->second, "invoke"); - void* result = NULL; - if (invokePlugin != NULL) { - result = invokePlugin(command, args); + void* lib = NULL; + + if (library == NULL) { + PluginTable::iterator it; + it = m_pluginTable.find(plugin); + if (it != m_pluginTable.end()) { + lib = it->second; } else { - LOG((CLOG_DEBUG "no invoke function in %s", it->first.c_str())); + LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s", + plugin, command)); + return NULL; } - return result; } else { - LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s", - plugin, command)); - return NULL; + lib = library; } + + invokeFunc invokePlugin = (invokeFunc)dlsym(lib, "invoke"); + void* result = NULL; + if (invokePlugin != NULL) { + result = invokePlugin(command, args); + } + else { + LOG((CLOG_DEBUG "no invoke function in %s", plugin)); + } + + return result; } String diff --git a/src/lib/arch/unix/ArchPluginUnix.h b/src/lib/arch/unix/ArchPluginUnix.h index 5438dffb..894c675b 100644 --- a/src/lib/arch/unix/ArchPluginUnix.h +++ b/src/lib/arch/unix/ArchPluginUnix.h @@ -38,7 +38,8 @@ public: bool exists(const char* name); virtual void* invoke(const char* pluginName, const char* functionName, - void** args); + void** args, + void* library = NULL); private: String getPluginsDir(); diff --git a/src/lib/arch/win32/ArchPluginWindows.cpp b/src/lib/arch/win32/ArchPluginWindows.cpp index 81fd7a32..63a1cf41 100644 --- a/src/lib/arch/win32/ArchPluginWindows.cpp +++ b/src/lib/arch/win32/ArchPluginWindows.cpp @@ -70,19 +70,18 @@ ArchPluginWindows::load() void* lib = reinterpret_cast(library); String pluginName = synergy::string::removeFileExt(*it); - m_pluginTable.insert(std::make_pair(pluginName, lib)); - - char* version = (char*)invoke(pluginName.c_str(), "version", NULL); + char* version = (char*)invoke(pluginName.c_str(), "version", NULL, lib); String expectedVersion(pluginVersion(pluginName.c_str())); + if (version != NULL && expectedVersion.compare(version) == 0) { LOG((CLOG_DEBUG "loaded plugin: %s (%s)", (*it).c_str(), version)); + m_pluginTable.insert(std::make_pair(pluginName, lib)); } else { LOG((CLOG_WARN "plugin version doesn't match")); LOG((CLOG_DEBUG "expected plugin version: %s actual plugin version: %s", expectedVersion.c_str(), version)); LOG((CLOG_WARN "skip plugin: %s", (*it).c_str())); - m_pluginTable.erase(pluginName); FreeLibrary(library); } } @@ -158,28 +157,37 @@ void* ArchPluginWindows::invoke( const char* plugin, const char* command, - void** args) + void** args, + void* library) { - PluginTable::iterator it; - it = m_pluginTable.find(plugin); - if (it != m_pluginTable.end()) { - HINSTANCE lib = reinterpret_cast(it->second); - invokeFunc invokePlugin = (invokeFunc)GetProcAddress(lib, "invoke"); - void* result = NULL; - if (invokePlugin != NULL) { - result = invokePlugin(command, args); + HINSTANCE lib = NULL; + + if (library == NULL) { + PluginTable::iterator it; + it = m_pluginTable.find(plugin); + if (it != m_pluginTable.end()) { + lib = reinterpret_cast(it->second); } else { - LOG((CLOG_DEBUG "no invoke function in %s", it->first.c_str())); + LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s", + plugin, command)); + return NULL; } - - return result; } else { - LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s", - plugin, command)); - return NULL; + lib = reinterpret_cast(library); } + + invokeFunc invokePlugin = (invokeFunc)GetProcAddress(lib, "invoke"); + void* result = NULL; + if (invokePlugin != NULL) { + result = invokePlugin(command, args); + } + else { + LOG((CLOG_DEBUG "no invoke function in %s", plugin)); + } + + return result; } void diff --git a/src/lib/arch/win32/ArchPluginWindows.h b/src/lib/arch/win32/ArchPluginWindows.h index fd325dfe..50f77a64 100644 --- a/src/lib/arch/win32/ArchPluginWindows.h +++ b/src/lib/arch/win32/ArchPluginWindows.h @@ -41,7 +41,8 @@ public: bool exists(const char* name); void* invoke(const char* pluginName, const char* functionName, - void** args); + void** args, + void* library = NULL); private: void getFilenames(const String& pattern, std::vector& filenames);