From bfe1bd0fc087be44c70904aee0fe4276643d206d Mon Sep 17 00:00:00 2001
From: George Hazan <george.hazan@gmail.com>
Date: Fri, 20 Jul 2012 15:56:25 +0000
Subject: - db3x_mmap is completely moved to a class; - the old nightmare in
 the core "How to detect a db plugin and load it" is eliminated forever; -
 databases are the usual plugins now (loadable via Load) - dynamic
 DATABASELINK registration

git-svn-id: http://svn.miranda-ng.org/main/trunk@1082 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
---
 src/core/miranda.h                      |  3 ++
 src/mir_core/db.cpp                     |  2 +-
 src/mir_core/lists.cpp                  |  6 +--
 src/mir_core/mir_core.def               |  3 +-
 src/modules/database/database.cpp       | 76 +++++++++++++++------------------
 src/modules/database/dbintf.cpp         | 34 ++++++++++++++-
 src/modules/database/profilemanager.cpp | 65 ++++++++++------------------
 src/modules/database/profilemanager.h   | 11 -----
 src/modules/plugins/dll_sniffer.cpp     |  2 +-
 src/modules/plugins/newplugins.cpp      | 70 +++++++-----------------------
 src/modules/plugins/plugins.h           |  7 +--
 11 files changed, 115 insertions(+), 164 deletions(-)

(limited to 'src')

diff --git a/src/core/miranda.h b/src/core/miranda.h
index 00eab4fcae..aeaa1fd593 100644
--- a/src/core/miranda.h
+++ b/src/core/miranda.h
@@ -111,6 +111,8 @@ extern LPFN_WSAADDRESSTOSTRINGA MyWSAAddressToString;
 /**** database.cpp *********************************************************************/
 
 extern MIDatabase* currDb;
+extern DATABASELINK* currDblink;
+extern LIST<DATABASELINK> arDbPlugins;
 
 /**** fontService.cpp ******************************************************************/
 
@@ -251,4 +253,5 @@ public:
 extern "C"
 {
 	MIR_CORE_DLL(int) Langpack_MarkPluginLoaded(PLUGININFOEX* pInfo);
+	MIR_CORE_DLL(void) db_setCurrent(MIDatabase* _db);
 };
diff --git a/src/mir_core/db.cpp b/src/mir_core/db.cpp
index f18f288d33..f9a1ba1118 100644
--- a/src/mir_core/db.cpp
+++ b/src/mir_core/db.cpp
@@ -227,7 +227,7 @@ MIR_CORE_DLL(INT_PTR) db_set_blob(HANDLE hContact, const char *szModule, const c
 	return currDb->WriteContactSetting(hContact, &cws);
 }
 
-MIR_CORE_DLL(void) db_setCurrent(MIDatabase* _db)
+extern "C" MIR_CORE_DLL(void) db_setCurrent(MIDatabase* _db)
 {
 	currDb = _db;
 }
diff --git a/src/mir_core/lists.cpp b/src/mir_core/lists.cpp
index e4996fc156..bcd2ad040c 100644
--- a/src/mir_core/lists.cpp
+++ b/src/mir_core/lists.cpp
@@ -65,14 +65,12 @@ MIR_CORE_DLL(void*) List_Find(SortedList* p_list, void* p_value)
 
 MIR_CORE_DLL(int) List_GetIndex(SortedList* p_list, void* p_value, int* p_index)
 {
-	if (p_value == NULL)
-	{
+	if (p_value == NULL) {
 		*p_index = -1;
 		return 0;
 	}
 
-	switch ((INT_PTR)p_list->sortFunc)
-	{
+	switch ((INT_PTR)p_list->sortFunc) {
 	case 0:
 		break;
 
diff --git a/src/mir_core/mir_core.def b/src/mir_core/mir_core.def
index 2939f2feda..4d231dbc70 100644
--- a/src/mir_core/mir_core.def
+++ b/src/mir_core/mir_core.def
@@ -125,4 +125,5 @@ db_set_ws                     @122
 UnloadCoreModule              @123
 Thread_SetName                @124
 replaceStr                    @125
-replaceStrW                   @126
\ No newline at end of file
+replaceStrW                   @126
+db_setCurrent                 @127
\ No newline at end of file
diff --git a/src/modules/database/database.cpp b/src/modules/database/database.cpp
index 8686d50bc6..13ce6bbfa9 100644
--- a/src/modules/database/database.cpp
+++ b/src/modules/database/database.cpp
@@ -23,8 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "..\..\core\commonheaders.h"
 #include "profilemanager.h"
 
-MIR_CORE_DLL(void) db_setCurrent(MIDatabase* _db);
-
 // contains the location of mirandaboot.ini
 extern TCHAR mirandabootini[MAX_PATH];
 bool dbCreated;
@@ -413,59 +411,59 @@ int makeDatabase(TCHAR *profile, DATABASELINK * link, HWND hwndDlg)
 }
 
 // enumerate all plugins that had valid DatabasePluginInfo()
-static int FindDbPluginForProfile(const TCHAR*, DATABASELINK *dblink, LPARAM lParam)
+int tryOpenDatabase(const TCHAR* tszProfile)
 {
-	TCHAR* tszProfile = (TCHAR*)lParam;
-	int res = DBPE_CONT;
-	if (dblink && dblink->cbSize == sizeof(DATABASELINK)) {
+	for (int i=0; i < arDbPlugins.getCount(); i++) {
+		DATABASELINK* p = arDbPlugins[i];
+
 		// liked the profile?
 		int err = 0;
-		if (dblink->grokHeader(tszProfile, &err) == 0) {
+		if ( p->grokHeader(tszProfile, &err) == 0) {
 			// added APIs?
-			MIDatabase* pDb = dblink->Load(tszProfile);
+			MIDatabase* pDb = p->Load(tszProfile);
 			if (pDb) {
 				fillProfileName(tszProfile);
+				currDblink = p;
 				db_setCurrent(currDb = pDb);
-				res = DBPE_DONE;
+				return 0;
 			}
-			else res = DBPE_HALT;
+			return 1;
 		}
 		else {
-			res = DBPE_HALT;
 			switch (err) {
 			case EGROKPRF_CANTREAD:
 			case EGROKPRF_UNKHEADER:
 				// just not supported.
-				res = DBPE_CONT;
+				continue;
 
 			case EGROKPRF_VERNEWER:
 			case EGROKPRF_DAMAGED:
-				break;
+				return 1;
 			}
 		} //if
 	}
-	return res;
+	return 1;
 }
 
 // enumerate all plugins that had valid DatabasePluginInfo()
-static int FindDbPluginAutoCreate(const TCHAR* ptszProfile, DATABASELINK * dblink, LPARAM lParam)
+static int tryCreateDatabase(const TCHAR* ptszProfile)
 {
-	int res = DBPE_CONT;
-	if (dblink && dblink->cbSize == sizeof(DATABASELINK)) {
-		TCHAR* tszProfile = NEWTSTR_ALLOCA(ptszProfile);
-		CreatePathToFileT(tszProfile);
+	TCHAR* tszProfile = NEWTSTR_ALLOCA(ptszProfile);
+	CreatePathToFileT(tszProfile);
+
+	for (int i=0; i < arDbPlugins.getCount(); i++) {
+		DATABASELINK* p = arDbPlugins[i];
 
 		int err;
-		if (dblink->makeDatabase(tszProfile, &err) == 0) {
-			dbCreated = true;
-			if ( !dblink->Load(tszProfile)) {
+		if (p->makeDatabase(tszProfile, &err) == 0) {
+			if ( !p->Load(tszProfile)) {
 				fillProfileName(tszProfile);
-				res = DBPE_DONE;
+				return 0;
 			}
-			else res = DBPE_HALT;
+			return 1;
 		}
 	}
-	return res;
+	return 1;
 }
 
 typedef struct {
@@ -514,28 +512,24 @@ int LoadDatabaseModule(void)
 	if ( !getProfile(szProfile, SIZEOF(szProfile)))
 		return 1;
 
-	pfnDbEnumCallback pFunc;
-	if (_taccess(szProfile, 0) && shouldAutoCreate(szProfile))
-		pFunc = FindDbPluginAutoCreate;
-	else
-		pFunc = FindDbPluginForProfile;
+	if ( arDbPlugins.getCount() == 0) {
+		TCHAR buf[256];
+		TCHAR* p = _tcsrchr(szProfile, '\\');
+		mir_sntprintf(buf, SIZEOF(buf), TranslateT("Miranda is unable to open '%s' because you do not have any profile plugins installed.\nYou need to install dbx_3x.dll or equivalent."), p ? ++p : szProfile);
+		MessageBox(0, buf, TranslateT("No profile support installed!"), MB_OK | MB_ICONERROR);
+	}
 
 	// find a driver to support the given profile	
 	bool retry;
 	int rc;
 	do {
 		retry = false;
-		rc = enumDbPlugins(pFunc, (LPARAM)szProfile);
-		switch (rc) {
-		case -1: {
-			// no plugins at all
-			TCHAR buf[256];
-			TCHAR* p = _tcsrchr(szProfile, '\\');
-			mir_sntprintf(buf, SIZEOF(buf), TranslateT("Miranda is unable to open '%s' because you do not have any profile plugins installed.\nYou need to install dbx_3x.dll or equivalent."), p ? ++p : szProfile);
-			MessageBox(0, buf, TranslateT("No profile support installed!"), MB_OK | MB_ICONERROR);
-			break;
-		}
-		case 1:
+		if ( _taccess(szProfile, 0) && shouldAutoCreate(szProfile))
+			rc = tryCreateDatabase(szProfile);
+		else
+			rc = tryOpenDatabase(szProfile);
+
+		if (rc != 0) {
 			// if there were drivers but they all failed cos the file is locked, try and find the miranda which locked it
 			if (fileExist(szProfile)) {
 				// file isn't locked, just no driver could open it.
diff --git a/src/modules/database/dbintf.cpp b/src/modules/database/dbintf.cpp
index c3bf4f3b5c..2f7cf4ea72 100644
--- a/src/modules/database/dbintf.cpp
+++ b/src/modules/database/dbintf.cpp
@@ -23,7 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "..\..\core\commonheaders.h"
 
-MIDatabase* currDb = NULL;
+MIDatabase *currDb = NULL;
+DATABASELINK *currDblink = NULL;
 
 MIR_CORE_DLL(void) db_setCurrent(MIDatabase*);
 
@@ -159,6 +160,34 @@ static INT_PTR srvEnumResidentSettings(WPARAM wParam,LPARAM lParam)
 {	return (currDb) ? (INT_PTR)currDb->EnumResidentSettings((DBMODULEENUMPROC)wParam, (void*)lParam) : 0;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+// Database list
+
+LIST<DATABASELINK> arDbPlugins(5);
+
+static INT_PTR srvRegisterPlugin(WPARAM wParam,LPARAM lParam)
+{
+	DATABASELINK* pPlug = (DATABASELINK*)lParam;
+	if (pPlug == NULL)
+		return 1;
+
+	arDbPlugins.insert(pPlug);
+	return 0;
+}
+
+static INT_PTR srvFindPlugin(WPARAM wParam,LPARAM lParam)
+{
+	for (int i=0; i < arDbPlugins.getCount(); i++) {
+		int error;
+		if (arDbPlugins[i]->grokHeader((TCHAR*)lParam, &error) == ERROR_SUCCESS)
+			return (INT_PTR)arDbPlugins[i];
+	}
+
+	return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 int LoadDbintfModule()
 {
 	CreateServiceFunction(MS_DB_SETSAFETYMODE, srvSetSafetyMode);
@@ -194,5 +223,8 @@ int LoadDbintfModule()
 	CreateServiceFunction(MS_DB_CONTACT_ENUMSETTINGS, srvEnumContactSettings);
 	CreateServiceFunction(MS_DB_SETSETTINGRESIDENT, srvSetSettingResident);
 	CreateServiceFunction("DB/ResidentSettings/Enum", srvEnumResidentSettings);
+
+	CreateServiceFunction(MS_DB_REGISTER_PLUGIN, srvRegisterPlugin);
+	CreateServiceFunction(MS_DB_FIND_PLUGIN, srvFindPlugin);
 	return 0;
 }
diff --git a/src/modules/database/profilemanager.cpp b/src/modules/database/profilemanager.cpp
index 4e8ebc381f..6ca3206574 100644
--- a/src/modules/database/profilemanager.cpp
+++ b/src/modules/database/profilemanager.cpp
@@ -115,20 +115,6 @@ static LRESULT CALLBACK ProfileNameValidate(HWND edit, UINT msg, WPARAM wParam,
 	return CallWindowProc((WNDPROC)GetWindowLongPtr(edit, GWLP_USERDATA), edit, msg, wParam, lParam);
 }
 
-static int FindDbProviders(const TCHAR* tszProfileName, DATABASELINK *dblink, LPARAM lParam)
-{
-	HWND hwndDlg = (HWND)lParam;
-	HWND hwndCombo = GetDlgItem(hwndDlg, IDC_PROFILEDRIVERS);
-	TCHAR szName[64];
-
-	if (dblink->getFriendlyName(szName, SIZEOF(szName), 1) == 0) {
-		// add to combo box
-		LRESULT index = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)szName);
-		SendMessage(hwndCombo, CB_SETITEMDATA, index, (LPARAM)dblink);
-	}
-	return DBPE_CONT;
-}
-
 static INT_PTR CALLBACK DlgProfileNew(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
 	struct DlgProfData * dat = (struct DlgProfData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
@@ -138,18 +124,26 @@ static INT_PTR CALLBACK DlgProfileNew(HWND hwndDlg, UINT msg, WPARAM wParam, LPA
 		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
 		dat = (struct DlgProfData *)lParam;
 		{
-			// fill in the db plugins present
-			if (enumDbPlugins(FindDbProviders, (LPARAM)hwndDlg) == -1) {
-				// what, no plugins?!
-				EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILEDRIVERS), FALSE);
+			HWND hwndCombo = GetDlgItem(hwndDlg, IDC_PROFILEDRIVERS);
+
+			// what, no plugins?!
+			if (arDbPlugins.getCount() == 0) {
+				EnableWindow(hwndCombo, FALSE);
 				EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILENAME), FALSE);
 				ShowWindow(GetDlgItem(hwndDlg, IDC_NODBDRIVERS), TRUE);
 			}
+			else {
+				for (int i=0; i < arDbPlugins.getCount(); i++) {
+					DATABASELINK* p = arDbPlugins[i];
+					LRESULT index = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)TranslateTS(p->szFullName));
+					SendMessage(hwndCombo, CB_SETITEMDATA, index, (LPARAM)p);
+				}
+			}
+
 			// default item
-			SendDlgItemMessage(hwndDlg, IDC_PROFILEDRIVERS, CB_SETCURSEL, 0, 0);
-		}
-		// subclass the profile name box
-		{
+			SendMessage(hwndCombo, CB_SETCURSEL, 0, 0);
+
+			// subclass the profile name box
 			HWND hwndProfile = GetDlgItem(hwndDlg, IDC_PROFILENAME);
 			WNDPROC proc = (WNDPROC)GetWindowLongPtr(hwndProfile, GWLP_WNDPROC);
 			SetWindowLongPtr(hwndProfile, GWLP_USERDATA, (LONG_PTR)proc);
@@ -157,8 +151,7 @@ static INT_PTR CALLBACK DlgProfileNew(HWND hwndDlg, UINT msg, WPARAM wParam, LPA
 		}
 
 		// decide if there is a default profile name given in the INI and if it should be used
-		if (dat->pd->noProfiles || (shouldAutoCreate(dat->pd->szProfile) && _taccess(dat->pd->szProfile, 0))) 
-		{
+		if (dat->pd->noProfiles || (shouldAutoCreate(dat->pd->szProfile) && _taccess(dat->pd->szProfile, 0))) {
 			TCHAR* profile = _tcsrchr(dat->pd->szProfile, '\\');
 			if (profile) ++profile;
 			else profile = dat->pd->szProfile;
@@ -216,21 +209,6 @@ static INT_PTR CALLBACK DlgProfileNew(HWND hwndDlg, UINT msg, WPARAM wParam, LPA
 	return FALSE;
 }
 
-static int DetectDbProvider(const TCHAR*, DATABASELINK * dblink, LPARAM lParam)
-{
-	int error;
-	int ret = dblink->grokHeader((TCHAR*)lParam, &error);
-	if (ret == 0) {
-
-		TCHAR tmp[ MAX_PATH ];
-		dblink->getFriendlyName(tmp, SIZEOF(tmp), 1);
-		_tcsncpy((TCHAR*)lParam, tmp, MAX_PATH);
-		return DBPE_HALT;
-	}
-
-	return DBPE_CONT;
-}
-
 BOOL EnumProfilesForList(TCHAR *fullpath, TCHAR *profile, LPARAM lParam)
 {
 	ProfileEnumData *ped = (ProfileEnumData*)lParam;
@@ -260,7 +238,6 @@ BOOL EnumProfilesForList(TCHAR *fullpath, TCHAR *profile, LPARAM lParam)
 			_tcscpy(sizeBuf+5, _T(" KB"));
 		}
 		bFileExists = TRUE;
-
 		bFileLocked = !fileExist(fullpath);
 	}
 
@@ -283,7 +260,8 @@ BOOL EnumProfilesForList(TCHAR *fullpath, TCHAR *profile, LPARAM lParam)
 		item2.mask = LVIF_TEXT;
 		item2.iItem = iItem;
 
-		if ( enumDbPlugins(DetectDbProvider, (LPARAM)szPath) == 1) {
+		DATABASELINK* dblink = FindDatabasePlugin(szPath);
+		if (dblink != NULL) {
 			if (bFileLocked) {
 				// file locked
 				item2.pszText = TranslateT("<In Use>");
@@ -291,10 +269,11 @@ BOOL EnumProfilesForList(TCHAR *fullpath, TCHAR *profile, LPARAM lParam)
 				SendMessage(hwndList, LVM_SETITEMTEXT, iItem, (LPARAM)&item2);
 			}
 			else {
-				item.pszText = szPath;
+				item.pszText = TranslateTS(dblink->szFullName);
 				item.iSubItem = 1;
 				SendMessage(hwndList, LVM_SETITEMTEXT, iItem, (LPARAM)&item);
-		}	}
+			}
+		}
 
 		item2.iSubItem = 3;
 		item2.pszText = trtrim(_tctime(&statbuf.st_ctime));
diff --git a/src/modules/database/profilemanager.h b/src/modules/database/profilemanager.h
index 64e4960fdc..e3ed554e56 100644
--- a/src/modules/database/profilemanager.h
+++ b/src/modules/database/profilemanager.h
@@ -42,14 +42,3 @@ bool shouldAutoCreate(TCHAR *szProfile);
 
 extern TCHAR g_profileDir[MAX_PATH];
 extern TCHAR g_profileName[MAX_PATH];
-
-///////////////////////////////////////////////////////////////////////////////
-// former m_plugins.h
-
-#define DBPE_DONE 1
-#define DBPE_CONT 0
-#define DBPE_HALT (-1)
-
-typedef int (*pfnDbEnumCallback) (const TCHAR *pluginname, DATABASELINK* link, LPARAM lParam);
-
-int enumDbPlugins(pfnDbEnumCallback pFunc, LPARAM lParam);
diff --git a/src/modules/plugins/dll_sniffer.cpp b/src/modules/plugins/dll_sniffer.cpp
index 469cebf931..531c9e6919 100644
--- a/src/modules/plugins/dll_sniffer.cpp
+++ b/src/modules/plugins/dll_sniffer.cpp
@@ -42,7 +42,7 @@ MUUID* GetPluginInterfaces(const TCHAR* ptszFileName, bool& bIsPlugin)
 
 	MUUID* pResult = NULL;
 	BYTE* ptr = NULL;
-	HANDLE hMap = CreateFileMapping( hFile, NULL, PAGE_WRITECOPY, 0, 0, NULL );
+	HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL );
 
 	__try
 	{
diff --git a/src/modules/plugins/newplugins.cpp b/src/modules/plugins/newplugins.cpp
index 083338614d..ce412e8d34 100644
--- a/src/modules/plugins/newplugins.cpp
+++ b/src/modules/plugins/newplugins.cpp
@@ -76,7 +76,7 @@ static int serviceModeIdx = -1, sttFakeID = -100;
 static HANDLE hPluginListHeap = NULL;
 static int askAboutIgnoredPlugins;
 
-static pluginEntry *pluginListSM, *pluginListDb, *pluginListUI, *pluginList_freeimg, *pluginList_crshdmp;
+static pluginEntry *pluginListSM, *pluginListUI, *pluginList_freeimg, *pluginList_crshdmp;
 
 int  InitIni(void);
 void UninitIni(void);
@@ -197,11 +197,6 @@ static int isPluginBanned(MUUID u1, DWORD dwVersion)
 	return 0;
 }
 
-// returns true if the API exports were good, otherwise, passed in data is returned
-#define CHECKAPI_NONE  0
-#define CHECKAPI_DB    1
-#define CHECKAPI_CLIST 2
-
 /*
  * historyeditor added by nightwish - plugin is problematic and can ruin database as it does not understand UTF-8 message
  * storage
@@ -291,17 +286,6 @@ LBL_Ok:
 		return 1;
 	}
 
-	// check for DB?
-	if (checkTypeAPI == CHECKAPI_DB) {
-		bpi->DbInfo = (Database_Plugin_Info) GetProcAddress(h, "DatabasePluginInfo");
-		if (bpi->DbInfo) {
-			// fetch internal database function pointers
-			bpi->dblink = bpi->DbInfo(NULL);
-			// validate returned link structure
-			if (bpi->dblink && bpi->dblink->cbSize == sizeof(DATABASELINK))
-				goto LBL_Ok;
-	}	}
-
 	// check clist ?
 	if (checkTypeAPI == CHECKAPI_CLIST) {
 		bpi->clistlink = (CList_Initialise) GetProcAddress(h, "CListInitialise");
@@ -316,10 +300,6 @@ LBL_Ok:
 // perform any API related tasks to freeing
 void Plugin_Uninit(pluginEntry* p)
 {
-	// if it was an installed database plugin, call its unload
-	if (p->pclass & PCLASS_DB)
-		p->bpi.dblink->Unload(p->pclass & PCLASS_OK);
-
 	// if the basic API check had passed, call Unload if Load(void) was ever called
 	if (p->pclass & PCLASS_LOADED)
 		p->bpi.Unload();
@@ -406,33 +386,6 @@ void enumPlugins(SCAN_PLUGINS_CALLBACK cb, WPARAM wParam, LPARAM lParam)
 	}
 }
 
-// this is called by the db module to return all DBs plugins, then when it finds the one it likes the others are unloaded
-int enumDbPlugins(pfnDbEnumCallback pFunc, LPARAM lParam)
-{
-	pluginEntry *x = pluginListDb;
-	if (pFunc == NULL)
-		return 1;
-
-	while (x != NULL) {
-		int rc = pFunc(x->pluginname, x->bpi.dblink, lParam);
-		if (rc == DBPE_DONE) {
-			// this db has been picked, get rid of all the others
-			pluginEntry *y = pluginListDb, *n;
-			while (y != NULL) {
-				n = y->nextclass;
-				if (x != y)
-					Plugin_Uninit(y);
-				y = n;
-			} // while
-			x->pclass |= PCLASS_LOADED | PCLASS_OK | PCLASS_LAST;
-			return 0;
-		}
-		else if (rc == DBPE_HALT) return 1;
-		x = x->nextclass;
-	} // while
-	return pluginListDb != NULL ? 1 : -1;
-}
-
 pluginEntry* OpenPlugin(TCHAR *tszFileName, TCHAR *dir, TCHAR *path)
 {
 	pluginEntry* p = (pluginEntry*)HeapAlloc(hPluginListHeap, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, sizeof(pluginEntry));
@@ -455,18 +408,19 @@ pluginEntry* OpenPlugin(TCHAR *tszFileName, TCHAR *dir, TCHAR *path)
 	// plugin declared that it's a database. load it asap!
 	if ( hasMuuid(pIds, miid_database)) {
 		BASIC_PLUGIN_INFO bpi;
-		if (checkAPI(tszFullPath, &bpi, mirandaVersion, CHECKAPI_DB)) {
+		if (checkAPI(tszFullPath, &bpi, mirandaVersion, CHECKAPI_NONE)) {
 			// db plugin is valid
 			p->pclass |= (PCLASS_DB | PCLASS_BASICAPI);
 			// copy the dblink stuff
 			p->bpi = bpi;
-			// keep a faster list.
-			if (pluginListDb != NULL) p->nextclass = pluginListDb;
-			pluginListDb = p;
+
+			RegisterModule(p->bpi.hInst);
+			if (bpi.Load() != 0)
+				p->pclass |= PCLASS_FAILED;
+			else
+				p->pclass |= PCLASS_LOADED;
 		}
-		else
-			// didn't have basic APIs or DB exports - failed.
-			p->pclass |= PCLASS_FAILED;
+		else p->pclass |= PCLASS_FAILED;
 	}
 	// plugin declared that it's a contact list. mark it for the future load
 	else if ( hasMuuid(pIds, miid_clist)) {
@@ -859,6 +813,12 @@ void UnloadNewPluginsModule(void)
 		Plugin_Uninit(pluginList_crshdmp);
 
 	// unload the DB
+	if (currDb != NULL) {
+		db_setCurrent(NULL);
+		currDblink->Unload(currDb);
+		currDb = NULL;
+	}
+
 	for (int k = pluginList.getCount()-1; k >= 0; k--) {
 		pluginEntry* p = pluginList[k];
 		Plugin_Uninit(p);
diff --git a/src/modules/plugins/plugins.h b/src/modules/plugins/plugins.h
index 64118a45ed..e0466ccc35 100644
--- a/src/modules/plugins/plugins.h
+++ b/src/modules/plugins/plugins.h
@@ -1,8 +1,7 @@
 
 // returns true if the API exports were good, otherwise, passed in data is returned
 #define CHECKAPI_NONE 	 0
-#define CHECKAPI_DB 	 1
-#define CHECKAPI_CLIST   2
+#define CHECKAPI_CLIST   1
 
 // block these plugins
 #define DEFMOD_REMOVED_UIPLUGINOPTS     21
@@ -13,8 +12,6 @@ typedef int (__cdecl * Miranda_Plugin_Load) (void);
 typedef int (__cdecl * Miranda_Plugin_Unload) (void);
 // version control
 typedef PLUGININFOEX * (__cdecl * Miranda_Plugin_InfoEx) (DWORD mirandaVersion);
-// prototype for databases
-typedef DATABASELINK * (__cdecl * Database_Plugin_Info) (void * reserved);
 // prototype for clists
 typedef int (__cdecl * CList_Initialise) (void);
 
@@ -25,11 +22,9 @@ struct BASIC_PLUGIN_INFO
 	Miranda_Plugin_Load Load;
 	Miranda_Plugin_Unload Unload;
 	Miranda_Plugin_InfoEx InfoEx;
-	Database_Plugin_Info DbInfo;
 	CList_Initialise clistlink;
 	PLUGININFOEX * pluginInfo;	 // must be freed if hInst = = NULL then its a copy
 	MUUID *Interfaces;          // array of supported interfaces
-	DATABASELINK * dblink;		 // only valid during module being in memory
 };
 
 #define PCLASS_FAILED     0x1   // not a valid plugin, or API is invalid, pluginname is valid
-- 
cgit v1.2.3