summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mir_app/src/miranda.h4
-rw-r--r--src/mir_app/src/newplugins.cpp1
-rw-r--r--src/mir_app/src/pluginopts.cpp10
-rw-r--r--src/mir_app/src/proto_accs.cpp43
-rw-r--r--src/mir_app/src/proto_opts.cpp18
-rw-r--r--src/mir_app/src/protocols.cpp16
6 files changed, 64 insertions, 28 deletions
diff --git a/src/mir_app/src/miranda.h b/src/mir_app/src/miranda.h
index 6eeeaffa46..81360cc8fb 100644
--- a/src/mir_app/src/miranda.h
+++ b/src/mir_app/src/miranda.h
@@ -157,7 +157,7 @@ PROTOACCOUNT* __fastcall Proto_GetAccount(MCONTACT hContact);
PROTO_INTERFACE* AddDefaultAccount(const char *szProtoName);
int FreeDefaultAccount(PROTO_INTERFACE* ppi);
-bool ActivateAccount(PROTOACCOUNT *pa);
+bool ActivateAccount(PROTOACCOUNT *pa, bool bIsDynamic);
void EraseAccount(const char *pszProtoName);
void DeactivateAccount(PROTOACCOUNT *pa, bool bIsDynamic, bool bErase);
void UnloadAccount(PROTOACCOUNT *pa, bool bIsDynamic, bool bErase);
@@ -166,6 +166,8 @@ void OpenAccountOptions(PROTOACCOUNT *pa);
void LoadDbAccounts(void);
void WriteDbAccounts(void);
+void KillModuleAccounts(HINSTANCE);
+
INT_PTR CallProtoServiceInt(MCONTACT hContact, const char* szModule, const char* szService, WPARAM wParam, LPARAM lParam);
INT_PTR stubChainRecv(WPARAM, LPARAM);
diff --git a/src/mir_app/src/newplugins.cpp b/src/mir_app/src/newplugins.cpp
index 4497d195bd..cfeca33159 100644
--- a/src/mir_app/src/newplugins.cpp
+++ b/src/mir_app/src/newplugins.cpp
@@ -349,6 +349,7 @@ int Plugin_UnloadDyn(pluginEntry *p)
if (CallPluginEventHook(p->bpi.hInst, hOkToExitEvent, 0, 0) != 0)
return FALSE;
+ KillModuleAccounts(p->bpi.hInst);
KillModuleSubclassing(p->bpi.hInst);
CallPluginEventHook(p->bpi.hInst, hPreShutdownEvent, 0, 0);
diff --git a/src/mir_app/src/pluginopts.cpp b/src/mir_app/src/pluginopts.cpp
index 9ce4923e2a..df8868bc34 100644
--- a/src/mir_app/src/pluginopts.cpp
+++ b/src/mir_app/src/pluginopts.cpp
@@ -184,6 +184,16 @@ static bool LoadPluginDynamically(PluginListItemData *dat)
if (CallPluginEventHook(pPlug->bpi.hInst, hModulesLoadedEvent, 0, 0) != 0)
goto LBL_Error;
+ // if dynamically loaded plugin contains protocols, initialize the corresponding accounts
+ for (auto &pd : g_arProtos) {
+ if (pd->hInst != pPlug->bpi.hInst)
+ continue;
+
+ for (auto &pa : accounts)
+ if (pa->ppro == nullptr && !mir_strcmp(pa->szProtoName, pd->szName))
+ ActivateAccount(pa, true);
+ }
+
dat->hInst = pPlug->bpi.hInst;
NotifyFastHook(hevLoadModule, (WPARAM)pPlug->bpi.pluginInfo, (LPARAM)pPlug->bpi.hInst);
return true;
diff --git a/src/mir_app/src/proto_accs.cpp b/src/mir_app/src/proto_accs.cpp
index 8343314e05..8e05ba2c48 100644
--- a/src/mir_app/src/proto_accs.cpp
+++ b/src/mir_app/src/proto_accs.cpp
@@ -266,7 +266,7 @@ int LoadAccountsModule(void)
if (!pa->IsEnabled())
continue;
- if (!ActivateAccount(pa))
+ if (!ActivateAccount(pa, false))
pa->bDynDisabled = true;
}
@@ -286,7 +286,7 @@ static HANDLE CreateProtoServiceEx(const char* szModule, const char* szService,
return CreateServiceFunctionObj(tmp, pFunc, param);
}
-bool ActivateAccount(PROTOACCOUNT *pa)
+bool ActivateAccount(PROTOACCOUNT *pa, bool bIsDynamic)
{
PROTOCOLDESCRIPTOR* ppd = Proto_IsProtocolLoaded(pa->szProtoName);
if (ppd == nullptr)
@@ -303,6 +303,14 @@ bool ActivateAccount(PROTOACCOUNT *pa)
if (ppi->m_hProtoIcon == nullptr)
ppi->m_hProtoIcon = IcoLib_IsManaged(Skin_LoadProtoIcon(pa->szModuleName, ID_STATUS_ONLINE));
ppi->m_iDesiredStatus = ppi->m_iStatus = ID_STATUS_OFFLINE;
+
+ if (bIsDynamic) {
+ if (bModulesLoadedFired)
+ pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0);
+ if (!db_get_b(0, "CList", "MoveProtoMenus", true))
+ pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0);
+ pa->bDynDisabled = false;
+ }
return true;
}
@@ -374,18 +382,20 @@ static int DeactivationThread(DeactivationThreadParam* param)
void DeactivateAccount(PROTOACCOUNT *pa, bool bIsDynamic, bool bErase)
{
- if (pa->ppro == nullptr) {
- if (bErase)
- EraseAccount(pa->szModuleName);
- return;
- }
-
if (pa->hwndAccMgrUI) {
DestroyWindow(pa->hwndAccMgrUI);
pa->hwndAccMgrUI = nullptr;
pa->bAccMgrUIChanged = FALSE;
}
+ pa->iIconBase = -1;
+
+ if (pa->ppro == nullptr) {
+ if (bErase)
+ EraseAccount(pa->szModuleName);
+ return;
+ }
+
DeactivationThreadParam *param = new DeactivationThreadParam;
param->ppro = pa->ppro;
param->fnUninit = GetProtocolDestructor(pa->szProtoName);
@@ -400,6 +410,23 @@ void DeactivateAccount(PROTOACCOUNT *pa, bool bIsDynamic, bool bErase)
/////////////////////////////////////////////////////////////////////////////////////////
+void KillModuleAccounts(HINSTANCE hInst)
+{
+ for (auto &pd : g_arProtos.rev_iter()) {
+ if (pd->hInst != hInst)
+ continue;
+
+ for (auto &pa : accounts.rev_iter()) {
+ if (!mir_strcmp(pa->szProtoName, pd->szName)) {
+ DeactivateAccount(pa, false, false);
+ pa->bDynDisabled = true;
+ }
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
void EraseAccount(const char *pszModuleName)
{
// remove protocol contacts first
diff --git a/src/mir_app/src/proto_opts.cpp b/src/mir_app/src/proto_opts.cpp
index 239de7fbeb..70fdd82876 100644
--- a/src/mir_app/src/proto_opts.cpp
+++ b/src/mir_app/src/proto_opts.cpp
@@ -82,13 +82,7 @@ MIR_APP_DLL(PROTOACCOUNT*) Proto_CreateAccount(const char *pszInternal, const ch
db_set_s(0, pa->szModuleName, "AM_BaseProto", pszBaseProto);
accounts.insert(pa);
- if (ActivateAccount(pa)) {
- if (bModulesLoadedFired)
- pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0);
- if (!db_get_b(0, "CList", "MoveProtoMenus", true))
- pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0);
- }
-
+ ActivateAccount(pa, true);
WriteDbAccounts();
NotifyEventHooks(hAccListChanged, PRAC_ADDED, (LPARAM)pa);
return pa;
@@ -457,14 +451,8 @@ public:
return;
pa->bIsEnabled = !pa->bIsEnabled;
- if (pa->bIsEnabled) {
- if (ActivateAccount(pa)) {
- if (bModulesLoadedFired)
- pa->ppro->OnEvent(EV_PROTO_ONLOAD, 0, 0);
- if (!db_get_b(0, "CList", "MoveProtoMenus", TRUE))
- pa->ppro->OnEvent(EV_PROTO_ONMENU, 0, 0);
- }
- }
+ if (pa->bIsEnabled)
+ ActivateAccount(pa, true);
else {
if (pa->iRealStatus >= ID_STATUS_ONLINE) {
wchar_t buf[200];
diff --git a/src/mir_app/src/protocols.cpp b/src/mir_app/src/protocols.cpp
index 3384bef71d..7e0b49cdfc 100644
--- a/src/mir_app/src/protocols.cpp
+++ b/src/mir_app/src/protocols.cpp
@@ -106,16 +106,24 @@ MIR_APP_DLL(int) Proto_RegisterModule(PROTOCOLDESCRIPTOR *pd)
if (pd->cbSize != sizeof(PROTOCOLDESCRIPTOR) && pd->cbSize != PROTOCOLDESCRIPTOR_V3_SIZE)
return 1;
- MBaseProto *p = (MBaseProto*)mir_calloc(sizeof(MBaseProto));
- p->cbSize = pd->cbSize;
- p->szName = mir_strdup(pd->szName);
+ bool bTryActivate = false;
+ MBaseProto tmp;
+ tmp.szName = (char*)pd->szName;
+ MBaseProto *p = g_arProtos.find(&tmp);
+ if (p == nullptr) {
+ p = (MBaseProto*)mir_calloc(sizeof(MBaseProto));
+ p->cbSize = pd->cbSize;
+ p->szName = mir_strdup(pd->szName);
+ g_arProtos.insert(p);
+ }
+ else bTryActivate = true;
+
p->type = pd->type;
p->hInst = pd->hInst;
if (pd->cbSize == sizeof(PROTOCOLDESCRIPTOR)) {
p->fnInit = pd->fnInit;
p->fnUninit = pd->fnUninit;
}
- g_arProtos.insert(p);
if (p->fnInit == nullptr && (p->type == PROTOTYPE_PROTOCOL || p->type == PROTOTYPE_VIRTUAL)) {
// let's create a new container