updated pluging loader for Windows #4313

This commit is contained in:
XinyuHou
2015-01-09 13:46:35 +00:00
parent de8fe7e2a5
commit 1d7eb3f5cb
12 changed files with 180 additions and 48 deletions

View File

@@ -21,6 +21,8 @@
#define PLUGINS_DIR "plugins"
#include "common/IInterface.h"
#include "common/stdmap.h"
#include "base/String.h"
class IEventQueue;
@@ -34,11 +36,34 @@ public:
//! @name manipulators
//@{
//! Load plugins
//!Load plugins
/*!
Scan the plugins dir and load plugins.
*/
virtual void load() = 0;
//! Init plugins
/*!
Initializes loaded plugins.
*/
virtual void init(void* eventTarget, IEventQueue* events) = 0;
//! Check if exists
/*!
Returns true if the plugin exists and is loaded.
*/
virtual bool exists(const char* name) = 0;
//! Invoke function
/*!
Invokes a function from the plugin.
*/
virtual void* invoke(const char* plugin,
const char* command,
void* args) = 0;
//@}
protected:
typedef std::map<String, void*> PluginTable;
};

View File

@@ -28,6 +28,7 @@
#include <iostream>
typedef int (*initFunc)(void (*sendEvent)(const char*, void*), void (*log)(const char*));
typedef void* (*invokeFunc)(const char*, void*);
void* g_eventTarget = NULL;
IEventQueue* g_events = NULL;
@@ -41,11 +42,8 @@ ArchPluginWindows::~ArchPluginWindows()
}
void
ArchPluginWindows::init(void* eventTarget, IEventQueue* events)
ArchPluginWindows::load()
{
g_eventTarget = eventTarget;
g_events = events;
String dir = getPluginsDir();
LOG((CLOG_DEBUG "plugins dir: %s", dir.c_str()));
@@ -54,21 +52,63 @@ ArchPluginWindows::init(void* eventTarget, IEventQueue* events)
getFilenames(pattern, plugins);
std::vector<String>::iterator it;
for (it = plugins.begin(); it != plugins.end(); ++it)
load(*it);
for (it = plugins.begin(); it != plugins.end(); ++it) {
LOG((CLOG_DEBUG "loading plugin: %s", (*it).c_str()));
String path = String(getPluginsDir()).append("\\").append(*it);
HINSTANCE library = LoadLibrary(path.c_str());
if (library == NULL) {
throw XArch(new XArchEvalWindows);
}
void* lib = reinterpret_cast<void*>(library);
String filename = synergy::string::removeFileExt(*it);
m_pluginTable.insert(std::make_pair(filename, lib));
}
}
void
ArchPluginWindows::load(const String& dllFilename)
ArchPluginWindows::init(void* eventTarget, IEventQueue* events)
{
LOG((CLOG_DEBUG "loading plugin: %s", dllFilename.c_str()));
String path = String(getPluginsDir()).append("\\").append(dllFilename);
HINSTANCE library = LoadLibrary(path.c_str());
if (library == NULL)
throw XArch(new XArchEvalWindows);
g_eventTarget = eventTarget;
g_events = events;
initFunc initPlugin = (initFunc)GetProcAddress(library, "init");
initPlugin(&sendEvent, &log);
PluginTable::iterator it;
HINSTANCE lib;
for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) {
lib = reinterpret_cast<HINSTANCE>(it->second);
initFunc initPlugin = (initFunc)GetProcAddress(lib, "init");
initPlugin(&sendEvent, &log);
}
}
bool
ArchPluginWindows::exists(const char* name)
{
PluginTable::iterator it;
it = m_pluginTable.find(name);
return it != m_pluginTable.end() ? true : false;
}
void*
ArchPluginWindows::invoke(
const char* plugin,
const char* command,
void* args)
{
PluginTable::iterator it;
it = m_pluginTable.find(plugin);
if (it != m_pluginTable.end()) {
HINSTANCE lib = reinterpret_cast<HINSTANCE>(it->second);
invokeFunc invokePlugin = (invokeFunc)GetProcAddress(lib, "invoke");
return invokePlugin(command, args);
}
else {
LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s",
plugin, command));
return NULL;
}
}
String

View File

@@ -19,7 +19,6 @@
#pragma once
#include "arch/IArchPlugin.h"
#include "base/String.h"
#include <vector>
@@ -35,13 +34,20 @@ public:
virtual ~ArchPluginWindows();
// IArchPlugin overrides
void load();
void init(void* eventTarget, IEventQueue* events);
bool exists(const char* name);
void* invoke(const char* pluginName,
const char* functionName,
void* args);
private:
String getModuleDir();
void getFilenames(const String& pattern, std::vector<String>& filenames);
void load(const String& dllPath);
String getPluginsDir();
private:
PluginTable m_pluginTable;
};
void sendEvent(const char* text, void* data);

View File

@@ -168,6 +168,17 @@ findReplaceAll(
}
}
String
removeFileExt(String filename)
{
unsigned dot = filename.find_last_of('.');
if (dot == String::npos) {
return filename;
}
return filename.substr(0, dot);
}
//
// CaselessCmp

View File

@@ -64,6 +64,12 @@ Finds \c find inside \c subject and replaces it with \c replace
*/
void findReplaceAll(String& subject, const String& find, const String& replace);
//! Remove file extension
/*!
Finds the last dot and remove all characters from the dot to the end
*/
String removeFileExt(String filename);
//! Case-insensitive comparisons
/*!
This class provides case-insensitve comparison functions.

View File

@@ -18,6 +18,7 @@
#include "client/Client.h"
#include "../plugin/ns/SecureSocket.h"
#include "client/ServerProxy.h"
#include "synergy/Screen.h"
#include "synergy/Clipboard.h"
@@ -45,6 +46,12 @@
#include <sstream>
#include <fstream>
#if defined _WIN32
static const char s_networkSecurity[] = { "ns" };
#else
static const char s_networkSecurity[] = { "libns" };
#endif
//
// Client
//
@@ -75,7 +82,8 @@ Client::Client(
m_crypto(crypto),
m_sendFileThread(NULL),
m_writeToDropDirThread(NULL),
m_enableDragDrop(enableDragDrop)
m_enableDragDrop(enableDragDrop),
m_secureSocket(NULL)
{
assert(m_socketFactory != NULL);
assert(m_screen != NULL);
@@ -100,6 +108,11 @@ Client::Client(
new TMethodEventJob<Client>(this,
&Client::handleFileRecieveCompleted));
}
if (ARCH->plugin().exists(s_networkSecurity)) {
m_secureSocket = static_cast<SecureSocket*>(
ARCH->plugin().invoke("ns", "getSecureSocket", NULL));
}
}
Client::~Client()

View File

@@ -37,6 +37,7 @@ class IStreamFilterFactory;
class IEventQueue;
class CryptoStream;
class Thread;
class SecureSocket;
//! Synergy client
/*!
@@ -233,4 +234,5 @@ private:
Thread* m_sendFileThread;
Thread* m_writeToDropDirThread;
bool m_enableDragDrop;
SecureSocket* m_secureSocket;
};

View File

@@ -458,6 +458,9 @@ ClientApp::mainLoop()
SocketMultiplexer multiplexer;
setSocketMultiplexer(&multiplexer);
// load all available plugins.
ARCH->plugin().load();
// start client, etc
appUtil().startNode();
@@ -467,7 +470,7 @@ ClientApp::mainLoop()
initIpcClient();
}
// load all available plugins.
// init all available plugins.
ARCH->plugin().init(m_clientScreen->getEventTarget(), m_events);
// run event loop. if startClient() failed we're supposed to retry