diff --git a/src/dbg/plugin_loader.cpp b/src/dbg/plugin_loader.cpp index 947fa3d9..24fb6917 100644 --- a/src/dbg/plugin_loader.cpp +++ b/src/dbg/plugin_loader.cpp @@ -17,55 +17,57 @@ /** \brief List of plugins. */ -static std::vector pluginList; +static std::vector gPluginList; /** \brief Saved plugin directory */ -static std::wstring pluginDirectory; +static std::wstring gPluginDirectory; /** \brief The current plugin handle. */ -static int curPluginHandle = 0; +static int gCurPluginHandle = 0; /** \brief List of plugin callbacks. */ -static std::vector pluginCallbackList[CB_LAST]; +static std::vector gPluginCallbackList[CB_LAST]; /** \brief List of plugin commands. */ -static std::vector pluginCommandList; +static std::vector gPluginCommandList; /** \brief List of plugin menus. */ -static std::vector pluginMenuList; +static std::vector gPluginMenuList; /** \brief List of plugin menu entries. */ -static std::vector pluginMenuEntryList; +static std::vector gPluginMenuEntryList; /** \brief List of plugin exprfunctions. */ -static std::vector pluginExprfunctionList; +static std::vector gPluginExprfunctionList; /** \brief List of plugin formatfunctions. */ -static std::vector pluginFormatfunctionList; +static std::vector gPluginFormatfunctionList; -static PLUG_DATA pluginData; +/** +\brief Global data for the plugin currently being loaded +*/ +static PLUG_DATA gLoadingPlugin; -#ifdef _WIN64 -static const char* pluginExtension = ".dp64"; -#else -static const char* pluginExtension = ".dp32"; -#endif +/** +\brief Extension for the plugin file +*/ +static const wchar_t* gPluginExtension = ArchValue(L".dp32", L".dp64"); /** /brief Normalizes the plugin name. Strips the extension and path. @@ -77,152 +79,185 @@ 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("."); + auto extPos = pluginName.rfind(StringUtils::Utf16ToUtf8(gPluginExtension)); 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) +struct ChangeDirectory { - std::string pluginPath = StringUtils::Utf16ToUtf8(pluginDirectory) + "\\" + pluginName; + ChangeDirectory(const ChangeDirectory &) = delete; + ChangeDirectory(ChangeDirectory &&) = delete; - // Check if the plugin is in a sub-directory. - std::string pluginPathSubdir = pluginPath + "\\" + pluginName + pluginExtension; - if(PathFileExistsW(StringUtils::Utf8ToUtf16(pluginPathSubdir).c_str())) + explicit ChangeDirectory(const wchar_t* newDirectory) { - // Plugin resides in sub directory. - return pluginPathSubdir; + GetCurrentDirectoryW(_countof(mPreviousDirectory), mPreviousDirectory); + SetCurrentDirectoryW(newDirectory); } - // Check if plugin is from the main plugin directory. - std::string pluginPathWithExt = pluginPath + pluginExtension; - if(PathFileExistsW(StringUtils::Utf8ToUtf16(pluginPathWithExt).c_str())) + ~ChangeDirectory() { - // Plugin resides in main plugins directory. - return pluginPathWithExt; + SetCurrentDirectoryW(mPreviousDirectory); } - // Unable to determine the full path to the plugin, probably doesn't exist. - return ""; +private: + wchar_t mPreviousDirectory[deflen]; +}; + +static void* addDllDirectory(const wchar_t* newDirectory) +{ + typedef PVOID(WINAPI * pfnAddDllDirectory)(LPCWSTR); + static auto pAddDllDirectory = (pfnAddDllDirectory)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "AddDllDirectory"); + return pAddDllDirectory ? pAddDllDirectory(newDirectory) : nullptr; } +static bool removeDllDirectory(void* cookie) +{ + typedef BOOL(WINAPI * pfnRemoveDllDirectory)(PVOID Cookie); + static auto pRemoveDllDirectory = (pfnRemoveDllDirectory)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "RemoveDllDirectory"); + return pRemoveDllDirectory ? !!pRemoveDllDirectory(cookie) : false; +} + +struct DllDirectory +{ + DllDirectory(const DllDirectory &) = delete; + DllDirectory(DllDirectory &&) = delete; + + explicit DllDirectory(const wchar_t* directory) + { + if(directory != nullptr) + { + mCookie = addDllDirectory(directory); + } + } + + ~DllDirectory() + { + if(mCookie != nullptr) + { + removeDllDirectory(mCookie); + } + } + +private: + void* mCookie = nullptr; +}; + /** \brief Loads a plugin from the plugin directory. \param pluginName Name of the plugin. \param loadall true on unload all. \return true if it succeeds, false if it fails. */ -bool pluginload(const char* pluginName, bool loadall) +bool pluginload(const char* pluginName) { - //no empty plugin names allowed - if(!pluginName) + // No empty plugin names allowed + if(pluginName == nullptr || *pluginName == '\0') return false; - // Normalize the plugin name, this can be potentially called from the pluginload command. - std::string name = pluginNormalizeName(pluginName); + // Normalize the plugin name, for flexibility the pluginload command + auto normalizedName = pluginNormalizeName(pluginName); + auto pluginDirectory = gPluginDirectory; // Obtain the actual plugin path. - std::string pluginFullPath = pluginGetFullPath(name); - - wchar_t currentDir[deflen] = L""; - if(!loadall) + auto pluginPath = gPluginDirectory + L"\\" + StringUtils::Utf8ToUtf16(normalizedName); + auto pluginSubPath = pluginPath + L"\\" + StringUtils::Utf8ToUtf16(normalizedName) + gPluginExtension; + if(PathFileExistsW(pluginSubPath.c_str())) { - GetCurrentDirectoryW(deflen, currentDir); - SetCurrentDirectoryW(pluginDirectory.c_str()); + // Plugin resides in a subdirectory + pluginDirectory = pluginPath; + pluginPath = pluginSubPath; + } + else + { + pluginPath += gPluginExtension; } - //Check to see if this plugin is already loaded + // Check to see if this plugin is already loaded EXCLUSIVE_ACQUIRE(LockPluginList); - for(auto it = pluginList.begin(); it != pluginList.end(); ++it) + for(auto it = gPluginList.begin(); it != gPluginList.end(); ++it) { - if(_stricmp(it->plugname, name.c_str()) == 0) + if(_stricmp(it->plugname, normalizedName.c_str()) == 0) { - if(!loadall) - { - dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] %s already loaded\n"), it->plugname); - SetCurrentDirectoryW(currentDir); - } + dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] %s already loaded\n"), it->plugname); return false; } } - //check if the file exists - if(!loadall && !PathFileExistsW(StringUtils::Utf8ToUtf16(pluginFullPath).c_str())) + // Check if the file exists + if(!PathFileExistsW(pluginPath.c_str())) { - dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] Cannot find plugin: %s\n"), name.c_str()); + dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] Cannot find plugin: %s\n"), StringUtils::Utf16ToUtf8(pluginPath).c_str()); return false; } - //setup plugin data - memset(&pluginData, 0, sizeof(pluginData)); - pluginData.initStruct.pluginHandle = curPluginHandle; - pluginData.hPlugin = LoadLibraryW(StringUtils::Utf8ToUtf16(pluginFullPath).c_str()); //load the plugin library - if(!pluginData.hPlugin) + // Set the working and DLL load directories + ChangeDirectory cd(pluginDirectory.c_str()); + DllDirectory dd(pluginDirectory == gPluginDirectory ? nullptr : pluginDirectory.c_str()); + + // Setup plugin data + // NOTE: This is a global because during registration the plugin + // isn't in the gPluginList yet + gLoadingPlugin = {}; + gLoadingPlugin.initStruct.pluginHandle = gCurPluginHandle; + gLoadingPlugin.hPlugin = LoadLibraryW(pluginPath.c_str()); //load the plugin library + if(!gLoadingPlugin.hPlugin) { - dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] Failed to load plugin: %s\n"), name.c_str()); - SetCurrentDirectoryW(currentDir); + dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] Failed to load plugin: %s\n"), normalizedName.c_str()); return false; } - pluginData.pluginit = (PLUGINIT)GetProcAddress(pluginData.hPlugin, "pluginit"); - if(!pluginData.pluginit) + gLoadingPlugin.pluginit = (PLUGINIT)GetProcAddress(gLoadingPlugin.hPlugin, "pluginit"); + if(!gLoadingPlugin.pluginit) { - dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] Export \"pluginit\" not found in plugin: %s\n"), name.c_str()); + dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] Export \"pluginit\" not found in plugin: %s\n"), normalizedName.c_str()); for(int i = CB_INITDEBUG; i < CB_LAST; i++) - pluginunregistercallback(curPluginHandle, CBTYPE(i)); - FreeLibrary(pluginData.hPlugin); - SetCurrentDirectoryW(currentDir); + pluginunregistercallback(gCurPluginHandle, CBTYPE(i)); + FreeLibrary(gLoadingPlugin.hPlugin); return false; } - pluginData.plugstop = (PLUGSTOP)GetProcAddress(pluginData.hPlugin, "plugstop"); - pluginData.plugsetup = (PLUGSETUP)GetProcAddress(pluginData.hPlugin, "plugsetup"); + gLoadingPlugin.plugstop = (PLUGSTOP)GetProcAddress(gLoadingPlugin.hPlugin, "plugstop"); + gLoadingPlugin.plugsetup = (PLUGSETUP)GetProcAddress(gLoadingPlugin.hPlugin, "plugsetup"); - strncpy_s(pluginData.plugpath, pluginFullPath.c_str(), MAX_PATH); - strncpy_s(pluginData.plugname, name.c_str(), MAX_PATH); + strncpy_s(gLoadingPlugin.plugpath, StringUtils::Utf16ToUtf8(pluginPath).c_str(), _TRUNCATE); + strncpy_s(gLoadingPlugin.plugname, normalizedName.c_str(), _TRUNCATE); - //init plugin - if(!pluginData.pluginit(&pluginData.initStruct)) + // Init plugin + if(!gLoadingPlugin.pluginit(&gLoadingPlugin.initStruct)) { - dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] pluginit failed for plugin: %s\n"), name.c_str()); + dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] pluginit failed for plugin: %s\n"), normalizedName.c_str()); for(int i = CB_INITDEBUG; i < CB_LAST; i++) - pluginunregistercallback(curPluginHandle, CBTYPE(i)); - FreeLibrary(pluginData.hPlugin); - SetCurrentDirectoryW(currentDir); + pluginunregistercallback(gCurPluginHandle, CBTYPE(i)); + FreeLibrary(gLoadingPlugin.hPlugin); return false; } - if(pluginData.initStruct.sdkVersion < PLUG_SDKVERSION) //the plugin SDK is not compatible + if(gLoadingPlugin.initStruct.sdkVersion < PLUG_SDKVERSION) //the plugin SDK is not compatible { - dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] %s is incompatible with this SDK version\n"), pluginData.initStruct.pluginName); + dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] %s is incompatible with this SDK version\n"), gLoadingPlugin.initStruct.pluginName); for(int i = CB_INITDEBUG; i < CB_LAST; i++) - pluginunregistercallback(curPluginHandle, CBTYPE(i)); - FreeLibrary(pluginData.hPlugin); - SetCurrentDirectoryW(currentDir); + pluginunregistercallback(gCurPluginHandle, CBTYPE(i)); + FreeLibrary(gLoadingPlugin.hPlugin); return false; } - dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] %s v%d Loaded!\n"), pluginData.initStruct.pluginName, pluginData.initStruct.pluginVersion); + dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] %s v%d Loaded!\n"), gLoadingPlugin.initStruct.pluginName, gLoadingPlugin.initStruct.pluginVersion); - //auto-register callbacks for certain export names - auto cbPlugin = CBPLUGIN(GetProcAddress(pluginData.hPlugin, "CBALLEVENTS")); + // Auto-register callbacks for certain export names + auto cbPlugin = CBPLUGIN(GetProcAddress(gLoadingPlugin.hPlugin, "CBALLEVENTS")); if(cbPlugin) { for(int i = CB_INITDEBUG; i < CB_LAST; i++) - pluginregistercallback(curPluginHandle, CBTYPE(i), cbPlugin); + pluginregistercallback(gCurPluginHandle, CBTYPE(i), cbPlugin); } auto regExport = [](const char* exportname, CBTYPE cbType) { - auto cbPlugin = CBPLUGIN(GetProcAddress(pluginData.hPlugin, exportname)); + auto cbPlugin = CBPLUGIN(GetProcAddress(gLoadingPlugin.hPlugin, exportname)); if(cbPlugin) - pluginregistercallback(curPluginHandle, cbType, cbPlugin); + pluginregistercallback(gCurPluginHandle, cbType, cbPlugin); }; regExport("CBINITDEBUG", CB_INITDEBUG); regExport("CBSTOPDEBUG", CB_STOPDEBUG); - regExport("CB_STOPPINGDEBUG", CB_STOPPINGDEBUG); + regExport("CBSTOPPINGDEBUG", CB_STOPPINGDEBUG); regExport("CBCREATEPROCESS", CB_CREATEPROCESS); regExport("CBEXITPROCESS", CB_EXITPROCESS); regExport("CBCREATETHREAD", CB_CREATETHREAD); @@ -253,16 +288,16 @@ bool pluginload(const char* pluginName, bool loadall) regExport("CBVALTOSTRING", CB_VALTOSTRING); regExport("CBMENUPREPARE", CB_MENUPREPARE); - //add plugin menus + // Add plugin menus { SectionLocker menuLock; //exclusive lock auto addPluginMenu = [](GUIMENUTYPE type) { - int hNewMenu = GuiMenuAdd(type, pluginData.initStruct.pluginName); + int hNewMenu = GuiMenuAdd(type, gLoadingPlugin.initStruct.pluginName); if(hNewMenu == -1) { - dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] GuiMenuAdd(%d) failed for plugin: %s\n"), type, pluginData.initStruct.pluginName); + dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] GuiMenuAdd(%d) failed for plugin: %s\n"), type, gLoadingPlugin.initStruct.pluginName); return -1; } else @@ -270,45 +305,46 @@ bool pluginload(const char* pluginName, bool loadall) PLUG_MENU newMenu; newMenu.hEntryMenu = hNewMenu; newMenu.hParentMenu = type; - newMenu.pluginHandle = pluginData.initStruct.pluginHandle; - pluginMenuList.push_back(newMenu); + newMenu.pluginHandle = gLoadingPlugin.initStruct.pluginHandle; + gPluginMenuList.push_back(newMenu); return newMenu.hEntryMenu; } }; - pluginData.hMenu = addPluginMenu(GUI_PLUGIN_MENU); - pluginData.hMenuDisasm = addPluginMenu(GUI_DISASM_MENU); - pluginData.hMenuDump = addPluginMenu(GUI_DUMP_MENU); - pluginData.hMenuStack = addPluginMenu(GUI_STACK_MENU); - pluginData.hMenuGraph = addPluginMenu(GUI_GRAPH_MENU); - pluginData.hMenuMemmap = addPluginMenu(GUI_MEMMAP_MENU); - pluginData.hMenuSymmod = addPluginMenu(GUI_SYMMOD_MENU); + gLoadingPlugin.hMenu = addPluginMenu(GUI_PLUGIN_MENU); + gLoadingPlugin.hMenuDisasm = addPluginMenu(GUI_DISASM_MENU); + gLoadingPlugin.hMenuDump = addPluginMenu(GUI_DUMP_MENU); + gLoadingPlugin.hMenuStack = addPluginMenu(GUI_STACK_MENU); + gLoadingPlugin.hMenuGraph = addPluginMenu(GUI_GRAPH_MENU); + gLoadingPlugin.hMenuMemmap = addPluginMenu(GUI_MEMMAP_MENU); + gLoadingPlugin.hMenuSymmod = addPluginMenu(GUI_SYMMOD_MENU); } - //add the plugin to the list + // Add the plugin to the list { SectionLocker pluginLock; //exclusive lock - pluginList.push_back(pluginData); + gPluginList.push_back(gLoadingPlugin); } - //setup plugin - if(pluginData.plugsetup) + // Setup plugin + if(gLoadingPlugin.plugsetup) { PLUG_SETUPSTRUCT setupStruct; setupStruct.hwndDlg = GuiGetWindowHandle(); - setupStruct.hMenu = pluginData.hMenu; - setupStruct.hMenuDisasm = pluginData.hMenuDisasm; - setupStruct.hMenuDump = pluginData.hMenuDump; - setupStruct.hMenuStack = pluginData.hMenuStack; - setupStruct.hMenuGraph = pluginData.hMenuGraph; - setupStruct.hMenuMemmap = pluginData.hMenuMemmap; - setupStruct.hMenuSymmod = pluginData.hMenuSymmod; - pluginData.plugsetup(&setupStruct); + setupStruct.hMenu = gLoadingPlugin.hMenu; + setupStruct.hMenuDisasm = gLoadingPlugin.hMenuDisasm; + setupStruct.hMenuDump = gLoadingPlugin.hMenuDump; + setupStruct.hMenuStack = gLoadingPlugin.hMenuStack; + setupStruct.hMenuGraph = gLoadingPlugin.hMenuGraph; + setupStruct.hMenuMemmap = gLoadingPlugin.hMenuMemmap; + setupStruct.hMenuSymmod = gLoadingPlugin.hMenuSymmod; + gLoadingPlugin.plugsetup(&setupStruct); } - curPluginHandle++; + gCurPluginHandle++; + + // Clear the loading plugin structure (since it's now in the plugin list) + gLoadingPlugin = {}; - if(!loadall) - SetCurrentDirectoryW(currentDir); return true; } @@ -323,10 +359,10 @@ bool pluginunload(const char* pluginName, bool unloadall) // Normalize the plugin name. std::string name = pluginNormalizeName(pluginName); - auto found = pluginList.end(); + auto found = gPluginList.end(); { EXCLUSIVE_ACQUIRE(LockPluginList); - found = std::find_if(pluginList.begin(), pluginList.end(), [&name](const PLUG_DATA & a) + found = std::find_if(gPluginList.begin(), gPluginList.end(), [&name](const PLUG_DATA & a) { return _stricmp(a.plugname, name.c_str()) == 0; }); @@ -335,7 +371,7 @@ bool pluginunload(const char* pluginName, bool unloadall) // Will contain the actual plugin name if found. std::string actualName = name; - if(found != pluginList.end()) + if(found != gPluginList.end()) { bool canFreeLibrary = true; auto currentPlugin = *found; @@ -352,7 +388,7 @@ bool pluginunload(const char* pluginName, bool unloadall) //remove the callbacks { EXCLUSIVE_ACQUIRE(LockPluginCallbackList); - for(auto & cbList : pluginCallbackList) + for(auto & cbList : gPluginCallbackList) { for(auto it = cbList.begin(); it != cbList.end();) { @@ -376,7 +412,7 @@ bool pluginunload(const char* pluginName, bool unloadall) if(!unloadall) { //remove from main pluginlist. We do this so unloadall doesn't try to unload an already released plugin - pluginList.erase(found); + gPluginList.erase(found); } } @@ -389,17 +425,15 @@ bool pluginunload(const char* pluginName, bool unloadall) 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 enumerateAvailablePlugins(const std::wstring & pluginDir) { std::vector result; - const std::wstring pluginExt = StringUtils::Utf8ToUtf16(pluginExtension); + const std::wstring pluginExt = gPluginExtension; wchar_t searchQuery[deflen] = L""; - swprintf_s(searchQuery, L"%s\\*.*", pluginDir.c_str()); + swprintf_s(searchQuery, L"%s\\*", pluginDir.c_str()); WIN32_FIND_DATAW foundData; HANDLE hSearch = FindFirstFileW(searchQuery, &foundData); @@ -408,7 +442,7 @@ static std::vector enumerateAvailablePlugins(const std::wstring & return result; } - const auto stripExtension = [](const std::wstring & fileName)->std::wstring + const auto stripExtension = [](const std::wstring & fileName) -> std::wstring { size_t pos = fileName.find_last_of(L'.'); if(pos == std::wstring::npos) @@ -450,7 +484,16 @@ static std::vector enumerateAvailablePlugins(const std::wstring & continue; } - result.push_back(stripExtension(foundData.cFileName)); + auto pluginName = stripExtension(foundData.cFileName); + auto pluginFolderPath = pluginDir + L"\\" + pluginName + L"\\" + pluginName + gPluginExtension; + if(PathFileExistsW(pluginFolderPath.c_str())) + { + dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] Ignoring top-level plugin in favor of the directory 'plugins\\%s'\n"), StringUtils::Utf16ToUtf8(pluginName).c_str()); + } + else + { + result.push_back(pluginName); + } } } while(FindNextFileW(hSearch, &foundData)); @@ -470,47 +513,30 @@ static std::vector enumerateAvailablePlugins(const std::wstring & void pluginloadall(const char* pluginDir) { //reserve menu space - pluginMenuList.reserve(1024); - pluginMenuEntryList.reserve(1024); + gPluginMenuList.reserve(1024); + gPluginMenuEntryList.reserve(1024); //load new plugins wchar_t currentDir[deflen] = L""; - pluginDirectory = StringUtils::Utf8ToUtf16(pluginDir); - - //add the plugins directory as valid dependency directory - static auto pAddDllDirectory = (pfnAddDllDirectory)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "AddDllDirectory"); - if(pAddDllDirectory) - pAddDllDirectory(pluginDirectory.c_str()); + gPluginDirectory = StringUtils::Utf8ToUtf16(pluginDir); // Enumerate all plugins from plugins directory. const auto availablePlugins = enumerateAvailablePlugins(StringUtils::Utf8ToUtf16(pluginDir)); - // Check the sorted list for duplicate names. - for(size_t i = 1; i < availablePlugins.size(); ++i) - { - if(availablePlugins[i] == availablePlugins[i - 1]) - { - dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN] Plugin with same name found: %s, will only load plugin using sub-directory.\n"), StringUtils::Utf16ToUtf8(availablePlugins[i]).c_str()); - } - } - - GetCurrentDirectoryW(deflen, currentDir); - SetCurrentDirectoryW(pluginDirectory.c_str()); + // Add the plugins directory as valid dependency directory + auto pluginDirectoryCookie = addDllDirectory(gPluginDirectory.c_str()); for(const std::wstring & pluginName : availablePlugins) { - // Check if the plugin is a sub-directory and also add it to the search paths. - std::wstring pluginPath = pluginDirectory + L"\\" + pluginName; - - if(PathIsDirectoryW(pluginPath.c_str())) - { - pAddDllDirectory(pluginPath.c_str()); - } - - pluginload(StringUtils::Utf16ToUtf8(pluginName).c_str(), true); + dprintf("[pluginload] %S\n", pluginName.c_str()); + pluginload(StringUtils::Utf16ToUtf8(pluginName).c_str()); } - SetCurrentDirectoryW(currentDir); + // Remove the plugins directory after loading finished + if(pluginDirectoryCookie != nullptr) + { + removeDllDirectory(pluginDirectoryCookie); + } } /** @@ -522,7 +548,7 @@ void pluginunloadall() const auto pluginListCopy = []() { SHARED_ACQUIRE(LockPluginList); - return pluginList; + return gPluginList; }(); // Unload all plugins. @@ -531,7 +557,7 @@ void pluginunloadall() // Remove all plugins from the list. SHARED_ACQUIRE(LockPluginList); - pluginList.clear(); + gPluginList.clear(); SHARED_RELEASE(); } @@ -542,7 +568,7 @@ void pluginunloadall() void plugincmdunregisterall(int pluginHandle) { SHARED_ACQUIRE(LockPluginCommandList); - auto commandList = pluginCommandList; //copy for thread-safety reasons + auto commandList = gPluginCommandList; //copy for thread-safety reasons SHARED_RELEASE(); for(auto itr = commandList.begin(); itr != commandList.end();) { @@ -566,7 +592,7 @@ void plugincmdunregisterall(int pluginHandle) void pluginexprfuncunregisterall(int pluginHandle) { SHARED_ACQUIRE(LockPluginExprfunctionList); - auto exprFuncList = pluginExprfunctionList; //copy for thread-safety reasons + auto exprFuncList = gPluginExprfunctionList; //copy for thread-safety reasons SHARED_RELEASE(); auto i = exprFuncList.begin(); while(i != exprFuncList.end()) @@ -589,7 +615,7 @@ void pluginexprfuncunregisterall(int pluginHandle) void pluginformatfuncunregisterall(int pluginHandle) { SHARED_ACQUIRE(LockPluginFormatfunctionList); - auto formatFuncList = pluginFormatfunctionList; //copy for thread-safety reasons + auto formatFuncList = gPluginFormatfunctionList; //copy for thread-safety reasons SHARED_RELEASE(); auto i = formatFuncList.begin(); while(i != formatFuncList.end()) @@ -619,7 +645,7 @@ void pluginregistercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin) cbStruct.cbType = cbType; cbStruct.cbPlugin = cbPlugin; EXCLUSIVE_ACQUIRE(LockPluginCallbackList); - pluginCallbackList[cbType].push_back(cbStruct); + gPluginCallbackList[cbType].push_back(cbStruct); } /** @@ -630,7 +656,7 @@ void pluginregistercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin) bool pluginunregistercallback(int pluginHandle, CBTYPE cbType) { EXCLUSIVE_ACQUIRE(LockPluginCallbackList); - auto & cbList = pluginCallbackList[cbType]; + auto & cbList = gPluginCallbackList[cbType]; for(auto it = cbList.begin(); it != cbList.end();) { if(it->pluginHandle == pluginHandle) @@ -651,10 +677,10 @@ bool pluginunregistercallback(int pluginHandle, CBTYPE cbType) */ void plugincbcall(CBTYPE cbType, void* callbackInfo) { - if(pluginCallbackList[cbType].empty()) + if(gPluginCallbackList[cbType].empty()) return; SHARED_ACQUIRE(LockPluginCallbackList); - auto cbList = pluginCallbackList[cbType]; //copy for thread-safety reasons + auto cbList = gPluginCallbackList[cbType]; //copy for thread-safety reasons SHARED_RELEASE(); for(const auto & currentCallback : cbList) currentCallback.cbPlugin(cbType, callbackInfo); @@ -667,18 +693,18 @@ void plugincbcall(CBTYPE cbType, void* callbackInfo) */ bool plugincbempty(CBTYPE cbType) { - return pluginCallbackList[cbType].empty(); + return gPluginCallbackList[cbType].empty(); } static bool findPluginName(int pluginHandle, String & name) { SHARED_ACQUIRE(LockPluginList); - if(pluginData.initStruct.pluginHandle == pluginHandle) + if(gLoadingPlugin.initStruct.pluginHandle == pluginHandle) { - name = pluginData.initStruct.pluginName; + name = gLoadingPlugin.initStruct.pluginName; return true; } - for(auto & plugin : pluginList) + for(auto & plugin : gPluginList) { if(plugin.initStruct.pluginHandle == pluginHandle) { @@ -714,7 +740,7 @@ bool plugincmdregister(int pluginHandle, const char* command, CBPLUGINCOMMAND cb return false; } EXCLUSIVE_ACQUIRE(LockPluginCommandList); - pluginCommandList.push_back(plugCmd); + gPluginCommandList.push_back(plugCmd); EXCLUSIVE_RELEASE(); dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN, %s] Command \"%s\" registered!\n"), plugName.c_str(), command); return true; @@ -734,12 +760,12 @@ bool plugincmdunregister(int pluginHandle, const char* command) if(!findPluginName(pluginHandle, plugName)) return false; EXCLUSIVE_ACQUIRE(LockPluginCommandList); - for(auto it = pluginCommandList.begin(); it != pluginCommandList.end(); ++it) + for(auto it = gPluginCommandList.begin(); it != gPluginCommandList.end(); ++it) { const auto & currentCommand = *it; if(currentCommand.pluginHandle == pluginHandle && !strcmp(currentCommand.command, command)) { - pluginCommandList.erase(it); + gPluginCommandList.erase(it); EXCLUSIVE_RELEASE(); if(!dbgcmddel(command)) goto beach; @@ -764,9 +790,9 @@ int pluginmenuadd(int hMenu, const char* title) return -1; EXCLUSIVE_ACQUIRE(LockPluginMenuList); int nFound = -1; - for(unsigned int i = 0; i < pluginMenuList.size(); i++) + for(unsigned int i = 0; i < gPluginMenuList.size(); i++) { - if(pluginMenuList.at(i).hEntryMenu == hMenu) + if(gPluginMenuList.at(i).hEntryMenu == hMenu) { nFound = i; break; @@ -776,10 +802,10 @@ int pluginmenuadd(int hMenu, const char* title) return -1; int hMenuNew = GuiMenuAdd(hMenu, title); PLUG_MENU newMenu; - newMenu.pluginHandle = pluginMenuList.at(nFound).pluginHandle; + newMenu.pluginHandle = gPluginMenuList.at(nFound).pluginHandle; newMenu.hEntryMenu = hMenuNew; newMenu.hParentMenu = hMenu; - pluginMenuList.push_back(newMenu); + gPluginMenuList.push_back(newMenu); return hMenuNew; } @@ -797,7 +823,7 @@ bool pluginmenuaddentry(int hMenu, int hEntry, const char* title) EXCLUSIVE_ACQUIRE(LockPluginMenuList); int pluginHandle = -1; //find plugin handle - for(const auto & currentMenu : pluginMenuList) + for(const auto & currentMenu : gPluginMenuList) { if(currentMenu.hEntryMenu == hMenu) { @@ -808,7 +834,7 @@ bool pluginmenuaddentry(int hMenu, int hEntry, const char* title) if(pluginHandle == -1) //not found return false; //search if hEntry was previously used - for(const auto & currentMenu : pluginMenuEntryList) + for(const auto & currentMenu : gPluginMenuEntryList) if(currentMenu.pluginHandle == pluginHandle && currentMenu.hEntryPlugin == hEntry) return false; int hNewEntry = GuiMenuAddEntry(hMenu, title); @@ -819,7 +845,7 @@ bool pluginmenuaddentry(int hMenu, int hEntry, const char* title) newMenu.hParentMenu = hMenu; newMenu.hEntryPlugin = hEntry; newMenu.pluginHandle = pluginHandle; - pluginMenuEntryList.push_back(newMenu); + gPluginMenuEntryList.push_back(newMenu); return true; } @@ -831,7 +857,7 @@ bool pluginmenuaddentry(int hMenu, int hEntry, const char* title) bool pluginmenuaddseparator(int hMenu) { SHARED_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuList) + for(const auto & currentMenu : gPluginMenuList) { if(currentMenu.hEntryMenu == hMenu) { @@ -849,17 +875,17 @@ bool pluginmenuaddseparator(int hMenu) static void pluginmenuclear_helper(int hMenu) { //delete menu entries - for(auto i = pluginMenuEntryList.size() - 1; i != -1; i--) - if(hMenu == pluginMenuEntryList.at(i).hParentMenu) //we found an entry that has the menu as parent - pluginMenuEntryList.erase(pluginMenuEntryList.begin() + i); + for(auto i = gPluginMenuEntryList.size() - 1; i != -1; i--) + if(hMenu == gPluginMenuEntryList.at(i).hParentMenu) //we found an entry that has the menu as parent + gPluginMenuEntryList.erase(gPluginMenuEntryList.begin() + i); //delete the menus std::vector menuClearQueue; - for(auto i = pluginMenuList.size() - 1; i != -1; i--) + for(auto i = gPluginMenuList.size() - 1; i != -1; i--) { - if(hMenu == pluginMenuList.at(i).hParentMenu) //we found a menu that has the menu as parent + if(hMenu == gPluginMenuList.at(i).hParentMenu) //we found a menu that has the menu as parent { - menuClearQueue.push_back(pluginMenuList.at(i).hEntryMenu); - pluginMenuList.erase(pluginMenuList.begin() + i); + menuClearQueue.push_back(gPluginMenuList.at(i).hEntryMenu); + gPluginMenuList.erase(gPluginMenuList.begin() + i); } } //recursively clear the menus @@ -876,14 +902,14 @@ bool pluginmenuclear(int hMenu, bool erase) { EXCLUSIVE_ACQUIRE(LockPluginMenuList); pluginmenuclear_helper(hMenu); - for(auto it = pluginMenuList.begin(); it != pluginMenuList.end(); ++it) + for(auto it = gPluginMenuList.begin(); it != gPluginMenuList.end(); ++it) { const auto & currentMenu = *it; if(currentMenu.hEntryMenu == hMenu) { if(erase) { - it = pluginMenuList.erase(it); + it = gPluginMenuList.erase(it); GuiMenuRemove(hMenu); } else @@ -904,8 +930,8 @@ void pluginmenucall(int hEntry) return; SectionLocker menuLock; //shared lock - auto i = pluginMenuEntryList.begin(); - while(i != pluginMenuEntryList.end()) + auto i = gPluginMenuEntryList.begin(); + while(i != gPluginMenuEntryList.end()) { const auto currentMenu = *i; ++i; @@ -914,7 +940,7 @@ void pluginmenucall(int hEntry) PLUG_CB_MENUENTRY menuEntryInfo; menuEntryInfo.hEntry = currentMenu.hEntryPlugin; SectionLocker callbackLock; //shared lock - const auto & cbList = pluginCallbackList[CB_MENUENTRY]; + const auto & cbList = gPluginCallbackList[CB_MENUENTRY]; for(auto j = cbList.begin(); j != cbList.end();) { auto currentCallback = *j++; @@ -968,7 +994,7 @@ bool pluginwineventglobal(MSG* message) void pluginmenuseticon(int hMenu, const ICONDATA* icon) { SHARED_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuList) + for(const auto & currentMenu : gPluginMenuList) { if(currentMenu.hEntryMenu == hMenu) { @@ -989,7 +1015,7 @@ void pluginmenuentryseticon(int pluginHandle, int hEntry, const ICONDATA* icon) if(hEntry == -1) return; SHARED_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuEntryList) + for(const auto & currentMenu : gPluginMenuEntryList) { if(currentMenu.pluginHandle == pluginHandle && currentMenu.hEntryPlugin == hEntry) { @@ -1004,7 +1030,7 @@ void pluginmenuentrysetchecked(int pluginHandle, int hEntry, bool checked) if(hEntry == -1) return; SHARED_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuEntryList) + for(const auto & currentMenu : gPluginMenuEntryList) { if(currentMenu.pluginHandle == pluginHandle && currentMenu.hEntryPlugin == hEntry) { @@ -1017,7 +1043,7 @@ void pluginmenuentrysetchecked(int pluginHandle, int hEntry, bool checked) void pluginmenusetvisible(int pluginHandle, int hMenu, bool visible) { SHARED_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuList) + for(const auto & currentMenu : gPluginMenuList) { if(currentMenu.hEntryMenu == hMenu) { @@ -1032,7 +1058,7 @@ void pluginmenuentrysetvisible(int pluginHandle, int hEntry, bool visible) if(hEntry == -1) return; SHARED_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuEntryList) + for(const auto & currentMenu : gPluginMenuEntryList) { if(currentMenu.pluginHandle == pluginHandle && currentMenu.hEntryPlugin == hEntry) { @@ -1047,7 +1073,7 @@ void pluginmenusetname(int pluginHandle, int hMenu, const char* name) if(!name) return; SHARED_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuList) + for(const auto & currentMenu : gPluginMenuList) { if(currentMenu.hEntryMenu == hMenu) { @@ -1062,7 +1088,7 @@ void pluginmenuentrysetname(int pluginHandle, int hEntry, const char* name) if(hEntry == -1 || !name) return; SHARED_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuEntryList) + for(const auto & currentMenu : gPluginMenuEntryList) { if(currentMenu.pluginHandle == pluginHandle && currentMenu.hEntryPlugin == hEntry) { @@ -1077,11 +1103,11 @@ void pluginmenuentrysethotkey(int pluginHandle, int hEntry, const char* hotkey) if(hEntry == -1 || !hotkey) return; SHARED_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuEntryList) + for(const auto & currentMenu : gPluginMenuEntryList) { if(currentMenu.pluginHandle == pluginHandle && currentMenu.hEntryPlugin == hEntry) { - for(const auto & plugin : pluginList) + for(const auto & plugin : gPluginList) { if(plugin.initStruct.pluginHandle == pluginHandle) { @@ -1103,7 +1129,7 @@ void pluginmenuentrysethotkey(int pluginHandle, int hEntry, const char* hotkey) bool pluginmenuremove(int hMenu) { EXCLUSIVE_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuList) + for(const auto & currentMenu : gPluginMenuList) if(currentMenu.hEntryMenu == hMenu && currentMenu.hParentMenu < 256) return false; return pluginmenuclear(hMenu, true); @@ -1112,13 +1138,13 @@ bool pluginmenuremove(int hMenu) bool pluginmenuentryremove(int pluginHandle, int hEntry) { EXCLUSIVE_ACQUIRE(LockPluginMenuList); - for(auto it = pluginMenuEntryList.begin(); it != pluginMenuEntryList.end(); ++it) + for(auto it = gPluginMenuEntryList.begin(); it != gPluginMenuEntryList.end(); ++it) { const auto & currentEntry = *it; if(currentEntry.pluginHandle == pluginHandle && currentEntry.hEntryPlugin == hEntry) { GuiMenuRemove(currentEntry.hEntryMenu); - pluginMenuEntryList.erase(it); + gPluginMenuEntryList.erase(it); return true; } } @@ -1172,7 +1198,7 @@ bool pluginexprfuncregister(int pluginHandle, const char* name, int argc, CBPLUG return false; } EXCLUSIVE_ACQUIRE(LockPluginExprfunctionList); - pluginExprfunctionList.push_back(plugExprfunction); + gPluginExprfunctionList.push_back(plugExprfunction); EXCLUSIVE_RELEASE(); dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN, %s] Expression function \"%s\" registered!\n"), plugName.c_str(), name); return true; @@ -1198,7 +1224,7 @@ bool pluginexprfuncregisterex(int pluginHandle, const char* name, const ValueTyp return false; } EXCLUSIVE_ACQUIRE(LockPluginExprfunctionList); - pluginExprfunctionList.push_back(plugExprfunction); + gPluginExprfunctionList.push_back(plugExprfunction); EXCLUSIVE_RELEASE(); dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN, %s] Expression function \"%s\" registered!\n"), plugName.c_str(), name); return true; @@ -1211,12 +1237,12 @@ bool pluginexprfuncunregister(int pluginHandle, const char* name) if(!findPluginName(pluginHandle, plugName)) return false; EXCLUSIVE_ACQUIRE(LockPluginExprfunctionList); - for(auto it = pluginExprfunctionList.begin(); it != pluginExprfunctionList.end(); ++it) + for(auto it = gPluginExprfunctionList.begin(); it != gPluginExprfunctionList.end(); ++it) { const auto & currentExprfunction = *it; if(currentExprfunction.pluginHandle == pluginHandle && !strcmp(currentExprfunction.name, name)) { - pluginExprfunctionList.erase(it); + gPluginExprfunctionList.erase(it); EXCLUSIVE_RELEASE(); if(!ExpressionFunctions::Unregister(name)) goto beach; @@ -1243,7 +1269,7 @@ bool pluginformatfuncregister(int pluginHandle, const char* type, CBPLUGINFORMAT return false; } EXCLUSIVE_ACQUIRE(LockPluginFormatfunctionList); - pluginFormatfunctionList.push_back(plugFormatfunction); + gPluginFormatfunctionList.push_back(plugFormatfunction); EXCLUSIVE_RELEASE(); dprintf(QT_TRANSLATE_NOOP("DBG", "[PLUGIN, %s] Format function \"%s\" registered!\n"), plugName.c_str(), type); return true; @@ -1255,12 +1281,12 @@ bool pluginformatfuncunregister(int pluginHandle, const char* type) if(!findPluginName(pluginHandle, plugName)) return false; EXCLUSIVE_ACQUIRE(LockPluginFormatfunctionList); - for(auto it = pluginFormatfunctionList.begin(); it != pluginFormatfunctionList.end(); ++it) + for(auto it = gPluginFormatfunctionList.begin(); it != gPluginFormatfunctionList.end(); ++it) { const auto & currentFormatfunction = *it; if(currentFormatfunction.pluginHandle == pluginHandle && !strcmp(currentFormatfunction.name, type)) { - pluginFormatfunctionList.erase(it); + gPluginFormatfunctionList.erase(it); EXCLUSIVE_RELEASE(); if(!FormatFunctions::Unregister(type)) goto beach; diff --git a/src/dbg/plugin_loader.h b/src/dbg/plugin_loader.h index 3eba3a0b..75e44b3c 100644 --- a/src/dbg/plugin_loader.h +++ b/src/dbg/plugin_loader.h @@ -66,7 +66,7 @@ struct PLUG_FORMATFUNCTION }; //plugin management functions -bool pluginload(const char* pluginname, bool loadall = false); +bool pluginload(const char* pluginname); bool pluginunload(const char* pluginname, bool unloadall = false); void pluginloadall(const char* pluginDir); void pluginunloadall(); diff --git a/src/exe/signaturecheck.cpp b/src/exe/signaturecheck.cpp index c82f5476..42f3b235 100644 --- a/src/exe/signaturecheck.cpp +++ b/src/exe/signaturecheck.cpp @@ -319,7 +319,7 @@ static VOID CALLBACK MyLdrDllNotification( typedef BOOL(WINAPI* pfnSetDefaultDllDirectories)(DWORD DirectoryFlags); typedef BOOL(WINAPI* pfnSetDllDirectoryW)(LPCWSTR lpPathName); -typedef BOOL(WINAPI* pfnAddDllDirectory)(LPCWSTR lpPathName); +typedef PVOID(WINAPI* pfnAddDllDirectory)(LPCWSTR lpPathName); static pfnSetDefaultDllDirectories pSetDefaultDllDirectories; static pfnSetDllDirectoryW pSetDllDirectoryW;