From d7f143dba9e53347a1d7897bcd3989751c7f45f8 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 4 Jul 2012 19:11:17 +0000 Subject: wiping objects during dynamic plugin unload git-svn-id: http://svn.miranda-ng.org/main/trunk@762 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- src/core/miranda.h | 16 ++++++++++++-- src/modules/clist/clistmenus.cpp | 11 ++++------ src/modules/clist/genmenu.cpp | 45 +++++++++++++++++++++++++++----------- src/modules/fonts/services.cpp | 29 +++++++++++++++++++++++- src/modules/icolib/skin2icons.cpp | 21 +++++++++++++++++- src/modules/plugins/newplugins.cpp | 22 ++++++++++++++----- src/modules/skin/hotkeys.cpp | 11 ++++++++++ src/modules/skin/sounds.cpp | 15 +++++++++++++ 8 files changed, 140 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/core/miranda.h b/src/core/miranda.h index 8b7d5769db..3446fc0a72 100644 --- a/src/core/miranda.h +++ b/src/core/miranda.h @@ -115,6 +115,14 @@ extern LPFN_WSAADDRESSTOSTRINGA MyWSAAddressToString; void PushFileEvent(HANDLE hContact, HANDLE hdbe, LPARAM lParam); +/**** fontService.cpp ******************************************************************/ + +void KillModuleFonts(int hLangpack); +void KillModuleColours(int hLangpack); +void KillModuleEffects(int hLangpack); +void KillModuleHotkeys(int hLangpack); +void KillModuleSounds(int hLangpack); + /**** miranda.cpp **********************************************************************/ extern HINSTANCE hInst; @@ -143,6 +151,8 @@ HICON IcoLib_GetIconByHandle(HANDLE hItem, bool big); HANDLE IcoLib_IsManaged(HICON hIcon); int IcoLib_ReleaseIcon(HICON hIcon, char* szIconName, bool big); +void KillModuleIcons(int hLangpack); + /**** skinicons.cpp ********************************************************************/ HICON LoadSkinProtoIcon(const char* szProto, int status, bool big = false); @@ -178,6 +188,8 @@ extern const int skinIconStatusFlags[ MAX_STATUS_COUNT ]; int TryProcessDoubleClick(HANDLE hContact); +void KillModuleMenus(int hLangpack); + /**** protocols.cpp *********************************************************************/ #define OFFSET_PROTOPOS 200 @@ -224,7 +236,7 @@ public: StrConvUT(const char* pSrc) : m_body(mir_a2u(pSrc)) {} - ~StrConvUT() { mir_free(m_body); } + ~StrConvUT() { mir_free(m_body); } operator const wchar_t* () const { return m_body; } }; @@ -237,7 +249,7 @@ public: StrConvAT(const wchar_t* pSrc) : m_body(mir_u2a(pSrc)) {} - ~StrConvAT() { mir_free(m_body); } + ~StrConvAT() { mir_free(m_body); } operator const char* () const { return m_body; } operator const wchar_t* () const { return (wchar_t*)m_body; } // type cast to fake the interface definition operator const LPARAM () const { return (LPARAM)m_body; } diff --git a/src/modules/clist/clistmenus.cpp b/src/modules/clist/clistmenus.cpp index dc9c4a69e2..677678d847 100644 --- a/src/modules/clist/clistmenus.cpp +++ b/src/modules/clist/clistmenus.cpp @@ -1193,7 +1193,7 @@ static INT_PTR AddStatusMenuItem(WPARAM wParam, LPARAM lParam) mir_free(ptszName); } if (pRoot == NULL) { - TMO_MenuItem tmi = { 0 }; + memset(&tmi, 0, sizeof(tmi)); tmi.cbSize = sizeof(tmi); tmi.flags = (mi->flags & CMIF_UNICODE) | CMIF_ROOTHANDLE; tmi.position = 1001; @@ -1233,12 +1233,9 @@ static INT_PTR AddStatusMenuItem(WPARAM wParam, LPARAM lParam) smep->hMenuItem = menuHandle; char buf[MAX_PATH+64]; - - { - char* p = (pRoot) ? mir_t2a(pRoot->mi.ptszName) : NULL; - mir_snprintf(buf, SIZEOF(buf), "%s/%s", (p) ? p : "", mi->pszService ? mi->pszService : ""); - mir_free(p); - } + char* p = (pRoot) ? mir_t2a(pRoot->mi.ptszName) : NULL; + mir_snprintf(buf, SIZEOF(buf), "%s/%s", (p) ? p : "", mi->pszService ? mi->pszService : ""); + mir_free(p); MO_SetOptionsMenuItem(menuHandle, OPT_MENUITEMSETUNIQNAME, (INT_PTR)buf); diff --git a/src/modules/clist/genmenu.cpp b/src/modules/clist/genmenu.cpp index 30f856b7ee..deb5de8227 100644 --- a/src/modules/clist/genmenu.cpp +++ b/src/modules/clist/genmenu.cpp @@ -80,6 +80,8 @@ LPTSTR GetMenuItemText(PMO_IntMenuItem pimi) return TranslateTH(pimi->mi.hLangpack, pimi->mi.ptszName); } +/////////////////////////////////////////////////////////////////////////////// + PMO_IntMenuItem MO_RecursiveWalkMenu(PMO_IntMenuItem parent, pfnWalkFunc func, void* param) { if (parent == NULL) @@ -102,6 +104,7 @@ PMO_IntMenuItem MO_RecursiveWalkMenu(PMO_IntMenuItem parent, pfnWalkFunc func, v return FALSE; } +/////////////////////////////////////////////////////////////////////////////// //wparam=0 //lparam=LPMEASUREITEMSTRUCT int MO_MeasureMenuItem(LPMEASUREITEMSTRUCT mis) @@ -128,6 +131,7 @@ int MO_MeasureMenuItem(LPMEASUREITEMSTRUCT mis) return TRUE; } +/////////////////////////////////////////////////////////////////////////////// //wparam=0 //lparam=LPDRAWITEMSTRUCT int MO_DrawMenuItem(LPDRAWITEMSTRUCT dis) @@ -453,16 +457,13 @@ int MO_SetOptionsMenuItem(PMO_IntMenuItem aHandle, int setting, INT_PTR value) int MO_SetOptionsMenuObject(HANDLE handle, int setting, INT_PTR value) { - int pimoidx; - int res = 0; - if ( !bIsGenMenuInited) return -1; mir_cslock lck(csMenuHook); - pimoidx = GetMenuObjbyId((int)handle); - res = pimoidx != -1; + int pimoidx = GetMenuObjbyId((int)handle); + int res = pimoidx != -1; if (res) { TIntMenuObject* pmo = g_menus[pimoidx]; @@ -552,6 +553,25 @@ INT_PTR MO_RemoveMenuItem(WPARAM wParam, LPARAM) return 0; } +/////////////////////////////////////////////////////////////////////////////// + +int KillMenuItems(PMO_IntMenuItem pimi, void* param) +{ + if (pimi->hLangpack == (int)param) + MO_RemoveMenuItem((WPARAM)pimi, 0); + return FALSE; +} + +void KillModuleMenus(int hLangpack) +{ + if (bIsGenMenuInited) { + mir_cslock lck(csMenuHook); + + for (int i=0; i < g_menus.getCount(); i++) + MO_RecursiveWalkMenu(g_menus[i]->m_items.first, KillMenuItems, (void*)hLangpack); + } +} + /////////////////////////////////////////////////////////////////////////////// // we presume that this function is being called inside csMenuHook only @@ -600,6 +620,7 @@ PMO_IntMenuItem MO_AddNewMenuItem(HANDLE menuobjecthandle, PMO_MenuItem pmi) p->iconId = -1; p->OverrideShow = TRUE; p->originalPosition = pmi->position; + p->hLangpack = pmi->hLangpack; if (pmi->flags & CMIF_UNICODE) p->mi.ptszName = mir_tstrdup(pmi->ptszName); @@ -1039,7 +1060,7 @@ static int MO_RegisterIcon(PMO_IntMenuItem pmi, void*) mir_snprintf(iconame, sizeof(iconame), "genmenu_%s_%s", pmi->parent->Name, uname && *uname ? uname : descr); - SKINICONDESC sid={0}; + SKINICONDESC sid = { 0 }; sid.cbSize = sizeof(sid); sid.cx = 16; sid.cy = 16; @@ -1054,14 +1075,12 @@ static int MO_RegisterIcon(PMO_IntMenuItem pmi, void*) if (hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)iconame)) { ImageList_ReplaceIcon(pmi->parent->m_hMenuIcons, pmi->iconId, hIcon); IconLib_ReleaseIcon(hIcon, 0); - } } - - - if ( !pmi->UniqName) - mir_free(uname); - mir_free(descr); - + } + } + if ( !pmi->UniqName) + mir_free(uname); + mir_free(descr); return FALSE; } diff --git a/src/modules/fonts/services.cpp b/src/modules/fonts/services.cpp index 3774cafe9f..f4804c839a 100644 --- a/src/modules/fonts/services.cpp +++ b/src/modules/fonts/services.cpp @@ -368,6 +368,15 @@ INT_PTR GetFont(WPARAM wParam, LPARAM lParam) return ret; } +///////////////////////////////////////////////////////////////////////////////////////// + +void KillModuleFonts(int hLangpack) +{ + for (int i=font_id_list.getCount()-1; i >= 0; i--) + if ( font_id_list[i].hLangpack == hLangpack) + font_id_list.remove(i); +} + ///////////////////////////////////////////////////////////////////////////////////////// // RegisterColour service @@ -434,6 +443,15 @@ INT_PTR GetColour(WPARAM wParam, LPARAM) return sttGetColourWorker(&temp); } +///////////////////////////////////////////////////////////////////////////////////////// + +void KillModuleColours(int hLangpack) +{ + for (int i=colour_id_list.getCount()-1; i >= 0; i--) + if (colour_id_list[i].hLangpack == hLangpack) + colour_id_list.remove(i); +} + ////////////////////////////////////////////////////////////////////////// // Effects @@ -451,7 +469,7 @@ void UpdateEffectSettings(EffectIDW* effect_id, FONTEFFECT* effectsettings) } ///////////////////////////////////////////////////////////////////////////////////////// -// RegisterFont service +// RegisterEffect service static INT_PTR sttRegisterEffectWorker(EffectIDW* effect_id, int hLangpack) { @@ -516,3 +534,12 @@ INT_PTR GetEffect(WPARAM wParam, LPARAM lParam) if ( !ConvertEffectID((EffectID*)wParam, &temp)) return -1; return sttGetEffectWorker(&temp, (FONTEFFECT*)lParam); } + +///////////////////////////////////////////////////////////////////////////////////////// + +void KillModuleEffects(int hLangpack) +{ + for (int i=effect_id_list.getCount()-1; i >= 0; i--) + if (effect_id_list[i].hLangpack == hLangpack) + effect_id_list.remove(i); +} diff --git a/src/modules/icolib/skin2icons.cpp b/src/modules/icolib/skin2icons.cpp index 6527d7a35e..62ab6b15cf 100644 --- a/src/modules/icolib/skin2icons.cpp +++ b/src/modules/icolib/skin2icons.cpp @@ -101,7 +101,6 @@ void __fastcall SafeDestroyIcon(HICON* icon) *icon = NULL; } } - // Helper functions to manage Icon resources IconSourceFile* IconSourceFile_Get(const TCHAR* file, bool isPath) @@ -589,6 +588,25 @@ static INT_PTR IcoLib_RemoveIcon(WPARAM, LPARAM lParam) return 1; // Failed } +void KillModuleIcons(int hLangpack) +{ + if ( !bModuleInitialized) + return; + + mir_cslock lck(csIconList); + for (int i=iconList.getCount()-1; i >= 0; i--) { + IconItem *item = iconList[i]; + if ( item->hLangpack == hLangpack) { + IcoLib_FreeIcon(item); + iconList.remove(i); + SAFE_FREE((void**)&item); + } + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// IconItem_GetDefaultIcon + HICON IconItem_GetDefaultIcon(IconItem* item, bool big) { HICON hIcon = NULL; @@ -873,4 +891,5 @@ void UnloadIcoLibModule(void) sectionList.destroy(); SafeDestroyIcon(&hIconBlank); + bModuleInitialized = false; } diff --git a/src/modules/plugins/newplugins.cpp b/src/modules/plugins/newplugins.cpp index 493c40bf10..237d2140b3 100644 --- a/src/modules/plugins/newplugins.cpp +++ b/src/modules/plugins/newplugins.cpp @@ -66,17 +66,14 @@ MuuidReplacement pluginDefault[] = static BOOL bModuleInitialized = FALSE; -TCHAR mirandabootini[MAX_PATH]; +TCHAR mirandabootini[MAX_PATH]; static DWORD mirandaVersion; static int serviceModeIdx = -1; -static pluginEntry * pluginListSM; -static pluginEntry * pluginListDb; -static pluginEntry * pluginListUI; -static pluginEntry * pluginList_freeimg; -static pluginEntry * pluginList_crshdmp; static HANDLE hPluginListHeap = NULL; static int askAboutIgnoredPlugins; +static pluginEntry *pluginListSM, *pluginListDb, *pluginListUI, *pluginList_freeimg, *pluginList_crshdmp; + int InitIni(void); void UninitIni(void); @@ -286,6 +283,19 @@ void Plugin_Uninit(pluginEntry* p, bool bDynamic) KillModuleEventHooks(p->bpi.hInst); KillModuleServices(p->bpi.hInst); + if (bDynamic) { + int hLangpack = Langpack_GetPluginHandle(p->bpi.pluginInfo); + if (hLangpack != 0) { + KillModuleMenus(hLangpack); + KillModuleFonts(hLangpack); + KillModuleColours(hLangpack); + KillModuleEffects(hLangpack); + KillModuleIcons(hLangpack); + KillModuleHotkeys(hLangpack); + KillModuleSounds(hLangpack); + } + } + FreeLibrary(p->bpi.hInst); ZeroMemory(&p->bpi, sizeof(p->bpi)); } diff --git a/src/modules/skin/hotkeys.cpp b/src/modules/skin/hotkeys.cpp index a36dd152d1..bf939d5716 100644 --- a/src/modules/skin/hotkeys.cpp +++ b/src/modules/skin/hotkeys.cpp @@ -300,6 +300,17 @@ void RegisterHotkeys() if (vk) RegisterHotKey(g_hwndHotkeyHost, item->idHotkey, mod, vk); } } } +void KillModuleHotkeys(int hLangpack) +{ + for (int i=hotkeys.getCount()-1; i >= 0; i--) { + THotkeyItem *item = hotkeys[i]; + if (item->hLangpack == hLangpack) { + FreeHotkey(item); + hotkeys.remove(i); + } + } +} + void UnregisterHotkeys() { for (int i = 0; i < hotkeys.getCount(); i++) { diff --git a/src/modules/skin/sounds.cpp b/src/modules/skin/sounds.cpp index 24b4e44476..05422ffef6 100644 --- a/src/modules/skin/sounds.cpp +++ b/src/modules/skin/sounds.cpp @@ -49,6 +49,21 @@ static int CompareSounds(const SoundItem* p1, const SoundItem* p2) static OBJLIST arSounds(10, CompareSounds); +/////////////////////////////////////////////////////////////////////////////// + +void KillModuleSounds(int hLangpack) +{ + for (int i=arSounds.getCount()-1; i >= 0; i--) { + SoundItem& p = arSounds[i]; + if (p.hLangpack == hLangpack) { + p.clear(); + arSounds.remove(i); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// + static BOOL bModuleInitialized = FALSE; static HANDLE hPlayEvent = NULL; -- cgit v1.2.3