2020-08-06 18:18:34 +08:00
|
|
|
//=====================================================================
|
|
|
|
// Copyright 2016-2018 (c), Advanced Micro Devices, Inc. All rights reserved.
|
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
// of this software and associated documentation files(the "Software"), to deal
|
|
|
|
// in the Software without restriction, including without limitation the rights
|
|
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
|
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
|
|
// furnished to do so, subject to the following conditions :
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
// THE SOFTWARE.
|
|
|
|
//
|
|
|
|
/// \file PluginManager.cpp
|
|
|
|
/// \version 3.1
|
|
|
|
/// \brief Declares the interface to the Compressonator & ArchitectMF SDK
|
|
|
|
//=====================================================================
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
#include "pluginmanager.h"
|
|
|
|
#include "plugininterface.h"
|
|
|
|
#include "cmp_fileio.h"
|
|
|
|
|
2020-08-06 18:18:34 +08:00
|
|
|
// Windows Header Files:
|
|
|
|
#ifdef _WIN32
|
|
|
|
#include <windows.h>
|
2021-09-08 10:54:22 +08:00
|
|
|
#define USE_NewLoader
|
2020-08-06 18:18:34 +08:00
|
|
|
#endif
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
#include <string>
|
2020-08-06 18:18:34 +08:00
|
|
|
|
|
|
|
#ifdef USE_NewLoader
|
2021-09-08 10:54:22 +08:00
|
|
|
#pragma warning(disable : 4091) //'fopen': This function or variable may be unsafe.
|
|
|
|
#include "imagehlp.h"
|
|
|
|
#pragma comment(lib, "imagehlp.lib")
|
2020-08-06 18:18:34 +08:00
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
bool GetDLLFileExports(LPCSTR szFileName, std::vector<std::string>& names)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
//printf("%s\n",__FUNCTION__);
|
|
|
|
_LOADED_IMAGE LoadedImage;
|
2020-08-06 18:18:34 +08:00
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
if (!MapAndLoad(szFileName, NULL, &LoadedImage, TRUE, TRUE))
|
2020-08-06 18:18:34 +08:00
|
|
|
return false;
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
_IMAGE_EXPORT_DIRECTORY* ImageExportDirectory;
|
|
|
|
ULONG DataSize;
|
2020-08-06 18:18:34 +08:00
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
ImageExportDirectory = (_IMAGE_EXPORT_DIRECTORY*)ImageDirectoryEntryToData(LoadedImage.MappedAddress, false, IMAGE_DIRECTORY_ENTRY_EXPORT, &DataSize);
|
|
|
|
if (ImageExportDirectory != NULL)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
DWORD* dExportNameAddress(0);
|
|
|
|
char* FileExportName;
|
2020-08-06 18:18:34 +08:00
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
dExportNameAddress = (DWORD*)ImageRvaToVa(LoadedImage.FileHeader, LoadedImage.MappedAddress, ImageExportDirectory->AddressOfNames, NULL);
|
|
|
|
if (!dExportNameAddress)
|
|
|
|
{
|
|
|
|
UnMapAndLoad(&LoadedImage);
|
|
|
|
return false;
|
|
|
|
}
|
2020-08-06 18:18:34 +08:00
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
for (size_t i = 0; i < ImageExportDirectory->NumberOfNames; i++)
|
|
|
|
{
|
|
|
|
FileExportName = (char*)ImageRvaToVa(LoadedImage.FileHeader, LoadedImage.MappedAddress, dExportNameAddress[i], NULL);
|
|
|
|
if (FileExportName)
|
|
|
|
names.push_back(FileExportName);
|
|
|
|
}
|
2020-08-06 18:18:34 +08:00
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
UnMapAndLoad(&LoadedImage);
|
|
|
|
|
|
|
|
// This code that does not use MapAndLoad() and is much lower level
|
|
|
|
// unsigned int nNoOfExports;
|
|
|
|
//
|
|
|
|
// HANDLE hFile;
|
|
|
|
// HANDLE hFileMapping;
|
|
|
|
// LPVOID lpFileBase;
|
|
|
|
// PIMAGE_DOS_HEADER pImg_DOS_Header;
|
|
|
|
// PIMAGE_NT_HEADERS pImg_NT_Header;
|
|
|
|
// PIMAGE_EXPORT_DIRECTORY pImg_Export_Dir;
|
|
|
|
//
|
|
|
|
// hFile = CreateFileA(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
|
|
|
// if (hFile == INVALID_HANDLE_VALUE)
|
|
|
|
// return false;
|
|
|
|
//
|
|
|
|
// hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
|
|
// if (hFileMapping == 0)
|
|
|
|
// {
|
|
|
|
// CloseHandle(hFile);
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
|
|
|
|
// if (lpFileBase == 0)
|
|
|
|
// {
|
|
|
|
// CloseHandle(hFileMapping);
|
|
|
|
// CloseHandle(hFile);
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// pImg_DOS_Header = (PIMAGE_DOS_HEADER)lpFileBase;
|
|
|
|
//
|
|
|
|
// pImg_NT_Header = (PIMAGE_NT_HEADERS)((BYTE*)pImg_DOS_Header + pImg_DOS_Header->e_lfanew);
|
|
|
|
//
|
|
|
|
// if (IsBadReadPtr(pImg_NT_Header, sizeof(IMAGE_NT_HEADERS)) || pImg_NT_Header->Signature != IMAGE_NT_SIGNATURE)
|
|
|
|
// {
|
|
|
|
// UnmapViewOfFile(lpFileBase);
|
|
|
|
// CloseHandle(hFileMapping);
|
|
|
|
// CloseHandle(hFile);
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// pImg_Export_Dir = (PIMAGE_EXPORT_DIRECTORY)pImg_NT_Header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
|
|
|
// if (!pImg_Export_Dir)
|
|
|
|
// {
|
|
|
|
// UnmapViewOfFile(lpFileBase);
|
|
|
|
// CloseHandle(hFileMapping);
|
|
|
|
// CloseHandle(hFile);
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// pImg_Export_Dir = (PIMAGE_EXPORT_DIRECTORY)ImageRvaToVa(pImg_NT_Header, pImg_DOS_Header, (DWORD)pImg_Export_Dir, 0);
|
|
|
|
//
|
|
|
|
// DWORD **ppdwNames = (DWORD **)pImg_Export_Dir->AddressOfNames;
|
|
|
|
//
|
|
|
|
// ppdwNames = (PDWORD*)ImageRvaToVa(pImg_NT_Header, pImg_DOS_Header, (DWORD)ppdwNames, 0);
|
|
|
|
// if (!ppdwNames)
|
|
|
|
// {
|
|
|
|
// UnmapViewOfFile(lpFileBase);
|
|
|
|
// CloseHandle(hFileMapping);
|
|
|
|
// CloseHandle(hFile);
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// nNoOfExports = pImg_Export_Dir->NumberOfNames;
|
|
|
|
//
|
|
|
|
// Bug here skips alternate names : error is in incr address of ppdwNames
|
|
|
|
// for (unsigned i = 0; i < nNoOfExports; i++)
|
|
|
|
// {
|
|
|
|
// char *szFunc = (PSTR)ImageRvaToVa(pImg_NT_Header, pImg_DOS_Header, (DWORD)*ppdwNames, 0);
|
|
|
|
// if (szFunc)
|
|
|
|
// names.push_back(szFunc);
|
|
|
|
// ppdwNames++;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// UnmapViewOfFile(lpFileBase);
|
|
|
|
// CloseHandle(hFileMapping);
|
|
|
|
// CloseHandle(hFile);
|
2020-08-06 18:18:34 +08:00
|
|
|
return true;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
PluginManager::PluginManager()
|
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
//printf("%s\n", __FUNCTION__);
|
|
|
|
|
2020-08-06 18:18:34 +08:00
|
|
|
m_pluginlistset = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
PluginManager::~PluginManager()
|
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
//printf("%s\n", __FUNCTION__);
|
|
|
|
|
2020-08-06 18:18:34 +08:00
|
|
|
clearPluginList();
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void PluginManager::registerStaticPlugin(char* pluginType, char* pluginName, void* makePlugin)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
//printf("%s\n", __FUNCTION__);
|
|
|
|
|
|
|
|
PluginDetails* curPlugin = new PluginDetails();
|
|
|
|
curPlugin->funcHandle = reinterpret_cast<PLUGIN_FACTORYFUNC>(makePlugin);
|
|
|
|
curPlugin->isStatic = true;
|
2020-08-06 18:18:34 +08:00
|
|
|
curPlugin->setType(pluginType);
|
|
|
|
curPlugin->setName(pluginName);
|
|
|
|
|
|
|
|
pluginRegister.push_back(curPlugin);
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void PluginManager::registerStaticPlugin(char* pluginType, char* pluginName, char* uuid, void* makePlugin)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
PluginDetails* curPlugin = new PluginDetails();
|
|
|
|
curPlugin->funcHandle = reinterpret_cast<PLUGIN_FACTORYFUNC>(makePlugin);
|
|
|
|
curPlugin->isStatic = true;
|
2020-08-06 18:18:34 +08:00
|
|
|
curPlugin->setType(pluginType);
|
|
|
|
curPlugin->setName(pluginName);
|
|
|
|
curPlugin->setUUID(uuid);
|
|
|
|
|
|
|
|
pluginRegister.push_back(curPlugin);
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void PluginManager::getPluginDetails(PluginDetails* curPlugin)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
//printf("%s\n", __FUNCTION__);
|
|
|
|
|
2020-08-06 18:18:34 +08:00
|
|
|
#ifdef _WIN32
|
|
|
|
HINSTANCE dllHandle;
|
|
|
|
|
|
|
|
dllHandle = LoadLibraryA(curPlugin->getFileName());
|
|
|
|
|
|
|
|
if (dllHandle != NULL)
|
|
|
|
{
|
|
|
|
PLUGIN_TEXTFUNC textFunc;
|
|
|
|
textFunc = reinterpret_cast<PLUGIN_TEXTFUNC>(GetProcAddress(dllHandle, "getPluginType"));
|
|
|
|
if (textFunc)
|
|
|
|
curPlugin->setType(textFunc());
|
|
|
|
|
|
|
|
textFunc = reinterpret_cast<PLUGIN_TEXTFUNC>(GetProcAddress(dllHandle, "getPluginName"));
|
|
|
|
if (textFunc)
|
|
|
|
curPlugin->setName(textFunc());
|
|
|
|
|
|
|
|
textFunc = reinterpret_cast<PLUGIN_TEXTFUNC>(GetProcAddress(dllHandle, "getPluginUUID"));
|
|
|
|
if (textFunc)
|
|
|
|
curPlugin->setUUID(textFunc());
|
|
|
|
|
|
|
|
textFunc = reinterpret_cast<PLUGIN_TEXTFUNC>(GetProcAddress(dllHandle, "getPluginCategory"));
|
|
|
|
if (textFunc)
|
|
|
|
curPlugin->setCategory(textFunc());
|
|
|
|
|
|
|
|
curPlugin->isRegistered = true;
|
|
|
|
|
|
|
|
FreeLibrary(dllHandle);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void PluginManager::clearPluginList()
|
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
//printf("%s\n", __FUNCTION__);
|
|
|
|
|
2020-08-06 18:18:34 +08:00
|
|
|
for (unsigned int i = 0; i < pluginRegister.size(); i++)
|
|
|
|
{
|
|
|
|
delete pluginRegister.at(i);
|
|
|
|
pluginRegister.at(i) = NULL;
|
|
|
|
}
|
|
|
|
pluginRegister.clear();
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void PluginManager::getPluginList(char* SubFolderName, bool append)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
//printf("%s\n", __FUNCTION__);
|
|
|
|
|
2020-08-06 18:18:34 +08:00
|
|
|
// Check for prior setting, if set clear for new one
|
|
|
|
if (m_pluginlistset)
|
|
|
|
{
|
|
|
|
if (!append)
|
|
|
|
clearPluginList();
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
m_pluginlistset = true;
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
WIN32_FIND_DATAA fd;
|
2021-09-08 10:54:22 +08:00
|
|
|
char fname[MAX_PATH];
|
2020-08-06 18:18:34 +08:00
|
|
|
|
|
|
|
//----------------------------------
|
|
|
|
// Load plugin List for processing
|
|
|
|
// Use an Enviornment var, search through systems path
|
|
|
|
// or use default app running folder.
|
|
|
|
//----------------------------------
|
|
|
|
char dirPath[MAX_PATH];
|
|
|
|
|
|
|
|
// v2.1 change - to check if path exists in PATH or AMDCOMPRESS_PLUGINS is set
|
|
|
|
// else use current exe directory
|
2021-09-08 10:54:22 +08:00
|
|
|
char* pPath;
|
2020-08-06 18:18:34 +08:00
|
|
|
size_t len;
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
_dupenv_s(&pPath, &len, "AMDCOMPRESS_PLUGINS");
|
|
|
|
#else
|
2021-09-08 10:54:22 +08:00
|
|
|
pPath = getenv("AMDCOMPRESS_PLUGINS") + '\0';
|
|
|
|
len = strlen(pPath);
|
2020-08-06 18:18:34 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if (len > 0)
|
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
snprintf(dirPath, 260, "%s", pPath + '\0');
|
2020-08-06 18:18:34 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bool pathFound = false;
|
|
|
|
|
|
|
|
//Get the exe directory
|
2021-09-08 10:54:22 +08:00
|
|
|
DWORD pathsize;
|
2020-08-06 18:18:34 +08:00
|
|
|
HMODULE hModule = GetModuleHandleA(NULL);
|
2021-09-08 10:54:22 +08:00
|
|
|
pathsize = GetModuleFileNameA(hModule, dirPath, MAX_PATH);
|
2020-08-06 18:18:34 +08:00
|
|
|
if (pathsize > 0)
|
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
char* appName = (strrchr(dirPath, '\\') + 1);
|
|
|
|
int pathLen = (int)strlen(dirPath);
|
|
|
|
int appNameLen = (int)strlen(appName);
|
2020-08-06 18:18:34 +08:00
|
|
|
|
|
|
|
// Null terminate the dirPath so that FileName is removed
|
2021-09-08 10:54:22 +08:00
|
|
|
pathLen = pathLen - appNameLen;
|
2020-08-06 18:18:34 +08:00
|
|
|
dirPath[pathLen] = 0;
|
|
|
|
if (dirPath[pathLen - 1] == '/' || dirPath[pathLen - 1] == '\\')
|
|
|
|
{
|
|
|
|
pathLen--;
|
|
|
|
dirPath[pathLen] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
strcat_s(dirPath, SubFolderName);
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
snprintf(fname, 260, "%s\\*.dll", dirPath);
|
2020-08-06 18:18:34 +08:00
|
|
|
|
|
|
|
HANDLE hFind = FindFirstFileA(fname, &fd);
|
|
|
|
|
|
|
|
if (hFind != INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
pathFound = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
FindClose(hFind);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pathFound)
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
_dupenv_s(&pPath, &len, "PATH");
|
|
|
|
#else
|
|
|
|
pPath = getenv("PATH");
|
2021-09-08 10:54:22 +08:00
|
|
|
len = strlen(pPath);
|
2020-08-06 18:18:34 +08:00
|
|
|
#endif
|
|
|
|
if (len > 0)
|
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
std::string s = pPath;
|
2020-08-06 18:18:34 +08:00
|
|
|
std::string delimiter = ";";
|
2021-09-08 10:54:22 +08:00
|
|
|
size_t pos = 0;
|
2020-08-06 18:18:34 +08:00
|
|
|
std::string token;
|
2021-09-08 10:54:22 +08:00
|
|
|
while ((pos = s.find(delimiter)) != std::string::npos)
|
|
|
|
{
|
2020-08-06 18:18:34 +08:00
|
|
|
token = s.substr(0, pos);
|
|
|
|
snprintf(dirPath, 260, "%s\\compressonatorCLI.exe", token.c_str());
|
|
|
|
if (CMP_FileExists(dirPath))
|
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
snprintf(dirPath, 260, "%s", token.c_str());
|
2020-08-06 18:18:34 +08:00
|
|
|
strcat_s(dirPath, SubFolderName);
|
|
|
|
pathFound = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
s.erase(0, pos + delimiter.length());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
2021-09-08 10:54:22 +08:00
|
|
|
strcpy_s(fname, dirPath);
|
2020-08-06 18:18:34 +08:00
|
|
|
#else
|
|
|
|
strcpy(fname, dirPath);
|
|
|
|
#endif
|
2021-09-08 10:54:22 +08:00
|
|
|
len = strlen(fname);
|
|
|
|
if (fname[len - 1] == '/' || fname[len - 1] == '\\')
|
|
|
|
strcat_s(fname, "*.dll");
|
|
|
|
else
|
|
|
|
strcat_s(fname, "\\*.dll");
|
2020-08-06 18:18:34 +08:00
|
|
|
HANDLE hFind = FindFirstFileA(fname, &fd);
|
|
|
|
|
|
|
|
if (hFind == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
FindClose(hFind);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
HINSTANCE dllHandle = NULL;
|
2020-08-06 18:18:34 +08:00
|
|
|
std::vector<std::string> names;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
snprintf(fname, MAX_PATH, "%s\\%s", dirPath, fd.cFileName);
|
2020-08-06 18:18:34 +08:00
|
|
|
|
|
|
|
#ifdef USE_NewLoader
|
2021-09-08 10:54:22 +08:00
|
|
|
|
|
|
|
//printf("GetDLL File exports %s\n", fd.cFileName);
|
2020-08-06 18:18:34 +08:00
|
|
|
// Valid only for Windows need one for Linux
|
|
|
|
names.clear();
|
|
|
|
GetDLLFileExports(fname, names);
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
if ((names.size() >= 3) && (names.size() <= 15))
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
bool bmakePlugin = false;
|
|
|
|
bool bgetPluginType = false;
|
|
|
|
bool bgetPluginName = false;
|
2020-08-06 18:18:34 +08:00
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
for (std::vector<std::string>::const_iterator str = names.begin(); str != names.end(); ++str)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
if (*str == "makePlugin")
|
|
|
|
bmakePlugin = true;
|
|
|
|
else if (*str == "getPluginType")
|
|
|
|
bgetPluginType = true;
|
|
|
|
else if (*str == "getPluginName")
|
|
|
|
bgetPluginName = true;
|
2020-08-06 18:18:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (bmakePlugin && bgetPluginType && bgetPluginName)
|
|
|
|
{
|
|
|
|
// we have a vaild plugin to register to use when needed save it!
|
2021-09-08 10:54:22 +08:00
|
|
|
PluginDetails* curPlugin = new PluginDetails();
|
2020-08-06 18:18:34 +08:00
|
|
|
curPlugin->setFileName(fname);
|
|
|
|
pluginRegister.push_back(curPlugin);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
dllHandle = LoadLibraryA(fname);
|
|
|
|
if (dllHandle != NULL)
|
|
|
|
{
|
|
|
|
// Is this DLL a plugin for us if so keep its type and name details
|
|
|
|
PLUGIN_FACTORYFUNC funcHandle;
|
|
|
|
funcHandle = reinterpret_cast<PLUGIN_FACTORYFUNC>(GetProcAddress(dllHandle, "makePlugin"));
|
2021-09-08 10:54:22 +08:00
|
|
|
if (funcHandle != NULL)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
PluginDetails* curPlugin = new PluginDetails();
|
2020-08-06 18:18:34 +08:00
|
|
|
//printf("new: %s\n", fname);
|
|
|
|
curPlugin->setFileName(fname);
|
|
|
|
|
|
|
|
PLUGIN_TEXTFUNC textFunc;
|
|
|
|
textFunc = reinterpret_cast<PLUGIN_TEXTFUNC>(GetProcAddress(dllHandle, "getPluginType"));
|
|
|
|
if (textFunc)
|
|
|
|
curPlugin->setType(textFunc());
|
|
|
|
|
|
|
|
textFunc = reinterpret_cast<PLUGIN_TEXTFUNC>(GetProcAddress(dllHandle, "getPluginName"));
|
|
|
|
if (textFunc)
|
|
|
|
curPlugin->setName(textFunc());
|
|
|
|
|
|
|
|
textFunc = reinterpret_cast<PLUGIN_TEXTFUNC>(GetProcAddress(dllHandle, "getPluginUUID"));
|
|
|
|
if (textFunc)
|
|
|
|
curPlugin->setUUID(textFunc());
|
|
|
|
|
|
|
|
textFunc = reinterpret_cast<PLUGIN_TEXTFUNC>(GetProcAddress(dllHandle, "getPluginCategory"));
|
|
|
|
if (textFunc)
|
|
|
|
curPlugin->setCategory(textFunc());
|
|
|
|
|
|
|
|
curPlugin->isRegistered = true;
|
|
|
|
|
|
|
|
pluginRegister.push_back(curPlugin);
|
|
|
|
}
|
|
|
|
FreeLibrary(dllHandle);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
2021-09-08 10:54:22 +08:00
|
|
|
catch (...)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (dllHandle != NULL)
|
|
|
|
FreeLibrary(dllHandle);
|
|
|
|
}
|
|
|
|
} while (FindNextFileA(hFind, &fd));
|
|
|
|
|
|
|
|
FindClose(hFind);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void* PluginManager::makeNewPluginInstance(int index)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (!pluginRegister.at(index)->isRegistered)
|
|
|
|
getPluginDetails(pluginRegister.at(index));
|
|
|
|
|
|
|
|
return pluginRegister.at(index)->makeNewInstance();
|
|
|
|
}
|
|
|
|
|
|
|
|
int PluginManager::getNumPlugins()
|
|
|
|
{
|
|
|
|
return static_cast<int>(pluginRegister.size());
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
char* PluginManager::getPluginName(int index)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (!pluginRegister.at(index)->isRegistered)
|
|
|
|
getPluginDetails(pluginRegister.at(index));
|
|
|
|
return pluginRegister.at(index)->getName();
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
char* PluginManager::getPluginUUID(int index)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (!pluginRegister.at(index)->isRegistered)
|
|
|
|
getPluginDetails(pluginRegister.at(index));
|
|
|
|
return pluginRegister.at(index)->getUUID();
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
char* PluginManager::getPluginCategory(int index)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (!pluginRegister.at(index)->isRegistered)
|
|
|
|
getPluginDetails(pluginRegister.at(index));
|
|
|
|
return pluginRegister.at(index)->getCategory();
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
char* PluginManager::getPluginType(int index)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (!pluginRegister.at(index)->isRegistered)
|
|
|
|
getPluginDetails(pluginRegister.at(index));
|
|
|
|
return pluginRegister.at(index)->getType();
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void* PluginManager::GetPlugin(char* type, const char* name)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (!m_pluginlistset)
|
|
|
|
{
|
|
|
|
getPluginList(DEFAULT_PLUGINLIST_DIR);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int numPlugins = getNumPlugins();
|
2021-09-08 10:54:22 +08:00
|
|
|
for (unsigned int i = 0; i < numPlugins; i++)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
PluginDetails* pPlugin = pluginRegister.at(i);
|
2020-08-06 18:18:34 +08:00
|
|
|
if (!pPlugin->isRegistered)
|
|
|
|
getPluginDetails(pPlugin);
|
2021-09-08 10:54:22 +08:00
|
|
|
//printf("%2d getPlugin(Type %s name %s) == [%s,%s] \n", i, getPluginType(i), getPluginName(i), type, name);
|
|
|
|
if ((strcmp(getPluginType(i), type) == 0) && (strcmp(getPluginName(i), name) == 0))
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
return ((void*)makeNewPluginInstance(i));
|
2020-08-06 18:18:34 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
bool PluginManager::RemovePlugin(char* type, char* name)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (!m_pluginlistset)
|
|
|
|
{
|
|
|
|
getPluginList(DEFAULT_PLUGINLIST_DIR);
|
|
|
|
}
|
|
|
|
|
|
|
|
int numPlugins = getNumPlugins();
|
2021-09-08 10:54:22 +08:00
|
|
|
for (int i = 0; i < numPlugins; i++)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (!pluginRegister.at(i)->isRegistered)
|
|
|
|
getPluginDetails(pluginRegister.at(i));
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
if ((strcmp(getPluginType(i), type) == 0) && (strcmp(getPluginName(i), name) == 0))
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
delete pluginRegister.at(i);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void* PluginManager::GetPlugin(char* uuid)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (!m_pluginlistset)
|
|
|
|
{
|
|
|
|
getPluginList(DEFAULT_PLUGINLIST_DIR);
|
|
|
|
}
|
|
|
|
|
|
|
|
int numPlugins = getNumPlugins();
|
2021-09-08 10:54:22 +08:00
|
|
|
for (int i = 0; i < numPlugins; i++)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (!pluginRegister.at(i)->isRegistered)
|
|
|
|
getPluginDetails(pluginRegister.at(i));
|
|
|
|
|
|
|
|
if (strcmp(getPluginUUID(i), uuid) == 0)
|
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
return ((void*)makeNewPluginInstance(i));
|
2020-08-06 18:18:34 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
bool PluginManager::PluginSupported(char* type, char* name)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
2021-09-08 10:54:22 +08:00
|
|
|
if (!type)
|
|
|
|
return false;
|
|
|
|
if (!name)
|
|
|
|
return false;
|
2020-08-06 18:18:34 +08:00
|
|
|
if (!m_pluginlistset)
|
|
|
|
{
|
|
|
|
getPluginList(DEFAULT_PLUGINLIST_DIR);
|
|
|
|
}
|
|
|
|
|
|
|
|
int numPlugins = getNumPlugins();
|
2021-09-08 10:54:22 +08:00
|
|
|
for (int i = 0; i < numPlugins; i++)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (!pluginRegister.at(i)->isRegistered)
|
|
|
|
getPluginDetails(pluginRegister.at(i));
|
|
|
|
|
|
|
|
//PrintInfo("Type : %s Name : %s\n",pluginManager.getPluginType(i),pluginManager.getPluginName(i));
|
2021-09-08 10:54:22 +08:00
|
|
|
if ((strcmp(getPluginType(i), type) == 0) && (strcmp(getPluginName(i), name) == 0))
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
return (true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------
|
|
|
|
|
|
|
|
PluginDetails::~PluginDetails()
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
2021-09-08 10:54:22 +08:00
|
|
|
if (dllHandle)
|
|
|
|
FreeLibrary(dllHandle);
|
2020-08-06 18:18:34 +08:00
|
|
|
#endif
|
|
|
|
clearMembers();
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void PluginDetails::setFileName(char* nm)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
2021-09-08 10:54:22 +08:00
|
|
|
strcpy_s(filename, MAX_PLUGIN_FILENAME_STR, nm);
|
2020-08-06 18:18:34 +08:00
|
|
|
#else
|
2021-09-08 10:54:22 +08:00
|
|
|
strcpy(filename, nm);
|
2020-08-06 18:18:34 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void PluginDetails::setName(char* nm)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
2021-09-08 10:54:22 +08:00
|
|
|
strcpy_s(pluginName, MAX_PLUGIN_NAME_STR, nm);
|
2020-08-06 18:18:34 +08:00
|
|
|
#else
|
2021-09-08 10:54:22 +08:00
|
|
|
strcpy(pluginName, nm);
|
2020-08-06 18:18:34 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void PluginDetails::setUUID(char* nm)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
strcpy_s(pluginUUID, MAX_PLUGIN_UUID_STR, nm);
|
|
|
|
#else
|
|
|
|
strcpy(pluginUUID, nm);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void PluginDetails::setType(char* nm)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
2021-09-08 10:54:22 +08:00
|
|
|
strcpy_s(pluginType, MAX_PLUGIN_TYPE_STR, nm);
|
2020-08-06 18:18:34 +08:00
|
|
|
#else
|
2021-09-08 10:54:22 +08:00
|
|
|
strcpy(pluginType, nm);
|
2020-08-06 18:18:34 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void PluginDetails::setCategory(char* nm)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
strcpy_s(pluginCategory, MAX_PLUGIN_CATEGORY_STR, nm);
|
|
|
|
#else
|
|
|
|
strcpy(pluginCategory, nm);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
void* PluginDetails::makeNewInstance()
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
if (isStatic)
|
|
|
|
{
|
|
|
|
return funcHandle();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
2021-09-08 10:54:22 +08:00
|
|
|
if (!dllHandle)
|
|
|
|
dllHandle = LoadLibraryA(filename);
|
2020-08-06 18:18:34 +08:00
|
|
|
|
2021-09-08 10:54:22 +08:00
|
|
|
if (dllHandle != NULL)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
funcHandle = reinterpret_cast<PLUGIN_FACTORYFUNC>(GetProcAddress(dllHandle, "makePlugin"));
|
2021-09-08 10:54:22 +08:00
|
|
|
if (funcHandle != NULL)
|
2020-08-06 18:18:34 +08:00
|
|
|
{
|
|
|
|
return funcHandle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|