summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2021-02-16 22:01:27 +0300
committerGeorge Hazan <ghazan@miranda.im>2021-02-16 22:01:27 +0300
commit72348ec753695b71234631f4c358ca4505a1d737 (patch)
tree7877ec2c315878cec15e6090eb6b9705c2d2e97a
parent9cc1ea5f3c117a5416ea5baf213bb691c0a5e9eb (diff)
fixes #2745 (Dbx_sqlite: wrong behaviour when launching second Miranda with the same profile)
-rwxr-xr-xplugins/Dbx_sqlite/src/dbintf.cpp82
-rwxr-xr-xplugins/Dbx_sqlite/src/dbintf.h14
-rw-r--r--plugins/Dbx_sqlite/src/main.cpp30
-rw-r--r--plugins/Dbx_sqlite/src/stdafx.h2
-rw-r--r--plugins/Dbx_sqlite/src/version.h2
5 files changed, 78 insertions, 52 deletions
diff --git a/plugins/Dbx_sqlite/src/dbintf.cpp b/plugins/Dbx_sqlite/src/dbintf.cpp
index bb977059e7..7523153359 100755
--- a/plugins/Dbx_sqlite/src/dbintf.cpp
+++ b/plugins/Dbx_sqlite/src/dbintf.cpp
@@ -1,9 +1,11 @@
#include "stdafx.h"
-CDbxSQLite::CDbxSQLite(sqlite3 *database) :
- m_db(database),
+CDbxSQLite::CDbxSQLite(const wchar_t *pwszFileName, bool bReadOnly, bool bShared) :
m_impl(*this),
+ m_wszFileName(mir_wstrdup(pwszFileName)),
m_safetyMode(true),
+ m_bReadOnly(bReadOnly),
+ m_bShared(bShared),
m_modules(1, strcmp)
{
}
@@ -27,50 +29,47 @@ CDbxSQLite::~CDbxSQLite()
/////////////////////////////////////////////////////////////////////////////////////////
-int CDbxSQLite::Create(const wchar_t *profile)
+int CDbxSQLite::Create()
{
- sqlite3 *database = nullptr;
- ptrA path(mir_utf8encodeW(profile));
- int rc = sqlite3_open_v2(path, &database, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_EXCLUSIVE, nullptr);
+ ptrA path(mir_utf8encodeW(m_wszFileName));
+ int rc = sqlite3_open_v2(path, &m_db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_EXCLUSIVE, nullptr);
logError(rc, __FILE__, __LINE__);
if (rc != SQLITE_OK) {
logError(rc, __FILE__, __LINE__);
return 1;
}
- rc = sqlite3_exec(database, "CREATE TABLE contacts (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT);", nullptr, nullptr, nullptr);
+ rc = sqlite3_exec(m_db, "CREATE TABLE contacts (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT);", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
- rc = sqlite3_exec(database, "CREATE TABLE events (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, contact_id INTEGER NOT NULL, module TEXT NOT NULL,"
+ rc = sqlite3_exec(m_db, "CREATE TABLE events (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, contact_id INTEGER NOT NULL, module TEXT NOT NULL,"
"timestamp INTEGER NOT NULL, type INTEGER NOT NULL, flags INTEGER NOT NULL, data BLOB, server_id TEXT);", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
- rc = sqlite3_exec(database, "CREATE INDEX idx_events_contactid_timestamp ON events(contact_id, timestamp);", nullptr, nullptr, nullptr);
+ rc = sqlite3_exec(m_db, "CREATE INDEX idx_events_contactid_timestamp ON events(contact_id, timestamp);", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
- rc = sqlite3_exec(database, "CREATE INDEX idx_events_module_serverid ON events(module, server_id);", nullptr, nullptr, nullptr);
+ rc = sqlite3_exec(m_db, "CREATE INDEX idx_events_module_serverid ON events(module, server_id);", nullptr, nullptr, nullptr);
if (rc != SQLITE_OK)
logError(rc, __FILE__, __LINE__);
- rc = sqlite3_exec(database, "CREATE TABLE events_srt (id INTEGER NOT NULL, contact_id INTEGER NOT NULL, timestamp INTEGER, PRIMARY KEY(contact_id, timestamp, id));", nullptr, nullptr, nullptr);
+ rc = sqlite3_exec(m_db, "CREATE TABLE events_srt (id INTEGER NOT NULL, contact_id INTEGER NOT NULL, timestamp INTEGER, PRIMARY KEY(contact_id, timestamp, id));", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
- rc = sqlite3_exec(database, "CREATE TABLE settings (contact_id INTEGER NOT NULL, module TEXT NOT NULL, setting TEXT NOT NULL, type INTEGER NOT NULL, value ANY,"
+ rc = sqlite3_exec(m_db, "CREATE TABLE settings (contact_id INTEGER NOT NULL, module TEXT NOT NULL, setting TEXT NOT NULL, type INTEGER NOT NULL, value ANY,"
"PRIMARY KEY(contact_id, module, setting)) WITHOUT ROWID;", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
- rc = sqlite3_exec(database, "CREATE INDEX idx_settings_module ON settings(module);", nullptr, nullptr, nullptr);
+ rc = sqlite3_exec(m_db, "CREATE INDEX idx_settings_module ON settings(module);", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
-
- sqlite3_close(database);
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
-int CDbxSQLite::Check(const wchar_t *profile)
+int CDbxSQLite::Check()
{
- FILE *hFile = _wfopen(profile, L"rb");
+ FILE *hFile = _wfopen(m_wszFileName, L"rb");
if (hFile == INVALID_HANDLE_VALUE)
return EGROKPRF_CANTREAD;
@@ -88,7 +87,7 @@ int CDbxSQLite::Check(const wchar_t *profile)
return EGROKPRF_UNKHEADER;
sqlite3 *database = nullptr;
- ptrA path(mir_utf8encodeW(profile));
+ ptrA path(mir_utf8encodeW(m_wszFileName));
int rc = sqlite3_open_v2(path, &database, SQLITE_OPEN_READONLY | SQLITE_OPEN_EXCLUSIVE, nullptr);
if (rc != SQLITE_OK) {
logError(rc, __FILE__, __LINE__);
@@ -102,48 +101,49 @@ int CDbxSQLite::Check(const wchar_t *profile)
/////////////////////////////////////////////////////////////////////////////////////////
-MDatabaseCommon* CDbxSQLite::Load(const wchar_t *profile, int readonly)
+int CDbxSQLite::Load()
{
- sqlite3 *database = nullptr;
- ptrA path(mir_utf8encodeW(profile));
- int flags = SQLITE_OPEN_EXCLUSIVE;
- if (readonly)
+ if (!LockName(m_wszFileName))
+ return EGROKPRF_CANTREAD;
+
+ ptrA path(mir_utf8encodeW(m_wszFileName));
+ int flags = 0;
+ if (!m_bShared)
+ flags |= SQLITE_OPEN_EXCLUSIVE;
+ if (m_bReadOnly)
flags |= SQLITE_OPEN_READONLY;
else
flags |= SQLITE_OPEN_READWRITE;
- int rc = sqlite3_open_v2(path, &database, flags, nullptr);
+ int rc = sqlite3_open_v2(path, &m_db, flags, nullptr);
if (rc != SQLITE_OK) {
logError(rc, __FILE__, __LINE__);
- return nullptr;
+ return EGROKPRF_CANTREAD;
}
- rc = sqlite3_exec(database, "pragma locking_mode = EXCLUSIVE;", nullptr, nullptr, nullptr);
+ rc = sqlite3_exec(m_db, "pragma locking_mode = EXCLUSIVE;", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
- rc = sqlite3_exec(database, "pragma synchronous = NORMAL;", nullptr, nullptr, nullptr);
+ rc = sqlite3_exec(m_db, "pragma synchronous = NORMAL;", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
- rc = sqlite3_exec(database, "pragma foreign_keys = OFF;", nullptr, nullptr, nullptr);
+ rc = sqlite3_exec(m_db, "pragma foreign_keys = OFF;", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
- rc = sqlite3_exec(database, "pragma journal_mode = OFF;", nullptr, nullptr, nullptr);
+ rc = sqlite3_exec(m_db, "pragma journal_mode = OFF;", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
if (rc == SQLITE_BUSY) {
- sqlite3_close(database);
- return nullptr;
+ sqlite3_close(m_db);
+ return EGROKPRF_CANTREAD;
}
- CDbxSQLite *db = new CDbxSQLite(database);
- db->InitContacts();
- db->InitSettings();
- db->InitEvents();
+ InitContacts();
+ InitSettings();
+ InitEvents();
- if (db->InitCrypt()) {
- delete db;
- return nullptr;
- }
+ if (InitCrypt())
+ return EGROKPRF_CANTREAD;
- rc = sqlite3_exec(database, "begin transaction;", nullptr, nullptr, nullptr);
+ rc = sqlite3_exec(m_db, "begin transaction;", nullptr, nullptr, nullptr);
logError(rc, __FILE__, __LINE__);
- return db;
+ return EGROKPRF_NOERROR;
}
/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/plugins/Dbx_sqlite/src/dbintf.h b/plugins/Dbx_sqlite/src/dbintf.h
index 9acbe25db9..b2f2c264ca 100755
--- a/plugins/Dbx_sqlite/src/dbintf.h
+++ b/plugins/Dbx_sqlite/src/dbintf.h
@@ -36,7 +36,8 @@ private:
class CDbxSQLite : public MDatabaseCommon, public MZeroedObject
{
- sqlite3 *m_db;
+ ptrW m_wszFileName;
+ sqlite3 *m_db = nullptr;
sqlite3_stmt *evt_cur_fwd = nullptr, *evt_cur_backwd = nullptr;
MCONTACT evt_cnt_fwd = 0, evt_cnt_backwd = 0;
@@ -61,9 +62,7 @@ class CDbxSQLite : public MDatabaseCommon, public MZeroedObject
}
} m_impl;
- bool m_safetyMode;
-
- CDbxSQLite(sqlite3 *database);
+ bool m_safetyMode, m_bReadOnly, m_bShared;
void InitContacts();
void UninitContacts();
@@ -78,11 +77,12 @@ class CDbxSQLite : public MDatabaseCommon, public MZeroedObject
void DBFlush(bool bForce = false);
public:
+ CDbxSQLite(const wchar_t *pwszFileName, bool bReadOnly, bool bShared);
~CDbxSQLite();
- static int Create(const wchar_t *profile);
- static int Check(const wchar_t *profile);
- static MDatabaseCommon* Load(const wchar_t *profile, int readonly);
+ int Create();
+ int Check();
+ int Load();
STDMETHODIMP_(BOOL) IsRelational(void) override;
STDMETHODIMP_(void) SetCacheSafetyMode(BOOL) override;
diff --git a/plugins/Dbx_sqlite/src/main.cpp b/plugins/Dbx_sqlite/src/main.cpp
index e3fe8b51d9..6c0f75b741 100644
--- a/plugins/Dbx_sqlite/src/main.cpp
+++ b/plugins/Dbx_sqlite/src/main.cpp
@@ -27,14 +27,38 @@ CMPlugin::CMPlugin() :
/////////////////////////////////////////////////////////////////////////////////////////
+// returns 0 if the profile is created, EMKPRF*
+static int makeDatabase(const wchar_t *profile)
+{
+ std::unique_ptr<CDbxSQLite> db(new CDbxSQLite(profile, false, false));
+ return db->Create();
+}
+
+// returns 0 if the given profile has a valid header
+static int grokHeader(const wchar_t *profile)
+{
+ std::unique_ptr<CDbxSQLite> db(new CDbxSQLite(profile, true, true));
+ return db->Check();
+}
+
+// returns 0 if all the APIs are injected otherwise, 1
+static MDatabaseCommon* loadDatabase(const wchar_t *profile, BOOL bReadOnly)
+{
+ std::unique_ptr<CDbxSQLite> db(new CDbxSQLite(profile, bReadOnly, false));
+ if (db->Load() != ERROR_SUCCESS)
+ return nullptr;
+
+ return db.release();
+}
+
static DATABASELINK dblink =
{
MDB_CAPS_CREATE | MDB_CAPS_COMPACT,
"dbx_sqlite",
L"SQLite database driver",
- &CDbxSQLite::Create,
- &CDbxSQLite::Check,
- &CDbxSQLite::Load,
+ makeDatabase,
+ grokHeader,
+ loadDatabase ,
};
STDMETHODIMP_(DATABASELINK *) CDbxSQLite::GetDriver()
diff --git a/plugins/Dbx_sqlite/src/stdafx.h b/plugins/Dbx_sqlite/src/stdafx.h
index 90cba22430..ff83996237 100644
--- a/plugins/Dbx_sqlite/src/stdafx.h
+++ b/plugins/Dbx_sqlite/src/stdafx.h
@@ -4,6 +4,8 @@
#include <malloc.h>
#include <crtdbg.h>
+#include <memory>
+
#include <newpluginapi.h>
#include <m_crypto.h>
#include <m_database.h>
diff --git a/plugins/Dbx_sqlite/src/version.h b/plugins/Dbx_sqlite/src/version.h
index 5f086b9e31..04c7f4a7a4 100644
--- a/plugins/Dbx_sqlite/src/version.h
+++ b/plugins/Dbx_sqlite/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
#define __MINOR_VERSION 95
#define __RELEASE_NUM 13
-#define __BUILD_NUM 3
+#define __BUILD_NUM 4
#include <stdver.h>