📄 pluginmgr.cxx
字号:
/*
* pluginmgr.cxx
*
* Plugin Manager Class
*
* Portable Windows Library
*
* Contributor(s): Snark at GnomeMeeting
*
* $Revision: 19516 $
* $Author: rjongbloed $
* $Date: 2008-02-14 08:05:40 +0000 (Thu, 14 Feb 2008) $
*/
#include <ptlib.h>
#include <ptlib/pprocess.h>
#include <ptlib/pluginmgr.h>
#ifndef __BEOS__
#include <algorithm>
#endif
#ifndef P_DEFAULT_PLUGIN_DIR
# if defined (_WIN32_WCE)
# define P_DEFAULT_PLUGIN_DIR "\\Windows\\Plugins"
# elif defined (_WIN32)
# define P_DEFAULT_PLUGIN_DIR ".;C:\\PTLib_PlugIns;C:\\PWLIB_PLUGINS"
# else
# define P_DEFAULT_PLUGIN_DIR ".:/usr/lib/ptlib:/usr/lib/pwlib"
# endif
#endif
#ifdef _WIN32
#define DIR_SEP ";"
#else
#define DIR_SEP ":"
#endif
#ifndef PDIR_SEPARATOR
#ifdef _WIN32
#define PDIR_SEPARATOR '\\'
#else
#define PDIR_SEPARATOR '/'
#endif
#endif
#define ENV_PTLIB_PLUGIN_DIR "PTLIBPLUGINDIR"
#define ENV_PWLIB_PLUGIN_DIR "PWLIBPLUGINDIR"
#define PTPLUGIN_SUFFIX "_ptplugin"
#define PWPLUGIN_SUFFIX "_pwplugin"
const char PDevicePluginServiceDescriptor::SeparatorChar = '\t';
class PluginLoaderStartup : public PProcessStartup
{
PCLASSINFO(PluginLoaderStartup, PProcessStartup);
public:
void OnStartup();
void OnShutdown();
protected:
std::vector<PPluginModuleManager *> managers;
};
#define new PNEW
//////////////////////////////////////////////////////
void PPluginManager::LoadPluginDirectory (const PDirectory & directory)
{
PStringList suffixes;
suffixes.AppendString(PTPLUGIN_SUFFIX);
suffixes.AppendString(PWPLUGIN_SUFFIX);
PFactory<PPluginSuffix>::KeyList_T keys = PFactory<PPluginSuffix>::GetKeyList();
PFactory<PPluginSuffix>::KeyList_T::const_iterator r;
for (r = keys.begin(); r != keys.end(); ++r)
suffixes.AppendString(*r);
LoadPluginDirectory(directory, suffixes);
}
void PPluginManager::LoadPluginDirectory (const PDirectory & directory, const PStringList & suffixes)
{
PDirectory dir = directory;
if (!dir.Open()) {
PTRACE(4, "PLUGIN\tCannot open plugin directory " << dir);
return;
}
PTRACE(4, "PLUGIN\tEnumerating plugin directory " << dir);
do {
PString entry = dir + dir.GetEntryName();
PDirectory subdir = entry;
if (subdir.Open())
LoadPluginDirectory(entry, suffixes);
else {
PFilePath fn(entry);
for (PStringList::const_iterator i = suffixes.begin(); i != suffixes.end(); ++i) {
PString suffix = *i;
PTRACE(5, "PLUGIN\tChecking " << fn << " against suffix " << suffix);
if ((fn.GetType() *= PDynaLink::GetExtension()) && (fn.GetTitle().Right(strlen(suffix)) *= suffix))
LoadPlugin(entry);
}
}
} while (dir.Next());
}
PStringArray PPluginManager::GetPluginDirs()
{
PString env = ::getenv(ENV_PTLIB_PLUGIN_DIR);
if (env.IsEmpty())
env = ::getenv(ENV_PWLIB_PLUGIN_DIR);
if (env.IsEmpty())
env = P_DEFAULT_PLUGIN_DIR;
// split into directories on correct seperator
return env.Tokenise(DIR_SEP, PTrue);
}
PPluginManager & PPluginManager::GetPluginManager()
{
static PPluginManager systemPluginMgr;
return systemPluginMgr;
}
PBoolean PPluginManager::LoadPlugin(const PString & fileName)
{
PWaitAndSignal m(pluginsMutex);
PDynaLink *dll = new PDynaLink(fileName);
if (!dll->IsLoaded()) {
PTRACE(4, "PLUGIN\tFailed to open " << fileName);
}
else {
PDynaLink::Function fn;
if (!dll->GetFunction("PWLibPlugin_GetAPIVersion", fn))
PTRACE(2, "PLUGIN\t" << fileName << " is not a PWLib plugin");
else {
unsigned (*GetAPIVersion)() = (unsigned (*)())fn;
int version = (*GetAPIVersion)();
switch (version) {
case 0 : // old-style service plugins, and old-style codec plugins
{
// call the register function (if present)
if (!dll->GetFunction("PWLibPlugin_TriggerRegister", fn))
PTRACE(2, "PLUGIN\t" << fileName << " has no registration-trigger function");
else {
void (*triggerRegister)(PPluginManager *) = (void (*)(PPluginManager *))fn;
(*triggerRegister)(this);
}
}
// fall through to new version
case 1 : // factory style plugins
// call the notifier
CallNotifier(*dll, 0);
// add the plugin to the list of plugins
plugins.Append(dll);
return PTrue;
default:
PTRACE(2, "PLUGIN\t" << fileName << " uses version " << version << " of the PWLIB PLUGIN API, which is not supported");
break;
}
}
}
// loading the plugin failed - return error
dll->Close();
delete dll;
return PFalse;
}
PStringArray PPluginManager::GetPluginTypes() const
{
PWaitAndSignal n(servicesMutex);
PStringArray result;
for (PINDEX i = 0; i < services.GetSize(); i++) {
PString serviceType = services[i].serviceType;
if (result.GetStringsIndex(serviceType) == P_MAX_INDEX)
result.AppendString(services[i].serviceType);
}
return result;
}
PStringArray PPluginManager::GetPluginsProviding(const PString & serviceType) const
{
PWaitAndSignal n(servicesMutex);
PStringArray result;
for (PINDEX i = 0; i < services.GetSize(); i++) {
if (services[i].serviceType *= serviceType)
result.AppendString(services[i].serviceName);
}
return result;
}
PPluginServiceDescriptor * PPluginManager::GetServiceDescriptor (const PString & serviceName,
const PString & serviceType) const
{
PWaitAndSignal n(servicesMutex);
for (PINDEX i = 0; i < services.GetSize(); i++) {
if ((services[i].serviceName *= serviceName) &&
(services[i].serviceType *= serviceType))
return services[i].descriptor;
}
return NULL;
}
PObject * PPluginManager::CreatePluginsDevice(const PString & serviceName,
const PString & serviceType,
int userData) const
{
PDevicePluginServiceDescriptor * descr = (PDevicePluginServiceDescriptor *)GetServiceDescriptor(serviceName, serviceType);
if (descr != NULL)
return descr->CreateInstance(userData);
return NULL;
}
PObject * PPluginManager::CreatePluginsDeviceByName(const PString & deviceName,
const PString & serviceType,
int userData,
const PString & serviceName) const
{
// If have tab character, then have explicit driver name in device
PINDEX tab = deviceName.Find(PDevicePluginServiceDescriptor::SeparatorChar);
if (tab != P_MAX_INDEX)
return CreatePluginsDevice(deviceName.Left(tab), serviceType, userData);
PWaitAndSignal m(servicesMutex);
// If we know the service name of the device we want to create.
if (!serviceName) {
PDevicePluginServiceDescriptor * desc = (PDevicePluginServiceDescriptor *)GetServiceDescriptor(serviceName, serviceType);
if (desc != NULL && desc->ValidateDeviceName(deviceName, userData))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -