summaryrefslogtreecommitdiff
path: root/src/mir_app
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2018-06-13 14:14:35 +0300
committerGeorge Hazan <ghazan@miranda.im>2018-06-13 14:14:35 +0300
commit00d71971d9cf831b991d391bb073dd846a15855f (patch)
treef121836446e42c395749d6e4ecdddb8d1aea72b6 /src/mir_app
parent1723a03ef74caa86cbfde4144541afb92147395f (diff)
profile lock detection unbound from contact list services
Diffstat (limited to 'src/mir_app')
-rw-r--r--src/mir_app/src/MDatabaseCommon.cpp34
-rw-r--r--src/mir_app/src/database.cpp38
-rw-r--r--src/mir_app/src/db_util.cpp16
-rw-r--r--src/mir_app/src/mir_app.def3
-rw-r--r--src/mir_app/src/mir_app64.def3
-rw-r--r--src/mir_app/src/profilemanager.cpp2
-rw-r--r--src/mir_app/src/profilemanager.h2
7 files changed, 70 insertions, 28 deletions
diff --git a/src/mir_app/src/MDatabaseCommon.cpp b/src/mir_app/src/MDatabaseCommon.cpp
index 74f33688dc..db053e03fd 100644
--- a/src/mir_app/src/MDatabaseCommon.cpp
+++ b/src/mir_app/src/MDatabaseCommon.cpp
@@ -38,6 +38,7 @@ MDatabaseCommon::MDatabaseCommon() :
MDatabaseCommon::~MDatabaseCommon()
{
+ UnlockName();
delete (MDatabaseCache*)m_cache;
}
@@ -60,6 +61,39 @@ int MDatabaseCommon::CheckProto(DBCachedContact *cc, const char *proto)
return !mir_strcmp(cc->szProto, proto);
}
+bool MDatabaseCommon::LockName(const wchar_t *pwszProfileName)
+{
+ if (m_hLock != nullptr)
+ return true;
+
+ if (pwszProfileName == nullptr)
+ return false;
+
+ CMStringW wszPhysName(pwszProfileName);
+ wszPhysName.Replace(L"\\", L"_");
+ wszPhysName.Insert(0, L"Global\\");
+
+ HANDLE hMutex = ::CreateMutexW(nullptr, false, wszPhysName);
+ if (hMutex == nullptr)
+ return false;
+
+ if (GetLastError() == ERROR_ALREADY_EXISTS) {
+ ::CloseHandle(hMutex);
+ return false;
+ }
+
+ m_hLock = hMutex;
+ return true;
+}
+
+void MDatabaseCommon::UnlockName()
+{
+ if (m_hLock) {
+ CloseHandle(m_hLock);
+ m_hLock = nullptr;
+ }
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
// Modules
diff --git a/src/mir_app/src/database.cpp b/src/mir_app/src/database.cpp
index e7f5483e59..29f5bdd512 100644
--- a/src/mir_app/src/database.cpp
+++ b/src/mir_app/src/database.cpp
@@ -431,38 +431,21 @@ static int tryCreateDatabase(const wchar_t *ptszProfile)
return -1; // no suitable driver found
}
-typedef struct
-{
- wchar_t *profile;
- UINT msg;
- ATOM aPath;
- int found;
-} ENUMMIRANDAWINDOW;
+/////////////////////////////////////////////////////////////////////////////////////////
static BOOL CALLBACK EnumMirandaWindows(HWND hwnd, LPARAM lParam)
{
wchar_t classname[256];
- ENUMMIRANDAWINDOW *x = (ENUMMIRANDAWINDOW *)lParam;
- DWORD_PTR res = 0;
if (GetClassName(hwnd, classname, _countof(classname)) && mir_wstrcmp(L"Miranda", classname) == 0) {
- if (SendMessageTimeout(hwnd, x->msg, (WPARAM)x->aPath, 0, SMTO_ABORTIFHUNG, 100, &res) && res) {
- x->found++;
+ DWORD_PTR res = 0;
+ if (SendMessageTimeout(hwnd, uMsgProcessProfile, lParam, 0, SMTO_ABORTIFHUNG, 100, &res) && res)
return FALSE;
- }
}
+
return TRUE;
}
-int findMirandaForProfile(wchar_t *szProfile)
-{
- ENUMMIRANDAWINDOW x = {};
- x.profile = szProfile;
- x.msg = RegisterWindowMessage(L"Miranda::ProcessProfile");
- x.aPath = GlobalAddAtom(szProfile);
- EnumWindows(EnumMirandaWindows, (LPARAM)&x);
- GlobalDeleteAtom(x.aPath);
- return x.found;
-}
+/////////////////////////////////////////////////////////////////////////////////////////
static wchar_t tszNoDrivers[] = LPGENW("Miranda is unable to open '%s' because you do not have any profile plugins installed.\nYou need to install dbx_mdbx.dll");
static wchar_t tszUnknownFormat[] = LPGENW("Miranda was unable to open '%s', it's in an unknown format.");
@@ -484,15 +467,18 @@ int LoadDatabaseModule(void)
ptszFileName = (ptszFileName) ? ptszFileName + 1 : szProfile;
if (arDbPlugins.getCount() == 0) {
- MessageBox(nullptr,
- CMStringW(FORMAT, TranslateW(tszNoDrivers), ptszFileName),
- TranslateT("No profile support installed!"), MB_OK | MB_ICONERROR);
+ MessageBox(nullptr, CMStringW(FORMAT, TranslateW(tszNoDrivers), ptszFileName), TranslateT("No profile support installed!"), MB_OK | MB_ICONERROR);
return 1;
}
// if this profile is already opened in another miranda, silently return
- if (findMirandaForProfile(szProfile))
+ if (Profile_CheckOpened(szProfile)) {
+ uMsgProcessProfile = RegisterWindowMessage(L"Miranda::ProcessProfile");
+ ATOM aPath = GlobalAddAtom(szProfile);
+ EnumWindows(EnumMirandaWindows, (LPARAM)aPath);
+ GlobalDeleteAtom(aPath);
return 1;
+ }
// find a driver to support the given profile
bool retry;
diff --git a/src/mir_app/src/db_util.cpp b/src/mir_app/src/db_util.cpp
index 1853ff2319..7b95357a4f 100644
--- a/src/mir_app/src/db_util.cpp
+++ b/src/mir_app/src/db_util.cpp
@@ -71,3 +71,19 @@ MIR_APP_DLL(void) Profile_SetDefault(const wchar_t *pwszPath)
extern wchar_t* g_defaultProfile;
replaceStrW(g_defaultProfile, pwszPath);
}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+MIR_APP_DLL(bool) Profile_CheckOpened(const wchar_t *pwszProfileName)
+{
+ CMStringW wszPhysName(pwszProfileName);
+ wszPhysName.Replace(L"\\", L"_");
+ wszPhysName.Insert(0, L"Global\\");
+
+ HANDLE hMutex = ::OpenMutexW(SYNCHRONIZE, false, wszPhysName);
+ if (hMutex == nullptr)
+ return false;
+
+ ::CloseHandle(hMutex);
+ return true;
+}
diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def
index 513d8cae5c..cde723cefb 100644
--- a/src/mir_app/src/mir_app.def
+++ b/src/mir_app/src/mir_app.def
@@ -619,3 +619,6 @@ UnregisterPlugin @633
?Unload@CMPluginBase@@UAEHXZ @648 NONAME
Srmm_ClickStatusIcon @649
?getModule@CMPluginBase@@QBEPBDXZ @650 NONAME
+?LockName@MDatabaseCommon@@IAE_NPB_W@Z @651 NONAME
+?UnlockName@MDatabaseCommon@@IAEXXZ @652 NONAME
+Profile_CheckOpened @653
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def
index 732effd29f..44634d5ce9 100644
--- a/src/mir_app/src/mir_app64.def
+++ b/src/mir_app/src/mir_app64.def
@@ -619,3 +619,6 @@ UnregisterPlugin @633
?Unload@CMPluginBase@@UEAAHXZ @648 NONAME
Srmm_ClickStatusIcon @649
?getModule@CMPluginBase@@QEBAPEBDXZ @650 NONAME
+?LockName@MDatabaseCommon@@IEAA_NPEB_W@Z @651 NONAME
+?UnlockName@MDatabaseCommon@@IEAAXXZ @652 NONAME
+Profile_CheckOpened @653
diff --git a/src/mir_app/src/profilemanager.cpp b/src/mir_app/src/profilemanager.cpp
index f5b6e486d7..ad50cbbde8 100644
--- a/src/mir_app/src/profilemanager.cpp
+++ b/src/mir_app/src/profilemanager.cpp
@@ -270,7 +270,7 @@ class CChooseProfileDlg : public CDlgBase
mir_snwprintf(sizeBuf, L"%.3lf", (double)statbuf.st_size / 1024.0);
mir_wstrcpy(sizeBuf + 5, L" KB");
}
- bFileLocked = findMirandaForProfile(tszFullPath) != 0;
+ bFileLocked = Profile_CheckOpened(tszFullPath);
}
else bFileLocked = true;
diff --git a/src/mir_app/src/profilemanager.h b/src/mir_app/src/profilemanager.h
index a3c238f9ca..11b5c6ed52 100644
--- a/src/mir_app/src/profilemanager.h
+++ b/src/mir_app/src/profilemanager.h
@@ -35,7 +35,6 @@ struct PROFILEMANAGERDATA
DATABASELINK *dblink; // out
};
-int findMirandaForProfile(wchar_t *szProfile);
char* makeFileName(const wchar_t *tszOriginalName);
int touchDatabase(const wchar_t *tszProfile, DATABASELINK **pDblink);
int getProfileManager(PROFILEMANAGERDATA *pd);
@@ -46,3 +45,4 @@ bool shouldAutoCreate(wchar_t *szProfile);
extern wchar_t g_profileDir[MAX_PATH], g_profileName[MAX_PATH], g_shortProfileName[MAX_PATH];
extern bool g_bDbCreated;
+extern UINT uMsgProcessProfile;