updated pluging loader for Windows #4313
This commit is contained in:
parent
de8fe7e2a5
commit
1d7eb3f5cb
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
* Copyright (C) 2015 Synergy Si Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -24,21 +24,22 @@
|
|||
//
|
||||
// SecureSocket
|
||||
//
|
||||
struct CSsl {
|
||||
struct Ssl {
|
||||
SSL_CTX* m_context;
|
||||
SSL* m_ssl;
|
||||
};
|
||||
CSecureSocket::CSecureSocket() :
|
||||
|
||||
SecureSocket::SecureSocket() :
|
||||
m_ready(false),
|
||||
m_errorSize(65535)
|
||||
{
|
||||
m_ssl = new CSsl();
|
||||
m_ssl = new Ssl();
|
||||
m_ssl->m_context = NULL;
|
||||
m_ssl->m_ssl = NULL;
|
||||
m_error = new char[m_errorSize];
|
||||
}
|
||||
|
||||
CSecureSocket::~CSecureSocket()
|
||||
SecureSocket::~SecureSocket()
|
||||
{
|
||||
if (m_ssl->m_ssl != NULL) {
|
||||
SSL_free(m_ssl->m_ssl);
|
||||
|
@ -51,7 +52,7 @@ CSecureSocket::~CSecureSocket()
|
|||
}
|
||||
|
||||
void
|
||||
CSecureSocket::initContext(bool server)
|
||||
SecureSocket::initContext(bool server)
|
||||
{
|
||||
SSL_library_init();
|
||||
|
||||
|
@ -80,7 +81,7 @@ CSecureSocket::initContext(bool server)
|
|||
}
|
||||
|
||||
void
|
||||
CSecureSocket::loadCertificates(const char* filename)
|
||||
SecureSocket::loadCertificates(const char* filename)
|
||||
{
|
||||
int r = 0;
|
||||
r = SSL_CTX_use_certificate_file(m_ssl->m_context, filename, SSL_FILETYPE_PEM);
|
||||
|
@ -100,7 +101,7 @@ CSecureSocket::loadCertificates(const char* filename)
|
|||
}
|
||||
}
|
||||
void
|
||||
CSecureSocket::createSSL()
|
||||
SecureSocket::createSSL()
|
||||
{
|
||||
// I assume just one instance is needed
|
||||
// get new SSL state with context
|
||||
|
@ -110,7 +111,7 @@ CSecureSocket::createSSL()
|
|||
}
|
||||
|
||||
void
|
||||
CSecureSocket::accept(int socket)
|
||||
SecureSocket::accept(int socket)
|
||||
{
|
||||
createSSL();
|
||||
|
||||
|
@ -131,7 +132,7 @@ CSecureSocket::accept(int socket)
|
|||
}
|
||||
|
||||
void
|
||||
CSecureSocket::connect(int socket)
|
||||
SecureSocket::connect(int socket)
|
||||
{
|
||||
createSSL();
|
||||
|
||||
|
@ -152,7 +153,7 @@ CSecureSocket::connect(int socket)
|
|||
}
|
||||
|
||||
size_t
|
||||
CSecureSocket::write(const void* buffer, int size)
|
||||
SecureSocket::write(const void* buffer, int size)
|
||||
{
|
||||
bool retry = false;
|
||||
int n = 0;
|
||||
|
@ -168,7 +169,7 @@ CSecureSocket::write(const void* buffer, int size)
|
|||
}
|
||||
|
||||
size_t
|
||||
CSecureSocket::read(void* buffer, int size)
|
||||
SecureSocket::read(void* buffer, int size)
|
||||
{
|
||||
bool retry = false;
|
||||
int n = 0;
|
||||
|
@ -184,7 +185,7 @@ CSecureSocket::read(void* buffer, int size)
|
|||
}
|
||||
|
||||
void
|
||||
CSecureSocket::showCertificate()
|
||||
SecureSocket::showCertificate()
|
||||
{
|
||||
X509* cert;
|
||||
char* line;
|
||||
|
@ -207,7 +208,7 @@ CSecureSocket::showCertificate()
|
|||
}
|
||||
|
||||
bool
|
||||
CSecureSocket::checkResult(int n)
|
||||
SecureSocket::checkResult(int n)
|
||||
{
|
||||
bool retry = false;
|
||||
int errorCode = SSL_get_error(m_ssl->m_ssl, n);
|
||||
|
@ -253,16 +254,15 @@ CSecureSocket::checkResult(int n)
|
|||
}
|
||||
|
||||
void
|
||||
CSecureSocket::showError()
|
||||
SecureSocket::showError()
|
||||
{
|
||||
if (getError()) {
|
||||
LOG((CLOG_ERR "secure socket error: %s", m_error));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CSecureSocket::throwError(const char* reason)
|
||||
SecureSocket::throwError(const char* reason)
|
||||
{
|
||||
if (getError()) {
|
||||
throw XSecureSocket(synergy::string::sprintf(
|
||||
|
@ -271,7 +271,7 @@ CSecureSocket::throwError(const char* reason)
|
|||
}
|
||||
|
||||
bool
|
||||
CSecureSocket::getError()
|
||||
SecureSocket::getError()
|
||||
{
|
||||
unsigned long e = ERR_get_error();
|
||||
bool errorUpdated = false;
|
||||
|
@ -288,7 +288,7 @@ CSecureSocket::getError()
|
|||
}
|
||||
|
||||
bool
|
||||
CSecureSocket::isReady()
|
||||
SecureSocket::isReady()
|
||||
{
|
||||
return m_ready;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
* Copyright (C) 2015 Synergy Si Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -28,12 +28,12 @@ XBASE_SUBCLASS(XSecureSocket, XBase);
|
|||
Secure socket layer using OpenSSL.
|
||||
*/
|
||||
|
||||
struct CSsl;
|
||||
struct Ssl;
|
||||
|
||||
class CSecureSocket {
|
||||
class SecureSocket {
|
||||
public:
|
||||
CSecureSocket();
|
||||
~CSecureSocket();
|
||||
SecureSocket();
|
||||
~SecureSocket();
|
||||
|
||||
void initContext(bool server);
|
||||
void loadCertificates(const char* CertFile);
|
||||
|
@ -52,7 +52,7 @@ private:
|
|||
bool getError();
|
||||
|
||||
private:
|
||||
CSsl* m_ssl;
|
||||
Ssl* m_ssl;
|
||||
bool m_ready;
|
||||
char* m_error;
|
||||
const size_t m_errorSize;
|
||||
|
|
|
@ -17,21 +17,41 @@
|
|||
|
||||
#include "ns.h"
|
||||
|
||||
#include "SecureSocket.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
SecureSocket* g_secureSocket = NULL;
|
||||
|
||||
extern "C" {
|
||||
|
||||
int
|
||||
init(void (*sendEvent)(const char*, void*), void (*log)(const char*))
|
||||
{
|
||||
std::cout << "hello world" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void*
|
||||
invoke(const char* command, void* args)
|
||||
{
|
||||
if (strcmp(command, "getSecureSocket") == 0) {
|
||||
if (g_secureSocket == NULL) {
|
||||
g_secureSocket = new SecureSocket();
|
||||
}
|
||||
return g_secureSocket;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
cleanup()
|
||||
{
|
||||
std::cout << "goodbye world" << std::endl;
|
||||
if (g_secureSocket != NULL) {
|
||||
delete g_secureSocket;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#if defined _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
|
@ -26,9 +27,14 @@
|
|||
#define NS_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define NS_API
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
NS_API int init(void (*sendEvent)(const char*, void*), void (*log)(const char*));
|
||||
NS_API int cleanup();
|
||||
NS_API int init(void (*sendEvent)(const char*, void*), void (*log)(const char*));
|
||||
NS_API void* invoke(const char* command, void* args);
|
||||
NS_API int cleanup();
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue