summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2012-07-26 14:56:53 +0000
committerGeorge Hazan <george.hazan@gmail.com>2012-07-26 14:56:53 +0000
commitd5d6965af7e69367babf40b7fb1d7fca8617cabe (patch)
tree614f57382fcf26c3895d4166f67657c3b0e23e3e /plugins
parent78eb36ffcbd1b71eee1b912a927522fd3f19b347 (diff)
dbtool is divided into two parts: DbChecker & appendix for db3x_mmap plugin
git-svn-id: http://svn.miranda-ng.org/main/trunk@1195 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Db3x_mmap/db3x_mmap_10.vcxproj40
-rw-r--r--plugins/Db3x_mmap/db3x_mmap_10.vcxproj.filters58
-rw-r--r--plugins/Db3x_mmap/src/dbintf.h10
-rw-r--r--plugins/Db3x_mmap/src/dbtool/aggressive.cpp63
-rw-r--r--plugins/Db3x_mmap/src/dbtool/contactchain.cpp99
-rw-r--r--plugins/Db3x_mmap/src/dbtool/disk.cpp112
-rw-r--r--plugins/Db3x_mmap/src/dbtool/eventchain.cpp363
-rw-r--r--plugins/Db3x_mmap/src/dbtool/finaltasks.cpp78
-rw-r--r--plugins/Db3x_mmap/src/dbtool/initialchecks.cpp81
-rw-r--r--plugins/Db3x_mmap/src/dbtool/modulechain.cpp146
-rw-r--r--plugins/Db3x_mmap/src/dbtool/settingschain.cpp72
-rw-r--r--plugins/Db3x_mmap/src/dbtool/user.cpp71
-rw-r--r--plugins/Db3x_mmap/src/init.cpp22
-rw-r--r--plugins/DbChecker/dbchecker_10.vcxproj212
-rw-r--r--plugins/DbChecker/dbchecker_10.vcxproj.filters68
-rw-r--r--plugins/DbChecker/docs/dbchecker-translation.txt138
-rw-r--r--plugins/DbChecker/res/dbthdr.emfbin0 -> 2912 bytes
-rw-r--r--plugins/DbChecker/res/dbtool.cdrbin0 -> 20826 bytes
-rw-r--r--plugins/DbChecker/res/dbtool.emfbin0 -> 4380 bytes
-rw-r--r--plugins/DbChecker/res/dbtool.icobin0 -> 9062 bytes
-rw-r--r--plugins/DbChecker/res/delete.icobin0 -> 2550 bytes
-rw-r--r--plugins/DbChecker/res/profileg.icobin0 -> 2550 bytes
-rw-r--r--plugins/DbChecker/res/profiler.icobin0 -> 2550 bytes
-rw-r--r--plugins/DbChecker/res/profiley.icobin0 -> 2550 bytes
-rw-r--r--plugins/DbChecker/res/resource.rc269
-rw-r--r--plugins/DbChecker/res/version.rc59
-rw-r--r--plugins/DbChecker/src/cleaning.cpp67
-rw-r--r--plugins/DbChecker/src/dbchecker.h105
-rw-r--r--plugins/DbChecker/src/fileaccess.cpp73
-rw-r--r--plugins/DbChecker/src/finished.cpp86
-rw-r--r--plugins/DbChecker/src/main.cpp26
-rw-r--r--plugins/DbChecker/src/openerror.cpp58
-rw-r--r--plugins/DbChecker/src/progress.cpp224
-rw-r--r--plugins/DbChecker/src/resource.h54
-rw-r--r--plugins/DbChecker/src/selectdb.cpp296
-rw-r--r--plugins/DbChecker/src/utf.cpp69
-rw-r--r--plugins/DbChecker/src/version.h5
-rw-r--r--plugins/DbChecker/src/welcome.cpp70
-rw-r--r--plugins/DbChecker/src/wizard.cpp141
-rw-r--r--plugins/DbChecker/src/worker.cpp79
40 files changed, 3299 insertions, 15 deletions
diff --git a/plugins/Db3x_mmap/db3x_mmap_10.vcxproj b/plugins/Db3x_mmap/db3x_mmap_10.vcxproj
index 620786b9c6..a96259c565 100644
--- a/plugins/Db3x_mmap/db3x_mmap_10.vcxproj
+++ b/plugins/Db3x_mmap/db3x_mmap_10.vcxproj
@@ -208,6 +208,46 @@
<ClCompile Include="src\dbintfm.cpp" />
<ClCompile Include="src\dbmodulechain.cpp" />
<ClCompile Include="src\dbsettings.cpp" />
+ <ClCompile Include="src\dbtool\aggressive.cpp">
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\commonheaders.h</PrecompiledHeaderFile>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\contactchain.cpp">
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\commonheaders.h</PrecompiledHeaderFile>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\eventchain.cpp">
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\commonheaders.h</PrecompiledHeaderFile>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\finaltasks.cpp">
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\commonheaders.h</PrecompiledHeaderFile>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\initialchecks.cpp">
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\commonheaders.h</PrecompiledHeaderFile>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\modulechain.cpp">
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\commonheaders.h</PrecompiledHeaderFile>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\settingschain.cpp">
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\commonheaders.h</PrecompiledHeaderFile>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\user.cpp">
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\commonheaders.h</PrecompiledHeaderFile>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
<ClCompile Include="src\init.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
diff --git a/plugins/Db3x_mmap/db3x_mmap_10.vcxproj.filters b/plugins/Db3x_mmap/db3x_mmap_10.vcxproj.filters
index 2d3667a179..23c6351e22 100644
--- a/plugins/Db3x_mmap/db3x_mmap_10.vcxproj.filters
+++ b/plugins/Db3x_mmap/db3x_mmap_10.vcxproj.filters
@@ -13,52 +13,82 @@
<UniqueIdentifier>{e5e10389-c0d7-4cf8-8442-6714f0d5aff1}</UniqueIdentifier>
<Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
</Filter>
+ <Filter Include="Source Files\Checker">
+ <UniqueIdentifier>{18e1a858-92e5-48e6-98f1-e08f4b562ea8}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="database.cpp">
+ <ClCompile Include="src\database.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\dbcache.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="dbcontacts.cpp">
+ <ClCompile Include="src\dbcontacts.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="dbevents.cpp">
+ <ClCompile Include="src\dbevents.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="dbheaders.cpp">
+ <ClCompile Include="src\dbheaders.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="dbmodulechain.cpp">
+ <ClCompile Include="src\dbintf.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="dbsettings.cpp">
+ <ClCompile Include="src\dbintfm.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="init.cpp">
+ <ClCompile Include="src\dbmodulechain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="dbintf.cpp">
+ <ClCompile Include="src\dbsettings.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="dbcache.cpp">
+ <ClCompile Include="src\init.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\dbtool\aggressive.cpp">
+ <Filter>Source Files\Checker</Filter>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\contactchain.cpp">
+ <Filter>Source Files\Checker</Filter>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\eventchain.cpp">
+ <Filter>Source Files\Checker</Filter>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\finaltasks.cpp">
+ <Filter>Source Files\Checker</Filter>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\initialchecks.cpp">
+ <Filter>Source Files\Checker</Filter>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\modulechain.cpp">
+ <Filter>Source Files\Checker</Filter>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\settingschain.cpp">
+ <Filter>Source Files\Checker</Filter>
+ </ClCompile>
+ <ClCompile Include="src\dbtool\user.cpp">
+ <Filter>Source Files\Checker</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
- <ClInclude Include="commonheaders.h">
+ <ClInclude Include="src\commonheaders.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="database.h">
+ <ClInclude Include="src\database.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="dbintf.h">
+ <ClInclude Include="src\dbintf.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
- <ResourceCompile Include="db3x_mmap.rc">
+ <ResourceCompile Include="res\db3x_mmap.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
- <ResourceCompile Include="version.rc">
+ <ResourceCompile Include="res\version.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
diff --git a/plugins/Db3x_mmap/src/dbintf.h b/plugins/Db3x_mmap/src/dbintf.h
index 2aa1ceea73..c13bdc5eb0 100644
--- a/plugins/Db3x_mmap/src/dbintf.h
+++ b/plugins/Db3x_mmap/src/dbintf.h
@@ -221,6 +221,14 @@ protected:
virtual void EncodeDBWrite(DWORD ofs, void *src, int size);
virtual void DecodeDBWrite(DWORD ofs, void *src, int size);
+public: // Check functions
+ int WorkInitialChecks(DBCHeckCallback*, int);
+ int WorkModuleChain(DBCHeckCallback*, int);
+ int WorkUser(DBCHeckCallback*, int);
+ int WorkContactChain(DBCHeckCallback*, int);
+ int WorkAggressive(DBCHeckCallback*, int);
+ int WorkFinalTasks(DBCHeckCallback*, int);
+
protected:
TCHAR* m_tszProfileName;
HANDLE m_hDbFile;
@@ -312,3 +320,5 @@ protected:
void Map();
void ReMap(DWORD needed);
};
+
+typedef int (CDb3Mmap::*CheckWorker)(DBCHeckCallback*, int);
diff --git a/plugins/Db3x_mmap/src/dbtool/aggressive.cpp b/plugins/Db3x_mmap/src/dbtool/aggressive.cpp
new file mode 100644
index 0000000000..7cafb63043
--- /dev/null
+++ b/plugins/Db3x_mmap/src/dbtool/aggressive.cpp
@@ -0,0 +1,63 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "..\commonheaders.h"
+
+#define BLOCKSIZE 65536
+
+extern DWORD sourceFileSize;
+extern DWORD spaceProcessed;
+extern DWORD sp;
+static DWORD ofsCurrent;
+
+int WorkAggressive(int firstTime)
+{
+ int blockBytes,i;
+ BYTE *buf;
+
+ if (firstTime) {
+ if (!opts.bAggressive)
+ return ERROR_NO_MORE_ITEMS;
+
+ AddToStatus(STATUS_MESSAGE,TranslateT("Performing aggressive pass"));
+ ofsCurrent = 0;
+ spaceProcessed = 0;
+ sp = 0;
+ }
+ blockBytes = min(BLOCKSIZE+3,(int)(sourceFileSize-ofsCurrent));
+ if (blockBytes <= 0)
+ return ERROR_NO_MORE_ITEMS;
+
+ buf = opts.pFile+ofsCurrent;
+ blockBytes -= 3;
+ for(i = 0;i<blockBytes;i++) {
+ if (buf[i]) {
+ if ((*(PDWORD)&buf[i]&0x00FFFFFF) != 0xDECADE)
+ AddToStatus(STATUS_WARNING,TranslateT("Aggressive: random junk at %08X: skipping"),ofsCurrent+i);
+ else {
+ //TODO: give user the option of placing manually
+ AddToStatus(STATUS_ERROR,TranslateT("Aggressive: unlinked data at %08X: can't automatically place"),ofsCurrent+i);
+ }
+ for(; i < blockBytes; i++)
+ if (buf[i] == 0) {i--; break;}
+ }
+ }
+ ofsCurrent += BLOCKSIZE;
+ spaceProcessed = ofsCurrent;
+ return ERROR_SUCCESS;
+}
diff --git a/plugins/Db3x_mmap/src/dbtool/contactchain.cpp b/plugins/Db3x_mmap/src/dbtool/contactchain.cpp
new file mode 100644
index 0000000000..0993371848
--- /dev/null
+++ b/plugins/Db3x_mmap/src/dbtool/contactchain.cpp
@@ -0,0 +1,99 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "..\commonheaders.h"
+
+int WorkSettingsChain(DWORD ofsContact,DBContact *dbc,int firstTime);
+int WorkEventChain(DWORD ofsContact,DBContact *dbc,int firstTime);
+
+static DWORD ofsThisContact,ofsDestPrevContact;
+static DWORD contactCount;
+static DWORD ofsDestThis,ofsNextContact;
+static int phase;
+static DBContact dbc;
+
+int WorkContactChain(int firstTime)
+{
+ int first = 0;
+ int ret;
+
+ if (firstTime) {
+ AddToStatus(STATUS_MESSAGE,TranslateT("Processing contact chain"));
+ ofsDestPrevContact = 0;
+ ofsThisContact = dbhdr.ofsFirstContact;
+ contactCount = 0;
+ dbhdr.ofsFirstContact = 0;
+ phase = 0;
+ }
+
+ switch(phase) {
+ case 0:
+ if (ofsThisContact == 0) {
+LBL_FinishUp:
+ if (contactCount != dbhdr.contactCount)
+ AddToStatus(STATUS_WARNING,TranslateT("Contact count marked wrongly: correcting"));
+ dbhdr.contactCount = contactCount;
+ return ERROR_NO_MORE_ITEMS;
+ }
+ if (!SignatureValid(ofsThisContact,DBCONTACT_SIGNATURE)) {
+ AddToStatus(STATUS_ERROR,TranslateT("Contact chain corrupted, further entries ignored"));
+ goto LBL_FinishUp;
+ }
+ if (ReadSegment(ofsThisContact,&dbc,sizeof(dbc)) != ERROR_SUCCESS)
+ goto LBL_FinishUp;
+
+ ofsNextContact = dbc.ofsNext;
+ dbc.ofsNext = 0;
+ if (!opts.bCheckOnly) {
+ if ((ofsDestThis = WriteSegment(WSOFS_END,&dbc,sizeof(dbc))) == WS_ERROR)
+ return ERROR_HANDLE_DISK_FULL;
+ if (ofsDestPrevContact)
+ WriteSegment(ofsDestPrevContact+offsetof(DBContact,ofsNext),&ofsDestThis,sizeof(DWORD));
+ else
+ dbhdr.ofsFirstContact = ofsDestThis;
+ } else
+ ofsDestThis = ofsThisContact; // needed in event chain worker
+ contactCount++;
+ phase++; first = 1;
+ //fall thru
+ case 1:
+ ret = WorkSettingsChain(ofsDestThis,&dbc,first);
+ if (ret == ERROR_NO_MORE_ITEMS) {
+ phase++; first = 1;
+ }
+ else if (ret) return ret;
+ else break;
+ //fall thru
+ case 2:
+ ret = WorkEventChain(ofsDestThis,&dbc,first);
+ if (ret == ERROR_NO_MORE_ITEMS) {
+ phase++; first = 1;
+ }
+ else if (ret) return ret;
+ else break;
+ //fall thru
+ case 3:
+ if (WriteSegment(ofsDestThis,&dbc,sizeof(DBContact)) == WS_ERROR)
+ return ERROR_HANDLE_DISK_FULL;
+ ofsDestPrevContact = ofsDestThis;
+ ofsThisContact = ofsNextContact;
+ phase = 0;
+ break;
+ }
+ return ERROR_SUCCESS;
+}
diff --git a/plugins/Db3x_mmap/src/dbtool/disk.cpp b/plugins/Db3x_mmap/src/dbtool/disk.cpp
new file mode 100644
index 0000000000..2cf9136a71
--- /dev/null
+++ b/plugins/Db3x_mmap/src/dbtool/disk.cpp
@@ -0,0 +1,112 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "dbtool.h"
+
+extern DWORD spaceProcessed, sourceFileSize;
+
+int SignatureValid(DWORD ofs, DWORD signature)
+{
+ DWORD sig;
+
+ if (ofs+sizeof(sig) >= sourceFileSize) {
+ AddToStatus(STATUS_ERROR, TranslateT("Invalid offset found (database truncated?)"));
+ return 0;
+ }
+
+ sig = *(DWORD*)(opts.pFile+ofs);
+
+ return sig == signature;
+}
+
+int PeekSegment(DWORD ofs, PVOID buf, int cbBytes)
+{
+ DWORD bytesRead;
+
+ if (ofs >= sourceFileSize) {
+ AddToStatus(STATUS_ERROR, TranslateT("Invalid offset found"));
+ return ERROR_SEEK;
+ }
+
+ if (ofs+cbBytes>sourceFileSize)
+ bytesRead = sourceFileSize - ofs;
+ else
+ bytesRead = cbBytes;
+
+ if (bytesRead == 0) {
+ AddToStatus(STATUS_ERROR, TranslateT("Error reading, database truncated? (%u)"), GetLastError());
+ return ERROR_READ_FAULT;
+ }
+
+ CopyMemory(buf, opts.pFile+ofs, bytesRead);
+
+ if ((int)bytesRead<cbBytes) return ERROR_HANDLE_EOF;
+ return ERROR_SUCCESS;
+}
+
+int ReadSegment(DWORD ofs, PVOID buf, int cbBytes)
+{
+ int ret;
+
+ ret = PeekSegment(ofs, buf, cbBytes);
+ if (ret != ERROR_SUCCESS && ret != ERROR_HANDLE_EOF) return ret;
+
+ if (opts.bAggressive) {
+ if (ofs+cbBytes>sourceFileSize) {
+ AddToStatus(STATUS_WARNING, TranslateT("Can't write to working file, aggressive mode may be too aggressive now"));
+ ZeroMemory(opts.pFile+ofs, sourceFileSize-ofs);
+ }
+ else
+ ZeroMemory(opts.pFile+ofs, cbBytes);
+ }
+ spaceProcessed += cbBytes;
+ return ERROR_SUCCESS;
+}
+
+DWORD WriteSegment(DWORD ofs, PVOID buf, int cbBytes)
+{
+ DWORD bytesWritten;
+ if (opts.bCheckOnly) return 0xbfbfbfbf;
+ if (ofs == WSOFS_END) {
+ ofs = dbhdr.ofsFileEnd;
+ dbhdr.ofsFileEnd += cbBytes;
+ }
+ SetFilePointer(opts.hOutFile, ofs, NULL, FILE_BEGIN);
+ WriteFile(opts.hOutFile, buf, cbBytes, &bytesWritten, NULL);
+ if ((int)bytesWritten<cbBytes) {
+ AddToStatus(STATUS_FATAL, TranslateT("Can't write to output file - disk full? (%u)"), GetLastError());
+ return WS_ERROR;
+ }
+ return ofs;
+}
+
+
+int ReadWrittenSegment(DWORD ofs, PVOID buf, int cbBytes)
+{
+ DWORD bytesRead;
+ if (opts.bCheckOnly) return 0xbfbfbfbf;
+ if (ofs + cbBytes > dbhdr.ofsFileEnd)
+ return ERROR_SEEK;
+
+ SetFilePointer(opts.hOutFile, ofs, NULL, FILE_BEGIN);
+ ReadFile(opts.hOutFile, buf, cbBytes, &bytesRead, NULL);
+ if ((int)bytesRead<cbBytes)
+ return ERROR_READ_FAULT;
+
+ return ERROR_SUCCESS;
+}
diff --git a/plugins/Db3x_mmap/src/dbtool/eventchain.cpp b/plugins/Db3x_mmap/src/dbtool/eventchain.cpp
new file mode 100644
index 0000000000..1e0076371d
--- /dev/null
+++ b/plugins/Db3x_mmap/src/dbtool/eventchain.cpp
@@ -0,0 +1,363 @@
+/*
+Miranda Database Tool
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2011 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "..\commonheaders.h"
+
+static BOOL backLookup;
+static DWORD ofsThisEvent,ofsPrevEvent;
+static DWORD ofsDestPrevEvent;
+static DWORD eventCount;
+static DWORD lastTimestamp;
+static DWORD ofsFirstUnread,timestampFirstUnread;
+static DWORD memsize = 0;
+static DBEvent* memblock = NULL;
+static DBEvent* dbePrevEvent = NULL;
+
+static void ConvertOldEvent(DBEvent*& dbei)
+{
+ int msglen = (int)strlen((char*)dbei->blob) + 1, msglenW = 0;
+ if (msglen != (int) dbei->cbBlob) {
+ int i, count = ((dbei->cbBlob - msglen) / sizeof(WCHAR));
+ WCHAR* p = (WCHAR*)&dbei->blob[ msglen ];
+ for ( i = 0; i < count; i++) {
+ if (p[i] == 0) {
+ msglenW = i;
+ break;
+ } } }
+ else {
+ if (!is_utf8_string((char*)dbei->blob))
+ dbei->flags &= ~DBEF_UTF;
+ }
+
+ if (msglenW > 0 && msglenW <= msglen) {
+ char* utf8str = Utf8EncodeW((WCHAR*)&dbei->blob[ msglen ]);
+ dbei->cbBlob = (DWORD)strlen(utf8str)+1;
+ dbei->flags |= DBEF_UTF;
+ if (offsetof(DBEvent,blob)+dbei->cbBlob > memsize) {
+ memsize = offsetof(DBEvent,blob)+dbei->cbBlob;
+ memblock = (DBEvent*)realloc(memblock, memsize);
+ dbei = memblock;
+ }
+ memcpy(&dbei->blob, utf8str, dbei->cbBlob);
+ free(utf8str);
+} }
+
+static void WriteOfsNextToPrevious(DWORD ofsPrev,DBContact *dbc,DWORD ofsNext)
+{
+ if (ofsPrev)
+ WriteSegment(ofsPrev+offsetof(DBEvent,ofsNext),&ofsNext,sizeof(DWORD));
+ else
+ dbc->ofsFirstEvent = ofsNext;
+}
+
+static void FinishUp(DWORD ofsLast,DBContact *dbc)
+{
+ WriteOfsNextToPrevious(ofsLast,dbc,0);
+ if (eventCount != dbc->eventCount)
+ AddToStatus(STATUS_WARNING,TranslateT("Event count marked wrongly: correcting"));
+ dbc->eventCount = eventCount;
+ dbc->ofsLastEvent = ofsLast;
+ if (opts.bMarkRead) {
+ dbc->ofsFirstUnreadEvent = 0;
+ dbc->timestampFirstUnread = 0;
+ }
+ else {
+ dbc->ofsFirstUnreadEvent = ofsFirstUnread;
+ dbc->timestampFirstUnread = timestampFirstUnread;
+ }
+ if (memsize && memblock) {
+ free(memblock);
+ memsize = 0;
+ memblock = NULL;
+ }
+}
+
+static DWORD WriteEvent(DBEvent *dbe)
+{
+ DWORD ofs = WriteSegment(WSOFS_END, dbe, offsetof(DBEvent,blob)+dbe->cbBlob);
+ if (ofs == WS_ERROR) {
+ free(memblock);
+ memblock = NULL;
+ memsize = 0;
+ return 0;
+ }
+ return ofs;
+}
+
+int WorkEventChain(DWORD ofsContact,DBContact *dbc,int firstTime)
+{
+ DBEvent *dbeNew,dbeOld;
+ DBEvent *dbePrev = NULL;
+ DWORD ofsDestThis;
+ int isUnread = 0;
+
+ if (firstTime) {
+ dbePrevEvent = NULL;
+ ofsPrevEvent = 0;
+ ofsDestPrevEvent = 0;
+ ofsThisEvent = dbc->ofsFirstEvent;
+ eventCount = 0;
+ backLookup = 0;
+ lastTimestamp = 0;
+ ofsFirstUnread = timestampFirstUnread = 0;
+ if (opts.bEraseHistory) {
+ dbc->eventCount = 0;
+ dbc->ofsFirstEvent = 0;
+ dbc->ofsLastEvent = 0;
+ dbc->ofsFirstUnreadEvent = 0;
+ dbc->timestampFirstUnread = 0;
+ return ERROR_NO_MORE_ITEMS;
+ } }
+
+ if (ofsThisEvent == 0) {
+ FinishUp(ofsDestPrevEvent,dbc);
+ return ERROR_NO_MORE_ITEMS;
+ }
+ if (!SignatureValid(ofsThisEvent,DBEVENT_SIGNATURE))
+ {
+ DWORD ofsNew = 0;
+ DWORD ofsTmp = dbc->ofsLastEvent;
+
+ if (!backLookup && ofsTmp) {
+ backLookup = 1;
+ while(SignatureValid(ofsTmp,DBEVENT_SIGNATURE))
+ {
+ if (PeekSegment(ofsTmp,&dbeOld,sizeof(dbeOld)) != ERROR_SUCCESS)
+ break;
+ ofsNew = ofsTmp;
+ ofsTmp = dbeOld.ofsPrev;
+ }
+ }
+ if (ofsNew) {
+ AddToStatus(STATUS_WARNING,TranslateT("Event chain corrupted, trying to recover..."));
+ ofsThisEvent = ofsNew;
+ } else {
+ AddToStatus(STATUS_ERROR,TranslateT("Event chain corrupted, further entries ignored"));
+ FinishUp(ofsDestPrevEvent,dbc);
+ return ERROR_NO_MORE_ITEMS;
+ }
+ }
+
+ if (PeekSegment(ofsThisEvent,&dbeOld,sizeof(dbeOld)) != ERROR_SUCCESS) {
+ FinishUp(ofsDestPrevEvent,dbc);
+ return ERROR_NO_MORE_ITEMS;
+ }
+
+ if (firstTime) {
+ if (!(dbeOld.flags&DBEF_FIRST)) {
+ AddToStatus(STATUS_WARNING,TranslateT("First event not marked as such: correcting"));
+ dbeOld.flags|=DBEF_FIRST;
+ }
+ dbeOld.ofsPrev = ofsContact;
+ lastTimestamp = dbeOld.timestamp;
+ }
+ else if (dbeOld.flags&DBEF_FIRST) {
+ AddToStatus(STATUS_WARNING,TranslateT("Event marked as first which is not: correcting"));
+ dbeOld.flags&=~DBEF_FIRST;
+ }
+
+ if (dbeOld.flags&~(DBEF_FIRST|DBEF_READ|DBEF_SENT|DBEF_RTL|DBEF_UTF)) {
+ AddToStatus(STATUS_WARNING,TranslateT("Extra flags found in event: removing"));
+ dbeOld.flags&=(DBEF_FIRST|DBEF_READ|DBEF_SENT|DBEF_RTL|DBEF_UTF);
+ }
+
+ if (!(dbeOld.flags&(DBEF_READ|DBEF_SENT))) {
+ if (opts.bMarkRead) dbeOld.flags|=DBEF_READ;
+ else if (ofsFirstUnread == 0) {
+ if (dbc->ofsFirstUnreadEvent != ofsThisEvent || dbc->timestampFirstUnread != dbeOld.timestamp)
+ AddToStatus(STATUS_WARNING,TranslateT("First unread event marked wrong: fixing"));
+ isUnread = 1;
+ } }
+
+ if (dbeOld.cbBlob>1024*1024 || dbeOld.cbBlob == 0) {
+ AddToStatus(STATUS_ERROR,TranslateT("Infeasibly large event blob: skipping"));
+ ofsThisEvent = dbeOld.ofsNext;
+ return ERROR_SUCCESS;
+ }
+
+ if (dbePrevEvent && dbeOld.timestamp == lastTimestamp) {
+ int len = offsetof(DBEvent,blob)+dbePrevEvent->cbBlob;
+ dbePrev = (DBEvent*)malloc(len);
+ memcpy(dbePrev, dbePrevEvent, len);
+ }
+
+ if (offsetof(DBEvent,blob)+dbeOld.cbBlob > memsize) {
+ memsize = offsetof(DBEvent,blob)+dbeOld.cbBlob;
+ memblock = (DBEvent*)realloc(memblock, memsize);
+ }
+ dbeNew = memblock;
+
+ if (ReadSegment(ofsThisEvent,dbeNew,offsetof(DBEvent,blob)+dbeOld.cbBlob) != ERROR_SUCCESS) {
+ FinishUp(ofsDestPrevEvent,dbc);
+ return ERROR_NO_MORE_ITEMS;
+ }
+
+ if ((dbeNew->ofsModuleName = ConvertModuleNameOfs(dbeOld.ofsModuleName)) == 0) {
+ ofsThisEvent = dbeOld.ofsNext;
+ return ERROR_SUCCESS;
+ }
+
+ if (!firstTime && dbeOld.ofsPrev != ofsPrevEvent)
+ AddToStatus(STATUS_WARNING,TranslateT("Event not backlinked correctly: fixing"));
+
+ dbeNew->flags = dbeOld.flags;
+ dbeNew->ofsPrev = ofsDestPrevEvent;
+ dbeNew->ofsNext = 0;
+
+ if (dbeOld.eventType == EVENTTYPE_MESSAGE && opts.bConvertUtf)
+ ConvertOldEvent(dbeNew);
+
+ if (dbePrev)
+ {
+ if (dbePrev->cbBlob == dbeNew->cbBlob &&
+ dbePrev->ofsModuleName == dbeNew->ofsModuleName &&
+ dbePrev->eventType == dbeNew->eventType &&
+ (dbePrev->flags & DBEF_SENT) == (dbeNew->flags & DBEF_SENT) &&
+ !memcmp(dbePrev->blob, dbeNew->blob, dbeNew->cbBlob)
+ ) {
+ AddToStatus(STATUS_WARNING,TranslateT("Duplicate event was found: skipping"));
+ if (dbc->eventCount)
+ dbc->eventCount--;
+ free(dbePrev);
+ // ofsDestPrevEvent is still the same!
+ ofsPrevEvent = ofsThisEvent;
+ ofsThisEvent = dbeOld.ofsNext;
+ return ERROR_SUCCESS;
+ }
+ free(dbePrev);
+ }
+ else if (!firstTime && dbeNew->timestamp < lastTimestamp)
+ {
+ DWORD found = 0;
+ DBEvent dbeTmp;
+ DWORD ofsTmp;
+
+ if (opts.bCheckOnly)
+ {
+ if (!opts.bAggressive)
+ {
+ ofsTmp = dbeOld.ofsPrev;
+ while(PeekSegment(ofsTmp,&dbeTmp,sizeof(dbeTmp)) == ERROR_SUCCESS)
+ {
+ if (dbeTmp.ofsPrev == ofsContact) {
+ found = 1;
+ break;
+ }
+ if (dbeTmp.timestamp < dbeNew->timestamp) {
+ found = 2;
+ break;
+ }
+ ofsTmp = dbeTmp.ofsPrev;
+ }
+ }
+ AddToStatus(STATUS_WARNING,TranslateT("Event position in chain is not correct"));
+ }
+ else
+ {
+ ofsTmp = ofsDestPrevEvent;
+ while(ReadWrittenSegment(ofsTmp,&dbeTmp,sizeof(dbeTmp)) == ERROR_SUCCESS)
+ {
+ if (dbeTmp.ofsPrev == ofsContact) {
+ found = 1;
+ break;
+ }
+ if (dbeTmp.timestamp < dbeNew->timestamp) {
+ found = 2;
+ break;
+ }
+ ofsTmp = dbeTmp.ofsPrev;
+ }
+ if (found)
+ AddToStatus(STATUS_WARNING,TranslateT("Event position in chain is not correct: fixing"));
+ else
+ AddToStatus(STATUS_WARNING,TranslateT("Event position in chain is not correct: unable to fix"));
+ }
+
+ // insert before FIRST
+ if (found == 1 && !opts.bCheckOnly) {
+ dbeNew->flags|=DBEF_FIRST;
+ dbeNew->ofsPrev = ofsContact;
+ dbeNew->ofsNext = dbc->ofsFirstEvent;
+
+ ofsDestThis = WriteEvent(dbeNew);
+ if (!ofsDestThis)
+ return ERROR_HANDLE_DISK_FULL;
+
+ if (isUnread && timestampFirstUnread >= dbeNew->timestamp) {
+ ofsFirstUnread = ofsDestThis;
+ timestampFirstUnread = dbeNew->timestamp;
+ }
+ // fix first event
+ WriteOfsNextToPrevious(0,dbc,ofsDestThis);
+ // fix next event
+ WriteSegment(dbeNew->ofsNext+offsetof(DBEvent,ofsPrev),&ofsDestThis,sizeof(DWORD));
+ dbeTmp.flags &=~DBEF_FIRST;
+ WriteSegment(dbeNew->ofsNext+offsetof(DBEvent,flags),&dbeTmp.flags,sizeof(DWORD));
+ }
+ else if (found == 2 && !opts.bCheckOnly) {
+
+ dbeNew->ofsPrev = ofsTmp;
+ dbeNew->ofsNext = dbeTmp.ofsNext;
+
+ ofsDestThis = WriteEvent(dbeNew);
+ if (!ofsDestThis)
+ return ERROR_HANDLE_DISK_FULL;
+
+ if (isUnread && timestampFirstUnread >= dbeNew->timestamp) {
+ ofsFirstUnread = ofsDestThis;
+ timestampFirstUnread = dbeNew->timestamp;
+ }
+ // fix previous event
+ WriteOfsNextToPrevious(dbeNew->ofsPrev,dbc,ofsDestThis);
+ // fix next event
+ WriteSegment(dbeNew->ofsNext+offsetof(DBEvent,ofsPrev),&ofsDestThis,sizeof(DWORD));
+ }
+
+ if (found) {
+ eventCount++;
+ // ofsDestPrevEvent is still the same!
+ ofsPrevEvent = ofsThisEvent;
+ ofsThisEvent = dbeOld.ofsNext;
+ return ERROR_SUCCESS;
+ }
+ }
+
+ lastTimestamp = dbeNew->timestamp;
+ dbePrevEvent = dbeNew;
+
+ ofsDestThis = WriteEvent(dbeNew);
+ if (!ofsDestThis)
+ return ERROR_HANDLE_DISK_FULL;
+
+ if (isUnread) {
+ ofsFirstUnread = ofsDestThis;
+ timestampFirstUnread = dbeOld.timestamp;
+ }
+
+ eventCount++;
+ WriteOfsNextToPrevious(ofsDestPrevEvent,dbc,ofsDestThis);
+
+ ofsDestPrevEvent = ofsDestThis;
+ ofsPrevEvent = ofsThisEvent;
+ ofsThisEvent = dbeOld.ofsNext;
+ return ERROR_SUCCESS;
+}
diff --git a/plugins/Db3x_mmap/src/dbtool/finaltasks.cpp b/plugins/Db3x_mmap/src/dbtool/finaltasks.cpp
new file mode 100644
index 0000000000..939fd680d1
--- /dev/null
+++ b/plugins/Db3x_mmap/src/dbtool/finaltasks.cpp
@@ -0,0 +1,78 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "..\commonheaders.h"
+
+extern int errorCount;
+
+int WorkFinalTasks(int firstTime)
+{
+ FreeModuleChain();
+ AddToStatus(STATUS_MESSAGE,TranslateT("Processing final tasks"));
+ dbhdr.slackSpace = 0;
+ if (WriteSegment(0,&dbhdr,sizeof(dbhdr)) == WS_ERROR)
+ return ERROR_WRITE_FAULT;
+ if (opts.hFile) {
+ CloseHandle(opts.hFile);
+ opts.hFile = NULL;
+ }
+ if (opts.hOutFile) {
+ CloseHandle(opts.hOutFile);
+ opts.hOutFile = NULL;
+ }
+ if (opts.pFile) {
+ UnmapViewOfFile(opts.pFile);
+ opts.pFile = NULL;
+ }
+ if (opts.hMap) {
+ CloseHandle(opts.hMap);
+ opts.hMap = NULL;
+ }
+ if (errorCount && !opts.bBackup && !opts.bCheckOnly) {
+ extern time_t ts;
+ time_t dlg_ts = time(NULL);
+ if (IDYES == MessageBox(NULL,
+ TranslateT("Errors were encountered, however you selected not to backup the original database. It is strongly recommended that you do so in case important data was omitted. Do you wish to keep a backup of the original database?"),
+ TranslateT("Miranda Database Tool"), MB_YESNO))
+ opts.bBackup = 1;
+ ts += time(NULL) - dlg_ts;
+ }
+ if (opts.bBackup) {
+ int i;
+ TCHAR dbPath[MAX_PATH],dbFile[MAX_PATH];
+ _tcscpy(dbPath, opts.filename);
+ TCHAR* str2 = _tcsrchr(dbPath, '\\');
+ if (str2 != NULL) {
+ _tcscpy(dbFile, str2+1);
+ *str2 = 0;
+ }
+ else {
+ _tcscpy(dbFile, dbPath);
+ dbPath[0] = 0;
+ }
+ for(i = 1;;i++) {
+ if (i == 1) wsprintf(opts.backupFilename,TranslateT("%s\\Backup of %s"),dbPath,dbFile);
+ else wsprintf(opts.backupFilename,TranslateT("%s\\Backup (%d) of %s"),dbPath,i,dbFile);
+ if (_taccess(opts.backupFilename,0) == -1) break;
+ }
+ MoveFile(opts.filename,opts.backupFilename) || AddToStatus(STATUS_WARNING,TranslateT("Unable to rename original file"));
+ }
+ else if (!opts.bCheckOnly) DeleteFile(opts.filename) || AddToStatus(STATUS_WARNING,TranslateT("Unable to delete original file"));
+ if (!opts.bCheckOnly) MoveFile(opts.outputFilename,opts.filename) || AddToStatus(STATUS_WARNING,TranslateT("Unable to rename output file"));
+ return ERROR_NO_MORE_ITEMS;
+}
diff --git a/plugins/Db3x_mmap/src/dbtool/initialchecks.cpp b/plugins/Db3x_mmap/src/dbtool/initialchecks.cpp
new file mode 100644
index 0000000000..21ccff5976
--- /dev/null
+++ b/plugins/Db3x_mmap/src/dbtool/initialchecks.cpp
@@ -0,0 +1,81 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "..\commonheaders.h"
+
+extern DWORD sourceFileSize,spaceUsed;
+
+int WorkInitialChecks(int firstTime)
+{
+ DWORD bytesRead;
+
+ sourceFileSize = GetFileSize(opts.hFile,NULL);
+ if (sourceFileSize == 0) {
+ AddToStatus(STATUS_WARNING,TranslateT("Database is newly created and has no data to process"));
+ AddToStatus(STATUS_SUCCESS,TranslateT("Processing completed successfully"));
+ return ERROR_INVALID_DATA;
+ }
+ ReadFile(opts.hFile,&dbhdr,sizeof(dbhdr),&bytesRead,NULL);
+ if (bytesRead<sizeof(dbhdr)) {
+ AddToStatus(STATUS_FATAL,TranslateT("Database is corrupted and too small to contain any recoverable data"));
+ return ERROR_BAD_FORMAT;
+ }
+ if (memcmp(dbhdr.signature,&dbSignature,sizeof(dbhdr.signature))) {
+ AddToStatus(STATUS_FATAL,TranslateT("Database signature is corrupted, automatic repair is impossible"));
+ return ERROR_BAD_FORMAT;
+ }
+ if (dbhdr.version != 0x00000700) {
+ AddToStatus(STATUS_FATAL,TranslateT("Database is marked as belonging to an unknown version of Miranda"));
+ return ERROR_BAD_FORMAT;
+ }
+ _tcscpy(opts.workingFilename,opts.filename);
+
+ if (opts.bCheckOnly) {
+ _tcscpy(opts.outputFilename, TranslateT("<check only>"));
+ opts.hOutFile = INVALID_HANDLE_VALUE;
+ }
+ else {
+ _tcscpy(opts.outputFilename,opts.filename);
+ *_tcsrchr(opts.outputFilename,'.') = 0;
+ _tcscat(opts.outputFilename,TranslateT(" (Output).dat"));
+ opts.hOutFile = CreateFile(opts.outputFilename,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
+ if (opts.hOutFile == INVALID_HANDLE_VALUE) {
+ AddToStatus(STATUS_FATAL,TranslateT("Can't create output file (%u)"),GetLastError());
+ return ERROR_ACCESS_DENIED;
+ }
+ }
+
+ opts.hMap = CreateFileMapping(opts.hFile, NULL, opts.bAggressive?PAGE_WRITECOPY:PAGE_READONLY, 0, 0, NULL);
+
+ if (opts.hMap)
+ opts.pFile = (BYTE*)MapViewOfFile(opts.hMap, opts.bAggressive?FILE_MAP_COPY:FILE_MAP_READ, 0, 0 ,0);
+ else {
+ AddToStatus(STATUS_FATAL,TranslateT("Can't create file mapping (%u)"),GetLastError());
+ return ERROR_ACCESS_DENIED;
+ }
+
+ if (!opts.pFile) {
+ AddToStatus(STATUS_FATAL,TranslateT("Can't create map view of file (%u)"),GetLastError());
+ return ERROR_ACCESS_DENIED;
+ }
+ if (ReadSegment(0,&dbhdr,sizeof(dbhdr)) != ERROR_SUCCESS) return ERROR_READ_FAULT;
+ if (WriteSegment(0,&dbhdr,sizeof(dbhdr)) == WS_ERROR) return ERROR_HANDLE_DISK_FULL;
+ spaceUsed = dbhdr.ofsFileEnd-dbhdr.slackSpace;
+ dbhdr.ofsFileEnd = sizeof(dbhdr);
+ return ERROR_NO_MORE_ITEMS;
+}
diff --git a/plugins/Db3x_mmap/src/dbtool/modulechain.cpp b/plugins/Db3x_mmap/src/dbtool/modulechain.cpp
new file mode 100644
index 0000000000..f53f63c469
--- /dev/null
+++ b/plugins/Db3x_mmap/src/dbtool/modulechain.cpp
@@ -0,0 +1,146 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "..\commonheaders.h"
+
+struct ModChainEntry {
+ DWORD ofsOld,ofsNew;
+ int size;
+ char name[257];
+} static *modChain = NULL;
+static int modChainCount;
+static DWORD ofsCurrent;
+static int phase,iCurrentModName;
+static DWORD ofsLast;
+static int last_mod = 0;
+
+int WorkModuleChain(int firstTime)
+{
+ DBModuleName moduleName,*newModName;
+
+ if (firstTime) {
+ AddToStatus(STATUS_MESSAGE,TranslateT("Processing module name chain"));
+ modChainCount = 0;
+ last_mod = 0;
+ if (modChain != NULL) free(modChain);
+ modChain = (ModChainEntry*)malloc(sizeof(ModChainEntry));
+ phase = 0;
+ ofsCurrent = dbhdr.ofsFirstModuleName;
+ }
+ switch(phase) {
+ case 0:
+ if (ofsCurrent == 0) {
+ phase++;
+ return ERROR_SUCCESS;
+ }
+ if (!SignatureValid(ofsCurrent,DBMODULENAME_SIGNATURE)) {
+ AddToStatus(STATUS_ERROR,TranslateT("Module chain corrupted, further entries ignored"));
+ phase++;
+ return ERROR_SUCCESS;
+ }
+ if (PeekSegment(ofsCurrent,&moduleName,offsetof(DBModuleName,name)) != ERROR_SUCCESS) {
+ phase++;
+ return ERROR_SUCCESS;
+ }
+ if (moduleName.cbName>256)
+ AddToStatus(STATUS_WARNING,TranslateT("Unreasonably long module name, skipping"));
+ else {
+ modChain = (ModChainEntry*)realloc(modChain,sizeof(ModChainEntry)*++modChainCount);
+
+ modChain[modChainCount-1].ofsOld = ofsCurrent;
+ modChain[modChainCount-1].size = offsetof(DBModuleName,name)+moduleName.cbName;
+ modChain[modChainCount-1].ofsNew = 0;
+
+ if (moduleName.cbName)
+ PeekSegment(ofsCurrent+offsetof(DBModuleName,name),&modChain[modChainCount-1].name,moduleName.cbName);
+ modChain[modChainCount-1].name[moduleName.cbName] = 0;
+ }
+ ofsCurrent = moduleName.ofsNext;
+ break;
+ case 1:
+ ofsLast = 0;
+ iCurrentModName = 0;
+ dbhdr.ofsFirstModuleName = 0;
+ phase++;
+ case 2:
+ if (iCurrentModName >= modChainCount) {
+ DWORD dw = 0;
+ if (ofsLast) WriteSegment(ofsLast+offsetof(DBModuleName,ofsNext),&dw,sizeof(DWORD));
+ return ERROR_NO_MORE_ITEMS;
+ }
+ if (modChain[iCurrentModName].ofsNew == 0) {
+ newModName = (DBModuleName*)_alloca(modChain[iCurrentModName].size);
+ if (ReadSegment(modChain[iCurrentModName].ofsOld,newModName,modChain[iCurrentModName].size) != ERROR_SUCCESS)
+ return ERROR_NO_MORE_ITEMS;
+ if ((modChain[iCurrentModName].ofsNew = WriteSegment(WSOFS_END,newModName,modChain[iCurrentModName].size)) == WS_ERROR)
+ return ERROR_HANDLE_DISK_FULL;
+ { // check duplicated modulenames
+ int i, n = 0;
+ for(i = iCurrentModName+1;i<modChainCount;i++)
+ if (!strcmp(modChain[i].name, modChain[iCurrentModName].name)) {
+ modChain[i].ofsNew = modChain[iCurrentModName].ofsNew;
+ n++;
+ }
+ if (n) {
+ TCHAR *pszModuleName;
+
+ TCHAR szModuleName[257];
+ MultiByteToWideChar(CP_ACP, 0, modChain[iCurrentModName].name, -1, szModuleName, sizeof(szModuleName) / sizeof(TCHAR));
+ pszModuleName = szModuleName;
+
+ AddToStatus(STATUS_WARNING,TranslateT("Module name '%s' is not unique: %d duplicates found)"), pszModuleName, n);
+ }
+ }
+ if (iCurrentModName == 0)
+ dbhdr.ofsFirstModuleName = modChain[iCurrentModName].ofsNew;
+ else
+ if (WriteSegment(ofsLast+offsetof(DBModuleName,ofsNext),&modChain[iCurrentModName].ofsNew,sizeof(DWORD)) == WS_ERROR)
+ return ERROR_HANDLE_DISK_FULL;
+ ofsLast = modChain[iCurrentModName].ofsNew;
+ }
+ iCurrentModName++;
+ break;
+ }
+ return ERROR_SUCCESS;
+}
+
+DWORD ConvertModuleNameOfs(DWORD ofsOld)
+{
+ int i;
+
+ if (modChain[last_mod].ofsOld == ofsOld)
+ return modChain[last_mod].ofsNew;
+
+ for(i = 0;i<modChainCount;i++)
+ if (modChain[i].ofsOld == ofsOld) {
+ last_mod = i;
+ return modChain[last_mod].ofsNew;
+ }
+
+ AddToStatus(STATUS_ERROR,TranslateT("Invalid module name offset, skipping data"));
+ return 0;
+}
+
+void FreeModuleChain()
+{
+ if (modChain != NULL) {
+ free(modChain);
+ modChain = NULL;
+ last_mod = 0;
+ }
+}
diff --git a/plugins/Db3x_mmap/src/dbtool/settingschain.cpp b/plugins/Db3x_mmap/src/dbtool/settingschain.cpp
new file mode 100644
index 0000000000..a2bfc48482
--- /dev/null
+++ b/plugins/Db3x_mmap/src/dbtool/settingschain.cpp
@@ -0,0 +1,72 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "..\commonheaders.h"
+
+static DWORD ofsThisSettings,ofsDestPrevSettings;
+
+int WorkSettingsChain(DWORD ofsContact,DBContact *dbc,int firstTime)
+{
+ DBContactSettings *dbcsNew,dbcsOld;
+ DWORD ofsDestThis;
+ int ret;
+
+ if (firstTime) {
+ ofsDestPrevSettings = 0;
+ ofsThisSettings = dbc->ofsFirstSettings;
+ dbc->ofsFirstSettings = 0;
+ }
+ if (ofsThisSettings == 0)
+ return ERROR_NO_MORE_ITEMS;
+ if (!SignatureValid(ofsThisSettings,DBCONTACTSETTINGS_SIGNATURE)) {
+ AddToStatus(STATUS_ERROR,TranslateT("Settings chain corrupted, further entries ignored"));
+ return ERROR_NO_MORE_ITEMS;
+ }
+ if (PeekSegment(ofsThisSettings,&dbcsOld,sizeof(dbcsOld)) != ERROR_SUCCESS)
+ return ERROR_NO_MORE_ITEMS;
+ if (dbcsOld.cbBlob>256*1024 || dbcsOld.cbBlob == 0) {
+ AddToStatus(STATUS_ERROR,TranslateT("Infeasibly large settings blob: skipping"));
+ ofsThisSettings = dbcsOld.ofsNext;
+ return ERROR_SUCCESS;
+ }
+ dbcsNew = (DBContactSettings*)_alloca(offsetof(DBContactSettings,blob)+dbcsOld.cbBlob);
+ if ((ret = ReadSegment(ofsThisSettings,dbcsNew,offsetof(DBContactSettings,blob)+dbcsOld.cbBlob)) != ERROR_SUCCESS) {
+ if (ret != ERROR_HANDLE_EOF) { //eof is OK because blank space at the end doesn't matter
+ return ERROR_NO_MORE_ITEMS;
+ }
+ }
+ if ((dbcsNew->ofsModuleName = ConvertModuleNameOfs(dbcsOld.ofsModuleName)) == 0) {
+ ofsThisSettings = dbcsOld.ofsNext;
+ return ERROR_SUCCESS;
+ }
+ if (dbcsNew->blob[0] == 0) {
+ AddToStatus(STATUS_MESSAGE,TranslateT("Empty settings group at %08X: skipping"),ofsThisSettings);
+ ofsThisSettings = dbcsOld.ofsNext;
+ return ERROR_SUCCESS;
+ }
+ dbcsNew->ofsNext = 0;
+ //TODO? validate all settings in blob/compact if necessary
+ if ((ofsDestThis = WriteSegment(WSOFS_END,dbcsNew,offsetof(DBContactSettings,blob)+dbcsNew->cbBlob)) == WS_ERROR) {
+ return ERROR_HANDLE_DISK_FULL;
+ }
+ if (ofsDestPrevSettings) WriteSegment(ofsDestPrevSettings+offsetof(DBContactSettings,ofsNext),&ofsDestThis,sizeof(DWORD));
+ else dbc->ofsFirstSettings = ofsDestThis;
+ ofsDestPrevSettings = ofsDestThis;
+ ofsThisSettings = dbcsOld.ofsNext;
+ return ERROR_SUCCESS;
+}
diff --git a/plugins/Db3x_mmap/src/dbtool/user.cpp b/plugins/Db3x_mmap/src/dbtool/user.cpp
new file mode 100644
index 0000000000..d61add09d4
--- /dev/null
+++ b/plugins/Db3x_mmap/src/dbtool/user.cpp
@@ -0,0 +1,71 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "..\commonheaders.h"
+
+static DBContact user;
+static int phase;
+static DWORD ofsUser;
+
+int WorkSettingsChain(DWORD ofsContact,DBContact *dbc,int firstTime);
+int WorkEventChain(DWORD ofsContact,DBContact *dbc,int firstTime);
+
+int WorkUser(int firstTime)
+{
+ int first = 0;
+
+ if (firstTime) {
+ AddToStatus(STATUS_MESSAGE,TranslateT("Processing user data"));
+ if (!SignatureValid(dbhdr.ofsUser,DBCONTACT_SIGNATURE)) {
+ AddToStatus(STATUS_ERROR,TranslateT("User corrupted, this could cause major problems"));
+ return ERROR_NO_MORE_ITEMS;
+ }
+ if (ReadSegment(dbhdr.ofsUser,&user,sizeof(DBContact)) != ERROR_SUCCESS)
+ return ERROR_NO_MORE_ITEMS;
+ if (user.ofsNext) {
+ AddToStatus(STATUS_WARNING,TranslateT("More than one user contact: keeping only first"));
+ user.ofsNext = 0;
+ }
+ if ((ofsUser = WriteSegment(WSOFS_END,&user,sizeof(DBContact))) == WS_ERROR)
+ return ERROR_HANDLE_DISK_FULL;
+ dbhdr.ofsUser = ofsUser;
+ phase = 0;
+ first = 1;
+ }
+ switch(phase) {
+ int ret;
+
+ case 0:
+ ret = WorkSettingsChain(ofsUser,&user,first);
+ if (ret == ERROR_NO_MORE_ITEMS) {
+ phase++; first = 1;
+ }
+ else if (ret) return ret;
+ else break;
+ case 1:
+ ret = WorkEventChain(ofsUser,&user,first);
+ if (ret == ERROR_NO_MORE_ITEMS) {
+ if (WriteSegment(ofsUser,&user,sizeof(DBContact)) == WS_ERROR)
+ return ERROR_HANDLE_DISK_FULL;
+ return ERROR_NO_MORE_ITEMS;
+ }
+ else if (ret) return ret;
+ break;
+ }
+ return ERROR_SUCCESS;
+} \ No newline at end of file
diff --git a/plugins/Db3x_mmap/src/init.cpp b/plugins/Db3x_mmap/src/init.cpp
index 032b43b5d4..ae530c6457 100644
--- a/plugins/Db3x_mmap/src/init.cpp
+++ b/plugins/Db3x_mmap/src/init.cpp
@@ -120,7 +120,26 @@ static int UnloadDatabase(MIDatabase* db)
delete (CDb3Mmap*)db;
return 0;
}
+/*
+static CheckWorker Workers[6] =
+{
+ &CDb3Mmap::WorkInitialChecks,
+ &CDb3Mmap::WorkModuleChain,
+ &CDb3Mmap::WorkUser,
+ &CDb3Mmap::WorkContactChain,
+ &CDb3Mmap::WorkAggressive,
+ &CDb3Mmap::WorkFinalTasks
+};
+static int CheckDb(DBCHeckCallback *callback, int phase, int firstTime)
+{
+ if (phase >= SIZEOF(Workers))
+ return ERROR_NO_MORE_ITEMS;
+
+ CDb3Mmap* db = (CDb3Mmap*)callback->db;
+ return (db->*Workers[phase])(callback, firstTime);
+}
+*/
static DATABASELINK dblink =
{
sizeof(DATABASELINK),
@@ -129,7 +148,8 @@ static DATABASELINK dblink =
makeDatabase,
grokHeader,
LoadDatabase,
- UnloadDatabase
+ UnloadDatabase,
+ //CheckDb
};
/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/plugins/DbChecker/dbchecker_10.vcxproj b/plugins/DbChecker/dbchecker_10.vcxproj
new file mode 100644
index 0000000000..e81afbb368
--- /dev/null
+++ b/plugins/DbChecker/dbchecker_10.vcxproj
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>DbChecker</ProjectName>
+ <ProjectGuid>{A2E9DA24-95E4-4414-94AF-488A382E276A}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <CharacterSet>Unicode</CharacterSet>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary>true</IgnoreImportLibrary>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;DATABASE_INDEPENDANT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>dbchecker.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalLibraryDirectories>$(SolutionDir)\lib</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;WIN64;_WINDOWS;DATABASE_INDEPENDANT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>dbtool.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\miranda\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalManifestDependencies>type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27*%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalLibraryDirectories>$(SolutionDir)\lib</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;DATABASE_INDEPENDANT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>false</ExceptionHandling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>dbchecker.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <SubSystem>Windows</SubSystem>
+ <AdditionalLibraryDirectories>$(SolutionDir)\lib</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;WIN64;_WINDOWS;DATABASE_INDEPENDANT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>false</ExceptionHandling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>dbtool.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\miranda\include\msapi</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalManifestDependencies>type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27*%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <SubSystem>Windows</SubSystem>
+ <AdditionalLibraryDirectories>$(SolutionDir)\lib</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="src\main.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="src\utf.cpp" />
+ <ClCompile Include="src\wizard.cpp" />
+ <ClCompile Include="src\worker.cpp" />
+ <ClCompile Include="src\cleaning.cpp" />
+ <ClCompile Include="src\fileaccess.cpp" />
+ <ClCompile Include="src\finished.cpp" />
+ <ClCompile Include="src\openerror.cpp" />
+ <ClCompile Include="src\progress.cpp" />
+ <ClCompile Include="src\selectdb.cpp" />
+ <ClCompile Include="src\welcome.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\dbchecker.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res\resource.rc" />
+ <ResourceCompile Include="res\version.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/DbChecker/dbchecker_10.vcxproj.filters b/plugins/DbChecker/dbchecker_10.vcxproj.filters
new file mode 100644
index 0000000000..0bf3b22913
--- /dev/null
+++ b/plugins/DbChecker/dbchecker_10.vcxproj.filters
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{72e8c0e0-409e-4656-8598-9a0c769f0e34}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Source Files\Wizard Pages">
+ <UniqueIdentifier>{eccf4f04-aceb-441f-924b-ead9bbb92168}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{12ab2eb9-15e3-4147-ae4a-847ddc95c531}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{07c47951-e20f-43c5-912f-ea300b807935}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="src\main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\utf.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\worker.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\cleaning.cpp">
+ <Filter>Source Files\Wizard Pages</Filter>
+ </ClCompile>
+ <ClCompile Include="src\fileaccess.cpp">
+ <Filter>Source Files\Wizard Pages</Filter>
+ </ClCompile>
+ <ClCompile Include="src\finished.cpp">
+ <Filter>Source Files\Wizard Pages</Filter>
+ </ClCompile>
+ <ClCompile Include="src\openerror.cpp">
+ <Filter>Source Files\Wizard Pages</Filter>
+ </ClCompile>
+ <ClCompile Include="src\progress.cpp">
+ <Filter>Source Files\Wizard Pages</Filter>
+ </ClCompile>
+ <ClCompile Include="src\selectdb.cpp">
+ <Filter>Source Files\Wizard Pages</Filter>
+ </ClCompile>
+ <ClCompile Include="src\welcome.cpp">
+ <Filter>Source Files\Wizard Pages</Filter>
+ </ClCompile>
+ <ClCompile Include="src\wizard.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\dbchecker.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res\resource.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ <ResourceCompile Include="res\version.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/DbChecker/docs/dbchecker-translation.txt b/plugins/DbChecker/docs/dbchecker-translation.txt
new file mode 100644
index 0000000000..f5d1b5eba0
--- /dev/null
+++ b/plugins/DbChecker/docs/dbchecker-translation.txt
@@ -0,0 +1,138 @@
+; Common strings that belong to many files
+;[Cancel]
+;[Miranda Database Tool]
+
+; ../dbtool/aggressive.cpp
+;[Aggressive: random junk at %08X: skipping]
+;[Aggressive: unlinked data at %08X: can't automatically place]
+;[Performing aggressive pass]
+
+; ../dbtool/contactchain.cpp
+;[Contact chain corrupted, further entries ignored]
+;[Contact count marked wrongly: correcting]
+;[Processing contact chain]
+
+; ../dbtool/disk.cpp
+;[Can't write to output file - disk full? (%u)]
+;[Can't write to working file, aggressive mode may be too aggressive now]
+;[Error reading, database truncated? (%u)]
+;[Invalid offset found]
+;[Invalid offset found (database truncated?)]
+
+; ../dbtool/eventchain.cpp
+;[Duplicate event was found: skipping]
+;[Event chain corrupted, further entries ignored]
+;[Event chain corrupted, trying to recover...]
+;[Event count marked wrongly: correcting]
+;[Event marked as first which is not: correcting]
+;[Event not backlinked correctly: fixing]
+;[Event position in chain is not correct]
+;[Event position in chain is not correct: fixing]
+;[Event position in chain is not correct: unable to fix]
+;[Extra flags found in event: removing]
+;[First event not marked as such: correcting]
+;[First unread event marked wrong: fixing]
+;[Infeasibly large event blob: skipping]
+
+; ../dbtool/finaltasks.cpp
+;[%s\\Backup (%d) of %s]
+;[%s\\Backup of %s]
+;[Errors were encountered, however you selected not to backup the original database. It is strongly recommended that you do so in case important data was omitted. Do you wish to keep a backup of the original database?]
+;[Processing final tasks]
+;[Unable to delete original file]
+;[Unable to rename original file]
+;[Unable to rename output file]
+
+; ../dbtool/finished.cpp
+;[&Finish]
+
+; ../dbtool/initialchecks.cpp
+;[ (Output).dat]
+;[<check only>]
+;[Can't create file mapping (%u)]
+;[Can't create map view of file (%u)]
+;[Can't create output file (%u)]
+;[Database is corrupted and too small to contain any recoverable data]
+;[Database is marked as belonging to an unknown version of Miranda]
+;[Database is newly created and has no data to process]
+;[Database signature is corrupted, automatic repair is impossible]
+;[Processing completed successfully]
+
+; ../dbtool/modulechain.cpp
+;[Invalid module name offset, skipping data]
+;[Module chain corrupted, further entries ignored]
+;[Module name '%s' is not unique: %d duplicates found)]
+;[Processing module name chain]
+;[Unreasonably long module name, skipping]
+
+; ../dbtool/progress.cpp
+;[Click Next to continue]
+;[Processing has not yet completed, if you cancel now then the changes that have currently been made will be rolled back and the original database will be restored. Do you still want to cancel?]
+;[Processing has not yet completed, if you go back now then the changes that have currently been made will be rolled back and the original database will be restored. Do you still want to go back?]
+
+; ../dbtool/resource.rc
+;[&File:]
+;[&Next >]
+;[&Other...]
+;[< &Back]
+;[Aggressively find corruption]
+;[All tasks have been completed.]
+;[Backup:]
+;[Check consistency only]
+;[Cleaning Options]
+;[Click Next to try opening the file again, or click Back to select a new profile database to manipulate.]
+;[Convert old Unicode messages to UTF8]
+;[Converts history messages in pre-0.7 format (ANSI+UCS2) to the new UTF8 format supported by 0.7. Saves the database space in most cases (recommended).]
+;[Create backup]
+;[Creates a backup copy of the database before any of the requested changes are made.]
+;[Erase all histories]
+;[Error Opening Database]
+;[File Access Options]
+;[Finished!]
+;[Just checks that the database is valid, without writing anything to the disk.]
+;[Launch Miranda with this profile]
+;[Launches Miranda with the profile that was just worked on.]
+;[Mark all events read]
+;[Marks all the history events as read. This will rectify any problems with old messages always appearing in the message window log box.]
+;[Please wait while the requested operations are being performed.]
+;[Progress1]
+;[Removes all the saved history for all contacts in the database.]
+;[Scans the database for data that is not linked to any other data. This requires more disk space and more time, so is only required if you suspect corruption.]
+;[Select Miranda Profile]
+;[Select the &profile database from the list below. If the database you wish to use is not listed here then click Other to browse your computer.]
+;[The file may be in use by a currently running copy of Miranda. Exit any running Mirandas and click Next to retry.]
+;[The processing of the database has been completed. Click Next to return to the start of the wizard to select another database to check, or click Finish to exit the wizard.]
+;[There was an error opening the profile database given.]
+;[This programme is licenced under the terms of the GNU General Public License.]
+;[To continue, click Next.]
+;[Using this Wizard you can compact your Miranda profile database to remove dead space created during normal usage, as well as repair a large number of issues that could affect the database.]
+;[Welcome to the Miranda Database Wizard]
+;[Working...]
+;[You can choose the Miranda profile database to compact or repair.]
+;[You can choose to remove information from the database while it is being processed.]
+;[You can select low level options to determine how the database is processed.]
+;[whiterect]
+
+; ../dbtool/selectdb.cpp
+;[All Files]
+;[Database]
+;[Miranda Databases (*.dat)]
+;[Total size]
+;[Wasted]
+
+; ../dbtool/settingschain.cpp
+;[Empty settings group at %08X: skipping]
+;[Infeasibly large settings blob: skipping]
+;[Settings chain corrupted, further entries ignored]
+
+; ../dbtool/user.cpp
+;[More than one user contact: keeping only first]
+;[Processing user data]
+;[User corrupted, this could cause major problems]
+
+; ../dbtool/worker.cpp
+;[All tasks completed but with errors (%d)]
+;[All tasks completed successfully]
+;[Database worker thread activated]
+;[Elapsed time: %d sec]
+;[Processing aborted by user]
diff --git a/plugins/DbChecker/res/dbthdr.emf b/plugins/DbChecker/res/dbthdr.emf
new file mode 100644
index 0000000000..554d11b5ea
--- /dev/null
+++ b/plugins/DbChecker/res/dbthdr.emf
Binary files differ
diff --git a/plugins/DbChecker/res/dbtool.cdr b/plugins/DbChecker/res/dbtool.cdr
new file mode 100644
index 0000000000..e5aef201be
--- /dev/null
+++ b/plugins/DbChecker/res/dbtool.cdr
Binary files differ
diff --git a/plugins/DbChecker/res/dbtool.emf b/plugins/DbChecker/res/dbtool.emf
new file mode 100644
index 0000000000..abce0632ee
--- /dev/null
+++ b/plugins/DbChecker/res/dbtool.emf
Binary files differ
diff --git a/plugins/DbChecker/res/dbtool.ico b/plugins/DbChecker/res/dbtool.ico
new file mode 100644
index 0000000000..e10cf950ad
--- /dev/null
+++ b/plugins/DbChecker/res/dbtool.ico
Binary files differ
diff --git a/plugins/DbChecker/res/delete.ico b/plugins/DbChecker/res/delete.ico
new file mode 100644
index 0000000000..6e39da592b
--- /dev/null
+++ b/plugins/DbChecker/res/delete.ico
Binary files differ
diff --git a/plugins/DbChecker/res/profileg.ico b/plugins/DbChecker/res/profileg.ico
new file mode 100644
index 0000000000..1cd1caa5e4
--- /dev/null
+++ b/plugins/DbChecker/res/profileg.ico
Binary files differ
diff --git a/plugins/DbChecker/res/profiler.ico b/plugins/DbChecker/res/profiler.ico
new file mode 100644
index 0000000000..2dc702c863
--- /dev/null
+++ b/plugins/DbChecker/res/profiler.ico
Binary files differ
diff --git a/plugins/DbChecker/res/profiley.ico b/plugins/DbChecker/res/profiley.ico
new file mode 100644
index 0000000000..d482ee47ad
--- /dev/null
+++ b/plugins/DbChecker/res/profiley.ico
Binary files differ
diff --git a/plugins/DbChecker/res/resource.rc b/plugins/DbChecker/res/resource.rc
new file mode 100644
index 0000000000..17e11c5796
--- /dev/null
+++ b/plugins/DbChecker/res/resource.rc
@@ -0,0 +1,269 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "..\src\resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <windows.h>
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_WELCOME DIALOGEX 0, 0, 262, 143
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "",IDC_WATERMARK,"Static",SS_ENHMETAFILE,0,0,63,143
+ LTEXT "whiterect",IDC_STATIC,63,0,199,143
+ LTEXT "Welcome to the Miranda Database Wizard",IDC_TITLE,77,12,178,24,0,WS_EX_TRANSPARENT
+ LTEXT "Using this Wizard you can compact your Miranda profile database to remove dead space created during normal usage, as well as repair a large number of issues that could affect the database.",IDC_STATIC,77,46,178,32,0,WS_EX_TRANSPARENT
+ LTEXT "To continue, click Next.",IDC_STATIC,77,85,178,8,0,WS_EX_TRANSPARENT
+ LTEXT "This programme is licenced under the terms of the GNU General Public License.",IDC_STATIC,77,122,178,16,WS_DISABLED
+END
+
+IDD_WIZARD DIALOGEX 0, 0, 262, 174
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Miranda Database Tool"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ PUSHBUTTON "< &Back",IDC_BACK,96,153,50,14
+ DEFPUSHBUTTON "&Next >",IDOK,146,153,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,205,153,50,14
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,-5,143,269,1
+END
+
+IDD_SELECTDB DIALOGEX 0, 0, 262, 143
+STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "whiterect",IDC_STATIC,0,0,262,32
+ LTEXT "Select Miranda Profile",IDC_STATIC,11,6,206,8,WS_BORDER
+ CONTROL "",IDC_HDRLOGO,"Static",SS_ENHMETAFILE,234,3,25,25
+ LTEXT "You can choose the Miranda profile database to compact or repair.",IDC_STATIC,20,14,197,16
+ LTEXT "Select the &profile database from the list below. If the database you wish to use is not listed here then click Other to browse your computer.",IDC_STATIC,10,35,242,16
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,-1,32,264,1
+ CONTROL "List1",IDC_DBLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_AUTOARRANGE | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,10,53,242,72
+ LTEXT "&File:",IDC_STATIC,10,130,12,8
+ EDITTEXT IDC_FILE,24,128,184,12,ES_AUTOHSCROLL
+ PUSHBUTTON "&Other...",IDC_OTHER,212,128,40,12
+END
+
+IDD_OPENERROR DIALOGEX 0, 0, 262, 143
+STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "whiterect",IDC_STATIC,0,0,262,32
+ LTEXT "Error Opening Database",IDC_STATIC,11,6,206,8,WS_BORDER
+ CONTROL "",IDC_HDRLOGO,"Static",SS_ENHMETAFILE,234,3,25,25
+ LTEXT "There was an error opening the profile database given.",IDC_STATIC,20,14,197,16
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,-1,32,264,1
+ LTEXT "",IDC_ERRORTEXT,23,38,226,16,SS_NOPREFIX | WS_BORDER
+ LTEXT "Click Next to try opening the file again, or click Back to select a new profile database to manipulate.",IDC_STATIC,23,67,226,16
+ LTEXT "The file may be in use by a currently running copy of Miranda. Exit any running Mirandas and click Next to retry.",IDC_INUSE,23,87,226,16,NOT WS_VISIBLE
+ LTEXT "",IDC_FILE,23,57,226,8,SS_NOPREFIX
+END
+
+IDD_FILEACCESS DIALOGEX 0, 0, 262, 143
+STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "whiterect",IDC_STATIC,0,0,262,32
+ LTEXT "File Access Options",IDC_STATIC,11,6,206,8,WS_BORDER
+ CONTROL "",IDC_HDRLOGO,"Static",SS_ENHMETAFILE,234,3,25,25
+ LTEXT "You can select low level options to determine how the database is processed.",IDC_STATIC,20,14,197,16
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,-1,32,264,1
+ CONTROL "Create backup",IDC_BACKUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,69,226,10,WS_EX_CLIENTEDGE
+ LTEXT "Creates a backup copy of the database before any of the requested changes are made.",IDC_STBACKUP,37,80,212,16
+ CONTROL "Aggressively find corruption",IDC_AGGRESSIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,100,226,10,WS_EX_CLIENTEDGE
+ LTEXT "Scans the database for data that is not linked to any other data. This requires more disk space and more time, so is only required if you suspect corruption.",IDC_STATIC,37,111,212,24
+ CONTROL "Check consistency only",IDC_CHECKONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,38,226,10,WS_EX_CLIENTEDGE
+ LTEXT "Just checks that the database is valid, without writing anything to the disk.",IDC_STATIC,37,49,212,16
+END
+
+IDD_CLEANING DIALOGEX 0, 0, 262, 143
+STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "whiterect",IDC_STATIC,0,0,262,32
+ LTEXT "Cleaning Options",IDC_STATIC,11,6,206,8,WS_BORDER
+ CONTROL "",IDC_HDRLOGO,"Static",SS_ENHMETAFILE,234,3,25,25
+ LTEXT "You can choose to remove information from the database while it is being processed.",IDC_STATIC,20,14,197,16
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,-1,32,264,1
+ CONTROL "Erase all histories",IDC_ERASEHISTORY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,38,226,10,WS_EX_CLIENTEDGE
+ LTEXT "Removes all the saved history for all contacts in the database.",IDC_STATIC,37,49,212,8
+ CONTROL "Mark all events read",IDC_MARKREAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,62,226,10,WS_EX_CLIENTEDGE
+ LTEXT "Marks all the history events as read. This will rectify any problems with old messages always appearing in the message window log box.",IDC_STATIC,37,73,212,24
+ CONTROL "Convert old Unicode messages to UTF8",IDC_CONVERTUTF,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,101,226,10,WS_EX_CLIENTEDGE
+ LTEXT "Converts history messages in pre-0.7 format (ANSI+UCS2) to the new UTF8 format supported by 0.7. Saves the database space in most cases (recommended).",IDC_STATIC,37,111,212,25
+END
+
+IDD_PROGRESS DIALOGEX 0, 0, 262, 143
+STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "whiterect",-1,0,0,262,32
+ LTEXT "Working...",-1,11,6,206,8,WS_BORDER
+ CONTROL "",IDC_HDRLOGO,"Static",SS_ENHMETAFILE,234,3,25,25
+ LTEXT "Please wait while the requested operations are being performed.",-1,20,14,197,16
+ CONTROL "",-1,"Static",SS_ETCHEDHORZ,-1,32,264,1
+ CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH | WS_BORDER,20,38,222,11
+ LISTBOX IDC_STATUS,20,52,222,84,NOT LBS_NOTIFY | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | LBS_NOSEL | WS_VSCROLL | WS_TABSTOP
+END
+
+IDD_FINISHED DIALOGEX 0, 0, 262, 143
+STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "whiterect",IDC_STATIC,0,0,262,32
+ LTEXT "Finished!",IDC_STATIC,11,6,206,8,WS_BORDER
+ CONTROL "",IDC_HDRLOGO,"Static",SS_ENHMETAFILE,234,3,25,25
+ LTEXT "All tasks have been completed.",IDC_STATIC,20,14,197,16
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,-1,32,264,1
+ CONTROL "Launch Miranda with this profile",IDC_LAUNCHMIRANDA,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,87,226,10,WS_EX_CLIENTEDGE
+ LTEXT "Launches Miranda with the profile that was just worked on.",IDC_STATIC,37,98,212,8
+ LTEXT "",IDC_DBFILE,23,68,226,8,SS_NOPREFIX | WS_BORDER
+ RTEXT "Backup:",IDC_STBACKUP,23,76,30,8
+ LTEXT "",IDC_BACKUPFILE,56,76,193,8,SS_NOPREFIX
+ LTEXT "The processing of the database has been completed. Click Next to return to the start of the wizard to select another database to check, or click Finish to exit the wizard.",IDC_STATIC,23,38,226,24
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_WELCOME, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 255
+ VERTGUIDE, 77
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 138
+ END
+
+ IDD_WIZARD, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 255
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 167
+ END
+
+ IDD_SELECTDB, DIALOG
+ BEGIN
+ LEFTMARGIN, 23
+ RIGHTMARGIN, 249
+ TOPMARGIN, 38
+ BOTTOMMARGIN, 136
+ END
+
+ IDD_OPENERROR, DIALOG
+ BEGIN
+ LEFTMARGIN, 23
+ RIGHTMARGIN, 249
+ TOPMARGIN, 38
+ BOTTOMMARGIN, 136
+ END
+
+ IDD_FILEACCESS, DIALOG
+ BEGIN
+ LEFTMARGIN, 23
+ RIGHTMARGIN, 249
+ VERTGUIDE, 37
+ TOPMARGIN, 38
+ BOTTOMMARGIN, 136
+ END
+
+ IDD_CLEANING, DIALOG
+ BEGIN
+ LEFTMARGIN, 23
+ RIGHTMARGIN, 249
+ VERTGUIDE, 37
+ TOPMARGIN, 38
+ BOTTOMMARGIN, 136
+ END
+
+ IDD_PROGRESS, DIALOG
+ BEGIN
+ LEFTMARGIN, 20
+ RIGHTMARGIN, 242
+ TOPMARGIN, 38
+ BOTTOMMARGIN, 136
+ END
+
+ IDD_FINISHED, DIALOG
+ BEGIN
+ LEFTMARGIN, 23
+ RIGHTMARGIN, 249
+ VERTGUIDE, 37
+ TOPMARGIN, 38
+ BOTTOMMARGIN, 136
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// EMF
+//
+
+IDE_WATERMARK EMF "res\\dbtool.emf"
+IDE_HDRLOGO EMF "res\\dbthdr.emf"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_DBTOOL ICON "res\\dbtool.ico"
+IDI_PROFILEGREEN ICON "res\\profileg.ico"
+IDI_PROFILEYELLOW ICON "res\\profiley.ico"
+IDI_PROFILERED ICON "res\\profiler.ico"
+IDI_BAD ICON "res\\delete.ico"
+
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
diff --git a/plugins/DbChecker/res/version.rc b/plugins/DbChecker/res/version.rc
new file mode 100644
index 0000000000..93ddb70b68
--- /dev/null
+++ b/plugins/DbChecker/res/version.rc
@@ -0,0 +1,59 @@
+// Microsoft Visual C++ generated resource script.
+//
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+#include "..\src\resource.h"
+#include "..\src\version.h"
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page( 1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION __FILEVERSION_STRING
+ PRODUCTVERSION __FILEVERSION_STRING
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Miranda NG project"
+ VALUE "FileDescription", "Miranda NG Database Checker"
+ VALUE "FileVersion", __FILEVERSION_STRING
+ VALUE "InternalName", "dbchecker"
+ VALUE "LegalCopyright", "Copyright (C) 2012, George Hazan"
+ VALUE "LegalTrademarks", "Licensed under the Gnu General Public License V2 or any later version"
+ VALUE "OriginalFilename", "dbchecker.dll"
+ VALUE "ProductName", "Miranda NG Database Checker"
+ VALUE "ProductVersion", __FILEVERSION_STRING
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // AFX_RESOURCE_DLL
diff --git a/plugins/DbChecker/src/cleaning.cpp b/plugins/DbChecker/src/cleaning.cpp
new file mode 100644
index 0000000000..4ecd2772fb
--- /dev/null
+++ b/plugins/DbChecker/src/cleaning.cpp
@@ -0,0 +1,67 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "dbchecker.h"
+
+INT_PTR CALLBACK CleaningDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ INT_PTR bReturn;
+ if (DoMyControlProcessing(hdlg, message, wParam, lParam, &bReturn))
+ return bReturn;
+
+ switch(message) {
+ case WM_INITDIALOG:
+ CheckDlgButton(hdlg, IDC_ERASEHISTORY, opts.bEraseHistory);
+ EnableWindow(GetDlgItem(hdlg, IDC_ERASEHISTORY), !opts.bAggressive);
+ CheckDlgButton(hdlg, IDC_MARKREAD, opts.bMarkRead);
+ CheckDlgButton(hdlg, IDC_CONVERTUTF, opts.bConvertUtf);
+ TranslateDialogDefault(hdlg);
+ return TRUE;
+
+ case WZN_PAGECHANGING:
+ opts.bEraseHistory = IsDlgButtonChecked(hdlg, IDC_ERASEHISTORY)&&!opts.bAggressive;
+ opts.bMarkRead = IsDlgButtonChecked(hdlg, IDC_MARKREAD);
+ opts.bConvertUtf = IsDlgButtonChecked(hdlg, IDC_CONVERTUTF);
+ break;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_BACK:
+ if (opts.bCheckOnly)
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_SELECTDB, (LPARAM)SelectDbDlgProc);
+ else
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_FILEACCESS, (LPARAM)FileAccessDlgProc);
+ break;
+
+ case IDOK:
+ if (!opts.hFile) {
+ opts.hFile = CreateFile(opts.filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (opts.hFile == INVALID_HANDLE_VALUE) {
+ opts.hFile = NULL;
+ opts.error = GetLastError();
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_OPENERROR, (LPARAM)OpenErrorDlgProc);
+ break;
+ }
+ }
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_PROGRESS, (LPARAM)ProgressDlgProc);
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/DbChecker/src/dbchecker.h b/plugins/DbChecker/src/dbchecker.h
new file mode 100644
index 0000000000..39d64cb089
--- /dev/null
+++ b/plugins/DbChecker/src/dbchecker.h
@@ -0,0 +1,105 @@
+/*
+Miranda Database Tool
+Copyright 2000-2011 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#include <tchar.h>
+
+#include <windows.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <io.h>
+#include <stdarg.h>
+#include <process.h>
+#include <direct.h>
+#include <malloc.h>
+#include <commctrl.h>
+#include <time.h>
+
+#include <m_database.h>
+#include <m_db_int.h>
+
+#include "resource.h"
+
+#define WinVerMajor() LOBYTE(LOWORD(GetVersion()))
+#define IsWinVerXPPlus() (WinVerMajor()>=5 && LOWORD(GetVersion())!=5)
+
+#define WZM_GOTOPAGE (WM_USER+1)
+#define WZN_PAGECHANGING (WM_USER+1221)
+#define WZN_CANCELCLICKED (WM_USER+1222)
+
+struct DbToolOptions {
+ TCHAR filename[MAX_PATH];
+ TCHAR workingFilename[MAX_PATH];
+ TCHAR outputFilename[MAX_PATH];
+ TCHAR backupFilename[MAX_PATH];
+ HANDLE hFile;
+ HANDLE hOutFile;
+ HANDLE hMap;
+ BYTE *pFile;
+ DWORD error;
+ int bCheckOnly, bBackup, bAggressive;
+ int bEraseHistory, bMarkRead, bConvertUtf;
+};
+
+extern HINSTANCE hInst;
+extern DbToolOptions opts;
+extern HANDLE hEventRun, hEventAbort;
+extern int errorCount;
+
+int DoMyControlProcessing(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam, INT_PTR *bReturn);
+
+INT_PTR CALLBACK SelectDbDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK CleaningDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK ProgressDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK FileAccessDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK WizardDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK FinishedDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK WelcomeDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK OpenErrorDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
+
+struct DBSignature {
+ char name[15];
+ BYTE eof;
+};
+static struct DBSignature dbSignature = {"Miranda ICQ DB", 0x1A};
+
+#define SIZEOF(X) (sizeof(X)/sizeof(X[0]))
+
+#define STATUS_MESSAGE 0
+#define STATUS_WARNING 1
+#define STATUS_ERROR 2
+#define STATUS_FATAL 3
+#define STATUS_SUCCESS 4
+#define STATUS_CLASSMASK 0x0f
+void AddToStatus(int flags, const TCHAR* fmt, ...);
+void SetProgressBar(int perThou);
+
+int PeekSegment(DWORD ofs, PVOID buf, int cbBytes);
+int ReadSegment(DWORD ofs, PVOID buf, int cbBytes);
+#define WSOFS_END 0xFFFFFFFF
+#define WS_ERROR 0xFFFFFFFF
+DWORD WriteSegment(DWORD ofs, PVOID buf, int cbBytes);
+int ReadWrittenSegment(DWORD ofs, PVOID buf, int cbBytes);
+int SignatureValid(DWORD ofs, DWORD signature);
+DWORD ConvertModuleNameOfs(DWORD ofsOld);
+void FreeModuleChain();
+
+bool is_utf8_string(const char* str);
diff --git a/plugins/DbChecker/src/fileaccess.cpp b/plugins/DbChecker/src/fileaccess.cpp
new file mode 100644
index 0000000000..f9b6e2d656
--- /dev/null
+++ b/plugins/DbChecker/src/fileaccess.cpp
@@ -0,0 +1,73 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "dbchecker.h"
+
+INT_PTR CALLBACK FileAccessDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ INT_PTR bReturn;
+ if (DoMyControlProcessing(hdlg, message, wParam, lParam, &bReturn))
+ return bReturn;
+
+ switch(message) {
+ case WM_INITDIALOG:
+ CheckDlgButton(hdlg, IDC_CHECKONLY, opts.bCheckOnly);
+ CheckDlgButton(hdlg, IDC_BACKUP, opts.bBackup);
+ CheckDlgButton(hdlg, IDC_AGGRESSIVE, opts.bAggressive);
+ SendMessage(hdlg, WM_COMMAND, MAKEWPARAM(IDC_CHECKONLY, BN_CLICKED), 0);
+ TranslateDialogDefault(hdlg);
+ return TRUE;
+
+ case WZN_PAGECHANGING:
+ opts.bCheckOnly = IsDlgButtonChecked(hdlg, IDC_CHECKONLY);
+ opts.bAggressive = IsDlgButtonChecked(hdlg, IDC_AGGRESSIVE);
+ if (opts.bCheckOnly) opts.bBackup = 0;
+ else opts.bBackup = IsDlgButtonChecked(hdlg, IDC_BACKUP);
+ break;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_BACK:
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_SELECTDB, (LPARAM)SelectDbDlgProc);
+ break;
+
+ case IDOK:
+ if (opts.bCheckOnly) {
+ if (!opts.hFile) {
+ opts.hFile = CreateFile(opts.filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (opts.hFile == INVALID_HANDLE_VALUE) {
+ opts.hFile = NULL;
+ opts.error = GetLastError();
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_OPENERROR, (LPARAM)OpenErrorDlgProc);
+ break;
+ }
+ }
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_PROGRESS, (LPARAM)ProgressDlgProc);
+ }
+ else SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_CLEANING, (LPARAM)CleaningDlgProc);
+ break;
+
+ case IDC_CHECKONLY:
+ EnableWindow(GetDlgItem(hdlg, IDC_BACKUP), !IsDlgButtonChecked(hdlg, IDC_CHECKONLY));
+ EnableWindow(GetDlgItem(hdlg, IDC_STBACKUP), !IsDlgButtonChecked(hdlg, IDC_CHECKONLY));
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/DbChecker/src/finished.cpp b/plugins/DbChecker/src/finished.cpp
new file mode 100644
index 0000000000..96da1a0917
--- /dev/null
+++ b/plugins/DbChecker/src/finished.cpp
@@ -0,0 +1,86 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "dbchecker.h"
+
+#define WM_LAUNCHMIRANDA (WM_USER+1)
+INT_PTR CALLBACK FinishedDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ INT_PTR bReturn;
+ if ( DoMyControlProcessing(hdlg, message, wParam, lParam, &bReturn))
+ return bReturn;
+
+ switch(message) {
+ case WM_INITDIALOG:
+ EnableWindow(GetDlgItem(GetParent(hdlg), IDC_BACK), FALSE);
+ SetDlgItemText(GetParent(hdlg), IDCANCEL, TranslateT("&Finish"));
+ SetWindowLongPtr(GetDlgItem(hdlg, IDC_DBFILE), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hdlg, IDC_DBFILE), GWL_STYLE)|SS_PATHELLIPSIS);
+ SetDlgItemText(hdlg, IDC_DBFILE, opts.filename);
+ if (opts.bBackup) {
+ ShowWindow(GetDlgItem(hdlg, IDC_STBACKUP), TRUE);
+ SetWindowLongPtr(GetDlgItem(hdlg, IDC_BACKUPFILE), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hdlg, IDC_BACKUPFILE), GWL_STYLE)|SS_PATHELLIPSIS);
+ SetDlgItemText(hdlg, IDC_BACKUPFILE, opts.backupFilename);
+ }
+ else ShowWindow(GetDlgItem(hdlg, IDC_STBACKUP), FALSE);
+ TranslateDialogDefault(hdlg);
+ return TRUE;
+
+ case WM_LAUNCHMIRANDA:
+ if (IsDlgButtonChecked(hdlg, IDC_LAUNCHMIRANDA)) {
+ TCHAR dbFile[MAX_PATH], dbPath[MAX_PATH], *str2;
+ _tcscpy(dbPath, opts.filename);
+ str2 = _tcsrchr(dbPath, '\\');
+ if (str2 == NULL) {
+ _tcscpy(dbFile, dbPath);
+ dbPath[ 0 ] = 0;
+ }
+ else {
+ _tcscpy(dbFile, str2+1);
+ *str2 = 0;
+ }
+ str2 = _tcsrchr(dbFile, '.');
+ if (str2 != NULL)
+ *str2 = 0;
+ _tcscat(dbPath, _T("\\miranda32.exe"));
+ if (GetFileAttributes(dbPath) == INVALID_FILE_ATTRIBUTES) {
+ GetModuleFileName(NULL, dbPath, SIZEOF(dbPath));
+ if ((str2 = _tcsrchr(dbPath, '\\')) != NULL)
+ *str2 = 0;
+ else
+ dbPath[0] = 0;
+ _tcscat(dbPath, _T("\\miranda32.exe"));
+ }
+ ShellExecute(hdlg, NULL, dbPath, dbFile, _T(""), 0);
+ }
+ break;
+
+ case WZN_CANCELCLICKED:
+ SendMessage(hdlg, WM_LAUNCHMIRANDA, 0, 0);
+ break;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDOK:
+ SendMessage(hdlg, WM_LAUNCHMIRANDA, 0, 0);
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_SELECTDB, (LPARAM)SelectDbDlgProc);
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/DbChecker/src/main.cpp b/plugins/DbChecker/src/main.cpp
new file mode 100644
index 0000000000..f59f66a13a
--- /dev/null
+++ b/plugins/DbChecker/src/main.cpp
@@ -0,0 +1,26 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "dbchecker.h"
+
+HINSTANCE hInst;
+int hLangpack = 0;
+
+DbToolOptions opts = {0};
+
diff --git a/plugins/DbChecker/src/openerror.cpp b/plugins/DbChecker/src/openerror.cpp
new file mode 100644
index 0000000000..f86ba163cb
--- /dev/null
+++ b/plugins/DbChecker/src/openerror.cpp
@@ -0,0 +1,58 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "dbchecker.h"
+
+INT_PTR CALLBACK OpenErrorDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ INT_PTR bReturn;
+
+ if (DoMyControlProcessing(hdlg, message, wParam, lParam, &bReturn)) return bReturn;
+ switch(message) {
+ case WM_INITDIALOG:
+ {
+ TCHAR szError[256];
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, opts.error, 0, szError, SIZEOF(szError), NULL);
+ SetDlgItemText(hdlg, IDC_ERRORTEXT, szError);
+ }
+ if (opts.error == ERROR_SHARING_VIOLATION) ShowWindow(GetDlgItem(hdlg, IDC_INUSE), SW_SHOW);
+ SetWindowLongPtr(GetDlgItem(hdlg, IDC_FILE), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hdlg, IDC_FILE), GWL_STYLE) | SS_PATHELLIPSIS);
+ TranslateDialogDefault(hdlg);
+ SetDlgItemText(hdlg, IDC_FILE, opts.filename);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_BACK:
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_SELECTDB, (LPARAM)SelectDbDlgProc);
+ break;
+
+ case IDOK:
+ opts.hFile = CreateFile(opts.filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (opts.hFile == INVALID_HANDLE_VALUE) {
+ opts.hFile = NULL;
+ opts.error = GetLastError();
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_OPENERROR, (LPARAM)OpenErrorDlgProc);
+ }
+ else SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_FILEACCESS, (LPARAM)FileAccessDlgProc);
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/DbChecker/src/progress.cpp b/plugins/DbChecker/src/progress.cpp
new file mode 100644
index 0000000000..5465fee8fa
--- /dev/null
+++ b/plugins/DbChecker/src/progress.cpp
@@ -0,0 +1,224 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "dbchecker.h"
+
+#define WM_PROCESSINGDONE (WM_USER+1)
+
+void __cdecl WorkerThread(void *unused);
+static HWND hwndStatus, hdlgProgress, hwndBar;
+HANDLE hEventRun = NULL, hEventAbort = NULL;
+int errorCount;
+
+void AddToStatus(int flags, const TCHAR* fmt, ...)
+{
+ va_list vararg;
+ va_start(vararg, fmt);
+
+ TCHAR str[256];
+ _vsntprintf(str, SIZEOF(str), fmt, vararg);
+ va_end(vararg);
+
+ int i = SendMessage(hwndStatus, LB_ADDSTRING, 0, (LPARAM)str);
+ SendMessage(hwndStatus, LB_SETITEMDATA, i, flags);
+ InvalidateRect(hwndStatus, NULL, FALSE);
+ SendMessage(hwndStatus, LB_SETTOPINDEX, i, 0);
+
+ #ifdef _DEBUG
+ OutputDebugString(str);
+ OutputDebugStringA("\n");
+ #endif
+
+ if ((flags & STATUS_CLASSMASK) == STATUS_ERROR)
+ errorCount++;
+}
+
+void SetProgressBar(int perThou)
+{
+ SendMessage(hwndBar, PBM_SETPOS, perThou, 0);
+}
+
+void ProcessingDone(void)
+{
+ if (opts.pFile) {
+ UnmapViewOfFile(opts.pFile);
+ opts.pFile = NULL;
+ }
+ if (opts.hMap) {
+ CloseHandle(opts.hMap);
+ opts.hMap = NULL;
+ }
+ SendMessage(hdlgProgress, WM_PROCESSINGDONE, 0, 0);
+}
+
+INT_PTR CALLBACK ProgressDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static int fontHeight, listWidth;
+ static int manualAbort;
+ static HFONT hBoldFont = NULL;
+
+ INT_PTR bReturn;
+ if (DoMyControlProcessing(hdlg, message, wParam, lParam, &bReturn))
+ return bReturn;
+
+ switch(message) {
+ case WM_INITDIALOG:
+ EnableWindow(GetDlgItem(GetParent(hdlg), IDOK), FALSE);
+ hdlgProgress = hdlg;
+ hwndStatus = GetDlgItem(hdlg, IDC_STATUS);
+ errorCount = 0;
+ hwndBar = GetDlgItem(hdlg, IDC_PROGRESS);
+ SendMessage(hwndBar, PBM_SETRANGE, 0, MAKELPARAM(0, 1000));
+ {
+ HDC hdc;
+ HFONT hFont, hoFont;
+ SIZE s;
+ hdc = GetDC(NULL);
+ hFont = (HFONT)SendMessage(hdlg, WM_GETFONT, 0, 0);
+ hoFont = (HFONT)SelectObject(hdc, hFont);
+ GetTextExtentPoint32(hdc, _T("x"), 1, &s);
+ SelectObject(hdc, hoFont);
+ ReleaseDC(NULL, hdc);
+ fontHeight = s.cy;
+
+ RECT rc;
+ GetClientRect(GetDlgItem(hdlg, IDC_STATUS), &rc);
+ listWidth = rc.right;
+
+ LOGFONT lf;
+ GetObject((HFONT)SendDlgItemMessage(hdlg, IDC_STATUS, WM_GETFONT, 0, 0), sizeof(lf), &lf);
+ lf.lfWeight = FW_BOLD;
+ hBoldFont = CreateFontIndirect(&lf);
+ }
+ manualAbort = 0;
+ hEventRun = CreateEvent(NULL, TRUE, TRUE, NULL);
+ hEventAbort = CreateEvent(NULL, TRUE, FALSE, NULL);
+ TranslateDialogDefault(hdlg);
+ _beginthread(WorkerThread, 0, NULL);
+ return TRUE;
+
+ case WM_MEASUREITEM:
+ {
+ LPMEASUREITEMSTRUCT mis = (LPMEASUREITEMSTRUCT)lParam;
+ mis->itemWidth = listWidth;
+ mis->itemHeight = fontHeight;
+ }
+ return TRUE;
+
+ case WM_DRAWITEM:
+ {
+ LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam;
+ TCHAR str[256];
+ int bold = 0;
+ HFONT hoFont;
+ if ((int)dis->itemID == -1) break;
+ SendMessage(dis->hwndItem, LB_GETTEXT, dis->itemID, (LPARAM)str);
+ switch(dis->itemData&STATUS_CLASSMASK) {
+ case STATUS_MESSAGE:
+ SetTextColor(dis->hDC, RGB(0, 0, 0));
+ break;
+ case STATUS_WARNING:
+ SetTextColor(dis->hDC, RGB(192, 128, 0));
+ break;
+ case STATUS_ERROR:
+ SetTextColor(dis->hDC, RGB(192, 0, 0));
+ break;
+ case STATUS_FATAL:
+ bold = 1;
+ SetTextColor(dis->hDC, RGB(192, 0, 0));
+ break;
+ case STATUS_SUCCESS:
+ bold = 1;
+ SetTextColor(dis->hDC, RGB(0, 192, 0));
+ break;
+ }
+ if (bold) hoFont = (HFONT)SelectObject(dis->hDC, hBoldFont);
+ ExtTextOut(dis->hDC, dis->rcItem.left, dis->rcItem.top, ETO_CLIPPED|ETO_OPAQUE, &dis->rcItem, str, (UINT)_tcslen(str), NULL);
+ if (bold) SelectObject(dis->hDC, hoFont);
+ }
+ return TRUE;
+
+ case WM_PROCESSINGDONE:
+ SetProgressBar(1000);
+ EnableWindow(GetDlgItem(GetParent(hdlg), IDOK), TRUE);
+ if (manualAbort == 1)
+ EndDialog(GetParent(hdlg), 0);
+ else if (manualAbort == 2) {
+ if (opts.bCheckOnly)
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_FILEACCESS, (LPARAM)FileAccessDlgProc);
+ else {
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_CLEANING, (LPARAM)CleaningDlgProc);
+ CloseHandle(opts.hOutFile);
+ opts.hOutFile = NULL;
+ }
+ break;
+ }
+ AddToStatus(STATUS_SUCCESS, TranslateT("Click Next to continue"));
+ break;
+
+ case WZN_CANCELCLICKED:
+ ResetEvent(hEventRun);
+ if (IsWindowEnabled(GetDlgItem(GetParent(hdlg), IDOK))) break;
+ if (MessageBox(hdlg, TranslateT("Processing has not yet completed, if you cancel now then the changes that have currently been made will be rolled back and the original database will be restored. Do you still want to cancel?"), TranslateT("Miranda Database Tool"), MB_YESNO) == IDYES) {
+ manualAbort = 1;
+ SetEvent(hEventAbort);
+ }
+ SetEvent(hEventRun);
+ SetWindowLongPtr(hdlg, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_BACK:
+ ResetEvent(hEventRun);
+ if (!IsWindowEnabled(GetDlgItem(GetParent(hdlg), IDOK))) {
+ if (MessageBox(hdlg, TranslateT("Processing has not yet completed, if you go back now then the changes that have currently been made will be rolled back and the original database will be restored. Do you still want to go back?"), TranslateT("Miranda Database Tool"), MB_YESNO) == IDYES) {
+ manualAbort = 2;
+ SetEvent(hEventAbort);
+ }
+ SetEvent(hEventRun);
+ break;
+ }
+ SetEvent(hEventRun);
+ if (opts.bCheckOnly)
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_FILEACCESS, (LPARAM)FileAccessDlgProc);
+ else
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_CLEANING, (LPARAM)CleaningDlgProc);
+ break;
+ case IDOK:
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_FINISHED, (LPARAM)FinishedDlgProc);
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ if (hEventAbort) {
+ CloseHandle(hEventAbort);
+ hEventAbort = NULL;
+ }
+ if (hEventRun) {
+ CloseHandle(hEventRun);
+ hEventRun = NULL;
+ }
+ if (hBoldFont) {
+ DeleteObject(hBoldFont);
+ hBoldFont = NULL;
+ }
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/DbChecker/src/resource.h b/plugins/DbChecker/src/resource.h
new file mode 100644
index 0000000000..a76f82ee1c
--- /dev/null
+++ b/plugins/DbChecker/src/resource.h
@@ -0,0 +1,54 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by resource.rc
+//
+#define IDC_BACK 3
+#define IDD_WIZARD 101
+#define IDE_WATERMARK 102
+#define IDI_DBTOOL 102
+#define IDE_HDRLOGO 103
+#define IDI_PROFILEGREEN 104
+#define IDR_DEFAULT1 104
+#define IDI_PROFILEYELLOW 105
+#define IDD_WELCOME 106
+#define IDI_PROFILERED 106
+#define IDD_SELECTDB 107
+#define IDD_OPENERROR 108
+#define IDD_FILEACCESS 109
+#define IDD_CLEANING 110
+#define IDD_PROGRESS 111
+#define IDD_FINISHED 112
+#define IDI_BAD 113
+#define IDC_WATERMARK 1000
+#define IDC_TITLE 1001
+#define IDC_HDRLOGO 1002
+#define IDC_DBLIST 1003
+#define IDC_FILE 1004
+#define IDC_OTHER 1005
+#define IDC_ERRORTEXT 1006
+#define IDC_INUSE 1007
+#define IDC_BACKUP 1008
+#define IDC_AGGRESSIVE 1009
+#define IDC_ERASEHISTORY 1010
+#define IDC_CHECKONLY 1010
+#define IDC_MARKREAD 1011
+#define IDC_PROGRESS 1011
+#define IDC_STATUS 1012
+#define IDC_STBACKUP 1013
+#define IDC_LAUNCHMIRANDA 1015
+#define IDC_DBFILE 1016
+#define IDC_BACKUPFILE 1017
+#define IDC_CHECK1 1018
+#define IDC_CONVERTUTF 1018
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 105
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1019
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/DbChecker/src/selectdb.cpp b/plugins/DbChecker/src/selectdb.cpp
new file mode 100644
index 0000000000..0b61d5c5b6
--- /dev/null
+++ b/plugins/DbChecker/src/selectdb.cpp
@@ -0,0 +1,296 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "dbchecker.h"
+
+void GetProfileDirectory(TCHAR* szMirandaDir, TCHAR* szPath, int cbPath)
+{
+ TCHAR szProfileDir[MAX_PATH], szExpandedProfileDir[MAX_PATH], szMirandaBootIni[MAX_PATH];
+
+ lstrcpy(szMirandaBootIni, szMirandaDir);
+ lstrcat(szMirandaBootIni, _T("\\mirandaboot.ini"));
+ GetPrivateProfileString( _T("Database"), _T("ProfileDir"), _T("./Profiles"), szProfileDir, SIZEOF(szProfileDir), szMirandaBootIni);
+ ExpandEnvironmentStrings(szProfileDir, szExpandedProfileDir, SIZEOF(szExpandedProfileDir));
+ _tchdir(szMirandaDir);
+ if ( !_tfullpath(szPath, szExpandedProfileDir, cbPath))
+ lstrcpyn(szPath, szMirandaDir, cbPath);
+ if (szPath[lstrlen(szPath)-1] == '\\')
+ szPath[lstrlen(szPath)-1] = 0;
+}
+
+static int AddDatabaseToList(HWND hwndList, const TCHAR* filename, TCHAR* dir)
+{
+ LV_ITEM lvi;
+ lvi.mask = LVIF_PARAM;
+ lvi.iSubItem = 0;
+ for(lvi.iItem = ListView_GetItemCount(hwndList)-1;lvi.iItem >= 0;lvi.iItem--) {
+ ListView_GetItem(hwndList, &lvi);
+ if (!_tcsicmp((TCHAR*)lvi.lParam, filename))
+ return lvi.iItem;
+ }
+
+ _stat st;
+ if ( _tstat(filename, &st) == -1)
+ return -1;
+
+ int broken = 0;
+ DWORD totalSize = st.st_size;
+ DWORD wasted = 0;
+
+ const TCHAR *pName = _tcsrchr(filename, '\\');
+ if (pName == NULL)
+ pName = (LPTSTR)filename;
+ else
+ pName++;
+
+ TCHAR szName[MAX_PATH];
+ mir_sntprintf(szName, MAX_PATH, _T("%s%s"), dir, pName);
+
+ TCHAR *pDot = _tcsrchr(szName, '.');
+ if (pDot != NULL && !_tcsicmp(pDot, _T(".dat")))
+ *pDot = 0;
+
+ lvi.iItem = 0;
+ lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
+ lvi.iSubItem = 0;
+ lvi.lParam = (LPARAM)_tcsdup(filename);
+ lvi.pszText = szName;
+ if (broken)
+ lvi.iImage = 3;
+ else if (wasted < 1024*128)
+ lvi.iImage = 0;
+ else if (wasted < 1024*256 + (DWORD)(totalSize > 2*1024*1024) ? 256 * 1024 : 0)
+ lvi.iImage = 1;
+ else
+ lvi.iImage = 2;
+
+ int iNewItem = ListView_InsertItem(hwndList, &lvi);
+ TCHAR szSize[20];
+ _stprintf(szSize, _T("%.2lf MB"), totalSize/1048576.0);
+ ListView_SetItemText(hwndList, iNewItem, 1, szSize);
+ if (!broken) {
+ _stprintf(szSize, _T("%.2lf MB"), wasted/1048576.0);
+ ListView_SetItemText(hwndList, iNewItem, 2, szSize);
+ }
+ return iNewItem;
+}
+
+void FindAdd(HWND hdlg, TCHAR *szProfileDir, TCHAR *szPrefix)
+{
+ HANDLE hFind;
+ WIN32_FIND_DATA fd;
+ TCHAR szSearchPath[MAX_PATH], szFilename[MAX_PATH];
+
+ lstrcpy(szSearchPath, szProfileDir);
+ lstrcat(szSearchPath, _T("\\*.*"));
+
+ hFind = FindFirstFile(szSearchPath, &fd);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ do {
+ if ( !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || !_tcscmp(fd.cFileName, _T(".")) || !_tcscmp(fd.cFileName, _T("..")))
+ continue;
+
+ wsprintf(szFilename, _T("%s\\%s\\%s.dat"), szProfileDir, fd.cFileName, fd.cFileName);
+ if ( _taccess(szFilename, 0) == 0)
+ AddDatabaseToList(GetDlgItem(hdlg, IDC_DBLIST), szFilename, szPrefix);
+ }
+ while(FindNextFile(hFind, &fd));
+ FindClose(hFind);
+ }
+}
+
+TCHAR *addstring(TCHAR *str, TCHAR *add)
+{
+ _tcscpy(str, add);
+ return str + _tcslen(add) + 1;
+}
+
+INT_PTR CALLBACK SelectDbDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ INT_PTR bReturn;
+ if (DoMyControlProcessing(hdlg, message, wParam, lParam, &bReturn))
+ return bReturn;
+
+ switch (message) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hdlg);
+ {
+ HIMAGELIST hIml = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
+ (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16) | ILC_MASK, 3, 3);
+ ImageList_AddIcon(hIml, LoadIcon(hInst, MAKEINTRESOURCE(IDI_PROFILEGREEN)));
+ ImageList_AddIcon(hIml, LoadIcon(hInst, MAKEINTRESOURCE(IDI_PROFILEYELLOW)));
+ ImageList_AddIcon(hIml, LoadIcon(hInst, MAKEINTRESOURCE(IDI_PROFILERED)));
+ ImageList_AddIcon(hIml, LoadIcon(hInst, MAKEINTRESOURCE(IDI_BAD)));
+ ListView_SetImageList(GetDlgItem(hdlg, IDC_DBLIST), hIml, LVSIL_SMALL);
+ }
+ ListView_SetExtendedListViewStyleEx(GetDlgItem(hdlg, IDC_DBLIST), LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
+ {
+ LV_COLUMN lvc;
+ lvc.mask = LVCF_WIDTH | LVCF_FMT | LVCF_TEXT;
+ lvc.cx = 205;
+ lvc.fmt = LVCFMT_LEFT;
+ lvc.pszText = TranslateT("Database");
+ ListView_InsertColumn(GetDlgItem(hdlg, IDC_DBLIST), 0, &lvc);
+ lvc.cx = 68;
+ lvc.fmt = LVCFMT_RIGHT;
+ lvc.pszText = TranslateT("Total size");
+ ListView_InsertColumn(GetDlgItem(hdlg, IDC_DBLIST), 1, &lvc);
+ lvc.pszText = TranslateT("Wasted");
+ ListView_InsertColumn(GetDlgItem(hdlg, IDC_DBLIST), 2, &lvc);
+
+ TCHAR szMirandaPath[MAX_PATH];
+ GetModuleFileName(NULL, szMirandaPath, SIZEOF(szMirandaPath));
+ TCHAR *str2 = _tcsrchr(szMirandaPath, '\\');
+ if (str2 != NULL)
+ *str2 = 0;
+
+ int i = 0;
+ HKEY hKey;
+ TCHAR szProfileDir[MAX_PATH];
+ TCHAR szMirandaProfiles[MAX_PATH];
+ DWORD cbData = SIZEOF(szMirandaPath);
+
+ _tcscpy(szMirandaProfiles, szMirandaPath);
+ _tcscat(szMirandaProfiles, _T("\\Profiles"));
+ GetProfileDirectory(szMirandaPath, szProfileDir, SIZEOF(szProfileDir));
+
+ // search in profile dir (using ini file)
+ if (lstrcmpi(szProfileDir, szMirandaProfiles))
+ FindAdd(hdlg, szProfileDir, _T("[ini]\\"));
+
+ FindAdd(hdlg, szMirandaProfiles, _T("[prf]\\"));
+ // search in current dir (as DBTOOL)
+ FindAdd(hdlg, szMirandaPath, _T("[ . ]\\"));
+
+ // search in profile dir (using registry path + ini file)
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\miranda32.exe"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
+ if (RegQueryValueEx(hKey, _T("Path"), NULL, NULL, (PBYTE)szMirandaPath, &cbData) == ERROR_SUCCESS) {
+ if (lstrcmp(szProfileDir, szMirandaPath)) {
+ GetProfileDirectory(szMirandaPath, szProfileDir, SIZEOF(szProfileDir));
+ FindAdd(hdlg, szProfileDir, _T("[reg]\\"));
+ }
+ }
+ RegCloseKey(hKey);
+ }
+ // select
+ if (opts.filename[0])
+ i = AddDatabaseToList(GetDlgItem(hdlg, IDC_DBLIST), opts.filename, _T(""));
+ if (i == -1)
+ i = 0;
+ ListView_SetItemState(GetDlgItem(hdlg, IDC_DBLIST), i, LVIS_SELECTED, LVIS_SELECTED);
+ }
+ if (opts.hFile != NULL && opts.hFile != INVALID_HANDLE_VALUE) {
+ CloseHandle(opts.hFile);
+ opts.hFile = NULL;
+ }
+ return TRUE;
+
+ case WZN_PAGECHANGING:
+ GetDlgItemText(hdlg, IDC_FILE, opts.filename, SIZEOF(opts.filename));
+ break;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_FILE:
+ if (HIWORD(wParam) == EN_CHANGE)
+ EnableWindow(GetDlgItem(GetParent(hdlg), IDOK), GetWindowTextLength(GetDlgItem(hdlg, IDC_FILE)));
+ break;
+
+ case IDC_OTHER:
+ {
+ OPENFILENAME ofn = {0};
+ TCHAR str[MAX_PATH];
+
+ // _T("Miranda Databases (*.dat)\0*.DAT\0All Files (*)\0*\0");
+ TCHAR *filter, *tmp, *tmp1, *tmp2;
+ tmp1 = TranslateT("Miranda Databases (*.dat)");
+ tmp2 = TranslateT("All Files");
+ filter = tmp = (TCHAR*)_alloca((_tcslen(tmp1)+_tcslen(tmp2)+11)*sizeof(TCHAR));
+ tmp = addstring(tmp, tmp1);
+ tmp = addstring(tmp, _T("*.DAT"));
+ tmp = addstring(tmp, tmp2);
+ tmp = addstring(tmp, _T("*"));
+ *tmp = 0;
+
+ GetDlgItemText(hdlg, IDC_FILE, str, SIZEOF(str));
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = hdlg;
+ ofn.hInstance = NULL;
+ ofn.lpstrFilter = filter;
+ ofn.lpstrDefExt = _T("dat");
+ ofn.lpstrFile = str;
+ ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
+ ofn.nMaxFile = SIZEOF(str);
+ ofn.nMaxFileTitle = MAX_PATH;
+ if (GetOpenFileName(&ofn)) {
+ int i = AddDatabaseToList(GetDlgItem(hdlg, IDC_DBLIST), str, _T(""));
+ if (i == -1)
+ i = 0;
+ ListView_SetItemState(GetDlgItem(hdlg, IDC_DBLIST), i, LVIS_SELECTED, LVIS_SELECTED);
+ }
+ }
+ break;
+
+ case IDC_BACK:
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_WELCOME, (LPARAM)WelcomeDlgProc);
+ break;
+
+ case IDOK:
+ opts.hFile = CreateFile(opts.filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (opts.hFile == INVALID_HANDLE_VALUE) {
+ opts.hFile = NULL;
+ opts.error = GetLastError();
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_OPENERROR, (LPARAM)OpenErrorDlgProc);
+ }
+ else SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_FILEACCESS, (LPARAM)FileAccessDlgProc);
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case IDC_DBLIST:
+ switch(((LPNMLISTVIEW)lParam)->hdr.code) {
+ case LVN_ITEMCHANGED:
+ {
+ LV_ITEM lvi;
+ lvi.iItem = ListView_GetNextItem(GetDlgItem(hdlg, IDC_DBLIST), -1, LVNI_SELECTED);
+ if (lvi.iItem == -1) break;
+ lvi.mask = LVIF_PARAM;
+ ListView_GetItem(GetDlgItem(hdlg, IDC_DBLIST), &lvi);
+ SetDlgItemText(hdlg, IDC_FILE, (TCHAR*)lvi.lParam);
+ SendMessage(hdlg, WM_COMMAND, MAKEWPARAM(IDC_FILE, EN_CHANGE), (LPARAM)GetDlgItem(hdlg, IDC_FILE));
+ }
+ break;
+ }
+ break;
+ }
+ break;
+
+ case WM_DESTROY:
+ {
+ LV_ITEM lvi;
+ lvi.mask = LVIF_PARAM;
+ for(lvi.iItem = ListView_GetItemCount(GetDlgItem(hdlg, IDC_DBLIST))-1;lvi.iItem >= 0;lvi.iItem--) {
+ ListView_GetItem(GetDlgItem(hdlg, IDC_DBLIST), &lvi);
+ free((char*)lvi.lParam);
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/DbChecker/src/utf.cpp b/plugins/DbChecker/src/utf.cpp
new file mode 100644
index 0000000000..ffb73d3280
--- /dev/null
+++ b/plugins/DbChecker/src/utf.cpp
@@ -0,0 +1,69 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+ Copyright 2000 Alexandre Julliard of Wine project
+ (UTF-8 conversion routines)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "dbchecker.h"
+
+bool is_utf8_string(const char* str)
+{
+ int expect_bytes = 0, utf_found = 0;
+
+ if (!str) return 0;
+
+ while (*str) {
+ if ((*str & 0x80) == 0) {
+ /* Looks like an ASCII character */
+ if (expect_bytes)
+ /* byte of UTF-8 character expected */
+ return 0;
+ }
+ else {
+ /* Looks like byte of an UTF-8 character */
+ if (expect_bytes) {
+ /* expect_bytes already set: first byte of UTF-8 char already seen */
+ if ((*str & 0xC0) != 0x80) {
+ /* again first byte ?!?! */
+ return 0;
+ }
+ }
+ else {
+ /* First byte of the UTF-8 character */
+ /* count initial one bits and set expect_bytes to 1 less */
+ char ch = *str;
+ while (ch & 0x80) {
+ expect_bytes++;
+ ch = (ch & 0x7f) << 1;
+ }
+ }
+ /* OK, next byte of UTF-8 character */
+ /* Decrement number of expected bytes */
+ if (--expect_bytes == 0)
+ utf_found = 1;
+ }
+ str++;
+ }
+
+ return (utf_found && expect_bytes == 0);
+}
diff --git a/plugins/DbChecker/src/version.h b/plugins/DbChecker/src/version.h
new file mode 100644
index 0000000000..58f9cf348c
--- /dev/null
+++ b/plugins/DbChecker/src/version.h
@@ -0,0 +1,5 @@
+#include <m_version.h>
+
+#define __FILEVERSION_STRING MIRANDA_VERSION_FILEVERSION
+#define __VERSION_STRING MIRANDA_VERSION_STRING
+#define __VERSION_DWORD MIRANDA_VERSION_DWORD
diff --git a/plugins/DbChecker/src/welcome.cpp b/plugins/DbChecker/src/welcome.cpp
new file mode 100644
index 0000000000..99d7a3091a
--- /dev/null
+++ b/plugins/DbChecker/src/welcome.cpp
@@ -0,0 +1,70 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "dbchecker.h"
+
+INT_PTR CALLBACK WelcomeDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static HENHMETAFILE hEmfWatermark;
+ static HFONT hTitleFont;
+
+ INT_PTR bReturn;
+ if ( DoMyControlProcessing(hdlg, message, wParam, lParam, &bReturn))
+ return bReturn;
+
+ switch(message) {
+ case WM_INITDIALOG:
+ {
+ HRSRC hRsrcWatermark = FindResourceA(hInst, MAKEINTRESOURCEA(IDE_WATERMARK), "EMF");
+ HGLOBAL hGlobWatermark = LoadResource(hInst, hRsrcWatermark);
+ hEmfWatermark = SetEnhMetaFileBits(SizeofResource(hInst, hRsrcWatermark), (PBYTE)LockResource(hGlobWatermark));
+ }
+ SendDlgItemMessage(hdlg, IDC_WATERMARK, STM_SETIMAGE, IMAGE_ENHMETAFILE, (LPARAM)hEmfWatermark);
+ {
+ NONCLIENTMETRICS ncm = {0};
+ ncm.cbSize = sizeof(ncm);
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
+ LOGFONT TitleLogFont = ncm.lfMessageFont;
+ TitleLogFont.lfWeight = FW_BOLD;
+ lstrcpy(TitleLogFont.lfFaceName, TEXT("Verdana Bold"));
+
+ HDC hdc = GetDC(NULL);
+ INT FontSize = 12;
+ TitleLogFont.lfHeight = 0 - GetDeviceCaps(hdc, LOGPIXELSY) * FontSize / 72;
+ hTitleFont = CreateFontIndirect(&TitleLogFont);
+ ReleaseDC(NULL, hdc);
+ }
+ SendDlgItemMessage(hdlg, IDC_TITLE, WM_SETFONT, (WPARAM)hTitleFont, 0);
+ EnableWindow(GetDlgItem(GetParent(hdlg), IDC_BACK), FALSE);
+ return FALSE;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDOK:
+ SendMessage(GetParent(hdlg), WZM_GOTOPAGE, IDD_SELECTDB, (LPARAM)SelectDbDlgProc);
+ break;
+ }
+ break;
+
+ case WM_DESTROY:
+ DeleteEnhMetaFile(hEmfWatermark);
+ DeleteObject(hTitleFont);
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/DbChecker/src/wizard.cpp b/plugins/DbChecker/src/wizard.cpp
new file mode 100644
index 0000000000..dd10b614ac
--- /dev/null
+++ b/plugins/DbChecker/src/wizard.cpp
@@ -0,0 +1,141 @@
+/*
+Miranda Database Tool
+Copyright 2000-2011 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "dbchecker.h"
+
+static HFONT hBoldFont = NULL;
+static HENHMETAFILE hEmfHeaderLogo = NULL;
+
+static BOOL CALLBACK MyControlsEnumChildren(HWND hwnd, LPARAM lParam)
+{
+ DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE);
+ DWORD exstyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
+ char szClass[64];
+ int makeBold = 0;
+
+ GetClassNameA(hwnd, szClass, sizeof(szClass));
+ if (!strcmp(szClass, "Static")) {
+ if (((style & SS_TYPEMASK) == SS_LEFT || (style & SS_TYPEMASK) == SS_CENTER || (style & SS_TYPEMASK) == SS_RIGHT) && exstyle & WS_EX_CLIENTEDGE)
+ makeBold = 1;
+ }
+ else if (!strcmp(szClass, "Button")) {
+ if (exstyle&WS_EX_CLIENTEDGE)
+ makeBold = 1;
+ }
+ if (makeBold) {
+ if (hBoldFont == NULL) {
+ LOGFONT lf;
+ hBoldFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
+ GetObject(hBoldFont, sizeof(lf), &lf);
+ lf.lfWeight = FW_BOLD;
+ hBoldFont = CreateFontIndirect(&lf);
+ }
+ SendMessage(hwnd, WM_SETFONT, (WPARAM)hBoldFont, 0);
+ SetWindowLongPtr(hwnd, GWL_EXSTYLE, exstyle&~WS_EX_CLIENTEDGE);
+ SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED);
+ }
+ return TRUE;
+}
+
+int DoMyControlProcessing(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam, INT_PTR *bReturn)
+{
+ switch(message) {
+ case WM_INITDIALOG:
+ EnumChildWindows(hdlg, MyControlsEnumChildren, 0);
+ if (hEmfHeaderLogo == NULL) {
+ HRSRC hRsrc = FindResourceA(hInst, MAKEINTRESOURCEA(IDE_HDRLOGO), "EMF");
+ HGLOBAL hGlob = LoadResource(hInst, hRsrc);
+ hEmfHeaderLogo = SetEnhMetaFileBits(SizeofResource(hInst, hRsrc), (PBYTE)LockResource(hGlob));
+ }
+ SendDlgItemMessage(hdlg, IDC_HDRLOGO, STM_SETIMAGE, IMAGE_ENHMETAFILE, (LPARAM)hEmfHeaderLogo);
+ break;
+
+ case WM_CTLCOLORSTATIC:
+ if ((GetWindowLongPtr((HWND)lParam, GWL_STYLE)&0xFFFF) == 0) {
+ char szText[256];
+ GetWindowTextA((HWND)lParam, szText, sizeof(szText));
+ if (!strcmp(szText, "whiterect")) {
+ SetTextColor((HDC)wParam, RGB(255, 255, 255));
+ SetBkColor((HDC)wParam, RGB(255, 255, 255));
+ SetBkMode((HDC)wParam, OPAQUE);
+ *bReturn = (INT_PTR)GetStockObject(WHITE_BRUSH);
+ return TRUE;
+ }
+ else {
+ SetBkMode((HDC)wParam, TRANSPARENT);
+ *bReturn = (INT_PTR)GetStockObject(NULL_BRUSH);
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+INT_PTR CALLBACK WizardDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static HWND hdlgPage;
+
+ switch(message) {
+ case WM_INITDIALOG:
+ SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_DBTOOL)));
+ hdlgPage = NULL;
+ SendMessage(hdlg, WZM_GOTOPAGE, IDD_WELCOME, (LPARAM)WelcomeDlgProc);
+ TranslateDialogDefault(hdlg);
+ return TRUE;
+
+ case WZM_GOTOPAGE:
+ if (hdlgPage != NULL) DestroyWindow(hdlgPage);
+ EnableWindow(GetDlgItem(hdlg, IDC_BACK), TRUE);
+ EnableWindow(GetDlgItem(hdlg, IDOK), TRUE);
+ EnableWindow(GetDlgItem(hdlg, IDCANCEL), TRUE);
+ SetDlgItemText(hdlg, IDCANCEL, TranslateT("Cancel"));
+ hdlgPage = CreateDialog(hInst, MAKEINTRESOURCE(wParam), hdlg, (DLGPROC)lParam);
+ TranslateDialogDefault(hdlgPage);
+ SetWindowPos(hdlgPage, 0, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOSIZE);
+ ShowWindow(hdlgPage, SW_SHOW);
+ break;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_BACK:
+ case IDOK:
+ 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);
+ break;
+ }
+ break;
+
+ case WM_DESTROY:
+ if (opts.hFile)
+ CloseHandle(opts.hFile);
+ if (opts.hOutFile)
+ CloseHandle(opts.hOutFile);
+ DestroyWindow(hdlgPage);
+ if (hBoldFont != NULL) DeleteObject(hBoldFont);
+ if (hEmfHeaderLogo != NULL) DeleteEnhMetaFile(hEmfHeaderLogo);
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/DbChecker/src/worker.cpp b/plugins/DbChecker/src/worker.cpp
new file mode 100644
index 0000000000..834a40f308
--- /dev/null
+++ b/plugins/DbChecker/src/worker.cpp
@@ -0,0 +1,79 @@
+/*
+Miranda Database Tool
+Copyright (C) 2001-2005 Richard Hughes
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "dbchecker.h"
+
+void ProcessingDone(void);
+int WorkInitialChecks(int firstTime);
+int WorkModuleChain(int firstTime);
+int WorkUser(int firstTime);
+int WorkContactChain(int firstTime);
+int WorkAggressive(int firstTime);
+int WorkFinalTasks(int firstTime);
+
+DATABASELINK* dblink;
+
+void __cdecl WorkerThread(void *unused)
+{
+ int task, firstTime;
+ time_t ts = time(NULL);
+
+ AddToStatus(STATUS_MESSAGE, TranslateT("Database worker thread activated"));
+ SetFilePointer(opts.hFile, 0, NULL, FILE_BEGIN);
+
+ DWORD sp = 0;
+ firstTime = 0;
+
+ DBCHeckCallback callback;
+ callback.cbSize = sizeof(callback);
+ callback.db = NULL;
+ callback.spaceUsed = 1;
+ callback.spaceProcessed = 0;
+ callback.pfnAddLogMessage = AddToStatus;
+
+ for(task = 0;;) {
+ if (callback.spaceProcessed/(callback.spaceUsed/1000+1) > sp) {
+ sp = callback.spaceProcessed/(callback.spaceUsed/1000+1);
+ SetProgressBar(sp);
+ }
+ WaitForSingleObject(hEventRun, INFINITE);
+ if (WaitForSingleObject(hEventAbort, 0) == WAIT_OBJECT_0) {
+ AddToStatus(STATUS_FATAL, TranslateT("Processing aborted by user"));
+ break;
+ }
+
+ int ret = dblink->CheckDb(&callback, task, firstTime);
+ firstTime = 0;
+ if (ret == ERROR_NO_MORE_ITEMS) {
+ AddToStatus(STATUS_MESSAGE, TranslateT("Elapsed time: %d sec"), time(NULL)-ts);
+ if (errorCount)
+ AddToStatus(STATUS_SUCCESS, TranslateT("All tasks completed but with errors (%d)"), errorCount);
+ else
+ AddToStatus(STATUS_SUCCESS, TranslateT("All tasks completed successfully"));
+ break;
+ }
+ else if (ret != ERROR_SUCCESS)
+ break;
+
+ task++;
+ firstTime = 1;
+ }
+
+ ProcessingDone();
+}