From e35464b3a1c3a5af68b348803049d90d73c1bc0d Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 20 Jul 2014 11:09:16 +0000 Subject: all profile conversion stuff moved to dbchecker git-svn-id: http://svn.miranda-ng.org/main/trunk@9880 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- include/m_database.h | 2 +- plugins/Db3x_mmap/src/dbcontacts.cpp | 40 +-------- plugins/Db3x_mmap/src/dbcrypt.cpp | 112 +++++++++++++++++++++++-- plugins/Db3x_mmap/src/dbevents.cpp | 74 ---------------- plugins/Db3x_mmap/src/dbintf.cpp | 27 +++--- plugins/Db3x_mmap/src/dbintf.h | 6 +- plugins/Db3x_mmap/src/dbtool/contactchain.cpp | 15 +++- plugins/Db3x_mmap/src/dbtool/disk.cpp | 4 +- plugins/Db3x_mmap/src/dbtool/eventchain.cpp | 37 +++++++- plugins/Db3x_mmap/src/dbtool/finaltasks.cpp | 6 ++ plugins/Db3x_mmap/src/dbtool/initialchecks.cpp | 15 +++- plugins/Db3x_mmap/src/dbtool/user.cpp | 3 +- plugins/Db3x_mmap/src/init.cpp | 2 +- plugins/DbChecker/src/dbchecker.h | 1 + plugins/DbChecker/src/finished.cpp | 2 +- plugins/DbChecker/src/main.cpp | 8 +- plugins/DbChecker/src/progress.cpp | 7 +- plugins/DbChecker/src/selectdb.cpp | 9 +- plugins/DbChecker/src/wizard.cpp | 7 +- src/modules/database/database.cpp | 10 +-- src/modules/database/dbintf.cpp | 2 +- src/modules/database/profilemanager.cpp | 42 +++++----- src/modules/database/profilemanager.h | 4 +- 23 files changed, 244 insertions(+), 191 deletions(-) diff --git a/include/m_database.h b/include/m_database.h index 6d1f18a29d..b8c01f3504 100644 --- a/include/m_database.h +++ b/include/m_database.h @@ -128,7 +128,7 @@ Analog of Database/DefaultProfile in mirandaboot.ini Checks the specified profile like dbtool did. Implemented in the dbchecker plugins, thus it might not exist wParam = (WPARAM)(TCHAR*)ptszProfileName - lParam = 0 (unused) + lParam = (BOOL)bConversionMode */ #define MS_DB_CHECKPROFILE "DB/CheckProfile" 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* 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 arSettings(1); + SettingUgraderParam param = { db, szModule, contactID, &arSettings }; + + DBCONTACTENUMSETTINGS dbces = { 0 }; + dbces.pfnEnumProc = sttSettingUgrader; + dbces.szModule = szModule; + dbces.lParam = (LPARAM)¶m; + 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 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(); diff --git a/plugins/DbChecker/src/dbchecker.h b/plugins/DbChecker/src/dbchecker.h index a487bf3dd9..1e97526d96 100644 --- a/plugins/DbChecker/src/dbchecker.h +++ b/plugins/DbChecker/src/dbchecker.h @@ -57,6 +57,7 @@ extern HINSTANCE hInst; extern DbToolOptions opts; extern HANDLE hEventRun, hEventAbort; extern int errorCount; +extern LRESULT wizardResult; extern bool bServiceMode, bLaunchMiranda, bShortMode; int DoMyControlProcessing(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam, INT_PTR *bReturn); diff --git a/plugins/DbChecker/src/finished.cpp b/plugins/DbChecker/src/finished.cpp index 47b272860f..6fc21564d3 100644 --- a/plugins/DbChecker/src/finished.cpp +++ b/plugins/DbChecker/src/finished.cpp @@ -44,7 +44,7 @@ INT_PTR CALLBACK FinishedDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM case WZN_CANCELCLICKED: bLaunchMiranda = IsDlgButtonChecked(hdlg, IDC_LAUNCHMIRANDA) == BST_CHECKED; CallService(MS_DB_SETDEFAULTPROFILE, (WPARAM)opts.filename, 0); - EndDialog(GetParent(hdlg), 1); + wizardResult = 1; return TRUE; } return FALSE; diff --git a/plugins/DbChecker/src/main.cpp b/plugins/DbChecker/src/main.cpp index cc09e35f78..ffd53b4b23 100644 --- a/plugins/DbChecker/src/main.cpp +++ b/plugins/DbChecker/src/main.cpp @@ -67,13 +67,13 @@ static INT_PTR ServiceMode(WPARAM, LPARAM) return (bLaunchMiranda) ? SERVICE_CONTINUE : SERVICE_FAILED; } -static INT_PTR CheckProfile(WPARAM wParam, LPARAM) +static INT_PTR CheckProfile(WPARAM wParam, LPARAM lParam) { bShortMode = true; - bLaunchMiranda = bServiceMode = false; + bLaunchMiranda = lParam != 0; + bServiceMode = false; _tcsncpy(opts.filename, (TCHAR*)wParam, SIZEOF(opts.filename)); - DialogBox(hInst, MAKEINTRESOURCE(IDD_WIZARD), NULL, WizardDlgProc); - return 0; + return DialogBox(hInst, MAKEINTRESOURCE(IDD_WIZARD), NULL, WizardDlgProc); } extern "C" __declspec(dllexport) int Load(void) diff --git a/plugins/DbChecker/src/progress.cpp b/plugins/DbChecker/src/progress.cpp index 467111a40b..ad12ca550c 100644 --- a/plugins/DbChecker/src/progress.cpp +++ b/plugins/DbChecker/src/progress.cpp @@ -26,6 +26,7 @@ static HWND hwndStatus, hdlgProgress, hwndBar; static bool bShortModeDone; HANDLE hEventRun = NULL, hEventAbort = NULL; int errorCount; +LRESULT wizardResult; void AddToStatus(int flags, const TCHAR* fmt, ...) { @@ -177,7 +178,9 @@ INT_PTR CALLBACK ProgressDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM case WZN_CANCELCLICKED: if (bShortModeDone) { - EndDialog( GetParent(hdlg), 1); + if (bLaunchMiranda) + CallService(MS_DB_SETDEFAULTPROFILE, (WPARAM)opts.filename, 0); + wizardResult = 1; return TRUE; } @@ -211,11 +214,13 @@ INT_PTR CALLBACK ProgressDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM else PostMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_CLEANING, (LPARAM)CleaningDlgProc); break; + case IDOK: PostMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_FINISHED, (LPARAM)FinishedDlgProc); break; } break; + case WM_DESTROY: if (hEventAbort) { CloseHandle(hEventAbort); diff --git a/plugins/DbChecker/src/selectdb.cpp b/plugins/DbChecker/src/selectdb.cpp index a013835748..c5455ef4fd 100644 --- a/plugins/DbChecker/src/selectdb.cpp +++ b/plugins/DbChecker/src/selectdb.cpp @@ -31,6 +31,7 @@ static bool CheckBroken(const TCHAR *ptszFullPath) int OpenDatabase(HWND hdlg, INT iNextPage) { TCHAR tszMsg[1024]; + int error = 0; if (opts.dbChecker == NULL) { DATABASELINK* dblink = FindDatabasePlugin(opts.filename); @@ -50,7 +51,6 @@ LBL_Error: goto LBL_Error; } - int error = 0; opts.dbChecker = dblink->CheckDB(opts.filename, &error); if (opts.dbChecker == NULL) { if ((opts.error = GetLastError()) == 0) @@ -61,7 +61,12 @@ LBL_Error: opts.dblink = dblink; } - if (iNextPage == IDD_FILEACCESS) + // force check + if (error == EGROKPRF_OBSOLETE) { + opts.bAggressive = opts.bBackup = true; + PostMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_PROGRESS, (LPARAM)ProgressDlgProc); + } + else if (iNextPage == IDD_FILEACCESS) PostMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_FILEACCESS, (LPARAM)FileAccessDlgProc); else PostMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_PROGRESS, (LPARAM)ProgressDlgProc); diff --git a/plugins/DbChecker/src/wizard.cpp b/plugins/DbChecker/src/wizard.cpp index e3641f7cf8..ca4b95885d 100644 --- a/plugins/DbChecker/src/wizard.cpp +++ b/plugins/DbChecker/src/wizard.cpp @@ -98,7 +98,6 @@ INT_PTR CALLBACK WizardDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lP case WM_INITDIALOG: SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_DBTOOL))); hdlgPage = NULL; - bLaunchMiranda = false; if (bShortMode) SendMessage(hdlg, WZM_GOTOPAGE, IDD_SELECTDB, (LPARAM)SelectDbDlgProc); else @@ -125,9 +124,11 @@ INT_PTR CALLBACK WizardDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lP SendMessage(hdlgPage, WZN_PAGECHANGING, wParam, 0); SendMessage(hdlgPage, message, wParam, lParam); break; + case IDCANCEL: - if (SendMessage(hdlgPage, WZN_CANCELCLICKED, 0, 0)) break; - EndDialog(hdlg, 0); + wizardResult = 0; + SendMessage(hdlgPage, WZN_CANCELCLICKED, 0, 0); + EndDialog(hdlg, wizardResult); break; } break; diff --git a/src/modules/database/database.cpp b/src/modules/database/database.cpp index a1da139802..5fdd136497 100644 --- a/src/modules/database/database.cpp +++ b/src/modules/database/database.cpp @@ -303,15 +303,13 @@ static int getProfile(TCHAR *szProfile, size_t cch) PROFILEMANAGERDATA pd = { 0 }; if (CmdLine_GetOption(_T("ForceShowPM"))) { LBL_Show: - pd.szProfile = szProfile; - pd.szProfileDir = g_profileDir; + pd.ptszProfile = szProfile; + pd.ptszProfileDir = g_profileDir; if (!getProfileManager(&pd)) return 0; - if (!pd.bRun) { - CallService(MS_DB_CHECKPROFILE, WPARAM(szProfile), 0); - return 0; - } + if (!pd.bRun) + return CallService(MS_DB_CHECKPROFILE, WPARAM(szProfile), TRUE); return 1; } diff --git a/src/modules/database/dbintf.cpp b/src/modules/database/dbintf.cpp index 6a3c332ed4..68009c9baf 100644 --- a/src/modules/database/dbintf.cpp +++ b/src/modules/database/dbintf.cpp @@ -107,7 +107,7 @@ static INT_PTR srvFindPlugin(WPARAM wParam,LPARAM lParam) { for (int i=arDbPlugins.getCount()-1; i >= 0; i--) { int error = arDbPlugins[i]->grokHeader((TCHAR*)lParam); - if (error == ERROR_SUCCESS) + if (error == ERROR_SUCCESS || error == EGROKPRF_OBSOLETE) return (INT_PTR)arDbPlugins[i]; } diff --git a/src/modules/database/profilemanager.cpp b/src/modules/database/profilemanager.cpp index 2d45cb0e40..8caf67b35b 100644 --- a/src/modules/database/profilemanager.cpp +++ b/src/modules/database/profilemanager.cpp @@ -198,10 +198,10 @@ static INT_PTR CALLBACK DlgProfileNew(HWND hwndDlg, UINT msg, WPARAM wParam, LPA } // decide if there is a default profile name given in the INI and if it should be used - if (dat->pd->noProfiles || (shouldAutoCreate(dat->pd->szProfile) && _taccess(dat->pd->szProfile, 0))) { - TCHAR *profile = _tcsrchr(dat->pd->szProfile, '\\'); + if (dat->pd->noProfiles || (shouldAutoCreate(dat->pd->ptszProfile) && _taccess(dat->pd->ptszProfile, 0))) { + TCHAR *profile = _tcsrchr(dat->pd->ptszProfile, '\\'); if (profile) ++profile; - else profile = dat->pd->szProfile; + else profile = dat->pd->ptszProfile; TCHAR *p = _tcsrchr(profile, '.'); TCHAR c = 0; @@ -245,11 +245,11 @@ static INT_PTR CALLBACK DlgProfileNew(HWND hwndDlg, UINT msg, WPARAM wParam, LPA break; // profile placed in "profile_name" subfolder - mir_sntprintf(dat->pd->szProfile, MAX_PATH, _T("%s\\%s\\%s.dat"), dat->pd->szProfileDir, szName, szName); + mir_sntprintf(dat->pd->ptszProfile, MAX_PATH, _T("%s\\%s\\%s.dat"), dat->pd->ptszProfileDir, szName, szName); dat->pd->newProfile = 1; dat->pd->dblink = (DATABASELINK *)SendDlgItemMessage(hwndDlg, IDC_PROFILEDRIVERS, CB_GETITEMDATA, (WPARAM)curSel, 0); - if (CreateProfile(dat->pd->szProfile, dat->pd->dblink, hwndDlg) == 0) + if (CreateProfile(dat->pd->ptszProfile, dat->pd->dblink, hwndDlg) == 0) SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); } break; @@ -340,15 +340,15 @@ void CheckProfile(HWND hwndList, int iItem, DlgProfData *dat) TCHAR profile[MAX_PATH], fullName[MAX_PATH]; LVITEM item = { 0 }; - item.mask = LVIF_TEXT; + item.mask = LVIF_TEXT | LVIF_IMAGE; item.iItem = iItem; item.pszText = profile; item.cchTextMax = SIZEOF(profile); if (!ListView_GetItem(hwndList, &item)) return; - mir_sntprintf(fullName, SIZEOF(fullName), _T("%s\\%s\\%s.dat"), dat->pd->szProfileDir, profile, profile); - CallService(MS_DB_CHECKPROFILE, (WPARAM)fullName, 0); + mir_sntprintf(fullName, SIZEOF(fullName), _T("%s\\%s\\%s.dat"), dat->pd->ptszProfileDir, profile, profile); + CallService(MS_DB_CHECKPROFILE, (WPARAM)fullName, item.iImage == 2); } void DeleteProfile(HWND hwndList, int iItem, DlgProfData *dat) @@ -371,7 +371,7 @@ void DeleteProfile(HWND hwndList, int iItem, DlgProfData *dat) if (IDYES != MessageBox(NULL, profilef, _T("Miranda NG"), MB_YESNO | MB_TASKMODAL | MB_ICONWARNING)) return; - mir_sntprintf(profilef, SIZEOF(profilef), _T("%s\\%s%c"), dat->pd->szProfileDir, profile, 0); + mir_sntprintf(profilef, SIZEOF(profilef), _T("%s\\%s%c"), dat->pd->ptszProfileDir, profile, 0); SHFILEOPSTRUCT sf = { 0 }; sf.wFunc = FO_DELETE; @@ -417,11 +417,11 @@ static void CheckRun(HWND hwndDlg, int uMsg) // profile is placed in "profile_name" subfolder TCHAR tmpPath[MAX_PATH]; - mir_sntprintf(tmpPath, SIZEOF(tmpPath), _T("%s\\%s.dat"), dat->pd->szProfileDir, profile); + mir_sntprintf(tmpPath, SIZEOF(tmpPath), _T("%s\\%s.dat"), dat->pd->ptszProfileDir, profile); if (_taccess(tmpPath, 2)) - mir_sntprintf(dat->pd->szProfile, MAX_PATH, _T("%s\\%s\\%s.dat"), dat->pd->szProfileDir, profile, profile); + mir_sntprintf(dat->pd->ptszProfile, MAX_PATH, _T("%s\\%s\\%s.dat"), dat->pd->ptszProfileDir, profile, profile); else - _tcsncpy_s(dat->pd->szProfile, MAX_PATH, tmpPath, _TRUNCATE); + _tcsncpy_s(dat->pd->ptszProfile, MAX_PATH, tmpPath, _TRUNCATE); if (uMsg == NM_DBLCLK) EndDialog(GetParent(hwndDlg), 1); @@ -528,11 +528,11 @@ static INT_PTR CALLBACK DlgProfileSelect(HWND hwndDlg, UINT msg, WPARAM wParam, ListView_GetExtendedListViewStyle(hwndList) | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT); // find all the profiles - ProfileEnumData ped = { hwndDlg, dat->pd->szProfile }; - findProfiles(dat->pd->szProfileDir, EnumProfilesForList, (LPARAM)&ped); + ProfileEnumData ped = { hwndDlg, dat->pd->ptszProfile }; + findProfiles(dat->pd->ptszProfileDir, EnumProfilesForList, (LPARAM)&ped); PostMessage(hwndDlg, WM_FOCUSTEXTBOX, 0, 0); - dat->hFileNotify = FindFirstChangeNotification(dat->pd->szProfileDir, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE); + dat->hFileNotify = FindFirstChangeNotification(dat->pd->ptszProfileDir, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE); if (dat->hFileNotify != INVALID_HANDLE_VALUE) SetTimer(hwndDlg, 0, 1200, NULL); return TRUE; @@ -546,15 +546,15 @@ static INT_PTR CALLBACK DlgProfileSelect(HWND hwndDlg, UINT msg, WPARAM wParam, case WM_TIMER: if (WaitForSingleObject(dat->hFileNotify, 0) == WAIT_OBJECT_0) { ListView_DeleteAllItems(hwndList); - ProfileEnumData ped = { hwndDlg, dat->pd->szProfile }; - findProfiles(dat->pd->szProfileDir, EnumProfilesForList, (LPARAM)&ped); + ProfileEnumData ped = { hwndDlg, dat->pd->ptszProfile }; + findProfiles(dat->pd->ptszProfileDir, EnumProfilesForList, (LPARAM)&ped); FindNextChangeNotification(dat->hFileNotify); } break; case WM_FOCUSTEXTBOX: SetFocus(hwndList); - if (dat->pd->szProfile[0] == 0 || ListView_GetSelectedCount(hwndList) == 0) + if (dat->pd->ptszProfile[0] == 0 || ListView_GetSelectedCount(hwndList) == 0) ListView_SetItemState(hwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); break; @@ -597,7 +597,7 @@ static INT_PTR CALLBACK DlgProfileSelect(HWND hwndDlg, UINT msg, WPARAM wParam, TCHAR profilename[MAX_PATH], tszFullPath[MAX_PATH]; struct _stat statbuf; ListView_GetItemText(hwndList, pInfoTip->iItem, 0, profilename, MAX_PATH); - mir_sntprintf(tszFullPath, SIZEOF(tszFullPath), _T("%s\\%s\\%s.dat"), dat->pd->szProfileDir, profilename, profilename); + mir_sntprintf(tszFullPath, SIZEOF(tszFullPath), _T("%s\\%s\\%s.dat"), dat->pd->ptszProfileDir, profilename, profilename); _tstat(tszFullPath, &statbuf); mir_sntprintf(pInfoTip->pszText, pInfoTip->cchTextMax, _T("%s\n%s: %s\n%s: %s"), tszFullPath, TranslateT("Created"), rtrimt(NEWTSTR_ALLOCA(_tctime(&statbuf.st_ctime))), TranslateT("Modified"), rtrimt(NEWTSTR_ALLOCA(_tctime(&statbuf.st_mtime)))); } @@ -643,13 +643,13 @@ static INT_PTR CALLBACK DlgProfileManager(HWND hwndDlg, UINT msg, WPARAM wParam, TCITEM tci; tci.mask = TCIF_TEXT; for (int i = 0; i < dat->pageCount; i++) { - dat->opd[i].pTemplate = (DLGTEMPLATE *)LockResource(LoadResource(odp[i].hInstance, FindResourceA(odp[i].hInstance, odp[i].pszTemplate, MAKEINTRESOURCEA(5)))); + dat->opd[i].pTemplate = (DLGTEMPLATE*)LockResource(LoadResource(odp[i].hInstance, FindResourceA(odp[i].hInstance, odp[i].pszTemplate, MAKEINTRESOURCEA(5)))); dat->opd[i].dlgProc = odp[i].pfnDlgProc; dat->opd[i].hInst = odp[i].hInstance; dat->opd[i].hwnd = NULL; dat->opd[i].changed = 0; tci.pszText = (TCHAR*)odp[i].ptszTitle; - if (dat->prof->pd->noProfiles || shouldAutoCreate(dat->prof->pd->szProfile)) + if (dat->prof->pd->noProfiles || shouldAutoCreate(dat->prof->pd->ptszProfile)) dat->currentPage = 1; TabCtrl_InsertItem(GetDlgItem(hwndDlg, IDC_TABS), i, &tci); } diff --git a/src/modules/database/profilemanager.h b/src/modules/database/profilemanager.h index dd16750c47..fa8e758edc 100644 --- a/src/modules/database/profilemanager.h +++ b/src/modules/database/profilemanager.h @@ -24,8 +24,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. struct PROFILEMANAGERDATA { - TCHAR *szProfile; // in/out - TCHAR *szProfileDir; // in/out + TCHAR *ptszProfile; // in/out + TCHAR *ptszProfileDir; // in/out BOOL noProfiles; // in BOOL bRun; // out -- cgit v1.2.3