summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2018-04-10 16:28:29 +0300
committerGeorge Hazan <ghazan@miranda.im>2018-04-10 16:28:29 +0300
commit95af2d0cfadb5707ac7fe941f1352b3c99eb2372 (patch)
tree6504436cbc0bfb1a4437d9c900dbefe60d20a51e
parenta17e6fd208ed45a0422f4fe468bd75019be98cbc (diff)
fix for one very rare crash due to unsynced array of status menus & accounts
-rw-r--r--include/m_protocols.h5
-rw-r--r--src/mir_app/src/menu_clist.cpp89
-rw-r--r--src/mir_app/src/miranda.h6
3 files changed, 36 insertions, 64 deletions
diff --git a/include/m_protocols.h b/include/m_protocols.h
index ee81f41ef8..3c8a70a444 100644
--- a/include/m_protocols.h
+++ b/include/m_protocols.h
@@ -32,6 +32,7 @@ struct PROTO_INTERFACE;
#include "statusmodes.h"
#include <m_core.h>
+#include <m_genmenu.h>
#include <m_system_cpp.h>
struct CCSDATA
@@ -281,6 +282,10 @@ struct MIR_APP_EXPORT PROTOACCOUNT
int iIconBase; // index of the first icon in ClistImages
int iRealStatus; // last status reported by protocol
+ int protoindex;
+ int protostatus[MAX_STATUS_COUNT];
+ HGENMENU menuhandle[MAX_STATUS_COUNT];
+
bool IsEnabled(void) const;
bool IsLocked(void) const;
bool IsVisible(void) const;
diff --git a/src/mir_app/src/menu_clist.cpp b/src/mir_app/src/menu_clist.cpp
index 649a60b727..1e4223ec5d 100644
--- a/src/mir_app/src/menu_clist.cpp
+++ b/src/mir_app/src/menu_clist.cpp
@@ -55,6 +55,7 @@ bool prochotkey;
HANDLE hPreBuildMainMenuEvent, hStatusModeChangeEvent, hPreBuildContactMenuEvent, hPreBuildStatusMenuEvent;
HMENU hMainMenu, hStatusMenu;
+
const int statusModeList[MAX_STATUS_COUNT] =
{
ID_STATUS_OFFLINE, ID_STATUS_ONLINE, ID_STATUS_AWAY, ID_STATUS_NA, ID_STATUS_OCCUPIED,
@@ -75,31 +76,7 @@ static const int statusModePf2List[MAX_STATUS_COUNT] =
static INT_PTR statusHotkeys[MAX_STATUS_COUNT];
-TMO_IntMenuItem **hStatusMainMenuHandles;
-int hStatusMainMenuHandlesCnt;
-
-struct tStatusMenuHandles
-{
- int protoindex;
- int protostatus[MAX_STATUS_COUNT];
- TMO_IntMenuItem *menuhandle[MAX_STATUS_COUNT];
-};
-
-tStatusMenuHandles *hStatusMenuHandles;
-int hStatusMenuHandlesCnt;
-
-struct BuildContactParam
-{
- char *szProto;
- int isOnList;
- int isOnline;
-};
-
-struct MenuItemData
-{
- HMENU OwnerMenu;
- int position;
-};
+static HGENMENU hStatusMainMenuHandles[MAX_STATUS_COUNT];
/////////////////////////////////////////////////////////////////////////////////////////
// service functions
@@ -239,6 +216,13 @@ MIR_APP_DLL(HGENMENU) Menu_AddContactMenuItem(TMO_MenuItem *pmi, const char *psz
/////////////////////////////////////////////////////////////////////////////////////////
+struct BuildContactParam
+{
+ char *szProto;
+ int isOnList;
+ int isOnline;
+};
+
EXTERN_C MIR_APP_DLL(HMENU) Menu_BuildContactMenu(MCONTACT hContact)
{
NotifyEventHooks(hPreBuildContactMenuEvent, hContact, 0);
@@ -369,6 +353,12 @@ MIR_APP_DLL(HMENU) Menu_GetStatusMenu()
/////////////////////////////////////////////////////////////////////////////////////////
+struct MenuItemData
+{
+ HMENU OwnerMenu;
+ int position;
+};
+
static BOOL FindMenuHandleByGlobalID(HMENU hMenu, TMO_IntMenuItem *id, MenuItemData* itdat)
{
if (!itdat)
@@ -714,21 +704,12 @@ void RebuildMenuOrder(void)
RecursiveDeleteMenu(hStatusMenu);
// status menu
- if (hStatusMenuObject != 0) {
+ if (hStatusMenuObject != 0)
Menu_RemoveObject(hStatusMenuObject);
- mir_free(hStatusMainMenuHandles);
- mir_free(hStatusMenuHandles);
- }
hStatusMenuObject = Menu_AddObject("StatusMenu", LPGEN("Status menu"), "StatusMenuCheckService", "StatusMenuExecService");
Menu_ConfigureObject(hStatusMenuObject, MCO_OPT_FREE_SERVICE, (INT_PTR)"CLISTMENUS/FreeOwnerDataStatusMenu");
- hStatusMainMenuHandles = (TMO_IntMenuItem**)mir_calloc(_countof(statusModeList) * sizeof(TMO_IntMenuItem*));
- hStatusMainMenuHandlesCnt = _countof(statusModeList);
-
- hStatusMenuHandles = (tStatusMenuHandles*)mir_calloc(sizeof(tStatusMenuHandles)*accounts.getCount());
- hStatusMenuHandlesCnt = accounts.getCount();
-
g_menuProtos.destroy();
for (int s = 0; s < accounts.getCount(); s++) {
@@ -819,12 +800,12 @@ void RebuildMenuOrder(void)
smep->pimi = (HGENMENU)i;
smep->szProto = mir_strdup(pa->szModuleName);
- hStatusMenuHandles[i].protoindex = i;
- hStatusMenuHandles[i].protostatus[j] = statusModeList[j];
- hStatusMenuHandles[i].menuhandle[j] = Menu_AddItem(hStatusMenuObject, &mi, smep);
+ pa->protoindex = i;
+ pa->protostatus[j] = statusModeList[j];
+ pa->menuhandle[j] = Menu_AddItem(hStatusMenuObject, &mi, smep);
mir_snprintf(buf, "ProtocolIcon_%s_%s", pa->szModuleName, mi.name.a);
- Menu_ConfigureItem(hStatusMenuHandles[i].menuhandle[j], MCI_OPT_UNIQUENAME, buf);
+ Menu_ConfigureItem(pa->menuhandle[j], MCI_OPT_UNIQUENAME, buf);
IcoLib_ReleaseIcon(mi.hIcon);
}
@@ -940,7 +921,6 @@ static int MenuProtoAck(WPARAM, LPARAM lParam)
ACKDATA *ack = (ACKDATA*)lParam;
if (ack->type != ACKTYPE_STATUS) return 0;
if (ack->result != ACKRESULT_SUCCESS) return 0;
- if (hStatusMainMenuHandles == nullptr) return 0;
if (Clist_GetProtocolVisibility(ack->szModule) == 0) return 0;
int overallStatus = Proto_GetAverageStatus();
@@ -950,13 +930,12 @@ static int MenuProtoAck(WPARAM, LPARAM lParam)
pos = 0;
// reset all current possible checked statuses
- for (int pos2 = 0; pos2 < hStatusMainMenuHandlesCnt; pos2++)
- if (pos2 >= 0 && pos2 < hStatusMainMenuHandlesCnt)
- Menu_ModifyItem(hStatusMainMenuHandles[pos2], nullptr, INVALID_HANDLE_VALUE, 0);
+ for (auto &it : hStatusMainMenuHandles)
+ Menu_ModifyItem(it, nullptr, INVALID_HANDLE_VALUE, 0);
currentStatusMenuItem = overallStatus;
pos = statustopos(currentStatusMenuItem);
- if (pos >= 0 && pos < hStatusMainMenuHandlesCnt)
+ if (pos >= 0 && pos < _countof(hStatusMainMenuHandles))
Menu_SetChecked(hStatusMainMenuHandles[pos], true);
}
else {
@@ -964,27 +943,27 @@ static int MenuProtoAck(WPARAM, LPARAM lParam)
if (pos == -1)
pos = 0;
- if (pos >= 0 && pos < hStatusMainMenuHandlesCnt)
+ if (pos >= 0 && pos < _countof(hStatusMainMenuHandles))
Menu_ModifyItem(hStatusMainMenuHandles[pos], nullptr, INVALID_HANDLE_VALUE, 0);
currentStatusMenuItem = 0;
}
- for (int i = 0; i < accounts.getCount(); i++) {
- if (!mir_strcmp(accounts[i]->szModuleName, ack->szModule)) {
+ for (auto &pa : accounts) {
+ if (!mir_strcmp(pa->szModuleName, ack->szModule)) {
int iOldStatus = (INT_PTR)ack->hProcess;
if ((iOldStatus >= ID_STATUS_OFFLINE || iOldStatus == 0) && iOldStatus < ID_STATUS_OFFLINE + _countof(statusModeList)) {
int pos = statustopos(iOldStatus);
if (pos == -1)
pos = 0;
for (pos = 0; pos < _countof(statusModeList); pos++)
- Menu_ModifyItem(hStatusMenuHandles[i].menuhandle[pos], nullptr, INVALID_HANDLE_VALUE, 0);
+ Menu_ModifyItem(pa->menuhandle[pos], nullptr, INVALID_HANDLE_VALUE, 0);
}
if (ack->lParam >= ID_STATUS_OFFLINE && ack->lParam < ID_STATUS_OFFLINE + _countof(statusModeList)) {
int pos = statustopos((int)ack->lParam);
if (pos >= 0 && pos < _countof(statusModeList))
- Menu_SetChecked(hStatusMenuHandles[i].menuhandle[pos], true);
+ Menu_SetChecked(pa->menuhandle[pos], true);
}
break;
}
@@ -1075,12 +1054,6 @@ void InitCustomMenus(void)
hMainMenu = CreatePopupMenu();
hStatusMenu = CreatePopupMenu();
- hStatusMainMenuHandles = nullptr;
- hStatusMainMenuHandlesCnt = 0;
-
- hStatusMenuHandles = nullptr;
- hStatusMenuHandlesCnt = 0;
-
// new menu sys
InitGenMenu();
@@ -1138,12 +1111,6 @@ void InitCustomMenus(void)
void UninitCustomMenus(void)
{
- mir_free(hStatusMainMenuHandles);
- hStatusMainMenuHandles = nullptr;
-
- mir_free(hStatusMenuHandles);
- hStatusMenuHandles = nullptr;
-
Menu_RemoveObject(hMainMenuObject);
Menu_RemoveObject(hStatusMenuObject);
diff --git a/src/mir_app/src/miranda.h b/src/mir_app/src/miranda.h
index 2cfd867299..442bf85e64 100644
--- a/src/mir_app/src/miranda.h
+++ b/src/mir_app/src/miranda.h
@@ -120,9 +120,9 @@ extern HANDLE hPreBuildMainMenuEvent, hPreBuildContactMenuEvent;
extern HANDLE hShutdownEvent, hPreShutdownEvent;
extern HMENU hMainMenu, hStatusMenu;
-extern const int statusModeList[ MAX_STATUS_COUNT ];
-extern const int skinIconStatusList[ MAX_STATUS_COUNT ];
-extern const int skinIconStatusFlags[ MAX_STATUS_COUNT ];
+extern const int statusModeList[MAX_STATUS_COUNT];
+extern const int skinIconStatusList[MAX_STATUS_COUNT];
+extern const int skinIconStatusFlags[MAX_STATUS_COUNT];
extern OBJLIST<CListEvent> g_cliEvents;