summaryrefslogtreecommitdiff
path: root/plugins/Db3x_mmap/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2014-07-20 11:09:16 +0000
committerGeorge Hazan <george.hazan@gmail.com>2014-07-20 11:09:16 +0000
commite35464b3a1c3a5af68b348803049d90d73c1bc0d (patch)
treebe5f05a3cb1b490653132afb735d9befeba4352b /plugins/Db3x_mmap/src
parent7663d8886a2e059232287b6652ead02142f6d6fc (diff)
all profile conversion stuff moved to dbchecker
git-svn-id: http://svn.miranda-ng.org/main/trunk@9880 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Db3x_mmap/src')
-rw-r--r--plugins/Db3x_mmap/src/dbcontacts.cpp40
-rw-r--r--plugins/Db3x_mmap/src/dbcrypt.cpp112
-rw-r--r--plugins/Db3x_mmap/src/dbevents.cpp74
-rw-r--r--plugins/Db3x_mmap/src/dbintf.cpp27
-rw-r--r--plugins/Db3x_mmap/src/dbintf.h6
-rw-r--r--plugins/Db3x_mmap/src/dbtool/contactchain.cpp15
-rw-r--r--plugins/Db3x_mmap/src/dbtool/disk.cpp4
-rw-r--r--plugins/Db3x_mmap/src/dbtool/eventchain.cpp37
-rw-r--r--plugins/Db3x_mmap/src/dbtool/finaltasks.cpp6
-rw-r--r--plugins/Db3x_mmap/src/dbtool/initialchecks.cpp15
-rw-r--r--plugins/Db3x_mmap/src/dbtool/user.cpp3
-rw-r--r--plugins/Db3x_mmap/src/init.cpp2
12 files changed, 192 insertions, 149 deletions
diff --git a/plugins/Db3x_mmap/src/dbcontacts.cpp b/plugins/Db3x_mmap/src/dbcontacts.cpp
index 218080763a..44af1cdc95 100644
--- a/plugins/Db3x_mmap/src/dbcontacts.cpp
+++ b/plugins/Db3x_mmap/src/dbcontacts.cpp
@@ -376,36 +376,6 @@ BOOL CDb3Mmap::MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub)
return ret;
}
-/////////////////////////////////////////////////////////////////////////////////////////
-// contacts convertor
-
-#define OLD_CONTACT_SIZE offsetof(DBContact, dwContactID)
-
-void CDb3Mmap::ConvertContacts()
-{
- DBContact *pPrev = NULL;
-
- m_dbHeader.ofsUser = ReallocSpace(m_dbHeader.ofsUser, OLD_CONTACT_SIZE, sizeof(DBContact));
- DBWrite(0, &m_dbHeader, sizeof(m_dbHeader));
-
- for (DWORD dwOffset = m_dbHeader.ofsFirstContact; dwOffset != 0;) {
- DBContact *pOld = (DBContact*)DBRead(dwOffset, sizeof(DBContact), NULL);
- DWORD dwNew = ReallocSpace(dwOffset, OLD_CONTACT_SIZE, sizeof(DBContact));
- DBContact *pNew = (DBContact*)DBRead(dwNew, sizeof(DBContact), NULL);
- pNew->dwContactID = m_dwMaxContactId++;
-
- if (pPrev == NULL)
- m_dbHeader.ofsFirstContact = dwNew;
- else
- pPrev->ofsNext = dwNew;
- pPrev = pNew;
-
- m_contactsMap.insert(new ConvertedContact(dwOffset, pNew->dwContactID));
- dwOffset = pNew->ofsNext;
- }
-
- FlushViewOfFile(m_pDbCache, 0);
-}
void CDb3Mmap::FillContacts()
{
@@ -416,13 +386,9 @@ void CDb3Mmap::FillContacts()
if (p->signature != DBCONTACT_SIGNATURE)
break;
- DWORD dwContactID;
- if (m_dbHeader.version >= DB_095_VERSION) {
- dwContactID = p->dwContactID;
- if (dwContactID >= m_dwMaxContactId)
- m_dwMaxContactId = dwContactID + 1;
- }
- else dwContactID = m_dwMaxContactId++;
+ DWORD dwContactID = p->dwContactID;
+ if (dwContactID >= m_dwMaxContactId)
+ m_dwMaxContactId = dwContactID + 1;
DBCachedContact *cc = m_cache->AddContactToCache(dwContactID);
cc->dwDriverData = dwOffset;
diff --git a/plugins/Db3x_mmap/src/dbcrypt.cpp b/plugins/Db3x_mmap/src/dbcrypt.cpp
index dddbfd2641..7e0b18cff9 100644
--- a/plugins/Db3x_mmap/src/dbcrypt.cpp
+++ b/plugins/Db3x_mmap/src/dbcrypt.cpp
@@ -23,37 +23,120 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "commonheaders.h"
+/////////////////////////////////////////////////////////////////////////////////////////
+
+//VERY VERY VERY BASIC ENCRYPTION FUNCTION
+
+static void Encrypt(char *msg, BOOL up)
+{
+ int jump = (up) ? 5 : -5;
+ for (int i = 0; msg[i]; i++)
+ msg[i] = msg[i] + jump;
+}
+
+__forceinline void DecodeString(LPSTR buf)
+{
+ Encrypt(buf, FALSE);
+}
+
struct VarDescr
{
VarDescr(LPCSTR var, LPCSTR value) :
szVar(mir_strdup(var)),
szValue(mir_strdup(value))
- {}
+ {}
VarDescr(LPCSTR var, LPSTR value) :
szVar(mir_strdup(var)),
szValue(value)
- {}
+ {}
VarDescr(LPCSTR var, PBYTE value, int len) :
szVar(mir_strdup(var)),
szValue((char*)memcpy(mir_alloc(len), value, len)),
iLen(len)
- {}
+ {}
ptrA szVar, szValue;
int iLen;
};
+struct SettingUgraderParam
+{
+ CDb3Mmap *db;
+ LPCSTR szModule;
+ MCONTACT contactID;
+ OBJLIST<VarDescr>* pList;
+};
+
+int sttSettingUgrader(const char *szSetting, LPARAM lParam)
+{
+ SettingUgraderParam *param = (SettingUgraderParam*)lParam;
+ if (param->db->IsSettingEncrypted(param->szModule, szSetting)) {
+ DBVARIANT dbv = { DBVT_UTF8 };
+ if (!param->db->GetContactSettingStr(param->contactID, param->szModule, szSetting, &dbv)) {
+ if (dbv.type == DBVT_UTF8) {
+ DecodeString(dbv.pszVal);
+ param->pList->insert(new VarDescr(szSetting, (LPCSTR)dbv.pszVal));
+ }
+ param->db->FreeVariant(&dbv);
+ }
+ }
+ return 0;
+}
+
+void sttContactEnum(MCONTACT contactID, const char *szModule, CDb3Mmap *db)
+{
+ OBJLIST<VarDescr> arSettings(1);
+ SettingUgraderParam param = { db, szModule, contactID, &arSettings };
+
+ DBCONTACTENUMSETTINGS dbces = { 0 };
+ dbces.pfnEnumProc = sttSettingUgrader;
+ dbces.szModule = szModule;
+ dbces.lParam = (LPARAM)&param;
+ db->EnumContactSettings(NULL, &dbces);
+
+ for (int i = 0; i < arSettings.getCount(); i++) {
+ VarDescr &p = arSettings[i];
+
+ size_t len;
+ BYTE *pResult = db->m_crypto->encodeString(p.szValue, &len);
+ if (pResult != NULL) {
+ DBCONTACTWRITESETTING dbcws = { szModule, p.szVar };
+ dbcws.value.type = DBVT_ENCRYPTED;
+ dbcws.value.pbVal = pResult;
+ dbcws.value.cpbVal = (WORD)len;
+ db->WriteContactSetting(contactID, &dbcws);
+
+ mir_free(pResult);
+ }
+ }
+}
+
+int sttModuleEnum(const char *szModule, DWORD, LPARAM lParam)
+{
+ CDb3Mmap *db = (CDb3Mmap*)lParam;
+ sttContactEnum(NULL, szModule, db);
+
+ for (MCONTACT contactID = db->FindFirstContact(); contactID; contactID = db->FindNextContact(contactID))
+ sttContactEnum(contactID, szModule, db);
+
+ return 0;
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
int CDb3Mmap::InitCrypt()
{
+ if (m_dbHeader.version == DB_OLD_VERSION)
+ return 0;
+
CRYPTO_PROVIDER *pProvider;
+ bool bMissingKey = false;
DBVARIANT dbv = { 0 };
dbv.type = DBVT_BLOB;
- if (GetContactSettingStr(NULL, "CryptoEngine", "Provider", &dbv)) {
+ if (GetContactSetting(NULL, "CryptoEngine", "Provider", &dbv)) {
LBL_CreateProvider:
CRYPTO_PROVIDER **ppProvs;
int iNumProvs;
@@ -70,6 +153,11 @@ LBL_CreateProvider:
WriteContactSetting(NULL, &dbcws);
}
else {
+ if (dbv.type != DBVT_BLOB) { // old version, clean it up
+ bMissingKey = true;
+ goto LBL_CreateProvider;
+ }
+
pProvider = Crypto_GetProvider(LPCSTR(dbv.pbVal));
FreeVariant(&dbv);
if (pProvider == NULL)
@@ -81,6 +169,8 @@ LBL_CreateProvider:
dbv.type = DBVT_BLOB;
if (GetContactSetting(NULL, "CryptoEngine", "StoredKey", &dbv)) {
+ bMissingKey = true;
+
LBL_SetNewKey:
m_crypto->generateKey(); // unencrypted key
StoreKey();
@@ -94,13 +184,23 @@ LBL_SetNewKey:
if (memcmp(m_dbHeader.signature, &dbSignatureE, sizeof(m_dbHeader.signature)))
goto LBL_SetNewKey;
- if (!EnterPassword(dbv.pbVal, iKeyLength)) // password protected?
- return 4;
+ if (!EnterPassword(dbv.pbVal, iKeyLength)) { // password protected?
+ if (m_dbHeader.version >= DB_094_VERSION)
+ return 4;
+
+ // one of the early used version of mmap was replaced then by mmap_sa
+ // simply remove old badly generated key
+ bMissingKey = true;
+ goto LBL_SetNewKey;
+ }
}
FreeVariant(&dbv);
}
+ if (bMissingKey)
+ EnumModuleNames(sttModuleEnum, this);
+
dbv.type = DBVT_BYTE;
if (!GetContactSetting(NULL, "CryptoEngine", "DatabaseEncryption", &dbv))
m_bEncrypted = dbv.bVal != 0;
diff --git a/plugins/Db3x_mmap/src/dbevents.cpp b/plugins/Db3x_mmap/src/dbevents.cpp
index 5bbb4853cb..0de122623d 100644
--- a/plugins/Db3x_mmap/src/dbevents.cpp
+++ b/plugins/Db3x_mmap/src/dbevents.cpp
@@ -508,77 +508,3 @@ int CDb3Mmap::WipeContactHistory(DBContact *dbc)
dbc->eventCount = 0; dbc->ofsFirstEvent = dbc->ofsLastEvent = dbc->ofsFirstUnread = dbc->tsFirstUnread = 0;
return 0;
}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// events convertor for DB_095_1_VERSION
-
-void CDb3Mmap::ConvertContactEvents(DBContact *dbc)
-{
- BYTE *pBlob = (PBYTE)mir_alloc(65536);
- DWORD ofsPrev = 0;
-
- __try {
- for (DWORD ofsEvent = dbc->ofsFirstEvent; ofsEvent != 0;) {
- DBEvent_094 pOld = *(DBEvent_094*)DBRead(ofsEvent, sizeof(DBEvent_094), NULL);
- if (pOld.signature != DBEVENT_SIGNATURE)
- break;
-
- if (pOld.cbBlob >= 65536) {
- ofsEvent = pOld.ofsNext;
- continue;
- }
- memcpy(pBlob, m_pDbCache + ofsEvent + offsetof(DBEvent_094, blob), pOld.cbBlob);
-
- DWORD ofsNew = ReallocSpace(ofsEvent, offsetof(DBEvent_094, blob) + pOld.cbBlob, offsetof(DBEvent, blob) + pOld.cbBlob);
- DBEvent *pNew = (DBEvent*)&m_pDbCache[ofsNew];
- pNew->signature = pOld.signature;
- pNew->contactID = dbc->dwContactID;
- memcpy(&pNew->ofsPrev, &pOld.ofsPrev, offsetof(DBEvent_094, blob) - sizeof(DWORD));
- memcpy(&pNew->blob, pBlob, pNew->cbBlob);
-
- if (pNew->flags & 1) {
- pNew->flags &= ~1;
- pNew->ofsPrev = 0;
- }
-
- if (ofsPrev == 0) // first event
- dbc->ofsFirstEvent = ofsNew, pNew->ofsPrev = 0;
- else {
- DBEvent *pPrev = (DBEvent*)&m_pDbCache[ofsPrev];
- pPrev->ofsNext = ofsNew, pNew->ofsPrev = ofsPrev;
- }
-
- if (dbc->ofsFirstUnread == ofsEvent)
- dbc->ofsFirstUnread = ofsNew;
- if (dbc->ofsLastEvent == ofsEvent)
- dbc->ofsLastEvent = ofsNew;
-
- ofsPrev = ofsNew;
- ofsEvent = pNew->ofsNext;
- }
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {}
-
- mir_free(pBlob);
-}
-
-void CDb3Mmap::ConvertEvents()
-{
- DBContact dbc = *(DBContact*)DBRead(m_dbHeader.ofsUser, sizeof(DBContact), NULL);
- ConvertContactEvents(&dbc);
- DBWrite(m_dbHeader.ofsUser, &dbc, sizeof(dbc));
-
- for (DWORD dwOffset = m_dbHeader.ofsFirstContact; dwOffset != 0;) {
- DBContact dbc = *(DBContact*)DBRead(dwOffset, sizeof(DBContact), NULL);
- ConvertContactEvents(&dbc);
- DBWrite(dwOffset, &dbc, sizeof(dbc));
-
- if (m_contactsMap.find((ConvertedContact*)&dbc.dwContactID) == NULL)
- m_contactsMap.insert(new ConvertedContact(dwOffset, dbc.dwContactID));
-
- dwOffset = dbc.ofsNext;
- }
-
- FlushViewOfFile(m_pDbCache, 0);
-}
diff --git a/plugins/Db3x_mmap/src/dbintf.cpp b/plugins/Db3x_mmap/src/dbintf.cpp
index 5b1b8e9712..99d0126696 100644
--- a/plugins/Db3x_mmap/src/dbintf.cpp
+++ b/plugins/Db3x_mmap/src/dbintf.cpp
@@ -116,9 +116,6 @@ CDb3Mmap::~CDb3Mmap()
free(m_pNull);
}
-static TCHAR szMsgConvert[] =
- LPGENT("Your database must be converted into the new format. This is potentially dangerous operation and might damage your profile, so please make a backup before.\n\nClick Yes to proceed with conversion or No to exit Miranda");
-
int CDb3Mmap::Load(bool bSkipInit)
{
log0("DB logging running");
@@ -146,17 +143,8 @@ int CDb3Mmap::Load(bool bSkipInit)
// everything is ok, go on
if (!m_bReadOnly) {
- if (m_dbHeader.version < DB_095_1_VERSION) {
- if (IDYES != MessageBox(NULL, TranslateTS(szMsgConvert), TranslateT("Database conversion required"), MB_YESNO | MB_ICONWARNING))
- return EGROKPRF_CANTREAD;
-
- if (m_dbHeader.version < DB_095_VERSION)
- ConvertContacts();
- ConvertEvents();
-
- m_dbHeader.version = DB_095_1_VERSION;
- DBWrite(sizeof(dbSignatureU), &m_dbHeader.version, sizeof(m_dbHeader.version));
- }
+ if (m_dbHeader.version < DB_095_1_VERSION)
+ return EGROKPRF_CANTREAD;
// we don't need events in the service mode
if (ServiceExists(MS_DB_SETSAFETYMODE)) {
@@ -183,11 +171,18 @@ int CDb3Mmap::Create()
return (m_hDbFile == INVALID_HANDLE_VALUE);
}
-int CDb3Mmap::PrepareCheck()
+int CDb3Mmap::PrepareCheck(int *error)
{
int ret = CheckDbHeaders(true);
- if (ret != ERROR_SUCCESS)
+ switch (ret) {
+ case ERROR_SUCCESS:
+ case EGROKPRF_OBSOLETE:
+ *error = ret;
+ break;
+
+ default:
return ret;
+ }
InitMap();
InitModuleNames();
diff --git a/plugins/Db3x_mmap/src/dbintf.h b/plugins/Db3x_mmap/src/dbintf.h
index f6f0f5f6de..7765644baf 100644
--- a/plugins/Db3x_mmap/src/dbintf.h
+++ b/plugins/Db3x_mmap/src/dbintf.h
@@ -196,7 +196,7 @@ struct CDb3Mmap : public MIDatabase, public MIDatabaseChecker, public MZeroedObj
void SetPassword(const TCHAR *ptszPassword);
void UpdateMenuItem(void);
- int PrepareCheck(void);
+ int PrepareCheck(int*);
__forceinline LPSTR GetMenuTitle() const { return m_bUsesPassword ? LPGEN("Change/remove password") : LPGEN("Set password"); }
@@ -319,9 +319,6 @@ protected:
OBJLIST<ConvertedContact> m_contactsMap;
- void ConvertContacts(void);
- void ConvertContactEvents(DBContact *dbc);
- void ConvertEvents(void);
int WipeContactHistory(DBContact *dbc);
////////////////////////////////////////////////////////////////////////////
@@ -358,6 +355,7 @@ protected:
DWORD WriteSegment(DWORD ofs, PVOID buf, int cbBytes);
DWORD WriteEvent(DBEvent *dbe);
+ DWORD PeekEvent(DWORD ofs, DWORD dwContactID, DBEvent *dbe);
void WriteOfsNextToPrevious(DWORD ofsPrev, DBContact *dbc, DWORD ofsNext);
void FinishUp(DWORD ofsLast, DBContact *dbc);
diff --git a/plugins/Db3x_mmap/src/dbtool/contactchain.cpp b/plugins/Db3x_mmap/src/dbtool/contactchain.cpp
index f1ba3ebe61..d149bd0e86 100644
--- a/plugins/Db3x_mmap/src/dbtool/contactchain.cpp
+++ b/plugins/Db3x_mmap/src/dbtool/contactchain.cpp
@@ -52,8 +52,16 @@ LBL_FinishUp:
cb->pfnAddLogMessage(STATUS_ERROR, TranslateT("Contact chain corrupted, further entries ignored"));
goto LBL_FinishUp;
}
- if (ReadSegment(ofsThisContact, &dbc, sizeof(dbc)) != ERROR_SUCCESS)
- goto LBL_FinishUp;
+
+ if (m_dbHeader.version < DB_095_VERSION) {
+ if (ReadSegment(ofsThisContact, &dbc, offsetof(DBContact, dwContactID)) != ERROR_SUCCESS)
+ goto LBL_FinishUp;
+ dbc.dwContactID = m_dwMaxContactId++;
+ }
+ else {
+ if (ReadSegment(ofsThisContact, &dbc, sizeof(dbc)) != ERROR_SUCCESS)
+ goto LBL_FinishUp;
+ }
ofsNextContact = dbc.ofsNext;
dbc.ofsNext = 0;
@@ -64,6 +72,9 @@ LBL_FinishUp:
WriteSegment(ofsDestPrevContact + offsetof(DBContact, ofsNext), &ofsDestThis, sizeof(DWORD));
else
m_dbHeader.ofsFirstContact = ofsDestThis;
+
+ if (m_dbHeader.version < DB_095_VERSION)
+ m_contactsMap.insert(new ConvertedContact(ofsThisContact, ofsDestThis));
}
else ofsDestThis = ofsThisContact; // needed in event chain worker
diff --git a/plugins/Db3x_mmap/src/dbtool/disk.cpp b/plugins/Db3x_mmap/src/dbtool/disk.cpp
index 7cd4dfd88c..692fdb7fde 100644
--- a/plugins/Db3x_mmap/src/dbtool/disk.cpp
+++ b/plugins/Db3x_mmap/src/dbtool/disk.cpp
@@ -26,8 +26,8 @@ int CDb3Mmap::SignatureValid(DWORD ofs, DWORD signature)
return 0;
}
- DWORD sig = *(DWORD*)(m_pDbCache + ofs);
- return sig == signature;
+ DWORD *sig = (DWORD*)(m_pDbCache + ofs);
+ return *sig == signature;
}
int CDb3Mmap::PeekSegment(DWORD ofs, PVOID buf, int cbBytes)
diff --git a/plugins/Db3x_mmap/src/dbtool/eventchain.cpp b/plugins/Db3x_mmap/src/dbtool/eventchain.cpp
index 9d3b227526..15fc96b0ec 100644
--- a/plugins/Db3x_mmap/src/dbtool/eventchain.cpp
+++ b/plugins/Db3x_mmap/src/dbtool/eventchain.cpp
@@ -102,6 +102,22 @@ void CDb3Mmap::FinishUp(DWORD ofsLast, DBContact *dbc)
}
}
+DWORD CDb3Mmap::PeekEvent(DWORD ofs, DWORD dwContactID, DBEvent *dbe)
+{
+ if (m_dbHeader.version == DB_095_1_VERSION)
+ return PeekSegment(ofs, dbe, sizeof(DBEvent));
+
+ DBEvent_094 oldEvent;
+ DWORD ret = PeekSegment(ofs, &oldEvent, sizeof(oldEvent));
+ if (ret != ERROR_SUCCESS)
+ return ret;
+
+ dbe->signature = oldEvent.signature;
+ dbe->contactID = dwContactID;
+ memcpy(&dbe->ofsPrev, &oldEvent.ofsPrev, sizeof(oldEvent) - sizeof(DWORD));
+ return ERROR_SUCCESS;
+}
+
DWORD CDb3Mmap::WriteEvent(DBEvent *dbe)
{
DWORD ofs = WriteSegment(WSOFS_END, dbe, offsetof(DBEvent, blob) + dbe->cbBlob);
@@ -152,7 +168,7 @@ int CDb3Mmap::WorkEventChain(DWORD ofsContact, DBContact *dbc, int firstTime)
if (!backLookup && ofsTmp) {
backLookup = 1;
while (SignatureValid(ofsTmp, DBEVENT_SIGNATURE)) {
- if (PeekSegment(ofsTmp, &dbeOld, sizeof(dbeOld)) != ERROR_SUCCESS)
+ if (PeekEvent(ofsTmp, dbc->dwContactID, &dbeOld) != ERROR_SUCCESS)
break;
ofsNew = ofsTmp;
ofsTmp = dbeOld.ofsPrev;
@@ -169,7 +185,7 @@ int CDb3Mmap::WorkEventChain(DWORD ofsContact, DBContact *dbc, int firstTime)
}
}
- if (PeekSegment(ofsThisEvent, &dbeOld, sizeof(dbeOld)) != ERROR_SUCCESS) {
+ if (PeekEvent(ofsThisEvent, dbc->dwContactID, &dbeOld) != ERROR_SUCCESS) {
FinishUp(ofsDestPrevEvent, dbc);
return ERROR_NO_MORE_ITEMS;
}
@@ -217,7 +233,20 @@ int CDb3Mmap::WorkEventChain(DWORD ofsContact, DBContact *dbc, int firstTime)
}
dbeNew = memblock;
- if (ReadSegment(ofsThisEvent, dbeNew, offsetof(DBEvent, blob) + dbeOld.cbBlob) != ERROR_SUCCESS) {
+ DWORD ret;
+ if (m_dbHeader.version < DB_095_1_VERSION) {
+ DBEvent_094 oldEvent;
+ ret = ReadSegment(ofsThisEvent, &oldEvent, offsetof(DBEvent_094, blob));
+ if (ret == ERROR_SUCCESS) {
+ dbeNew->signature = oldEvent.signature;
+ dbeNew->contactID = dbc->dwContactID;
+ memcpy(&dbeNew->ofsPrev, &oldEvent.ofsPrev, offsetof(DBEvent_094, blob) - sizeof(DWORD));
+ ret = ReadSegment(ofsThisEvent + offsetof(DBEvent_094, blob), &dbeNew->blob, dbeOld.cbBlob);
+ }
+ }
+ else ret = ReadSegment(ofsThisEvent, dbeNew, offsetof(DBEvent, blob) + dbeOld.cbBlob);
+
+ if (ret != ERROR_SUCCESS) {
FinishUp(ofsDestPrevEvent, dbc);
return ERROR_NO_MORE_ITEMS;
}
@@ -273,7 +302,7 @@ int CDb3Mmap::WorkEventChain(DWORD ofsContact, DBContact *dbc, int firstTime)
if (cb->bCheckOnly) {
if (!cb->bAggressive) {
ofsTmp = dbeOld.ofsPrev;
- while (PeekSegment(ofsTmp, &dbeTmp, sizeof(dbeTmp)) == ERROR_SUCCESS) {
+ while (PeekEvent(ofsTmp, dbc->dwContactID, &dbeTmp) == ERROR_SUCCESS) {
if (dbeTmp.ofsPrev == ofsContact) {
found = 1;
break;
diff --git a/plugins/Db3x_mmap/src/dbtool/finaltasks.cpp b/plugins/Db3x_mmap/src/dbtool/finaltasks.cpp
index 972999524b..5aa01e230c 100644
--- a/plugins/Db3x_mmap/src/dbtool/finaltasks.cpp
+++ b/plugins/Db3x_mmap/src/dbtool/finaltasks.cpp
@@ -24,6 +24,12 @@ int CDb3Mmap::WorkFinalTasks(int firstTime)
FreeModuleChain();
cb->pfnAddLogMessage(STATUS_MESSAGE, TranslateT("Processing final tasks"));
m_dbHeader.slackSpace = 0;
+
+ if (m_dbHeader.version < DB_095_1_VERSION) {
+ memcpy(&m_dbHeader.signature, &dbSignatureU, sizeof(m_dbHeader.signature));
+ m_dbHeader.version = DB_095_1_VERSION;
+ }
+
if (WriteSegment(0, &m_dbHeader, sizeof(m_dbHeader)) == WS_ERROR)
return ERROR_WRITE_FAULT;
diff --git a/plugins/Db3x_mmap/src/dbtool/initialchecks.cpp b/plugins/Db3x_mmap/src/dbtool/initialchecks.cpp
index 86bad8729d..ec1339d787 100644
--- a/plugins/Db3x_mmap/src/dbtool/initialchecks.cpp
+++ b/plugins/Db3x_mmap/src/dbtool/initialchecks.cpp
@@ -22,15 +22,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
int CDb3Mmap::WorkInitialCheckHeaders()
{
if (memcmp(m_dbHeader.signature, &dbSignatureU, sizeof(m_dbHeader.signature)) &&
- memcmp(m_dbHeader.signature, &dbSignatureE, sizeof(m_dbHeader.signature)))
+ memcmp(m_dbHeader.signature, &dbSignatureE, sizeof(m_dbHeader.signature)) &&
+ memcmp(m_dbHeader.signature, &dbSignatureIM, sizeof(m_dbHeader.signature)) &&
+ memcmp(m_dbHeader.signature, &dbSignatureSA, sizeof(m_dbHeader.signature)))
{
cb->pfnAddLogMessage(STATUS_FATAL, TranslateT("Database signature is corrupted, automatic repair is impossible"));
return ERROR_BAD_FORMAT;
}
- if (m_dbHeader.version != DB_095_1_VERSION) {
+
+ switch (m_dbHeader.version) {
+ case DB_OLD_VERSION:
+ case DB_094_VERSION:
+ case DB_095_VERSION:
+ case DB_095_1_VERSION:
+ break;
+
+ default:
cb->pfnAddLogMessage(STATUS_FATAL, TranslateT("Database version doesn't match this driver's one. Convert a database first"));
return ERROR_BAD_FORMAT;
}
+
return ERROR_SUCCESS;
}
diff --git a/plugins/Db3x_mmap/src/dbtool/user.cpp b/plugins/Db3x_mmap/src/dbtool/user.cpp
index 72d403f509..4f254bdbb9 100644
--- a/plugins/Db3x_mmap/src/dbtool/user.cpp
+++ b/plugins/Db3x_mmap/src/dbtool/user.cpp
@@ -34,7 +34,8 @@ int CDb3Mmap::WorkUser(int firstTime)
return ERROR_NO_MORE_ITEMS;
}
- if (ReadSegment(m_dbHeader.ofsUser, &user, sizeof(DBContact)) != ERROR_SUCCESS)
+ DWORD dwSize = (m_dbHeader.version < DB_095_VERSION) ? offsetof(DBContact, dwContactID) : sizeof(DBContact);
+ if (ReadSegment(m_dbHeader.ofsUser, &user, dwSize) != ERROR_SUCCESS)
return ERROR_NO_MORE_ITEMS;
if (user.ofsNext) {
diff --git a/plugins/Db3x_mmap/src/init.cpp b/plugins/Db3x_mmap/src/init.cpp
index debdbba05b..f4620b4e1d 100644
--- a/plugins/Db3x_mmap/src/init.cpp
+++ b/plugins/Db3x_mmap/src/init.cpp
@@ -95,7 +95,7 @@ MIDatabaseChecker* CheckDb(const TCHAR *profile, int *error)
return NULL;
}
- if (*error = db->PrepareCheck())
+ if (db->PrepareCheck(error))
return NULL;
return db.release();