summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2012-07-06 11:47:56 +0000
committerGeorge Hazan <george.hazan@gmail.com>2012-07-06 11:47:56 +0000
commited5bb0fad1a79a47774223e739902679d049299a (patch)
tree8929ea4f05f9228d94d274badfa100bac33a2a86 /src
parent4ba37ef39d7f0458a8accf3e54ce98c1b8421ce0 (diff)
valid Core plugins' processing during dynamic load/unload
git-svn-id: http://svn.miranda-ng.org/main/trunk@789 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'src')
-rw-r--r--src/mir_core/modules.cpp2
-rw-r--r--src/modules/clist/genmenu.cpp33
-rw-r--r--src/modules/plugins/newplugins.cpp102
-rw-r--r--src/modules/plugins/pluginopts.cpp4
-rw-r--r--src/modules/plugins/plugins.h21
5 files changed, 92 insertions, 70 deletions
diff --git a/src/mir_core/modules.cpp b/src/mir_core/modules.cpp
index f87c7bb192..67cf6ce267 100644
--- a/src/mir_core/modules.cpp
+++ b/src/mir_core/modules.cpp
@@ -157,7 +157,7 @@ MIR_CORE_DLL(int) SetHookDefaultForHookableEvent(HANDLE hEvent, MIRANDAHOOK pfnH
MIR_CORE_DLL(int) CallPluginEventHook(HINSTANCE hInst, HANDLE hEvent, WPARAM wParam, LPARAM lParam)
{
THook* p = (THook*)hEvent;
- if (p == NULL)
+ if (p == NULL || hInst == NULL)
return -1;
mir_cslock lck(p->csHook);
diff --git a/src/modules/clist/genmenu.cpp b/src/modules/clist/genmenu.cpp
index 33b94d6cf8..62749733d3 100644
--- a/src/modules/clist/genmenu.cpp
+++ b/src/modules/clist/genmenu.cpp
@@ -555,21 +555,38 @@ INT_PTR MO_RemoveMenuItem(WPARAM wParam, LPARAM)
///////////////////////////////////////////////////////////////////////////////
-int KillMenuItems(PMO_IntMenuItem pimi, void* param)
+struct KillMenuItemsParam
{
- if (pimi->hLangpack == (int)param)
- MO_RemoveMenuItem((WPARAM)pimi, 0);
+ KillMenuItemsParam(int _hLangpack) :
+ hLangpack(_hLangpack),
+ arItems(10)
+ {}
+
+ int hLangpack;
+ LIST<TMO_IntMenuItem> arItems;
+};
+
+int KillMenuItems(PMO_IntMenuItem pimi, KillMenuItemsParam* param)
+{
+ if (pimi->hLangpack == param->hLangpack)
+ param->arItems.insert(pimi);
return FALSE;
}
void KillModuleMenus(int hLangpack)
{
- if (bIsGenMenuInited) {
- mir_cslock lck(csMenuHook);
+ if (!bIsGenMenuInited)
+ return;
- for (int i=0; i < g_menus.getCount(); i++)
- MO_RecursiveWalkMenu(g_menus[i]->m_items.first, KillMenuItems, (void*)hLangpack);
- }
+ KillMenuItemsParam param(hLangpack);
+
+ mir_cslock lck(csMenuHook);
+ for (int i=0; i < g_menus.getCount(); i++)
+ MO_RecursiveWalkMenu(g_menus[i]->m_items.first, (pfnWalkFunc)KillMenuItems, &param);
+
+ for (int k=0; k < param.arItems.getCount(); k++)
+ MO_RemoveMenuItem((WPARAM)param.arItems[k], 0);
+ param.arItems.destroy();
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/modules/plugins/newplugins.cpp b/src/modules/plugins/newplugins.cpp
index 7bbcc57411..16606ff990 100644
--- a/src/modules/plugins/newplugins.cpp
+++ b/src/modules/plugins/newplugins.cpp
@@ -13,12 +13,12 @@ of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "..\..\core\commonheaders.h"
#include "plugins.h"
@@ -34,8 +34,8 @@ LIST<pluginEntry> pluginList(10, sttComparePluginsByName);
#define MAX_MIR_VER ULONG_MAX
struct PluginUUIDList {
- MUUID uuid;
- DWORD maxVersion;
+ MUUID uuid;
+ DWORD maxVersion;
}
static const pluginBannedList[] =
{
@@ -176,9 +176,9 @@ static int isPluginBanned(MUUID u1, DWORD dwVersion)
}
// returns true if the API exports were good, otherwise, passed in data is returned
-#define CHECKAPI_NONE 0
-#define CHECKAPI_DB 1
-#define CHECKAPI_CLIST 2
+#define CHECKAPI_NONE 0
+#define CHECKAPI_DB 1
+#define CHECKAPI_CLIST 2
/*
* historyeditor added by nightwish - plugin is problematic and can ruin database as it does not understand UTF-8 message
@@ -213,7 +213,7 @@ static int checkPI(BASIC_PLUGIN_INFO* bpi, PLUGININFOEX* pi)
if ( !validInterfaceList(bpi->Interfaces) || isPluginBanned(pi->uuid, pi->version))
return FALSE;
- if (pi->shortName == NULL || pi->description == NULL || pi->author == NULL ||
+ if (pi->shortName == NULL || pi->description == NULL || pi->author == NULL ||
pi->authorEmail == NULL || pi->copyright == NULL || pi->homepage == NULL)
return FALSE;
@@ -332,9 +332,10 @@ int Plugin_UnloadDyn(pluginEntry* p)
}
// release default plugin
- for (int i=0; i < SIZEOF(pluginDefault); i++)
- if (pluginDefault[i].pImpl == p)
- pluginDefault[i].pImpl = NULL;
+ if ( !(p->pclass & PCLASS_CORE))
+ for (int i=0; i < SIZEOF(pluginDefault); i++)
+ if (pluginDefault[i].pImpl == p)
+ LoadCorePlugin( pluginDefault[i] );
Plugin_Uninit(p);
return TRUE;
@@ -529,12 +530,13 @@ int isPluginOnWhiteList(const TCHAR* pluginname)
return rc == 0;
}
-bool TryLoadPlugin(pluginEntry *p, TCHAR* dir, bool bDynamic)
+bool TryLoadPlugin(pluginEntry *p, bool bDynamic)
{
TCHAR exe[MAX_PATH];
GetModuleFileName(NULL, exe, SIZEOF(exe));
TCHAR* slice = _tcsrchr(exe, '\\');
- if (slice) *slice = 0;
+ if (slice)
+ *slice = 0;
CharLower(p->pluginname);
if ( !(p->pclass & (PCLASS_LOADED | PCLASS_DB | PCLASS_CLIST))) {
@@ -542,40 +544,40 @@ bool TryLoadPlugin(pluginEntry *p, TCHAR* dir, bool bDynamic)
return false;
BASIC_PLUGIN_INFO bpi;
- mir_sntprintf(slice, &exe[SIZEOF(exe)] - slice, _T("\\%s\\%s"), dir, p->pluginname);
- if ( !checkAPI(exe, &bpi, mirandaVersion, CHECKAPI_NONE))
+ mir_sntprintf(slice, &exe[SIZEOF(exe)] - slice, _T("\\%s\\%s"), (p->pclass & PCLASS_CORE) ? _T("Core") : _T("Plugins"), p->pluginname);
+ if ( !checkAPI(exe, &bpi, mirandaVersion, CHECKAPI_NONE)) {
p->pclass |= PCLASS_FAILED;
- else {
- p->bpi = bpi;
- p->pclass |= PCLASS_OK | PCLASS_BASICAPI;
-
- if (p->bpi.Interfaces) {
- MUUID *piface = bpi.Interfaces();
- for (int i=0; !equalUUID(miid_last, piface[i]); i++) {
- int idx = getDefaultPluginIdx( piface[i] );
- if (idx != -1 && pluginDefault[idx].pImpl) {
- if ( !bDynamic) {
- SetPluginOnWhiteList(p->pluginname, 0);
- return false;
- }
+ return false;
+ }
+
+ p->bpi = bpi;
+ p->pclass |= PCLASS_OK | PCLASS_BASICAPI;
+
+ if (p->bpi.Interfaces) {
+ MUUID *piface = bpi.Interfaces();
+ for (int i=0; !equalUUID(miid_last, piface[i]); i++) {
+ int idx = getDefaultPluginIdx( piface[i] );
+ if (idx != -1 && pluginDefault[idx].pImpl) {
+ if ( !bDynamic) {
+ SetPluginOnWhiteList(p->pluginname, 0);
+ return false;
+ }
+ if ( !(p->pclass & PCLASS_CORE)) {
Plugin_UnloadDyn(pluginDefault[idx].pImpl);
pluginDefault[idx].pImpl = NULL;
- }
- }
- }
+ } } } }
- RegisterModule(p->bpi.hInst);
- if (bpi.Load() != 0)
- return false;
-
- p->pclass |= PCLASS_LOADED;
- if (p->bpi.Interfaces) {
- MUUID *piface = bpi.Interfaces();
- for (int i=0; !equalUUID(miid_last, piface[i]); i++) {
- int idx = getDefaultPluginIdx( piface[i] );
- if (idx != -1)
- pluginDefault[idx].pImpl = p;
- }
+ RegisterModule(p->bpi.hInst);
+ if (bpi.Load() != 0)
+ return false;
+
+ p->pclass |= PCLASS_LOADED;
+ if (p->bpi.Interfaces) {
+ MUUID *piface = bpi.Interfaces();
+ for (int i=0; !equalUUID(miid_last, piface[i]); i++) {
+ int idx = getDefaultPluginIdx( piface[i] );
+ if (idx != -1)
+ pluginDefault[idx].pImpl = p;
}
}
}
@@ -597,10 +599,13 @@ bool LoadCorePlugin(MuuidReplacement& mr)
if (pPlug->pclass & PCLASS_FAILED) {
LBL_Error:
Plugin_UnloadDyn(pPlug);
+ mr.pImpl = NULL;
return FALSE;
}
- if ( !TryLoadPlugin(pPlug, _T("Core"), true))
+ pPlug->pclass |= PCLASS_CORE;
+
+ if ( !TryLoadPlugin(pPlug, true))
goto LBL_Error;
if (CallPluginEventHook(pPlug->bpi.hInst, hModulesLoadedEvent, 0, 0) != 0)
@@ -740,13 +745,12 @@ int LoadNewPluginsModule(void)
askAboutIgnoredPlugins = (UINT) GetPrivateProfileInt(_T("PluginLoader"), _T("AskAboutIgnoredPlugins"), 0, mirandabootini);
// if Crash Dumper is present, load it to provide Crash Reports
- if (pluginList_crshdmp != NULL && isPluginOnWhiteList(pluginList_crshdmp->pluginname))
- {
+ if (pluginList_crshdmp != NULL && isPluginOnWhiteList(pluginList_crshdmp->pluginname)) {
if (pluginList_crshdmp->bpi.Load() == 0)
pluginList_crshdmp->pclass |= PCLASS_LOADED | PCLASS_LAST;
else
Plugin_Uninit(pluginList_crshdmp);
- }
+ }
// if freeimage is present, load it to provide the basic core functions
if (pluginList_freeimg != NULL) {
@@ -784,7 +788,7 @@ int LoadNewPluginsModule(void)
for (i=0; i < pluginList.getCount(); i++) {
p = pluginList[i];
- if ( !TryLoadPlugin(p, _T("Plugins"), false)) {
+ if ( !TryLoadPlugin(p, false)) {
Plugin_Uninit(p);
i--;
}
@@ -844,7 +848,7 @@ void UnloadNewPluginsModule(void)
Plugin_Uninit(p);
}
- if (pluginList_crshdmp)
+ if (pluginList_crshdmp)
Plugin_Uninit(pluginList_crshdmp);
// unload the DB
diff --git a/src/modules/plugins/pluginopts.cpp b/src/modules/plugins/pluginopts.cpp
index 15f9219192..4bd86c69c7 100644
--- a/src/modules/plugins/pluginopts.cpp
+++ b/src/modules/plugins/pluginopts.cpp
@@ -171,7 +171,7 @@ LBL_Error:
return FALSE;
}
- if ( !TryLoadPlugin(pPlug, _T("Plugins"), true))
+ if ( !TryLoadPlugin(pPlug, true))
goto LBL_Error;
if (CallPluginEventHook(pPlug->bpi.hInst, hModulesLoadedEvent, 0, 0) != 0)
@@ -425,4 +425,4 @@ void UnloadPluginOptions()
{
DestroyHookableEvent(hevLoadModule);
DestroyHookableEvent(hevUnloadModule);
-} \ No newline at end of file
+}
diff --git a/src/modules/plugins/plugins.h b/src/modules/plugins/plugins.h
index 4dcf76f439..6cfa8595c7 100644
--- a/src/modules/plugins/plugins.h
+++ b/src/modules/plugins/plugins.h
@@ -34,15 +34,16 @@ struct BASIC_PLUGIN_INFO
DATABASELINK * dblink; // only valid during module being in memory
};
-#define PCLASS_FAILED 0x1 // not a valid plugin, or API is invalid, pluginname is valid
-#define PCLASS_BASICAPI 0x2 // has Load, Unload, MirandaPluginInfo() -> PLUGININFO seems valid, this dll is in memory.
-#define PCLASS_DB 0x4 // has DatabasePluginInfo() and is valid as can be, and PCLASS_BASICAPI has to be set too
-#define PCLASS_LAST 0x8 // this plugin should be unloaded after everything else
-#define PCLASS_OK 0x10 // plugin should be loaded, if DB means nothing
-#define PCLASS_LOADED 0x20 // Load(void) has been called, Unload() should be called.
-#define PCLASS_STOPPED 0x40 // wasn't loaded cos plugin name not on white list
-#define PCLASS_CLIST 0x80 // a CList implementation
-#define PCLASS_SERVICE 0x100 // has Service Mode implementation
+#define PCLASS_FAILED 0x1 // not a valid plugin, or API is invalid, pluginname is valid
+#define PCLASS_BASICAPI 0x2 // has Load, Unload, MirandaPluginInfo() -> PLUGININFO seems valid, this dll is in memory.
+#define PCLASS_DB 0x4 // has DatabasePluginInfo() and is valid as can be, and PCLASS_BASICAPI has to be set too
+#define PCLASS_LAST 0x8 // this plugin should be unloaded after everything else
+#define PCLASS_OK 0x10 // plugin should be loaded, if DB means nothing
+#define PCLASS_LOADED 0x20 // Load(void) has been called, Unload() should be called.
+#define PCLASS_STOPPED 0x40 // wasn't loaded cos plugin name not on white list
+#define PCLASS_CLIST 0x80 // a CList implementation
+#define PCLASS_SERVICE 0x100 // has Service Mode implementation
+#define PCLASS_CORE 0x200 // a plugin from the /Core directory
struct pluginEntry
{
@@ -70,7 +71,7 @@ int checkAPI(TCHAR* plugin, BASIC_PLUGIN_INFO* bpi, DWORD mirandaVersion, int ch
pluginEntry* OpenPlugin(TCHAR *tszFileName, TCHAR *dir, TCHAR *path);
-bool TryLoadPlugin(pluginEntry *p, TCHAR *dir, bool bDynamic);
+bool TryLoadPlugin(pluginEntry *p, bool bDynamic);
void Plugin_Uninit(pluginEntry* p);
int Plugin_UnloadDyn(pluginEntry* p);