|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tpluginmanager.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsystem.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tconvert.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tlogger.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
#include <windows.h></windows.h>
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// QUALE DI QUESTI SERVE VERAMENTE??
|
|
Toshihiro Shimizu |
890ddd |
#include <grp.h></grp.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <utime.h></utime.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <sys param.h=""></sys>
|
|
Toshihiro Shimizu |
890ddd |
#include <unistd.h></unistd.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <sys types.h=""></sys>
|
|
Toshihiro Shimizu |
890ddd |
#include <sys timeb.h=""> // for ftime</sys>
|
|
Toshihiro Shimizu |
890ddd |
#include <stdio.h></stdio.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <unistd.h></unistd.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <dirent.h></dirent.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <sys dir.h=""></sys>
|
|
Toshihiro Shimizu |
890ddd |
#include <sys param.h=""> // for getfsstat</sys>
|
|
Campbell Barton |
107701 |
#ifdef MACOSX
|
|
Toshihiro Shimizu |
890ddd |
#include <sys ucred.h=""></sys>
|
|
Campbell Barton |
107701 |
#endif
|
|
Toshihiro Shimizu |
890ddd |
#include <sys mount.h=""></sys>
|
|
Toshihiro Shimizu |
890ddd |
#include <pwd.h></pwd.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <dlfcn.h></dlfcn.h>
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class TPluginManager::Plugin
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
typedef HINSTANCE Handle;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
typedef void *Handle;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Toshihiro Shimizu |
890ddd |
Handle m_handle;
|
|
Toshihiro Shimizu |
890ddd |
TPluginInfo m_info;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
Plugin(Handle handle)
|
|
Toshihiro Shimizu |
890ddd |
: m_handle(handle)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Handle getHandle() const { return m_handle; }
|
|
Toshihiro Shimizu |
890ddd |
const TPluginInfo &getInfo() const { return m_info; }
|
|
Toshihiro Shimizu |
890ddd |
void setInfo(const TPluginInfo &info) { m_info = info; }
|
|
Shinya Kitaoka |
3bfa54 |
std::string getName() const { return m_info.getName(); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef const TPluginInfo *TnzLibMainProcType();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
const char *TnzLibMainProcName = "TLibMain";
|
|
Shinya Kitaoka |
9f5a1b |
#if !defined(_WIN32)
|
|
Toshihiro Shimizu |
890ddd |
const char *TnzLibMainProcName2 = "_TLibMain";
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPluginManager::TPluginManager()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_ignoreList.insert("tnzimagevector");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPluginManager::~TPluginManager()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// try { unloadPlugins(); } catch(...) {}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPluginManager *TPluginManager::instance()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
static TPluginManager _instance;
|
|
Toshihiro Shimizu |
890ddd |
return &_instance;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
3bfa54 |
bool TPluginManager::isIgnored(std::string name) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_ignoreList.count(toLower(name)) > 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TPluginManager::unloadPlugins()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (PluginTable::iterator it = m_pluginTable.begin();
|
|
Toshihiro Shimizu |
890ddd |
it != m_pluginTable.end(); ++it) {
|
|
Toshihiro Shimizu |
890ddd |
Plugin::Handle handle = (*it)->getHandle();
|
|
Toshihiro Shimizu |
890ddd |
#ifndef LINUX
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
FreeLibrary(handle);
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
dlclose(handle);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
delete (*it);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
m_pluginTable.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TPluginManager::loadPlugin(const TFilePath &fp)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if ((int)m_loadedPlugins.count(fp) > 0) {
|
|
Toshihiro Shimizu |
890ddd |
TLogger::debug() << "Already loaded " << fp;
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
3bfa54 |
std::string name = fp.getName();
|
|
Toshihiro Shimizu |
890ddd |
if (isIgnored(name)) {
|
|
Toshihiro Shimizu |
890ddd |
TLogger::debug() << "Ignored " << fp;
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TLogger::debug() << "Loading " << fp;
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
Plugin::Handle handle = LoadLibraryW(fp.getWideString().c_str());
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
9eb50d |
Plugin::Handle handle = dlopen(::to_string(fp).c_str(), RTLD_NOW); // RTLD_LAZY
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
if (!handle) {
|
|
Toshihiro Shimizu |
890ddd |
// non riesce a caricare la libreria;
|
|
Toshihiro Shimizu |
890ddd |
TLogger::warning() << "Unable to load " << fp;
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Shinya Kitaoka |
3bfa54 |
std::wstring getFormattedMessage(DWORD lastError);
|
|
Shinya Kitaoka |
9eb50d |
TLogger::warning() << ::to_string(getFormattedMessage(GetLastError()));
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
TLogger::warning() << dlerror();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
m_loadedPlugins.insert(fp);
|
|
Toshihiro Shimizu |
890ddd |
Plugin *plugin = new Plugin(handle);
|
|
Toshihiro Shimizu |
890ddd |
m_pluginTable.push_back(plugin);
|
|
Toshihiro Shimizu |
890ddd |
//cout << "loaded" << endl;
|
|
Toshihiro Shimizu |
890ddd |
TnzLibMainProcType *tnzLibMain = 0;
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
tnzLibMain = (TnzLibMainProcType *)
|
|
Toshihiro Shimizu |
890ddd |
GetProcAddress(handle, TnzLibMainProcName);
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
tnzLibMain = (TnzLibMainProcType *)
|
|
Toshihiro Shimizu |
890ddd |
dlsym(handle, TnzLibMainProcName);
|
|
Toshihiro Shimizu |
890ddd |
if (!tnzLibMain) //provo _ come prefisso
|
|
Toshihiro Shimizu |
890ddd |
tnzLibMain = (TnzLibMainProcType *)dlsym(handle, TnzLibMainProcName2);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!tnzLibMain) {
|
|
Toshihiro Shimizu |
890ddd |
// La libreria non esporta TLibMain;
|
|
Toshihiro Shimizu |
890ddd |
TLogger::warning() << "Corrupted " << fp;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
FreeLibrary(handle);
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
dlclose(handle);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
const TPluginInfo *info = tnzLibMain();
|
|
Toshihiro Shimizu |
890ddd |
if (info)
|
|
Toshihiro Shimizu |
890ddd |
plugin->setInfo(*info);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TPluginManager::loadPlugins(const TFilePath &dir)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
9f5a1b |
#if defined(_WIN32)
|
|
Shinya Kitaoka |
3bfa54 |
const std::string extension = "dll";
|
|
Toshihiro Shimizu |
890ddd |
#elif defined(LINUX) || defined(__sgi)
|
|
Shinya Kitaoka |
3bfa54 |
const std::string extension = "so";
|
|
Toshihiro Shimizu |
890ddd |
#elif defined(MACOSX)
|
|
Shinya Kitaoka |
3bfa54 |
const std::string extension = "dylib";
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TFilePathSet dirContent = TSystem::readDirectory(dir, false);
|
|
Toshihiro Shimizu |
890ddd |
if (dirContent.empty())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (TFilePathSet::iterator it = dirContent.begin();
|
|
Toshihiro Shimizu |
890ddd |
it != dirContent.end(); it++) {
|
|
Toshihiro Shimizu |
890ddd |
TFilePath fp = *it;
|
|
Toshihiro Shimizu |
890ddd |
if (fp.getType() != extension)
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Shinya Kitaoka |
3bfa54 |
std::wstring fullpath = fp.getWideString();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool isDebugLibrary = (fullpath.find(L".d.") == fullpath.size() - (extension.size() + 3));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
if (!isDebugLibrary)
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
if (isDebugLibrary)
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
try {
|
|
Toshihiro Shimizu |
890ddd |
loadPlugin(fp);
|
|
Toshihiro Shimizu |
890ddd |
} catch (...) {
|
|
Toshihiro Shimizu |
890ddd |
TLogger::warning() << "unexpected error loading " << fp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TPluginManager::loadStandardPlugins()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TFilePath pluginsDir = TSystem::getDllDir() + "plugins";
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//loadPlugins(pluginsDir + "io");
|
|
Toshihiro Shimizu |
890ddd |
loadPlugins(pluginsDir + "fx");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
3bfa54 |
void TPluginManager::setIgnoredList(const std::set<std::string> &names)</std::string>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_ignoreList.clear();
|
|
Shinya Kitaoka |
3bfa54 |
for (std::set<std::string>::const_iterator it = names.begin(); it != names.end(); ++it)</std::string>
|
|
Toshihiro Shimizu |
890ddd |
m_ignoreList.insert(toLower(*it));
|
|
Toshihiro Shimizu |
890ddd |
}
|