1
0
Fork 0

Refactor plugin load/unload to only require the name

development
ζeh Matt 2023-09-21 10:56:59 +03:00
parent c28653700a
commit 517c82604f
No known key found for this signature in database
GPG Key ID: 18CE582C71A225B0
1 changed files with 74 additions and 22 deletions

View File

@ -12,6 +12,7 @@
#include "formatfunctions.h"
#include <algorithm>
#include <shlwapi.h>
#include <vector>
/**
\brief List of plugins.
@ -66,6 +67,46 @@ static const char* pluginExtension = ".dp64";
static const char* pluginExtension = ".dp32";
#endif
/**
/brief Normalizes the plugin name. Strips the extension and path.
\param pluginName Can be name or partial plugin path.
\return The normalized plugin name.
*/
static std::string pluginNormalizeName(std::string pluginName)
{
auto pathPos = pluginName.find_last_of("\\/");
if(pathPos != std::string::npos)
pluginName = pluginName.substr(pathPos + 1);
auto extPos = pluginName.find_last_of(".");
if(extPos != std::string::npos)
pluginName = pluginName.substr(0, extPos);
return pluginName;
}
/**
\brief Returns the full path to the plugin.
\param pluginName Name of the plugin, the parameter must not contain the extension.
\return The full path to the plugin.
*/
static std::string pluginGetFullPath(std::string pluginName)
{
std::string pluginPath = StringUtils::Utf16ToUtf8(pluginDirectory) + "\\" + pluginName;
// Check if the plugin is a directory.
if(PathIsDirectoryW(StringUtils::Utf8ToUtf16(pluginPath).c_str()))
{
// Plugin is probably inside the directory.
pluginPath += "\\" + pluginName + pluginExtension;
}
else
{
// Ordinary file
pluginPath += pluginExtension;
}
return pluginPath;
}
/**
\brief Loads a plugin from the plugin directory.
\param pluginName Name of the plugin.
@ -78,11 +119,11 @@ bool pluginload(const char* pluginName, bool loadall)
if(!pluginName)
return false;
char name[MAX_PATH] = "";
strncpy_s(name, pluginName, _TRUNCATE);
// Normalize the plugin name, this can be potentially called from the pluginload command.
std::string name = pluginNormalizeName(pluginName);
if(!loadall)
strncat_s(name, pluginExtension, _TRUNCATE);
// Obtain the actual plugin path.
std::string pluginFullPath = pluginGetFullPath(name);
wchar_t currentDir[deflen] = L"";
if(!loadall)
@ -91,16 +132,13 @@ bool pluginload(const char* pluginName, bool loadall)
SetCurrentDirectoryW(pluginDirectory.c_str());
}
char searchName[deflen] = "";
sprintf_s(searchName, "%s\\%s", StringUtils::Utf16ToUtf8(pluginDirectory.c_str()).c_str(), name);
//Check to see if this plugin is already loaded
if(!loadall)
{
EXCLUSIVE_ACQUIRE(LockPluginList);
for(auto it = pluginList.begin(); it != pluginList.end(); ++it)
{
if(_stricmp(it->plugname, name) == 0 && it->isLoaded)
if(_stricmp(it->plugname, name.c_str()) == 0 && it->isLoaded)
{
dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] %s already loaded\n"), name);
SetCurrentDirectoryW(currentDir);
@ -110,7 +148,7 @@ bool pluginload(const char* pluginName, bool loadall)
}
//check if the file exists
if(!loadall && !PathFileExistsW(StringUtils::Utf8ToUtf16(searchName).c_str()))
if(!loadall && !PathFileExistsW(StringUtils::Utf8ToUtf16(pluginFullPath).c_str()))
{
dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] Cannot find plugin: %s\n"), name);
return false;
@ -119,7 +157,7 @@ bool pluginload(const char* pluginName, bool loadall)
//setup plugin data
memset(&pluginData, 0, sizeof(pluginData));
pluginData.initStruct.pluginHandle = curPluginHandle;
pluginData.hPlugin = LoadLibraryW(StringUtils::Utf8ToUtf16(searchName).c_str()); //load the plugin library
pluginData.hPlugin = LoadLibraryW(StringUtils::Utf8ToUtf16(pluginFullPath).c_str()); //load the plugin library
if(!pluginData.hPlugin)
{
dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] Failed to load plugin: %s\n"), name);
@ -139,8 +177,8 @@ bool pluginload(const char* pluginName, bool loadall)
pluginData.plugstop = (PLUGSTOP)GetProcAddress(pluginData.hPlugin, "plugstop");
pluginData.plugsetup = (PLUGSETUP)GetProcAddress(pluginData.hPlugin, "plugsetup");
strncpy_s(pluginData.plugpath, searchName, MAX_PATH);
strncpy_s(pluginData.plugname, name, MAX_PATH);
strncpy_s(pluginData.plugpath, pluginFullPath.c_str(), MAX_PATH);
strncpy_s(pluginData.plugname, name.c_str(), MAX_PATH);
//init plugin
if(!pluginData.pluginit(&pluginData.initStruct))
@ -278,21 +316,21 @@ bool pluginload(const char* pluginName, bool loadall)
*/
bool pluginunload(const char* pluginName, bool unloadall)
{
char name[MAX_PATH] = "";
strncpy_s(name, pluginName, _TRUNCATE);
if(!unloadall)
strncat_s(name, pluginExtension, _TRUNCATE);
// Normalize the plugin name.
std::string name = pluginNormalizeName(pluginName);
auto found = pluginList.end();
{
EXCLUSIVE_ACQUIRE(LockPluginList);
found = std::find_if(pluginList.begin(), pluginList.end(), [&name](const PLUG_DATA & a)
{
return _stricmp(a.plugname, name) == 0;
return _stricmp(a.plugname, name.c_str()) == 0;
});
}
// Will contain the actual plugin name if found.
std::string actualName = name;
if(found != pluginList.end())
{
bool canFreeLibrary = true;
@ -304,6 +342,9 @@ bool pluginunload(const char* pluginName, bool unloadall)
pluginexprfuncunregisterall(pluginHandle);
pluginformatfuncunregisterall(pluginHandle);
// Copy the actual name.
actualName = currentPlugin.plugname;
//remove the callbacks
{
EXCLUSIVE_ACQUIRE(LockPluginCallbackList);
@ -337,15 +378,16 @@ bool pluginunload(const char* pluginName, bool unloadall)
if(canFreeLibrary)
FreeLibrary(currentPlugin.hPlugin);
dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] %s unloaded\n"), name);
dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] %s unloaded\n"), actualName.c_str());
return true;
}
dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] %s not found\n"), name);
dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] %s not found\n"), actualName.c_str());
return false;
}
typedef BOOL(WINAPI* pfnAddDllDirectory)(LPCWSTR lpPathName);
// Returns a list of all available plugins in the specified directory without the extension.
static std::vector<std::wstring> enumerateAvailablePlugins(const std::wstring & pluginDir)
{
std::vector<std::wstring> result;
@ -362,6 +404,16 @@ static std::vector<std::wstring> enumerateAvailablePlugins(const std::wstring &
return result;
}
const auto stripExtension = [](const std::wstring & fileName)->std::wstring
{
size_t pos = fileName.find_last_of(L'.');
if(pos == std::wstring::npos)
{
return fileName;
}
return fileName.substr(0, pos);
};
do
{
// Check if directory
@ -376,7 +428,7 @@ static std::vector<std::wstring> enumerateAvailablePlugins(const std::wstring &
if(PathFileExistsW(pluginPath))
{
result.push_back(pluginName);
result.push_back(foundData.cFileName);
}
}
else
@ -394,7 +446,7 @@ static std::vector<std::wstring> enumerateAvailablePlugins(const std::wstring &
continue;
}
result.push_back(foundData.cFileName);
result.push_back(stripExtension(foundData.cFileName));
}
}
while(FindNextFileW(hSearch, &foundData));