summaryrefslogtreecommitdiff
path: root/plugins/Import/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2012-07-24 17:57:46 +0000
committerGeorge Hazan <george.hazan@gmail.com>2012-07-24 17:57:46 +0000
commit9628bd0e796e0713377373863b962e3594204045 (patch)
tree92cc3afab82c75765cf038d00193a1679655d33a /plugins/Import/src
parentf4686842d390f8d5a2231f540c68b177111c7f87 (diff)
new import plugin for Miranda NG
git-svn-id: http://svn.miranda-ng.org/main/trunk@1166 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Import/src')
-rw-r--r--plugins/Import/src/ICQserver.cpp74
-rw-r--r--plugins/Import/src/ICQserver.h62
-rw-r--r--plugins/Import/src/import.cpp497
-rw-r--r--plugins/Import/src/import.h33
-rw-r--r--plugins/Import/src/main.cpp6
-rw-r--r--plugins/Import/src/mirabilis.cpp1493
-rw-r--r--plugins/Import/src/mirabilis.h200
-rw-r--r--plugins/Import/src/miranda.cpp1134
-rw-r--r--plugins/Import/src/mirandadb0700.h142
-rw-r--r--plugins/Import/src/progress.cpp4
-rw-r--r--plugins/Import/src/resource.h7
-rw-r--r--plugins/Import/src/utils.cpp115
-rw-r--r--plugins/Import/src/wizard.cpp59
13 files changed, 576 insertions, 3250 deletions
diff --git a/plugins/Import/src/ICQserver.cpp b/plugins/Import/src/ICQserver.cpp
deleted file mode 100644
index 372c0cb92c..0000000000
--- a/plugins/Import/src/ICQserver.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-
-Import plugin for Miranda IM
-
-Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede
-
-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.
-
-*/
-
-// ==============
-// == INCLUDES ==
-// ==============
-
-#include "import.h"
-
-#include "ICQserver.h"
-#include "resource.h"
-
-// ====================
-// ====================
-// == IMPLEMENTATION ==
-// ====================
-// ====================
-
-BOOL CALLBACK ICQserverPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam)
-{
- switch(message) {
- case WM_INITDIALOG:
- SendMessage(GetParent(hdlg),WIZM_DISABLEBUTTON,0,0);
- SendMessage(GetParent(hdlg),WIZM_ENABLEBUTTON,1,0);
- SendMessage(GetParent(hdlg),WIZM_DISABLEBUTTON,2,0);
- TranslateDialogDefault(hdlg);
- ICQserverImport();
- return TRUE;
-
- case WM_COMMAND:
- switch(LOWORD(wParam)) {
- case IDOK:
- PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_FINISHED,(LPARAM)FinishedPageProc);
- break;
- case IDCANCEL:
- PostMessage(GetParent(hdlg),WM_CLOSE,0,0);
- break;
- }
- break;
- }
- return FALSE;
-}
-
-static void ICQserverImport()
-{
- // Clear last update stamp
- DBDeleteContactSetting(NULL, szICQModuleName[ iICQAccount ], "SrvLastUpdate");
- DBDeleteContactSetting(NULL, szICQModuleName[ iICQAccount ], "SrvRecordCount");
-
- // Enable contacts downloading
- DBWriteContactSettingByte(NULL, szICQModuleName[ iICQAccount ], "UseServerCList", 1);
- DBWriteContactSettingByte(NULL, szICQModuleName[ iICQAccount ], "AddServerNew", 1);
- DBWriteContactSettingByte(NULL, szICQModuleName[ iICQAccount ], "UseServerNicks", 1);
- DBWriteContactSettingByte(NULL, szICQModuleName[ iICQAccount ], "ServerAddRemove", 1);
-}
diff --git a/plugins/Import/src/ICQserver.h b/plugins/Import/src/ICQserver.h
deleted file mode 100644
index 864890a978..0000000000
--- a/plugins/Import/src/ICQserver.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-
-Import plugin for Miranda IM
-
-Copyright (C) 2001,2002,2003,2004 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede
-
-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.
-
-*/
-
-
-
-#ifndef ICQSERVER_H
-#define ICQSERVER_H
-
-#include <windows.h>
-
-// ======================
-// == GLOBAL FUNCTIONS ==
-// ======================
-
-// =====================
-// == LOCAL FUNCTIONS ==
-// =====================
-
-// Main function
-static void ICQserverImport();
-
-// GUI callbacks
-INT_PTR CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
-
-
-// ======================
-// == GLOBAL VARIABLES ==
-// ======================
-
-extern int cICQAccounts;
-extern char ** szICQModuleName;
-extern TCHAR ** tszICQAccountName;
-extern int iICQAccount;
-
-// =====================
-// == LOCAL VARIABLES ==
-// =====================
-
-// =============
-// == DEFINES ==
-// =============
-
-#endif \ No newline at end of file
diff --git a/plugins/Import/src/import.cpp b/plugins/Import/src/import.cpp
new file mode 100644
index 0000000000..fe2c4916bf
--- /dev/null
+++ b/plugins/Import/src/import.cpp
@@ -0,0 +1,497 @@
+/*
+
+Import plugin for Miranda NG
+
+Copyright (C) 2012 George Hazan
+
+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 "import.h"
+#include <m_db_int.h>
+
+time_t dwSinceDate = 0;
+
+HWND hdlgProgress;
+
+static DWORD nDupes, nContactsCount, nMessagesCount, nGroupsCount, nSkippedEvents, nSkippedContacts;
+static MIDatabase *srcDb, *dstDb;
+
+static int myGet(HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv)
+{
+ dbv->type = 0;
+ DBCONTACTGETSETTING dgs = { szModule, szSetting, dbv };
+ return srcDb->GetContactSetting(hContact, &dgs);
+}
+
+static TCHAR* myGetWs(HANDLE hContact, const char *szModule, const char *szSetting)
+{
+ DBVARIANT dbv = { DBVT_TCHAR };
+ DBCONTACTGETSETTING dgs = { szModule, szSetting, &dbv };
+ return ( srcDb->GetContactSettingStr(hContact, &dgs)) ? NULL : dbv.ptszVal;
+}
+
+static char* myGetS(HANDLE hContact, const char *szModule, const char *szSetting)
+{
+ DBVARIANT dbv = { DBVT_ASCIIZ };
+ DBCONTACTGETSETTING dgs = { szModule, szSetting, &dbv };
+ return ( srcDb->GetContactSettingStr(hContact, &dgs)) ? NULL : dbv.pszVal;
+}
+
+void mySet(HANDLE hContact, const char *module, const char *var, DBVARIANT *dbv)
+{
+ DBCONTACTWRITESETTING dbw;
+ dbw.szModule = module;
+ dbw.szSetting = var;
+ dbw.value = *dbv;
+ dstDb->WriteContactSetting(hContact, &dbw);
+}
+
+static int ImportGroup(const char* szSettingName, LPARAM lParam)
+{
+ int* pnGroups = (int*)lParam;
+
+ TCHAR* tszGroup = myGetWs(NULL, "CListGroups", szSettingName);
+ if (tszGroup != NULL) {
+ if ( CreateGroup( tszGroup, NULL ))
+ pnGroups[0]++;
+ mir_free(tszGroup);
+ }
+ return 0;
+}
+
+static int ImportGroups()
+{
+ int nGroups = 0;
+
+ DBCONTACTENUMSETTINGS param = { 0 };
+ param.szModule = "CListGroups";
+ param.pfnEnumProc = ImportGroup;
+ param.lParam = (LPARAM)&nGroups;
+ srcDb->EnumContactSettings(NULL, &param);
+ return nGroups;
+}
+
+HANDLE AddContact(HWND hdlgProgress, char* pszProtoName, char* pszUniqueSetting, DBVARIANT* id, TCHAR *nick, TCHAR *group)
+{
+ HANDLE hContact;
+ char szid[ 40 ];
+ char* pszUserID = ( id->type == DBVT_DWORD ) ? _ltoa( id->dVal, szid, 10 ) : id->pszVal;
+
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_ADD, 0, 0);
+ if ( CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)pszProtoName) != 0) {
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0);
+ AddMessage( LPGEN("Failed to add %s contact %s"), pszProtoName, pszUserID );
+ srcDb->FreeVariant( id );
+ return INVALID_HANDLE_VALUE;
+ }
+
+ mySet( hContact, pszProtoName, pszUniqueSetting, id );
+
+ CreateGroup(group, hContact);
+
+ if (nick && *nick) {
+ db_set_ws(hContact, "CList", "MyHandle", nick );
+ AddMessage( LPGEN("Added %s contact %s, '%S'"), pszProtoName, pszUserID, nick);
+ }
+ else AddMessage( LPGEN("Added %s contact %s"), pszProtoName, pszUserID);
+
+ srcDb->FreeVariant( id );
+ return hContact;
+}
+
+static HANDLE ImportContact(HANDLE hSrc)
+{
+ HANDLE hDst;
+ char* pszUserName;
+ char id[ 40 ];
+
+ // Check what protocol this contact belongs to
+ mir_ptr<char> pszProtoName( myGetS(hSrc, "Protocol", "p"));
+ if ( !pszProtoName) {
+ AddMessage( LPGEN("Skipping contact with no protocol"));
+ return NULL;
+ }
+
+ if ( !IsProtocolLoaded(pszProtoName)) {
+ AddMessage( LPGEN("Skipping contact, %s not installed."), pszProtoName);
+ return NULL;
+ }
+
+ // Skip protocols with no unique id setting (some non IM protocols return NULL)
+ char* pszUniqueSetting = (char*)CallProtoService(pszProtoName, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
+ if ( !pszUniqueSetting || (INT_PTR)pszUniqueSetting == CALLSERVICE_NOTFOUND ) {
+ AddMessage( LPGEN("Skipping non-IM contact (%s)"), pszProtoName );
+ return NULL;
+ }
+
+ DBVARIANT dbv;
+ if ( myGet(hSrc, pszProtoName, pszUniqueSetting, &dbv)) {
+ AddMessage( LPGEN("Skipping %s contact, ID not found"), pszProtoName);
+ return NULL;
+ }
+
+ // Does the contact already exist?
+ if ( dbv.type == DBVT_DWORD ) {
+ pszUserName = _ltoa(dbv.dVal, id, 10);
+ hDst = HContactFromNumericID( pszProtoName, pszUniqueSetting, dbv.dVal );
+ }
+ else {
+ pszUserName = NEWSTR_ALLOCA(dbv.pszVal);
+ hDst = HContactFromID( pszProtoName, pszUniqueSetting, dbv.pszVal );
+ }
+
+ if (hDst != INVALID_HANDLE_VALUE) {
+ AddMessage( LPGEN("Skipping duplicate %s contact %s"), pszProtoName, pszUserName );
+ srcDb->FreeVariant( &dbv );
+ return NULL;
+ }
+
+ TCHAR *tszGroup = myGetWs(hSrc, "CList", "Group"), *tszNick = myGetWs(hSrc, "CList", "MyHandle");
+ if (tszNick == NULL)
+ tszNick = myGetWs(hSrc, pszProtoName, "Nick");
+
+ hDst = AddContact(hdlgProgress, pszProtoName, pszUniqueSetting, &dbv, tszNick, tszGroup);
+ mir_free(tszGroup), mir_free(tszNick);
+
+ if ( hDst != INVALID_HANDLE_VALUE) {
+ // Hidden?
+ if ( myGet(hSrc, "CList", "Hidden", &dbv )) {
+ mySet(hDst, "CList", "Hidden", &dbv);
+ srcDb->FreeVariant(&dbv);
+ }
+
+ // Ignore settings
+ if ( myGet(hSrc, "Ignore", "Mask1", &dbv )) {
+ mySet( hDst, "Ignore", "Mask1", &dbv );
+ srcDb->FreeVariant(&dbv);
+ }
+
+ // Apparent mode
+ if ( myGet(hSrc, pszProtoName, "ApparentMode", &dbv )) {
+ mySet( hDst, pszProtoName, "ApparentMode", &dbv );
+ srcDb->FreeVariant(&dbv);
+ }
+
+ // Nick
+ if ( myGet(hSrc, pszProtoName, "Nick", &dbv )) {
+ mySet( hDst, pszProtoName, "Nick", &dbv );
+ srcDb->FreeVariant(&dbv);
+ }
+
+ // Myhandle
+ if ( myGet(hSrc, pszProtoName, "MyHandle", &dbv )) {
+ mySet( hDst, pszProtoName, "MyHandle", &dbv );
+ srcDb->FreeVariant(&dbv);
+ }
+
+ // First name
+ if ( myGet(hSrc, pszProtoName, "FirstName", &dbv )) {
+ mySet( hDst, pszProtoName, "FirstName", &dbv );
+ srcDb->FreeVariant(&dbv);
+ }
+
+ // Last name
+ if ( myGet(hSrc, pszProtoName, "LastName", &dbv )) {
+ mySet( hDst, pszProtoName, "LastName", &dbv );
+ srcDb->FreeVariant(&dbv);
+ }
+
+ // About
+ if ( myGet(hSrc, pszProtoName, "About", &dbv )) {
+ mySet( hDst, pszProtoName, "About", &dbv );
+ srcDb->FreeVariant(&dbv);
+ }
+ }
+ else AddMessage( LPGEN("Unknown error while adding %s contact %s"), pszProtoName, pszUserName );
+
+ return hDst;
+}
+
+// This function should always be called after contact import. That is
+// why there are no messages for errors related to contacts. Those
+// would only be a repetition of the messages printed during contact
+// import.
+
+static void ImportHistory(HANDLE hContact, PROTOACCOUNT **protocol, int protoCount)
+{
+ HANDLE hDst = INVALID_HANDLE_VALUE;
+
+ // Is it contats history import?
+ if (protoCount == 0) {
+ // Check what protocol this contact belongs to
+ char* szProto = myGetS(hContact, "Protocol", "p");
+ if (szProto != NULL) {
+ // Protocol installed?
+ if ( IsProtocolLoaded(szProto)) {
+ // Is contact in database?
+ char* pszUniqueSetting = (char*)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
+
+ // Skip protocols with no unique id setting (some non IM protocols return NULL)
+ if ( pszUniqueSetting && ( INT_PTR )pszUniqueSetting != CALLSERVICE_NOTFOUND ) {
+ DBVARIANT dbv;
+ if ( myGet(hContact, szProto, pszUniqueSetting, &dbv)) {
+ if ( dbv.type == DBVT_DWORD )
+ hDst = HContactFromNumericID(szProto, pszUniqueSetting, dbv.dVal);
+ else
+ hDst = HContactFromID(szProto, pszUniqueSetting, dbv.pszVal);
+ srcDb->FreeVariant( &dbv );
+ } } }
+
+ mir_free(szProto);
+ }
+ }
+ else hDst = NULL; //system history import
+
+ // OK to import this chain?
+ if (hDst == INVALID_HANDLE_VALUE) {
+ nSkippedContacts++;
+ return;
+ }
+
+ int i = 0, skipAll = 0;
+ bool bIsVoidContact = dstDb->GetEventCount(hDst) == 0;
+
+ // Get the start of the event chain
+ HANDLE hEvent = srcDb->FindFirstEvent(hContact);
+ while (hEvent) {
+ int skip = 0;
+
+ // Copy the event and import it
+ DBEVENTINFO dbei = { 0 };
+ if ( !srcDb->GetEvent(hEvent, &dbei)) {
+ // check protocols during system history import
+ if (hDst == NULL) {
+ skipAll = 1;
+ for (int i = 0; i < protoCount; i++)
+ if ( !strcmp(dbei.szModule, protocol[i]->szModuleName)) {
+ skipAll = 0;
+ break;
+ }
+
+ skip = skipAll;
+ }
+
+ // custom filtering
+ if (!skip && nImportOption == IMPORT_CUSTOM) {
+ BOOL sent = (dbei.flags & DBEF_SENT);
+
+ if (dbei.timestamp < (DWORD)dwSinceDate)
+ skip = 1;
+
+ if (!skip) {
+ if (hDst) {
+ skip = 1;
+ switch(dbei.eventType) {
+ case EVENTTYPE_MESSAGE:
+ if ((sent ? IOPT_MSGSENT : IOPT_MSGRECV) & nCustomOptions)
+ skip = 0;
+ break;
+ case EVENTTYPE_FILE:
+ if ((sent ? IOPT_FILESENT : IOPT_FILERECV) & nCustomOptions)
+ skip = 0;
+ break;
+ case EVENTTYPE_URL:
+ if ((sent ? IOPT_URLSENT : IOPT_URLRECV) & nCustomOptions)
+ skip = 0;
+ break;
+ default:
+ if ((sent ? IOPT_OTHERSENT : IOPT_OTHERRECV) & nCustomOptions)
+ skip = 0;
+ break;
+ }
+ }
+ else if ( !( nCustomOptions & IOPT_SYSTEM ))
+ skip = 1;
+ }
+
+ if (skip)
+ nSkippedEvents++;
+ }
+
+ if (!skip) {
+ // Check for duplicate entries
+ if ( !IsDuplicateEvent( hDst, dbei )) {
+ // Add dbevent
+ if (!bIsVoidContact)
+ dbei.flags &= ~DBEF_FIRST;
+ if (dstDb->AddEvent(hDst, &dbei) != NULL)
+ nMessagesCount++;
+ else
+ AddMessage( LPGEN("Failed to add message"));
+ }
+ else
+ nDupes++;
+ }
+ }
+
+ if ( !( i%10 )) {
+ MSG msg;
+ if ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ } }
+
+ // skip this chain if needed
+ if ( skipAll )
+ break;
+
+ // Get next event
+ hEvent = srcDb->FindNextEvent(hEvent);
+ i++;
+ }
+}
+
+void MirandaImport(HWND hdlg)
+{
+ DWORD dwTimer;
+ char* pszModuleName = NULL;
+
+ // Just to keep the macros happy
+ hdlgProgress = hdlg;
+ if ((dstDb = GetCurrentDatabase()) == NULL) {
+ AddMessage( LPGEN("Error retrieving current profile, exiting."));
+ return;
+ }
+
+ DATABASELINK* dblink = FindDatabasePlugin(importFile);
+ if (dblink == NULL) {
+ AddMessage( LPGEN("There's no database driver to open the input file, exiting."));
+ return;
+ }
+
+ if ((srcDb = dblink->Load(importFile)) == NULL) {
+ AddMessage( LPGEN("Error loading source file, exiting."));
+ return;
+ }
+
+ // Reset statistics
+ nSkippedEvents = 0;
+ nDupes = 0;
+ nContactsCount = 0;
+ nMessagesCount = 0;
+ nGroupsCount = 0;
+ nSkippedContacts = 0;
+ SetProgress(0);
+
+ // Get number of contacts
+ int nNumberOfContacts = srcDb->GetContactCount();
+ AddMessage( LPGEN("Number of contacts in database: %d"), nNumberOfContacts );
+ AddMessage( "" );
+
+ // Configure database for fast writing
+ dstDb->SetCacheSafetyMode(FALSE);
+
+ // Start benchmark timer
+ dwTimer = time(NULL);
+
+ // Import Groups
+ if (nImportOption == IMPORT_ALL || (nCustomOptions & IOPT_GROUPS)) {
+ AddMessage( LPGEN("Importing groups."));
+ nGroupsCount = ImportGroups();
+ if (nGroupsCount == -1)
+ AddMessage( LPGEN("Group import failed."));
+
+ AddMessage( "" );
+ }
+ // End of Import Groups
+
+ // Import Contacts
+ if (nImportOption != IMPORT_CUSTOM || (nCustomOptions & IOPT_CONTACTS)) {
+ AddMessage( LPGEN("Importing contacts."));
+ int i = 1;
+ HANDLE hContact = srcDb->FindFirstContact();
+ while (hContact != NULL) {
+ if ( ImportContact(hContact))
+ nContactsCount++;
+
+ // Update progress bar
+ SetProgress(100 * i / nNumberOfContacts);
+ i++;
+
+ // Process queued messages
+ MSG msg;
+ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ // Get next contact in chain
+ hContact = srcDb->FindNextContact(hContact);
+ }
+ }
+ else AddMessage( LPGEN("Skipping new contacts import."));
+ AddMessage( "" );
+ // End of Import Contacts
+
+ // Import history
+ if (nImportOption != IMPORT_CONTACTS) {
+ // Import NULL contact message chain
+ if (nImportOption == IMPORT_ALL || (nCustomOptions & IOPT_SYSTEM)) {
+ AddMessage( LPGEN("Importing system history."));
+
+ int protoCount;
+ PROTOACCOUNT **accs;
+ CallService(MS_PROTO_ENUMACCOUNTS, (WPARAM)&protoCount, (LPARAM)&accs);
+
+ if (protoCount > 0)
+ ImportHistory(NULL, accs, protoCount);
+ }
+ else AddMessage( LPGEN("Skipping system history import."));
+
+ AddMessage( "" );
+
+ // Import other contact messages
+ if (nImportOption == IMPORT_ALL || (nCustomOptions & 2046)) { // 2 - 1024 types
+ AddMessage( LPGEN("Importing history."));
+ HANDLE hContact = srcDb->FindFirstContact();
+ for(int i=1; hContact != NULL; i++) {
+ ImportHistory(hContact, NULL, NULL);
+
+ SetProgress(100 * i / nNumberOfContacts);
+ hContact = srcDb->FindNextContact(hContact);
+ }
+ }
+ else AddMessage( LPGEN("Skipping history import."));
+
+ AddMessage( "" );
+ }
+ // End of Import History
+
+ // Restore database writing mode
+ dstDb->SetCacheSafetyMode(TRUE);
+
+ // Clean up before exit
+ dblink->Unload(srcDb);
+
+ // Stop timer
+ dwTimer = time(NULL) - dwTimer;
+
+ // Print statistics
+ AddMessage( LPGEN("Import completed in %d seconds."), dwTimer );
+ SetProgress(100);
+ AddMessage((nImportOption == IMPORT_CONTACTS) ?
+ LPGEN("Added %d contacts and %d groups.") : LPGEN("Added %d contacts, %d groups and %d events."),
+ nContactsCount, nGroupsCount, nMessagesCount);
+
+ if ( nImportOption != IMPORT_CONTACTS ) {
+ if (nSkippedContacts)
+ AddMessage( LPGEN("Skipped %d contacts."), nSkippedContacts );
+
+ AddMessage((nImportOption == IMPORT_CUSTOM) ?
+ LPGEN("Skipped %d duplicates and %d filtered events.") : LPGEN("Skipped %d duplicates."),
+ nDupes, nSkippedEvents);
+ }
+}
diff --git a/plugins/Import/src/import.h b/plugins/Import/src/import.h
index f0d9b022bd..43effb7a0f 100644
--- a/plugins/Import/src/import.h
+++ b/plugins/Import/src/import.h
@@ -1,8 +1,8 @@
/*
-Import plugin for Miranda IM
+Import plugin for Miranda NG
-Copyright (C) 2001,2002,2003,2004 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede
+Copyright (C) 2012 George Hazan
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -45,6 +45,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <newpluginapi.h>
#include <m_langpack.h>
#include <m_system.h>
+#include <m_system_cpp.h>
#include <m_database.h>
#include <m_protocols.h>
#include <m_protosvc.h>
@@ -101,11 +102,29 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
void AddMessage( const char* fmt, ... );
-void FreeVariant( DBVARIANT* dbv );
-void WriteVariant( HANDLE hContact, const char* module, const char* var, DBVARIANT* dbv );
+void mySet( HANDLE hContact, const char* module, const char* var, DBVARIANT* dbv );
-int CreateGroup(BYTE type, const char* name, HANDLE hContact);
+INT_PTR CALLBACK WizardIntroPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK ProgressPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
+INT_PTR CALLBACK MirandaPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK MirandaOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
+INT_PTR CALLBACK MirandaAdvOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
+INT_PTR CALLBACK FinishedPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
-extern HWND hdlgProgress;
+HANDLE HContactFromNumericID(char* pszProtoName, char* pszSetting, DWORD dwID);
+HANDLE HContactFromID(char* pszProtoName, char* pszSetting, char* pszID);
+
+HANDLE AddContact(HWND hdlgProgress, char* pszProtoName, char* pszUniqueSetting, DBVARIANT* id, TCHAR *nick, TCHAR *group);
+
+BOOL IsProtocolLoaded(char* pszProtocolName);
+BOOL IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei);
-extern DWORD nDupes, nContactsCount, nMessagesCount, nGroupsCount, nSkippedEvents, nSkippedContacts;
+int CreateGroup(const TCHAR* name, HANDLE hContact);
+
+extern HINSTANCE hInst;
+extern HWND hdlgProgress;
+extern void (*DoImport)(HWND);
+extern int nImportOption;
+extern int nCustomOptions;
+extern TCHAR importFile[];
+extern time_t dwSinceDate;
diff --git a/plugins/Import/src/main.cpp b/plugins/Import/src/main.cpp
index 89d3320d32..13f4f8f315 100644
--- a/plugins/Import/src/main.cpp
+++ b/plugins/Import/src/main.cpp
@@ -1,8 +1,8 @@
/*
-Import plugin for Miranda IM
+Import plugin for Miranda NG
-Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede
+Copyright (C) 2012 George Hazan
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -32,7 +32,7 @@ int nCustomOptions;
static HANDLE hImportService = NULL;
HINSTANCE hInst;
-DLGPROC WizardDlgProc;
+INT_PTR CALLBACK WizardDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
static HWND hwndWizard = NULL;
int hLangpack;
diff --git a/plugins/Import/src/mirabilis.cpp b/plugins/Import/src/mirabilis.cpp
deleted file mode 100644
index 1f032827af..0000000000
--- a/plugins/Import/src/mirabilis.cpp
+++ /dev/null
@@ -1,1493 +0,0 @@
-/*
-
-Import plugin for Miranda IM
-
-Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede
-
-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.
-
-*/
-
-// ==============
-// == INCLUDES ==
-// ==============
-
-#include "import.h"
-#include "mirabilis.h"
-#include "resource.h"
-
-BOOL IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei);
-BOOL IsProtocolLoaded(char* pszProtocolName);
-HANDLE HContactFromNumericID(char* pszProtoName, char* pszSetting, DWORD dwID);
-HANDLE AddContact(HWND hdlgProgress, char* pszProtoName, char* pszUniqueSetting, DBVARIANT* id, DBVARIANT* nick, DBVARIANT* group);
-
-// ====================
-// ====================
-// == IMPLEMENTATION ==
-// ====================
-// ====================
-
-static void SearchForDatabases(HWND hdlg, const TCHAR *dbPath, const TCHAR *type)
-{
- HANDLE hFind;
- WIN32_FIND_DATA fd;
- TCHAR szSearchPath[MAX_PATH];
- TCHAR szRootName[MAX_PATH],*str2;
-
- int i;
-
- wsprintf(szSearchPath, _T("%s\\*.idx"), dbPath);
- hFind=FindFirstFile(szSearchPath,&fd);
- if(hFind!=INVALID_HANDLE_VALUE) {
- do {
- lstrcpy(szRootName,fd.cFileName);
- str2=_tcsrchr(szRootName,'.');
- if(str2!=NULL) *str2=0;
- if(lstrlen(szRootName)>3 && !lstrcmpi(szRootName+lstrlen(szRootName)-3,_T("tmp")))
- continue;
- lstrcat(szRootName,type);
- i=SendDlgItemMessage(hdlg,IDC_LIST,LB_ADDSTRING,0,(LPARAM)szRootName);
- str2 = (TCHAR*)mir_alloc((lstrlen(dbPath) + 2+lstrlen(fd.cFileName))*sizeof(TCHAR));
- wsprintf(str2, _T("%s\\%s"), dbPath, fd.cFileName);
- SendDlgItemMessage(hdlg,IDC_LIST,LB_SETITEMDATA,i,(LPARAM)str2);
- }
- while( FindNextFile( hFind, &fd ));
-
- FindClose(hFind);
- }
-}
-
-INT_PTR CALLBACK MirabilisPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam)
-{
- switch(message) {
- case WM_INITDIALOG:
- {
- HKEY hKey;
- LONG lResult;
- int i;
- TranslateDialogDefault(hdlg);
- if (ERROR_SUCCESS != (lResult = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Mirabilis\\ICQ\\DefaultPrefs"), 0, KEY_QUERY_VALUE, &hKey)))
- lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Mirabilis\\ICQ\\DefaultPrefs"), 0, KEY_QUERY_VALUE, &hKey);
-
- if (lResult == ERROR_SUCCESS) {
- TCHAR dbPath[MAX_PATH];
- DWORD cch;
- cch=sizeof(dbPath);
- if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("New Database"),NULL,NULL,(LPBYTE)dbPath,&cch))
- SearchForDatabases(hdlg,dbPath,_T(" (99a)"));
- cch=sizeof(dbPath);
- if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("99b Database"),NULL,NULL,(LPBYTE)dbPath,&cch))
- SearchForDatabases(hdlg,dbPath,_T(" (99b)"));
- cch=sizeof(dbPath);
- if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2000a Database"),NULL,NULL,(LPBYTE)dbPath,&cch))
- SearchForDatabases(hdlg,dbPath,_T(" (2000a)"));
- cch=sizeof(dbPath);
- if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2000b Database"),NULL,NULL,(LPBYTE)dbPath,&cch))
- SearchForDatabases(hdlg,dbPath,_T(" (2000b)"));
- cch=sizeof(dbPath);
- if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2001a Database"),NULL,NULL,(LPBYTE)dbPath,&cch))
- SearchForDatabases(hdlg,dbPath,_T(" (2001a)"));
- cch=sizeof(dbPath);
- if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2001b Database"),NULL,NULL,(LPBYTE)dbPath,&cch))
- SearchForDatabases(hdlg,dbPath,_T(" (2001b)"));
- cch=sizeof(dbPath);
- if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2002a Database"),NULL,NULL,(LPBYTE)dbPath,&cch))
- SearchForDatabases(hdlg,dbPath,_T(" (2002a)"));
- cch=sizeof(dbPath);
- if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2003a Database"),NULL,NULL,(LPBYTE)dbPath,&cch))
- SearchForDatabases(hdlg,dbPath,_T(" (2003a)"));
- }
-
- for (i = 0; i < cICQAccounts; i++)
- {
- SendDlgItemMessage(hdlg, IDC_MIRABILISACCOUNT, CB_ADDSTRING, 0, (LPARAM)tszICQAccountName[i]);
- }
- SendDlgItemMessage(hdlg, IDC_MIRABILISACCOUNT, CB_SETCURSEL, 0, 0);
-
- SetTimer(hdlg,1,2000,NULL);
- SendMessage(hdlg,WM_TIMER,0,0);
- return TRUE;
- }
- case WM_TIMER:
- { HANDLE hMirabilisMutex;
- hMirabilisMutex=OpenMutexA(MUTEX_ALL_ACCESS,FALSE,"Mirabilis ICQ Mutex");
- if(hMirabilisMutex!=NULL) {
- CloseHandle(hMirabilisMutex);
- ShowWindow(GetDlgItem(hdlg,IDC_MIRABILISRUNNING),SW_SHOW);
- }
- else ShowWindow(GetDlgItem(hdlg,IDC_MIRABILISRUNNING),SW_HIDE);
- }
- break;
- case WM_COMMAND:
- switch(LOWORD(wParam)) {
- case IDC_BACK:
- PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_IMPORTTYPE,(LPARAM)ImportTypePageProc);
- break;
- case IDOK:
- { TCHAR filename[MAX_PATH];
- GetDlgItemText(hdlg,IDC_FILENAME,filename,SIZEOF(filename));
- if(_taccess(filename,4)) {
- MessageBox(hdlg,TranslateT("The given file does not exist. Please check that you have entered the name correctly."),TranslateT("Mirabilis Import"),MB_OK);
- break;
- }
- lstrcpy(importFile,filename);
- iICQAccount = SendDlgItemMessage(hdlg, IDC_MIRABILISACCOUNT, CB_GETCURSEL, 0, 0);
- PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_OPTIONS,(LPARAM)MirabilisOptionsPageProc);
- break;
- }
- case IDCANCEL:
- PostMessage(GetParent(hdlg),WM_CLOSE,0,0);
- break;
- case IDC_LIST:
- if(HIWORD(wParam)==LBN_SELCHANGE) {
- int sel=SendDlgItemMessage(hdlg,IDC_LIST,LB_GETCURSEL,0,0);
- if(sel==LB_ERR) break;
- SetDlgItemText(hdlg,IDC_FILENAME,(TCHAR*)SendDlgItemMessage(hdlg,IDC_LIST,LB_GETITEMDATA,sel,0));
- }
- break;
- case IDC_OTHER:
- { OPENFILENAME ofn;
- TCHAR str[MAX_PATH], text[256];
- int index;
-
- // TranslateTS doesnt translate \0 separated strings
- index = mir_sntprintf(text, 64, _T("%s (*.idx)"), TranslateT("Mirabilis ICQ database indexes")) + 1;
- _tcscpy(text + index, _T("*.idx")); index += 6;
- index += mir_sntprintf(text + index, 64, _T("%s (*.*)"), TranslateT("All Files")) + 1;
- _tcscpy(text + index, _T("*.*")); index += 4;
- text[index] = 0;
-
- GetDlgItemText(hdlg,IDC_FILENAME,str,SIZEOF(str));
- ZeroMemory(&ofn, sizeof(ofn));
- ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
- ofn.hwndOwner = hdlg;
- ofn.lpstrFilter = text;
- ofn.lpstrFile = str;
- ofn.Flags = OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_DONTADDTORECENT;
- ofn.nMaxFile = SIZEOF(str);
- ofn.lpstrDefExt = _T("idx");
- if(GetOpenFileName(&ofn))
- SetDlgItemText(hdlg,IDC_FILENAME,str);
- break;
- }
- }
- break;
-
- case WM_DESTROY:
- { int i;
- for(i=SendDlgItemMessage(hdlg,IDC_LIST,LB_GETCOUNT,0,0)-1;i>=0;i--)
- mir_free((char*)SendDlgItemMessage(hdlg,IDC_LIST,LB_GETITEMDATA,i,0));
- break;
- }
- }
- return FALSE;
-}
-
-
-INT_PTR CALLBACK MirabilisOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam)
-{
- switch(message) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hdlg);
- EnableWindow(GetDlgItem(hdlg, IDC_RADIO_ALL), TRUE);
- EnableWindow(GetDlgItem(hdlg, IDC_STATIC_ALL), TRUE);
- EnableWindow(GetDlgItem(hdlg, IDC_RADIO_CONTACTS), TRUE);
- EnableWindow(GetDlgItem(hdlg, IDC_STATIC_CONTACTS), TRUE);
- CheckDlgButton(hdlg, IDC_RADIO_ALL, BST_CHECKED);
- return TRUE;
-
- case WM_COMMAND:
- switch(LOWORD(wParam)) {
- case IDC_BACK:
- PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_MIRABILISDB, (LPARAM)MirabilisPageProc);
- break;
- case IDOK:
- if (IsDlgButtonChecked(hdlg, IDC_RADIO_ALL)) {
- DoImport = MirabilisImport;
- nImportOption = IMPORT_ALL;
- nCustomOptions = IOPT_MSGSENT|IOPT_MSGRECV|IOPT_URLSENT|IOPT_URLRECV;
- PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_PROGRESS, (LPARAM)ProgressPageProc);
- break;
- }
- if (IsDlgButtonChecked(hdlg, IDC_RADIO_CONTACTS)) {
- DoImport = MirabilisImport;
- nImportOption = IMPORT_CONTACTS;
- nCustomOptions = 0;
- PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_PROGRESS, (LPARAM)ProgressPageProc);
- break;
- }
- break;
- case IDCANCEL:
- PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0);
- break;
- }
- break;
- }
-
- return FALSE;
-}
-
-static int GetHighestIndexEntry(void)
-{
- struct TIdxIndexEntry *entry;
- DWORD ofs;
-
- ofs=*(PDWORD)(pIdx+12);
- for (;;) {
- entry=(struct TIdxIndexEntry*)(pIdx+ofs);
- if(entry->entryIdLow==(DWORD)-2) return ((struct TIdxDatEntry*)entry)->entryId;
- if(entry->ofsHigher>=0xF0000000) ofs=entry->ofsInHere;
- else ofs=entry->ofsHigher;
- }
-}
-
-static int GetIdDatOfs(DWORD id)
-{
- struct TIdxIndexEntry *entry;
- DWORD ofs = *(PDWORD)(pIdx+12);
- for (;;) {
- entry=(struct TIdxIndexEntry*)(pIdx+ofs);
- if(entry->entryIdLow==(DWORD)-2) {
- if(entry->entryIdHigh==id) return ((struct TIdxDatEntry*)entry)->datOfs;
- return 0;
- }
- if(id<entry->entryIdLow) ofs=entry->ofsLower;
- else if(entry->ofsHigher<0xF0000000 && id>=entry->entryIdHigh) ofs=entry->ofsHigher;
- else ofs=entry->ofsInHere;
- }
- return 0;
-}
-
-static int GetDatEntryType(DWORD ofs)
-{
- return *(int*)(pDat+ofs+4);
-}
-
-DWORD GetDBVersion()
-{
- dwDBVersion = *(PDWORD)(pIdx+16);
-
- switch (dwDBVersion) {
- case DBV99A:
- AddMessage( LPGEN("This looks like a ICQ 99a database."));
- break;
- case DBV99B:
- AddMessage( LPGEN("This looks like a ICQ 99b database."));
- break;
- case DBV2000A:
- AddMessage( LPGEN("This looks like a ICQ 2000a database."));
- break;
- case DBV2000B:
- AddMessage( LPGEN("This looks like a ICQ 2000b database."));
- break;
- case DBV2001A:
- AddMessage( LPGEN("This looks like a ICQ 2001, 2002 or 2003a database."));
- break;
- default:
- AddMessage( LPGEN("This database is an unknown version."));
- return 0;
- }
-
- return dwDBVersion;
-}
-
-int GetEntryVersion(WORD wSeparatorValue)
-{
- int nVersion;
-
- if (wSeparatorValue < ENTRYV99A)
- nVersion = 0; // Cannot handle ICQ98 contacts
- else if ((wSeparatorValue >= ENTRYV99A) && (wSeparatorValue < ENTRYV99B))
- nVersion = ENTRYV99A;
- else if ((wSeparatorValue >= ENTRYV99B) && (wSeparatorValue < ENTRYV2000A))
- nVersion = ENTRYV99B;
- else if ((wSeparatorValue >= ENTRYV2000A) && (wSeparatorValue < ENTRYV2000B))
- nVersion = ENTRYV2000A;
- else if ((wSeparatorValue >= ENTRYV2000B) && (wSeparatorValue < ENTRYV2001A))
- nVersion = ENTRYV2000B;
- else if ((wSeparatorValue >= ENTRYV2001A) && (wSeparatorValue < ENTRYV2001B))
- nVersion = ENTRYV2001A;
- else if ((wSeparatorValue >= ENTRYV2001B) && (wSeparatorValue < ENTRYV2002A))
- nVersion = ENTRYV2001B;
- else if (wSeparatorValue >= ENTRYV2002A)
- nVersion = ENTRYV2002A;
- else
- nVersion = ENTRYVUNKNOWN; // Just in case... Skip undocumented contact versions
-
- return nVersion;
-}
-
-DWORD ReadSubList(DWORD dwOffset)
-{
- DWORD dwSubType, dwProperties, n;
-
- #ifdef _LOGGING
- AddMessage( LPGEN("Attempting to parse sub list at offset %u."), dwOffset);
- #endif
-
- // Check number of properties in sub list
- dwProperties = *(PDWORD)(pDat+dwOffset);
- dwOffset+=4;
-
- // Check sub list type
- dwSubType = *(PBYTE)(pDat+dwOffset);
- dwOffset+=1;
-
- switch (dwSubType){
- case 0x6B:
- for(n=0;n<dwProperties;n++) dwOffset+=*(PWORD)(pDat+dwOffset)+2;
- break;
- case 0x6E:
- for(n=0;n<dwProperties;n++) {
- if (!(dwOffset = ReadPropertyBlock(dwOffset, NULL, NULL))) return 0;
- }
- break;
- default:
- // Unknown sub list type
- AddMessage( LPGEN("Error: Unknown sub list type (%u) at offset %u."), dwSubType, dwOffset);
- return 0;
- }
-
- return dwOffset;
-}
-
-DWORD ReadPropertyBlock(DWORD dwOffset, char* SearchWord, int* nSearchResult)
-{
- DWORD n, dwProperties, nameOfs;
- WORD nameLen;
-
- #ifdef _LOGGING
- AddMessage( LPGEN("Attempting to parse property block at offset %u."), dwOffset );
- #endif
-
- // Reset search result
- if (SearchWord) *nSearchResult = 0;
-
- // Check number of properties in block
- dwOffset+=2;
- dwProperties = *(PDWORD)(pDat+dwOffset);
-
- // Scan all properties and search for
- // 'SearchWord' (if it has been specified).
- dwOffset+=4;
- for(n=0;n<dwProperties;n++) {
- nameLen=*(PWORD)(pDat+dwOffset); // Length of current property name
- dwOffset+=2;
- nameOfs=dwOffset; // Save pointer to start of name
- dwOffset+=nameLen; // dwOffset now points to property value type
-
- if ( SearchWord ) {
- // Is this the property we are searching for?
- if (!lstrcmpA((char*)(pDat+nameOfs),SearchWord)) {
- *nSearchResult = 1;
- return dwOffset;
- } }
-
- // Increase 'dwOffset' to point to length of next property
- switch(*(pDat+dwOffset)) {
- case 0x64:
- case 0x65: dwOffset+=2; break;
- case 0x66:
- case 0x67: dwOffset+=3; break;
- case 0x68:
- case 0x69: dwOffset+=5; break;
- case 0x6b: dwOffset+=*(PWORD)(pDat+dwOffset+1)+3; break;
- case 0x6d:
- dwOffset = ReadSubList(dwOffset+1);
- if (!dwOffset) return 0;
- break;
- case 0x6f: dwOffset+=*(PDWORD)(pDat+dwOffset+1)+5; break;
- default:
- // Unknown property value type
- AddMessage( LPGEN("Error: Unknown datatype (%u) at offset %u."), *(pDat+dwOffset), dwOffset);
- return 0;
- } }
-
- // We have reached the end without finding
- // the property we searched for
- if (SearchWord) *nSearchResult = 0;
-
- // Return offset to the byte right after the
- // property list
- return dwOffset;
-}
-
-DWORD ReadPropertyBlockList(DWORD dwOffset, char* SearchWord, int* nSearchResult)
-{
- DWORD dwBlocks, n;
-
- #ifdef _LOGGING
- AddMessage( LPGEN("Attempting to parse property block list at offset %u."), dwOffset );
- #endif
-
- // Check number of blocks in list
- dwBlocks = *(PDWORD)(pDat+dwOffset);
-
- // Scan all blocks and search for 'SearchWord' (if
- // it has been specified).
- dwOffset += 4;
- for(n = 0;n<dwBlocks;n++) {
- if (!(dwOffset = ReadPropertyBlock(dwOffset, SearchWord, nSearchResult))) {
- AddMessage( LPGEN("Failed to read Property block."));
- return 0;
- }
- if (SearchWord)
- // Was the property found in the block?
- if (*nSearchResult) return dwOffset;
- }
-
- // We have reached the end without finding
- // the property we searched for
- if (SearchWord) *nSearchResult = 0;
-
- // Return offset to the byte right after the
- // property list
- return dwOffset;
-}
-
-DWORD ReadWavList(DWORD dwOffset)
-{
- DWORD dwWavEntries, n;
- WORD wNameLen;
-
- #ifdef _LOGGING
- AddMessage( LPGEN("Attempting to parse wav file list at offset %u."), dwOffset);
- #endif
-
- // Check number of wav entries
- dwWavEntries = *(PDWORD)(pDat+dwOffset);
-
- // Read entire list
- dwOffset+=4;
- for(n = 0;n<dwWavEntries;n++) {
- wNameLen = *(PWORD)(pDat+dwOffset+0x0A);
- dwOffset += wNameLen + 0x0C;
- }
-
- // Return the offset to the byte right
- // after the list
- return dwOffset;
-}
-
-DWORD FindMyDetails(void)
-{
- DWORD dwOffset = GetIdDatOfs(1005);
-
- if (!dwOffset) return 0;
- if (*(PDWORD)(pDat+dwOffset+0x08) != 1005) return 0;
- if (*(PBYTE)(pDat+dwOffset+0x0C) != 0xE4) return 0;
- if (*(int*)(pDat+dwOffset+0x1e) != 'USER') return 0;
- if (*(PDWORD)(pDat+dwOffset+0x22) != 6) return 0;
-
- return dwOffset;
-}
-
-// dwOffset must point to MyDetails
-DWORD FindGroupList(DWORD dwOffset)
-{
- DWORD n, dwPhoneEntries;
- WORD wSeparatorValue;
- int nFormat;
-
- wSeparatorValue = *(PWORD)(pDat+dwOffset+0x1c);
- nFormat = GetEntryVersion(wSeparatorValue);
-
- #ifdef _LOGGING
- AddMessage( LPGEN("Attempting to parse group list, type %d."), nFormat );
- #endif
-
- switch (nFormat) {
- case ENTRYV99A:
- if (!(dwOffset = ReadWavList(dwOffset+0x54))) return 0;
- if (!(dwOffset = ReadPropertyBlock(dwOffset+38, NULL, NULL))) return 0;
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // User name
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Nick name
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // First name
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Last name
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Primary e-mail
- dwOffset += 0x13; // Various fixed length data
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Home city
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Home state
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Additional details
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // User homepage
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Home phone number
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Notes
- dwOffset += 0x08; // Various fixed length data
- dwOffset += 0x04; // ++ UNKNOWN ++
- dwPhoneEntries = *(PDWORD)(pDat+dwOffset); // Phonebook starts here
- dwOffset += 0x04;
- for(n = 0;n<dwPhoneEntries;n++) {
- dwOffset += *(PWORD)(pDat+dwOffset)+2;
- dwOffset += *(PWORD)(pDat+dwOffset)+2;
- dwOffset += *(PWORD)(pDat+dwOffset)+2;
- dwOffset += *(PWORD)(pDat+dwOffset)+2;
- dwOffset += 2;
- dwOffset += *(PWORD)(pDat+dwOffset)+2;
- }
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Picture file name
- dwOffset += 0x06; // ++ UNKNOWN ++ (8 enligt spec)
- dwOffset += 0x06; // Various fixed length data
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Secondary e-mail
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Old e-mail
- dwOffset += 0x04; // ++ UNKNOWN ++
- dwOffset += 0x03; // Various fixed length data
- dwOffset += 0x08; // ++ UNKNOWN ++
- dwOffset += 0x03; // Various fixed length data
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Home street address
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Home fax number
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Home cell phone number
- dwOffset += 0x04; // ++ UNKNOWN ++
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Company Div/Dept
- dwOffset += 0x01; // Occupation
- dwOffset += 0x04; // ++ UNKNOWN ++
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Company position
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Company name
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Work street address
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Work state
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Work city
- dwOffset += 0x08; // Various fixed length data
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Work phone number
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Work fax number
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Work homepage
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Past background #1
- dwOffset += 0x02; // Past background #1 category
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Past background #2
- dwOffset += 0x02; // Past background #2 category
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Past background #3
- dwOffset += 0x02; // Past background #3 category
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Affiliation #1
- dwOffset += 0x02; // Affiliation #1 category
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Affiliation #2
- dwOffset += 0x02; // Affiliation #2 category
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Affiliation #3
- dwOffset += 0x02; // Affiliation #3 category
- dwOffset += 0x14; // ++ UNKNOWN ++
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Interest #1
- dwOffset += 0x02; // Interest #1 category
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Interest #2
- dwOffset += 0x02; // Interest #2 category
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Interest #3
- dwOffset += 0x02; // Interest #3 category
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Interest #4
- dwOffset += 0x02; // Interest #4 category
- dwOffset += 0x28; // ++ UNKNOWN ++
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // Password
- dwOffset += 0x04; // ++ UNKNOWN ++
- dwOffset += 0x0E; // ++ UNKNOWN ++
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // POP3 account name
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // POP3 account password
- dwOffset += *(PWORD)(pDat+dwOffset)+2; // POP server name
- dwOffset += 0x15; // ++ UNKNOWN ++
- return dwOffset;
-
- case ENTRYV99B:
- if (!(dwOffset = ReadWavList(dwOffset+0x2C))) return 0;
- if (!(dwOffset = ReadPropertyBlockList(dwOffset+0x02, NULL, NULL))) return 0;
- dwOffset += 0x08;
- dwPhoneEntries = *(PDWORD)(pDat+dwOffset); // Phonebook
- dwOffset += 0x04;
- for(n = 0;n<dwPhoneEntries;n++) {
- dwOffset += *(PWORD)(pDat+dwOffset)+2;
- dwOffset += *(PWORD)(pDat+dwOffset)+2;
- dwOffset += *(PWORD)(pDat+dwOffset)+2;
- dwOffset += *(PWORD)(pDat+dwOffset)+2;
- dwOffset += 2;
- dwOffset += *(PWORD)(pDat+dwOffset)+2;
- }
- return dwOffset + 0x06;
-
- case ENTRYV2000A:
- case ENTRYV2000B:
- case ENTRYV2002A:
- if (!(dwOffset = ReadWavList(dwOffset+0x2C))) return 0;
- if (!(dwOffset = ReadPropertyBlockList(dwOffset+0x02, NULL, NULL))) return 0;
- return dwOffset + 0x06;
-
- case ENTRYV2001A:
- case ENTRYV2001B:
- if (!(dwOffset = ReadPropertyBlockList(dwOffset+0x2C, NULL, NULL))) return 0;
- return dwOffset + 0x06;
-
- default:
- AddMessage( LPGEN("default"));
- return 0;
- }
-}
-
-// ------------------------------------------------
-// Finds the name of a group with a specific GroupID.
-// ------------------------------------------------
-// dwGroupID is the GroupID of the group.
-// Returns a pointer to the name string or NULL if
-// it was not found.
-char* GetGroupName(DWORD dwGroupID)
-{
- DWORD dwGroups, n, tmpOfs, dwOffset;
- char* strGroupName = 0;
- int nSearchResult;
-
- // Check for the existence of any group
- if (!dwGroupListOfs) return 0;
- dwOffset = dwGroupListOfs;
- dwGroups = *(PDWORD)(pDat + dwOffset);
- if (dwGroups == 0) return 0;
-
- dwOffset += 4;
-
- // Examine all groups
- switch (dwDBVersion) {
- case DBV99A:
- case DBV99B:
- for (n = 0; n < dwGroups; n++) {
- if (dwGroupID == *(PDWORD)(pDat + dwOffset)) {
- if (*(PWORD)(pDat + dwOffset + 4) > 1)
- return 6 + (char*)(pDat + dwOffset);
-
- break;
- }
- else
- // Skip to next group
- dwOffset += *(PWORD)(pDat + dwOffset + 4) + 12;
- }
- break;
-
- case DBV2000A:
- case DBV2000B:
- case DBV2001A:
- for (n = 0; n < dwGroups; n++) {
- if (tmpOfs = ReadPropertyBlock(dwOffset, "GroupID", &nSearchResult)) {
- if (nSearchResult) {
- if (dwGroupID == *(PDWORD)(pDat + tmpOfs + 1)) {
- strGroupName = 3 + (char*)(pDat + ReadPropertyBlock(dwOffset, "GroupName", &nSearchResult));
- if (nSearchResult) {
- if ((DWORD)*(strGroupName - 2) > 1)
- return strGroupName;
- break;
- } } } }
-
- // Skip to next group
- if ( dwOffset != ReadPropertyBlock(dwOffset, NULL, NULL))
- break;
- }
- break;
- }
-
- // The GroupID was not found, or it was found
- // but the group did not have a name, or there
- // was an error during parsing.
- return 0;
-}
-
-// ------------------------------------------------
-// Scans a group list and adds all found groups to
-// the Miranda contact list
-// ------------------------------------------------
-// dwOffset must point to the number of entries in
-// the following group list.
-// Returns the number of added groups, or -1 if an error
-// occurred
-
-int ImportGroups()
-{
- DWORD dwGroups, n, tmpOfs, dwOffset;
- int nImported = 0;
- int nSearchResult, nFormat;
- WORD wSeparatorValue;
-
- if (!(dwOffset = FindMyDetails())) {
- AddMessage( LPGEN("ERROR: Failed to find owner information."));
- return -1;
- }
-
- wSeparatorValue = *(PWORD)(pDat + dwOffset + 0x1c);
- nFormat = GetEntryVersion(wSeparatorValue);
-
- dwGroupListOfs = dwOffset = FindGroupList(dwOffset);
- if (!dwOffset) {
- AddMessage( LPGEN("ERROR: Failed to find contact list groups."));
- #ifdef _LOGGING
- { // If this is a debug build, dump MyDetails block to disk
- FILE *stream;
- DWORD dwSize;
- dwOffset = FindMyDetails();
- dwSize = *(PDWORD)(pDat + dwOffset);
- stream = fopen("import_grouplist_dump.bin", "w");
- fwrite(pDat + dwOffset, 1, dwSize, stream);
- fclose(stream);
- }
- #endif
- return -1;
- }
-
- // Check number of groups
- dwGroups = *(PDWORD)(pDat + dwOffset);
- if (dwGroups > 0)
- AddMessage( LPGEN("Importing groups."));
- else {
- AddMessage( LPGEN("This database does not contain any contact groups."));
- return 0;
- }
-
- dwOffset += 4;
-
- // Import all groups with a name
- switch (nFormat) {
- case ENTRYV99A:
- case ENTRYV99B:
- for (n = 0; n < dwGroups; n++) {
- if (*(PWORD)(pDat+dwOffset+4) > 1) {
- if ( CreateGroup(DBVT_ASCIIZ, (char*)(pDat + dwOffset) + 6, NULL ))
- nImported++;
- dwOffset += *(PWORD)(pDat + dwOffset + 4) + 12;
- } }
- break;
-
- case ENTRYV2000A:
- case ENTRYV2000B:
- case ENTRYV2001A:
- case ENTRYV2001B:
- case ENTRYV2002A:
- for (n = 0; n < dwGroups; n++) {
- if (tmpOfs = ReadPropertyBlock(dwOffset, "GroupName", &nSearchResult)) {
- if (nSearchResult) {
- if (CreateGroup( DBVT_ASCIIZ, (char*)(pDat + tmpOfs + 3), NULL ))
- nImported++;
- } }
-
- dwOffset = ReadPropertyBlock(dwOffset, NULL, NULL);
- if (!dwOffset) {
- AddMessage( LPGEN("ERROR: An error occurred while importing groups."));
- AddMessage( LPGEN("All groups may not have not been imported."));
- #ifdef _LOGGING
- { // If this is a debug build, dump MyDetails block to disk
- FILE *stream;
- DWORD dwSize;
- dwOffset = FindMyDetails();
- dwSize = *(PDWORD)(pDat + dwOffset);
- stream = fopen("import_grouplist_dump.bin", "w");
- fwrite(pDat + dwOffset, 1, dwSize, stream);
- fclose(stream);
- }
- #endif
- return -1;
- } }
- break;
-
- default:
- return -1;
- }
-
- return nImported;
-}
-
-// Imports the contact at offset dwOffset
-// Returns the HANDLE of the Miranda contact
-// or INVALID_HANDLE_VALUE on failure
-
-HANDLE ImportContact(DWORD dwOffset)
-{
- int nContactVersion, nSearchResult;
- BYTE Status;
- WORD wSeparatorValue;
- DWORD dwGroup, dwUIN = 0, tmpOfs = 0;
- char *strNickname = 0, *strGroupName = 0;
-
- if (*(int*)(pDat + dwOffset + 4) != DATENTRY_CONTACT)
- return INVALID_HANDLE_VALUE;
-
- if (*(int*)(pDat + dwOffset + 0x1e) != 'USER')
- return INVALID_HANDLE_VALUE;
-
- #ifdef _LOGGING
- { // If this is a debug build, dump contact to disk
- FILE *stream;
- DWORD dwSize;
- dwSize = *(PDWORD)(pDat + dwOffset);
- stream = fopen("import_last_contact.bin", "w");
- fwrite(pDat + dwOffset, 1, dwSize, stream);
- fclose(stream);
- }
- #endif
-
- Status = *(pDat + dwOffset + 0x22);
- wSeparatorValue = *(PWORD)(pDat + dwOffset + 0x1c);
- nContactVersion = GetEntryVersion(wSeparatorValue);
-
- dwGroup = *(PDWORD)(pDat + dwOffset + 0x26);
- if (dwGroup >= 1000)
- strGroupName = GetGroupName(dwGroup);
-
- if (Status == 5)
- return INVALID_HANDLE_VALUE; // Skip deleted contacts
-
- if ((Status != 2) && (Status != 3)) {
- AddMessage( LPGEN("Skipping inactive contact."));
- return INVALID_HANDLE_VALUE;
- }
-
- if ((nContactVersion < ENTRYV99A) || (nContactVersion == 0)) {
- AddMessage( LPGEN("Skipping contact with unsupported version."));
- return INVALID_HANDLE_VALUE;
- }
-
- switch(nContactVersion){
- case ENTRYV99A:
- if (!(dwOffset = ReadWavList(dwOffset + 0x54))) return INVALID_HANDLE_VALUE;
- if (!(dwOffset = ReadPropertyBlock(dwOffset + 0x26, NULL, NULL))) return INVALID_HANDLE_VALUE;
- // Check for custom nickname
- if (*(PWORD)(pDat + dwOffset) > 1) strNickname = (char*)(dwOffset + pDat + 2);
- // Find UIN
- dwOffset += *(PWORD)(pDat + dwOffset) + 2; // Custom nick name
- dwOffset += *(PWORD)(pDat + dwOffset) + 2; // Nick name
- dwOffset += *(PWORD)(pDat + dwOffset) + 2; // First name
- dwOffset += *(PWORD)(pDat + dwOffset) + 2; // Last name
- dwOffset += *(PWORD)(pDat + dwOffset) + 2; // E-mail
- dwUIN = *(PDWORD)(pDat + dwOffset); // UIN
- break;
-
- case ENTRYV99B:
- case ENTRYV2000A:
- case ENTRYV2000B:
- if (!(dwOffset = ReadWavList(dwOffset + 0x2C))) return INVALID_HANDLE_VALUE;
- tmpOfs = ReadPropertyBlockList(dwOffset + 0x02, "UIN", &nSearchResult);
- if (nSearchResult) dwUIN = *(PDWORD)(pDat + tmpOfs + 1);
- tmpOfs = ReadPropertyBlockList(dwOffset + 0x02, "MyDefinedHandle", &nSearchResult);
- if (nSearchResult) strNickname = (char*)(tmpOfs + pDat + 3);
- break;
-
- case ENTRYV2001A:
- case ENTRYV2001B:
- tmpOfs = ReadPropertyBlockList(dwOffset + 0x2C, "MyDefinedHandle", &nSearchResult);
- if (nSearchResult) strNickname = (char*)(tmpOfs + pDat + 3);
- tmpOfs = ReadPropertyBlockList(dwOffset + 0x2C, "UIN", &nSearchResult);
- if (nSearchResult) dwUIN = *(PDWORD)(pDat + tmpOfs + 1);
- break;
-
- case ENTRYV2002A:
- tmpOfs = ReadPropertyBlockList(dwOffset + 0x32, "MyDefinedHandle", &nSearchResult);
- if (nSearchResult) strNickname = (char*)(tmpOfs + pDat + 3);
- tmpOfs = ReadPropertyBlockList(dwOffset + 0x32, "UIN", &nSearchResult);
- if (nSearchResult) dwUIN = *(PDWORD)(pDat + tmpOfs + 1);
- break;
- }
-
- if (!dwUIN) {
- AddMessage( LPGEN("Skipping unrecognizable contact."));
- return INVALID_HANDLE_VALUE;
- }
-
- if (dwUIN < 10000) {
- AddMessage( LPGEN("Skipping non-ICQ contact %u."), dwUIN );
- return INVALID_HANDLE_VALUE;
- }
-
- if (HContactFromNumericID( szICQModuleName[ iICQAccount ], "UIN", dwUIN) == INVALID_HANDLE_VALUE) {
- DBVARIANT id, nick, group;
- id.type = DBVT_DWORD; id.dVal = dwUIN;
- if ( strNickname != NULL && strlen(strNickname) > 0 )
- nick.type = DBVT_ASCIIZ, nick.pszVal = strNickname;
- else
- nick.type = DBVT_DELETED;
- group.type = DBVT_ASCIIZ, group.pszVal = strGroupName;
- return AddContact(hdlgProgress, szICQModuleName[ iICQAccount ], "UIN", &id, &nick, &group);
- }
- else {
- if ((strNickname != NULL) && (strlen(strNickname) > 0))
- AddMessage( LPGEN("Skipping duplicate ICQ contact %u, %s"), dwUIN, strNickname);
- else
- AddMessage( LPGEN("Skipping duplicate ICQ contact %u"), dwUIN);
- }
-
- // Failure
- return INVALID_HANDLE_VALUE;
-}
-
-BOOL ImportMessage(DWORD dwOffset)
-{
- struct TDatMessage *msg = (struct TDatMessage*)(pDat + dwOffset);
- struct TDatEntryFooter *footer;
- DBEVENTINFO dbei;
- HANDLE hContact;
- int nUCTOffset;
- TIME_ZONE_INFORMATION TimeZoneInformation;
- int nHistoryCount = 0;
-
- // Get timestamp offset. In ICQ, event timestamps are stored
- // as UTC + (0-TZ offset). YES! That's the negation of the
- // timezone offset, only God and Mirabilis knows why.
- GetTimeZoneInformation(&TimeZoneInformation);
- nUCTOffset = -TimeZoneInformation.Bias * 60;
-
- // Ignore messages in 'Deleted' folder
- if (msg->filingStatus&FILING_DELETED)
- return FALSE;
-
- // Skip messages from non-icq contacts
- if (msg->uin < 10000) {
- AddMessage( LPGEN("Ignoring msg from user %d at ofs %d."), msg->uin, dwOffset );
- return FALSE;
- }
-
- // Ignore received messages?
- if (( msg->filingStatus & FILING_RECEIVED ) && !( nCustomOptions & IOPT_MSGRECV ))
- return FALSE;
-
- // Ignores sent messages?
- if ( !(msg->filingStatus & FILING_RECEIVED) && !( nCustomOptions & IOPT_MSGSENT ))
- return FALSE;
-
- // Check if contact exists in Miranda database
- hContact = HistoryImportFindContact(hdlgProgress, szICQModuleName[ iICQAccount ], msg->uin, nCustomOptions&IOPT_ADDUNKNOWN);
- if (hContact == INVALID_HANDLE_VALUE)
- return FALSE; // Contact couldn't be found/added
-
- // Convert the event to a Miranda dbevent
- footer = (struct TDatEntryFooter*)(pDat + dwOffset + msg->textLen + offsetof(struct TDatMessage, text));
- ZeroMemory(&dbei, sizeof(dbei));
- dbei.cbSize = sizeof(dbei);
- dbei.eventType = EVENTTYPE_MESSAGE;
- dbei.flags = footer->sent == 1 ? DBEF_SENT : DBEF_READ;
- dbei.szModule = szICQModuleName[ iICQAccount ];
- // Convert timestamp
- dbei.timestamp = footer->timestamp + nUCTOffset;
- dbei.cbBlob = msg->textLen;
- dbei.pBlob = (PBYTE)alloca(msg->textLen);
- CopyMemory(dbei.pBlob, msg->text, dbei.cbBlob);
- dbei.pBlob[dbei.cbBlob - 1] = 0;
-
- // Check for duplicate entries
- if (IsDuplicateEvent(hContact, dbei)) {
- nDupes++;
- }
- else {
- if (CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei))
- nMessagesCount++;
- }
-
- return TRUE;
-}
-
-BOOL ImportExtendedMessage(DWORD dwOffset)
-{
- struct TDatMessage *msg = (struct TDatMessage*)(pDat + dwOffset);
- struct TDatEntryFooter *footer;
- DBEVENTINFO dbei;
- HANDLE hContact;
- int nUCTOffset;
- TIME_ZONE_INFORMATION TimeZoneInformation;
- int nHistoryCount = 0;
- char* pszText = 0;
- DWORD dwRichTextOffset = 0;
- DWORD wRichTextLength = 0;
- DWORD wLength = 0;
- BOOL bFreeMe = FALSE;
-
- // Get timestamp offset. In ICQ, event timestamps are stored
- // as UTC + (0-TZ offset). YES! That's the negation of the
- // timezone offset, only God and Mirabilis knows why.
- GetTimeZoneInformation(&TimeZoneInformation);
- nUCTOffset = -TimeZoneInformation.Bias * 60;
-
- // Ignore messages in 'Deleted' folder
- if (msg->filingStatus&FILING_DELETED)
- return FALSE;
-
- // Skip messages from non-icq contacts
- if (msg->uin < 10000) {
- AddMessage( LPGEN("Ignoring msg from user %d at ofs %d."), msg->uin, dwOffset );
- return FALSE;
- }
-
- // Ignore received messages?
- if (( msg->filingStatus & FILING_RECEIVED) && !( nCustomOptions & IOPT_MSGRECV ))
- return FALSE;
-
- // Ignore sent messages?
- if ( !( msg->filingStatus & FILING_RECEIVED ) && !( nCustomOptions & IOPT_MSGSENT ))
- return FALSE;
-
- // Check if contact exists in Miranda database
- hContact = HistoryImportFindContact(hdlgProgress, szICQModuleName[ iICQAccount ], msg->uin, nCustomOptions&IOPT_ADDUNKNOWN);
- if (hContact == INVALID_HANDLE_VALUE)
- return FALSE; // Contact couldn't be found/added
-
- // Find a piece of usable text content
- if (msg->textLen <= 1) {
- // Skip past the RTF segment
- wRichTextLength = *(PWORD)(pDat + dwOffset + 0x2A + msg->textLen + 0x21);
- dwRichTextOffset = dwOffset + 0x2A + msg->textLen + 0x23;
-
- // Use the UTF-8 text segment
- wLength = *(PWORD)(pDat + dwRichTextOffset + wRichTextLength);
- if (wLength <= 1) {
- AddMessage( LPGEN("Ignoring msg with no text from %d ofs %d."), msg->uin, dwOffset );
- return FALSE;
- }
- pszText = _strdup((char*)pDat + dwRichTextOffset + wRichTextLength + 2);
- bFreeMe = TRUE;
- mir_utf8decode(pszText, NULL);
- wLength = (DWORD)strlen(pszText)+1;
- }
- else {
- // Use the ANSI text segment
- wLength = msg->textLen;
- pszText = (char*)(pDat + dwOffset + 0x2A);
- }
-
- // Convert the event to a Miranda dbevent
- footer = (struct TDatEntryFooter*)(pDat + dwOffset + msg->textLen + offsetof(struct TDatMessage, text));
- ZeroMemory(&dbei, sizeof(dbei));
- dbei.cbSize = sizeof(dbei);
- dbei.eventType = EVENTTYPE_MESSAGE;
- dbei.flags = footer->sent == 1 ? DBEF_SENT : DBEF_READ;
- dbei.szModule = szICQModuleName[ iICQAccount ];
- // Convert timestamp
- dbei.timestamp = footer->timestamp + nUCTOffset;
- dbei.cbBlob = wLength;
- dbei.pBlob = (PBYTE)calloc(wLength,1);
- CopyMemory(dbei.pBlob, pszText, dbei.cbBlob);
- dbei.pBlob[dbei.cbBlob - 1] = 0;
-
- // Check for duplicate entries
- if (IsDuplicateEvent(hContact, dbei)) {
- nDupes++;
- }
- else {
- if (CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei))
- nMessagesCount++;
- }
-
- free(dbei.pBlob);
- if (bFreeMe)
- free(pszText);
-
- return TRUE;
-}
-
-BOOL ImportURLMessage(DWORD dwOffset)
-{
- struct TDatMessage *msg = (struct TDatMessage*)(pDat + dwOffset);
- struct TDatEntryFooter *footer;
- DBEVENTINFO dbei;
- HANDLE hContact;
- int nUCTOffset;
- TIME_ZONE_INFORMATION TimeZoneInformation;
- int nHistoryCount = 0;
- char *pSeparator;
-
- // Get timestamp offset. In ICQ, event timestamps are stored
- // as UTC + (0-TZ offset). YES! That's the negation of the
- // timezone offset, only God and Mirabilis knows why.
- GetTimeZoneInformation(&TimeZoneInformation);
- nUCTOffset = -TimeZoneInformation.Bias * 60;
-
- // Ignore URLs in 'Deleted' folder
- if (msg->filingStatus&FILING_DELETED)
- return FALSE;
-
- // Skip URLs from non-icq contacts
- if (msg->uin < 10000) {
- AddMessage( LPGEN("Ignoring msg from user %d at ofs %d."), msg->uin, dwOffset );
- return FALSE;
- }
-
- // Ignore received URLs?
- if (( msg->filingStatus & FILING_RECEIVED ) && !( nCustomOptions & IOPT_URLRECV ))
- return FALSE;
-
- // Ignores sent URLs?
- if ( !( msg->filingStatus & FILING_RECEIVED ) && !( nCustomOptions & IOPT_URLSENT ))
- return FALSE;
-
- // Check if contact exists in Miranda database
- hContact = HistoryImportFindContact(hdlgProgress, szICQModuleName[ iICQAccount ], msg->uin, nCustomOptions&IOPT_ADDUNKNOWN);
- if (hContact == INVALID_HANDLE_VALUE)
- return FALSE; // Contact couldn't be found/added
-
- // Convert the event to a Miranda dbevent
- footer = (struct TDatEntryFooter*)(pDat + dwOffset + msg->textLen + offsetof(struct TDatMessage, text));
- ZeroMemory(&dbei, sizeof(dbei));
- dbei.cbSize = sizeof(dbei);
- dbei.eventType = EVENTTYPE_URL;
- dbei.flags = footer->sent == 1 ? DBEF_SENT : DBEF_READ;
- dbei.szModule = szICQModuleName[ iICQAccount ];
- // Convert timestamp
- dbei.timestamp = footer->timestamp + nUCTOffset;
- dbei.cbBlob = msg->textLen;
- dbei.pBlob = (PBYTE)alloca(msg->textLen);
- CopyMemory(dbei.pBlob, msg->text, dbei.cbBlob);
- dbei.pBlob[dbei.cbBlob - 1] = 0;
- // Separate URL and description
- pSeparator = strchr((char*)dbei.pBlob, 0xFE);
- if (pSeparator != NULL)
- *pSeparator = 0;
-
- // Check for duplicate entries
- if (IsDuplicateEvent(hContact, dbei))
- nDupes++;
- else if (CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei))
- nMessagesCount++;
-
- return TRUE;
-}
-
-BOOL ImportEvent(DWORD dwOffset)
-{
- struct TDatMessage *msg = (struct TDatMessage*)(pDat + dwOffset);
-
- // Events have IDs > 2000
- if (msg->hdr.entryId < 2001) {
- AddMessage( LPGEN("Skipping event with ID < 2001."));
- return FALSE;
- }
-
- // Separate code paths based on the event signature
- switch (msg->hdr.subType) {
-
- case SUBTYPE_MESSAGE: // All kinds of messages
- switch (msg->type) {
- case 1: // Normal message
- if ((nCustomOptions&IOPT_MSGRECV) || (nCustomOptions&IOPT_MSGSENT)) {
- return ImportMessage(dwOffset);
- }
- break;
-
- case 4: // URL
- if ((nCustomOptions&IOPT_URLSENT) || (nCustomOptions&IOPT_URLRECV)) {
- return ImportURLMessage(dwOffset);
- }
- break;
-
- case 6: // Request for authorization
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 'Request for auth.' msg, ofs %d."), dwOffset );
- #endif
- break;
-
- case 7: // Authorization request denied
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 'Auth. denied' msg, ofs %d."), dwOffset );
- #endif
- break;
-
- case 8: // Authorization request accepted
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 'Auth. accepted' msg, ofs %d."), dwOffset );
- #endif
- break;
-
- case 9: // System message
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 'System message', ofs %d."), dwOffset );
- #endif
- break;
-
- case 12: // You were added
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 'You were added' msg, ofs %d."), dwOffset );
- #endif
- break;
-
- case 13: // WWWPager ?
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 'WWW Pager' msg, ofs %d."), dwOffset );
- #endif
- break;
-
- case 14: // Email Express ?
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 'Email Express' msg, ofs %d."), dwOffset );
- #endif
- break;
-
- case 19: // Contact list
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 'Contact' msg, ofs %d."), dwOffset );
- #endif
- break;
-
- case 21: // Phonecall request?
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 'Phonecall' msg (?), ofs %d."), dwOffset );
- #endif
- break;
-
- case 26: // SMS request?
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 'SMS' msg (?), ofs %d."), dwOffset );
- #endif
- break;
-
- case 29: // Active list invitation ??
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 29 msg, ofs %d."), dwOffset );
- #endif
- break;
-
- case 30: // Birthday reminder
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 'Birthday' msg (?), ofs %d."), dwOffset );
- #endif
- break;
-
- case 32: // Unknown (Tomer)
- #ifdef _LOGGING
- AddMessage( LPGEN("Skipping 32 msg, ofs %d."), dwOffset );
- #endif
- break;
-
- default:
- AddMessage( LPGEN("Skipping unknown 0xE0 subtype (%d), ofs %d."), msg->type, dwOffset );
-
- #ifdef _LOGGING
- { // If this is a debug build, dump entry to disk
- FILE *stream;
- DWORD dwSize = *(PDWORD)(pDat + dwOffset);
- wsprintfA(str, "import_unknown_E0subtype_%u-%u.bin", msg->type, dwOffset);
- stream = fopen(str, "w");
- fwrite(pDat + dwOffset, 1, dwSize, stream);
- fclose(stream);
- }
- #endif
-
- return FALSE;
- }
- break;
-
- case SUBTYPE_CHATREQUEST: // 0xE1
- #ifdef _LOGGING
- if (nImportOption != IMPORT_CONTACTS)
- AddMessage( LPGEN("Skipping 'Chat request' msg, ofs %d."), dwOffset );
- #endif
- break;
-
- case SUBTYPE_FILEREQUEST: // 0xE2
- #ifdef _LOGGING
- if (nImportOption != IMPORT_CONTACTS)
- AddMessage( LPGEN("Skipping file message offset %d."), dwOffset );
- #endif
- break;
-
- case 0xE3: // External (IPhone, Battlecom) Maybe general voice calls?
- #ifdef _LOGGING
- if (nImportOption != IMPORT_CONTACTS)
- AddMessage( LPGEN("Skipping message type 0xE3 at offset %d."), dwOffset );
- #endif
- break;
-
- case 0xE4: // My details
- break;
- case 0xE5: // Contact
- break;
- case 0xE6: // Reminder
- break;
- case 0xE7: // Addressbook
- break;
- case 0xEC: // Voice message
- break;
- case 0xED: // Unknown, something to do with chatting and .CHT files
- // if (importHistory) {
- // wsprintf(str, "Skipping message type 0xED at offset %d.", dwOffset);
- // AddMessage( LPGEN(str);
- // }
- break;
- case 0xEE: // Note
- break;
- case 0xEF: // Event folder
- break;
- // case 0xF0: // Unknown
- // if (importHistory) {
- // wsprintf(str, "Skipping message type 0xF0 at offset %d.", dwOffset);
- // AddMessage( LPGEN(str);
- // }
- // break;
- case 0xF1: // Server list
- break;
- // case 0xF6: // Unknown
- // if (importHistory) {
- // wsprintf(str, "Skipping message type 0xF6 at offset %d.", dwOffset);
- // AddMessage( LPGEN(str);
- // }
- // break;
- case 0x50: // Extended message, ICQ 2000a+?
- if (nImportOption != IMPORT_CONTACTS) {
- return ImportExtendedMessage(dwOffset);
- }
- break;
-
- case 0xA0: // URL message type 2
- if (nImportOption != IMPORT_CONTACTS) {
- if ((msg->filingStatus&FILING_RECEIVED) || (nCustomOptions&IOPT_URLRECV)) {
- return ImportURLMessage(dwOffset);
- }
- }
- break;
-
- default:
- if (nImportOption != IMPORT_CONTACTS) {
- AddMessage( LPGEN("Skipping unknown event type %d at offset %d."), msg->hdr.subType, dwOffset );
-
-#ifdef _LOGGING
- { // If this is a debug build, dump entry to disk
- FILE *stream;
- DWORD dwSize;
- dwSize = *(PDWORD)(pDat + dwOffset);
- wsprintfA(str, "import_unknown_eventtype_%u-%u.bin", msg->hdr.subType, dwOffset);
- stream = fopen(str, "w");
- fwrite(pDat + dwOffset, 1, dwSize, stream);
- fclose(stream);
- }
-#endif
-
- }
- break;
- }
-
- return FALSE;
-}
-
-
-static void MirabilisImport(HWND hdlgProgressWnd)
-{
- HANDLE hIdx, hDat, hIdxMapping, hDatMapping;
- DWORD i, ofs, highestIndexEntry;
- TCHAR datFilename[MAX_PATH];
- MSG msg;
- DWORD dwTimer;
-
-
- int status = 0;
- hdlgProgress = hdlgProgressWnd;
- nDupes = nContactsCount = nMessagesCount = 0;
-
- SetProgress(0);
- lstrcpy(datFilename, importFile);
- {
- TCHAR* str2;
- str2 = _tcsrchr(datFilename,'.');
- if ( str2 != NULL )
- lstrcpy(str2, _T(".dat"));
- }
-
- hIdx = CreateFile(importFile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
- if (hIdx == INVALID_HANDLE_VALUE) {
- AddMessage( LPGEN("Failed to open index file"));
- AddMessage( LPGEN("Import aborted"));
- SetProgress(100);
- return;
- }
-
- hDat = CreateFile(datFilename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
- if (hDat == INVALID_HANDLE_VALUE) {
- AddMessage( LPGEN("Failed to open database file"));
- AddMessage( LPGEN("Import aborted"));
- SetProgress(100);
- return;
- }
-
- // Creating file mappings
- hIdxMapping = CreateFileMapping(hIdx, NULL, PAGE_READONLY, 0, 0, NULL);
- hDatMapping = CreateFileMapping(hDat, NULL, PAGE_READONLY, 0, 0, NULL);
-
- // Mapping views of files
- pIdx = (PBYTE)MapViewOfFile(hIdxMapping, FILE_MAP_READ, 0, 0, 0);
- pDat = (PBYTE)MapViewOfFile(hDatMapping, FILE_MAP_READ, 0, 0, 0);
-
- // Is this a supported format?
- if (GetDBVersion()) {
- AddMessage( "" );
-
- highestIndexEntry = GetHighestIndexEntry();
-
- // Import groups
- nGroupsCount = ImportGroups();
- if (nGroupsCount < 0) {
- AddMessage( LPGEN("Group import was not completed."));
- nGroupsCount = 0;
- }
- AddMessage( "" );
-
- // Start benchmark timer
- dwTimer = time(NULL);
-
- if ( !IsProtocolLoaded( szICQModuleName[iICQAccount] )) {
- AddMessage( LPGEN("ICQ account is not installed."));
- AddMessage( LPGEN("No ICQ contacts or history will be imported."));
- AddMessage( "" );
- }
- else {
- // Configure database for fast writing
- CallService(MS_DB_SETSAFETYMODE, FALSE, 0);
-
- // Import contacts
- AddMessage( LPGEN("Importing contacts"));
- for (i = 2001; i <= highestIndexEntry; i++) { //event ids start at 2001
- if (!(i%10)) {
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- if (!(i%100))
- SetProgress(100 * (i - 2001) / (highestIndexEntry - 2001));
-
- ofs = GetIdDatOfs(i);
- if (ofs != 0) {
- if (ImportContact(ofs) != INVALID_HANDLE_VALUE)
- nContactsCount++;
- }
- }
- AddMessage( "" );
-
- // Import history
- if (nImportOption != IMPORT_CONTACTS) {
- AddMessage( LPGEN("Importing history (this may take a while)"));
- for (i = 2001; i <= highestIndexEntry; i++) { //event ids start at 2001
- if (!(i%10)) {
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
-
- if (!(i%100))
- SetProgress(100 * (i - 2001) / (highestIndexEntry - 2001));
-
- ofs = GetIdDatOfs(i);
- if (ofs != 0) ImportEvent(ofs);
- }
- AddMessage( "" );
- }
-
- // Restore database writing mode
- CallService(MS_DB_SETSAFETYMODE, TRUE, 0);
- }
-
- dwTimer = time(NULL) - dwTimer;
-
- AddMessage( LPGEN("Import completed in %d seconds."), dwTimer );
- SetProgress(100);
- AddMessage( LPGEN("Added %d contacts and %d groups."), nContactsCount, nGroupsCount );
- if ( nImportOption != IMPORT_CONTACTS )
- AddMessage( LPGEN("Added %d events and skipped %d duplicates."), nMessagesCount, nDupes );
- }
-
- UnmapViewOfFile(pDat);
- UnmapViewOfFile(pIdx);
- CloseHandle(hDatMapping);
- CloseHandle(hIdxMapping);
- CloseHandle(hDat);
- CloseHandle(hIdx);
-}
diff --git a/plugins/Import/src/mirabilis.h b/plugins/Import/src/mirabilis.h
deleted file mode 100644
index 47f10141e1..0000000000
--- a/plugins/Import/src/mirabilis.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
-
-Import plugin for Miranda IM
-
-Copyright (C) 2001,2002,2003,2004 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede
-
-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.
-
-*/
-
-
-
-#ifndef MIRABILIS_H
-#define MIRABILIS_H
-
-#include <windows.h>
-#include <newpluginapi.h>
-#include <m_database.h>
-
-// ======================
-// == GLOBAL FUNCTIONS ==
-// ======================
-
-HANDLE HistoryImportFindContact(HWND hdlgProgress, char* szModuleName, DWORD uin,int addUnknown);
-
-// =====================
-// == LOCAL FUNCTIONS ==
-// =====================
-
-
-// Main function
-static void MirabilisImport(HWND hdlgProgressWnd);
-
-// GUI callbacks
-INT_PTR CALLBACK ImportTypePageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
-INT_PTR CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
-INT_PTR CALLBACK ProgressPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
-INT_PTR CALLBACK MirabilisPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
-INT_PTR CALLBACK MirabilisOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
-
-// Helper functions for entries
-static int GetHighestIndexEntry(void);
-static int GetIdDatOfs(DWORD id);
-static int GetDatEntryType(DWORD ofs);
-DWORD FindMyDetails(void);
-
-// Parsing functions
-DWORD GetDBVersion();
-int GetEntryVersion(WORD wSeparatorValue);
-DWORD ReadPropertyBlock(DWORD dwOffset, char* SearchWord, int* nSearchResult);
-DWORD ReadSubList(DWORD dwOffset);
-DWORD ReadPropertyBlock(DWORD dwOffset, char* SearchWord, int* nSearchResult);
-DWORD ReadPropertyBlockList(DWORD dwOffset, char* SearchWord, int* nSearchResult);
-DWORD ReadWavList(DWORD ofs);
-DWORD FindGroupList(DWORD dwOffset);
-char* GetGroupName(DWORD dwGroupID);
-int ImportGroups();
-static HANDLE ImportContact(DWORD dwOffset);
-
-BOOL ImportEvent(DWORD dwOffset);
-BOOL ImportMessage(DWORD dwOffset);
-BOOL ImportExtendedMessage(DWORD dwOffset);
-BOOL ImportURLMessage(DWORD dwOffset);
-
-
-
-
-// ======================
-// == GLOBAL VARIABLES ==
-// ======================
-
-extern TCHAR importFile[MAX_PATH];
-extern void (*DoImport)(HWND);
-extern int nImportOption;
-extern int nCustomOptions;
-
-
-extern int cICQAccounts;
-extern char ** szICQModuleName;
-extern TCHAR ** tszICQAccountName;
-extern int iICQAccount;
-
-// =====================
-// == LOCAL VARIABLES ==
-// =====================
-
-static DWORD dwDBVersion;
-static DWORD dwGroupListOfs;
-static PBYTE pIdx,pDat;
-
-// =============
-// == DEFINES ==
-// =============
-
-// Contact versions
-// These numbers are not 100% accurate
-#define ENTRYVUNKNOWN -1
-#define ENTRYV99A 200
-#define ENTRYV99B 300
-#define ENTRYV2000A 400
-#define ENTRYV2000B 455
-#define ENTRYV2001A 500
-#define ENTRYV2001B 515
-#define ENTRYV2002A 533
-
-// Database versions
-#define DBV99A 10
-#define DBV99B 14
-#define DBV2000A 17
-#define DBV2000B 18
-#define DBV2001A 19 // This is used by ICQ 2001a, 2001b & 2002a
-
-#define DATENTRY_UNFILED (DWORD)(-1)
-#define DATENTRY_MESSAGE 0
-#define DATENTRY_CONTACT 1
-#define DATENTRY_IGNORED 2
-#define DATENTRY_SYSTEM 9
-
-#define MAX_NON_ICQ_CONTACTS 100
-
-#define SUBTYPE_NEWMESSAGE 0x50
-#define SUBTYPE_NEWURL 0xA0
-
-#define SUBTYPE_MESSAGE 0xE0 //Message / URL Message / Request For Authorization / "Authorization" / System Request / "You Were Added" / Contacts List
-#define SUBTYPE_CHATREQUEST 0xE1
-#define SUBTYPE_FILEREQUEST 0xE2
-#define SUBTYPE_MYDETAILS 0xE4
-#define SUBTYPE_CONTACTINFO 0xE5
-#define SUBTYPE_REMINDER 0xE6
-#define SUBTYPE_ADDRESSBOOK 0xE7
-#define SUBTYPE_VOICEMSG 0xEC //???
-#define SUBTYPE_NOTE 0xEE
-#define SUBTYPE_EVENTFOLDER 0xEF
-#define SUBTYPE_SERVERLIST 0xF1 //and objectionable word list
-#define SUBTYPE_X1 0xF6 //(new to ICQ 99b???)
-
-#define FILING_RECEIVED 0x01
-#define FILING_DELETED 0x02
-#define FILING_MESSAGE 0x04
-#define MSGTYPE_MESSAGE 1
-#define MSGTYPE_URL 4
-#define MSGTYPE_CLIST 19
-#include <pshpack1.h>
-
-struct TIdxDatEntry {
- DWORD status; //-2=valid, else is an index entry
- DWORD entryId;
- DWORD ofsNext,ofsPrev;
- DWORD datOfs;
-};
-
-struct TIdxIndexEntry {
- DWORD entryIdLow;
- DWORD entryIdHigh;
- DWORD ofsLower;
- DWORD ofsInHere;
- DWORD ofsHigher;
-};
-
-struct TDatEntryHeader {
- DWORD entrySize; //in bytes
- DWORD entryType; //DATENTRY_* constant
- DWORD entryId; //same as in index
- BYTE subType; //SUBTYPE_* constant
- BYTE signature[15];
-};
-
-struct TDatEntryFooter {
- DWORD unknown;
- DWORD sent; //1 if sent, 0 if received
- WORD separator;
- DWORD timestamp; //unix time
-};
-
-struct TDatMessage {
- struct TDatEntryHeader hdr; //hdr.entryType==DATENTRY_MESSAGE && hdr.subType==MSGTYPE_MESSAGE
- WORD separator;
- DWORD filingStatus; //FILING_* flags
- WORD type; //MSGTYPE_* constant
- DWORD uin;
- WORD textLen;
- char text[1]; //0xFE separates description & URL in URLs
- //a struct TDatEntryFooter comes here
-};
-
-#include <poppack.h>
-
-#endif
diff --git a/plugins/Import/src/miranda.cpp b/plugins/Import/src/miranda.cpp
index 068f53acf0..0c20b61d7a 100644
--- a/plugins/Import/src/miranda.cpp
+++ b/plugins/Import/src/miranda.cpp
@@ -1,8 +1,8 @@
/*
-Import plugin for Miranda IM
+Import plugin for Miranda NG
-Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede
+Copyright (C) 2012 George Hazan
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -20,92 +20,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-// ==============
-// == INCLUDES ==
-// ==============
-
#include "import.h"
-
#include "resource.h"
-#include "mirandadb0700.h"
-
-// ======================
-// == GLOBAL FUNCTIONS ==
-// ======================
-
-HANDLE HContactFromNumericID(char* pszProtoName, char* pszSetting, DWORD dwID);
-HANDLE HContactFromID(char* pszProtoName, char* pszSetting, char* pszID);
-
-HANDLE AddContact(HWND hdlgProgress, char* pszProtoName, char* pszUniqueSetting, DBVARIANT* id, DBVARIANT* nick, DBVARIANT* group);
-
-BOOL IsProtocolLoaded(char* pszProtocolName);
-BOOL IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei);
-
-INT_PTR CALLBACK ImportTypePageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
-INT_PTR CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
-INT_PTR CALLBACK ProgressPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
-INT_PTR CALLBACK MirandaOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
-INT_PTR CALLBACK MirandaAdvOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam);
-
-// =====================
-// == LOCAL FUNCTIONS ==
-// =====================
void MirandaImport(HWND hdlgProgress);
-int CheckFileFormat(HANDLE hFile);
-static HANDLE ImportContact(HANDLE hDbFile, struct DBContact Contact);
-static void ImportHistory(HANDLE hDbFile, struct DBContact Contact, PROTOCOLDESCRIPTOR **protocol, int protoCount);
-static int ImportGroups(HANDLE hDbFile, struct DBHeader *pdbHeader);
-
-// Comment: The Find* functions only return a file offset.
-// The Get* functions actually reads the requested
-// data from the file and gives you a pointer to a structure
-// containing the data.
-
-DWORD FindFirstContact(struct DBHeader* pDbHeader);
-DWORD FindNextContact(struct DBContact* pDbContact);
-DWORD FindNextEvent(HANDLE hDbFile, DWORD dwOffset);
-DWORD FindOwnerContact(struct DBHeader* pDbHeader);
-
-int GetContactCount(struct DBHeader* pDbHeader);
-BOOL GetContact(HANDLE hDbFile, DWORD dwOffset, struct DBContact* pDbContact);
-BOOL GetSetting(HANDLE hDbFile, struct DBContact* pDbContact, char* pszModuleName, char* pszSettingName, DBVARIANT* pValue);
-char* GetNextSetting(char* pDbSetting);
-BOOL GetSettings(HANDLE hDbFile, DWORD dwOffset, struct DBContactSettings** pDbSettings);
-struct DBContactSettings* GetSettingsGroupByModuleName(HANDLE hdbFile, struct DBContact* pDbContact, char* pszName);
-DWORD GetBlobSize(struct DBContactSettings* pDbSettings);
-int GetSettingByName(struct DBContactSettings* pDbSettings, char* pszSettingName, DBVARIANT* pValue);
-int GetSettingValue(char* pBlob,DBVARIANT* pValue);
-
-BOOL GetEvent(HANDLE hDbFile, DWORD dwOffset, DBEVENTINFO* pDBEI);
-char* GetName(HANDLE hDbFile, DWORD dwOffset);
-
-
-// ======================
-// == GLOBAL VARIABLES ==
-// ======================
-
-extern void (*DoImport)(HWND);
-extern int nImportOption;
-extern int nCustomOptions;
-
// =====================
// == LOCAL VARIABLES ==
// =====================
TCHAR importFile[MAX_PATH];
-HWND hdlgProgress;
-DWORD dwFileSize;
-
-DWORD nDupes;
-DWORD nContactsCount;
-DWORD nMessagesCount;
-DWORD nGroupsCount;
-DWORD nSkippedEvents;
-DWORD nSkippedContacts;
-
-time_t dwSinceDate = 0;
// =============
// == DEFINES ==
@@ -115,56 +39,44 @@ time_t dwSinceDate = 0;
#define EVENTTYPE_URL 1
#define EVENTTYPE_FILE 1002
-
-// Supported database versions
-#define DB_INVALID 0x00000000 // Unknown or corrupted DAT
-#define DB_000700 0x00000700 // Miranda 0.1.0.0 - 0.1.2.2+
-
-// DAT file signature
-struct DBSignature {
- char name[15];
- BYTE eof;
-};
-
-static struct DBSignature dbSignature={"Miranda ICQ DB",0x1A};
-
// ====================
// ====================
// == IMPLEMENTATION ==
// ====================
// ====================
-static void SearchForLists(HWND hdlg, const TCHAR *mirandaPath, const TCHAR *mirandaProf, const TCHAR *pattern, const TCHAR *type)
+static void SearchForLists(HWND hdlg, const TCHAR *mirandaPath, const TCHAR *mirandaProf)
{
- HANDLE hFind;
+ // find in Miranda profile subfolders
+ TCHAR searchspec[MAX_PATH];
+ mir_sntprintf(searchspec, SIZEOF(searchspec), _T("%s\\*.*"), mirandaPath);
+
WIN32_FIND_DATA fd;
- TCHAR szSearchPath[MAX_PATH];
- TCHAR szRootName[MAX_PATH];
- TCHAR* str2;
- int i;
-
- mir_sntprintf(szSearchPath, SIZEOF(szSearchPath), _T("%s\\%s"), mirandaPath, pattern);
- hFind = FindFirstFile(szSearchPath, &fd);
- if (hFind != INVALID_HANDLE_VALUE)
- {
- do
- {
- _tcscpy(szRootName, fd.cFileName);
- str2 = _tcsrchr(szRootName, '.');
- if (str2 != NULL) *str2 = 0;
- if (mirandaProf == NULL || _tcsicmp(mirandaProf, szRootName))
- {
- _tcscat(szRootName, type);
- i = SendDlgItemMessage(hdlg, IDC_LIST, LB_ADDSTRING, 0, (LPARAM)szRootName);
- str2 = (TCHAR*)mir_alloc((_tcslen(mirandaPath) + 2 + _tcslen(fd.cFileName)) * sizeof(TCHAR));
- wsprintf(str2, _T("%s\\%s"), mirandaPath, fd.cFileName);
- SendDlgItemMessage(hdlg, IDC_LIST, LB_SETITEMDATA, i, (LPARAM)str2);
- }
- }
- while( FindNextFile( hFind, &fd ));
+ HANDLE hFind = FindFirstFile(searchspec, &fd);
+ if (hFind == INVALID_HANDLE_VALUE)
+ return;
- FindClose( hFind );
+ do {
+ // find all subfolders except "." and ".."
+ if ( !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || !_tcscmp(fd.cFileName, _T(".")) || !_tcscmp(fd.cFileName, _T("..")))
+ continue;
+
+ // skip the current profile too
+ if (mirandaProf != NULL && !_tcsicmp(mirandaProf, fd.cFileName))
+ continue;
+
+ TCHAR buf[MAX_PATH], profile[MAX_PATH];
+ mir_sntprintf(buf, SIZEOF(buf), _T("%s\\%s\\%s.dat"), mirandaPath, fd.cFileName, fd.cFileName);
+ if ( _taccess(buf, 0) == 0) {
+ mir_sntprintf(profile, SIZEOF(profile), _T("%s.dat"), fd.cFileName);
+
+ int i = SendDlgItemMessage(hdlg, IDC_LIST, LB_ADDSTRING, 0, (LPARAM)profile);
+ SendDlgItemMessage(hdlg, IDC_LIST, LB_SETITEMDATA, i, (LPARAM)mir_tstrdup(buf));
+ }
}
+ while (FindNextFile(hFind, &fd));
+
+ FindClose(hFind);
}
INT_PTR CALLBACK MirandaPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam)
@@ -184,10 +96,10 @@ INT_PTR CALLBACK MirandaPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lPa
pfd2 = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)_T("%miranda_profile%"), (LPARAM)&dat);
pfn = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)_T("%miranda_profilename%"), (LPARAM)&dat);
- SearchForLists(hdlg, pfd2, pfn, _T("*.dat"), _T(" (Miranda IM v0.x)"));
- SearchForLists(hdlg, pfd1, NULL, _T("*.dat"), _T(" (Miranda IM v0.x)"));
+ SearchForLists(hdlg, pfd2, pfn);
+ SearchForLists(hdlg, pfd1, NULL);
if (lstrcmpi(pfd, pfd2))
- SearchForLists(hdlg, pfd, NULL, _T("*.dat"), _T(" (Miranda IM v0.x)"));
+ SearchForLists(hdlg, pfd, NULL);
mir_free(pfn);
mir_free(pfd2);
@@ -199,7 +111,7 @@ INT_PTR CALLBACK MirandaPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lPa
case WM_COMMAND:
switch(LOWORD(wParam)) {
case IDC_BACK:
- PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_IMPORTTYPE,(LPARAM)ImportTypePageProc);
+ PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_WIZARDINTRO,(LPARAM)WizardIntroPageProc);
break;
case IDOK:
@@ -267,7 +179,6 @@ INT_PTR CALLBACK MirandaPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lPa
return FALSE;
}
-
INT_PTR CALLBACK MirandaOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message) {
@@ -459,980 +370,3 @@ INT_PTR CALLBACK MirandaAdvOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,
return FALSE;
}
-#ifndef INVALID_SET_FILE_POINTER
-#define INVALID_SET_FILE_POINTER ((DWORD)-1)
-#endif
-
-// Read header from file, returns null on failure
-struct DBHeader* GetHeader(HANDLE hDbFile)
-{
- struct DBHeader* pdbHeader;
- DWORD dwBytesRead;
-
- if (( pdbHeader = (DBHeader*)calloc(1, sizeof(struct DBHeader))) == NULL )
- return NULL;
-
- // Goto start of file
- if (SetFilePointer(hDbFile, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
- return FALSE;
-
- // Read header
- if ( !ReadFile(hDbFile, pdbHeader, sizeof(struct DBHeader), &dwBytesRead, NULL ) ||
- dwBytesRead != sizeof(struct DBHeader))
- return NULL;
-
- // Return pointer to header
- return pdbHeader;
-}
-
-int CheckFileFormat(HANDLE hDbFile)
-{
- struct DBHeader* pdbHeader;
-
- // Read header
- if (( pdbHeader = GetHeader(hDbFile)) == NULL )
- return DB_INVALID;
-
- // Check header signature
- if (memcmp(pdbHeader->signature, &dbSignature, sizeof(pdbHeader->signature))) {
- AddMessage( LPGEN("Signature mismatch" ));
- return DB_INVALID;
- }
-
- // Determine Miranda version
- switch (pdbHeader->version) {
- case DB_000700:
- AddMessage( LPGEN("This looks like a Miranda database, version 0.1.0.0 or above." ));
- free(pdbHeader);
- return DB_000700;
-
- default:
- AddMessage( LPGEN("Version mismatch" ));
- free(pdbHeader);
- return DB_INVALID;
-} }
-
-// High level Miranda DB access functions
-// Returns true if pValue points to the requested value
-
-BOOL GetSetting(HANDLE hDbFile, struct DBContact* pDbContact, char* pszModuleName, char* pszSettingName, DBVARIANT* pValue)
-{
- struct DBContactSettings* pDbSettings;
- if ( pDbSettings = GetSettingsGroupByModuleName(hDbFile, pDbContact, pszModuleName)) {
- if ( GetSettingByName( pDbSettings, pszSettingName, pValue )) {
- free(pDbSettings);
- return TRUE;
- }
- #ifdef _LOGGING
- AddMessage( LPGEN("Failed to find setting %s" ), pszSettingName );
- #endif
- free(pDbSettings);
- }
-#ifdef _LOGGING
- else AddMessage( LPGEN("Failed to find module %s" ), pszModuleName );
-#endif
-
- // Search failed
- pValue->type = 0;
- return FALSE;
-}
-
-// **
-// ** CONTACT CHAIN
-// **
-
-// Return offset to first contact
-DWORD FindFirstContact(struct DBHeader* pDbHeader)
-{
- if (!pDbHeader)
- return 0;
-
- return pDbHeader->ofsFirstContact;
-}
-
-DWORD FindOwnerContact(struct DBHeader* pDbHeader)
-{
- if (!pDbHeader)
- return 0;
-
- return pDbHeader->ofsUser;
-}
-
-// Return offset to next contact
-DWORD FindNextContact(struct DBContact* pDbContact)
-{
- if (!pDbContact)
- return 0;
-
- if (pDbContact->signature != DBCONTACT_SIGNATURE)
- return 0;
-
- return pDbContact->ofsNext;
-}
-
-
-// Read the contact at offset 'dwOffset'
-// Returns true if successful and pDbContact points to the contact struct
-// pDbContact must point to allocated struct
-BOOL GetContact(HANDLE hDbFile, DWORD dwOffset, struct DBContact* pDbContact)
-{
- DWORD dwBytesRead;
-
- // Early reject
- if (dwOffset == 0 || dwOffset >= dwFileSize)
- return FALSE;
-
- // ** Read and verify the struct
-
- if (SetFilePointer(hDbFile, (LONG)dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
- return FALSE;
-
- if ((!ReadFile(hDbFile, pDbContact, sizeof(struct DBContact), &dwBytesRead, NULL)) ||
- (dwBytesRead != sizeof(struct DBContact)))
- return FALSE;
-
- if ((pDbContact->signature != DBCONTACT_SIGNATURE) ||
- (pDbContact->ofsNext >= dwFileSize))
- return FALSE; // Contact corrupted
-
- return TRUE;
-}
-
-// Return ptr to next setting in settings struct
-char* GetNextSetting(char* pDbSetting)
-{
- // Get next setting
- pDbSetting = pDbSetting + *pDbSetting+1; // Skip name
- switch( *(BYTE*)pDbSetting ) {
- case DBVT_BYTE:
- pDbSetting = pDbSetting+1+1;
- break;
-
- case DBVT_WORD:
- pDbSetting = pDbSetting+1+2;
- break;
-
- case DBVT_DWORD:
- pDbSetting = pDbSetting+1+4;
- break;
-
- case DBVT_ASCIIZ:
- case DBVT_UTF8:
- case DBVT_BLOB:
- case DBVTF_VARIABLELENGTH:
- pDbSetting = pDbSetting + 3 + *(WORD*)(pDbSetting+1);
- break;
-
- case DBVT_DELETED:
- AddMessage( LPGEN("DEBUG: Deleted setting treated as 0-length setting"));
- pDbSetting = pDbSetting+1;
- break;
-
- default:
- // Unknown datatype assert
- AddMessage( LPGEN("ERROR: Faulty settings chain"));
- return NULL;
- }
-
- return pDbSetting;
-}
-
-
-// **
-// ** SETTINGS CHAIN
-// **
-
-// Return the settings at offset 'dwOffset'
-BOOL GetSettingsGroup(HANDLE hDbFile, DWORD dwOffset, struct DBContactSettings** pDbSettings)
-{
- DWORD dwBytesRead, dwBlobSize, dwHead;
- struct DBContactSettings pSettings;
-
- // Early reject
- if (dwOffset == 0 || dwOffset >= dwFileSize)
- return FALSE;
-
- // ** Read and verify the struct
- if (SetFilePointer(hDbFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
- return FALSE;
-
- dwHead = offsetof(struct DBContactSettings, blob);
- if ((!ReadFile(hDbFile, &pSettings, dwHead, &dwBytesRead, NULL)) ||
- (dwBytesRead != dwHead))
- return FALSE;
-
- if (pSettings.signature != DBCONTACTSETTINGS_SIGNATURE)
- return FALSE; // Setttings corrupted
-
- // ** Read the struct and the following blob
- dwBlobSize = pSettings.cbBlob;
- if (!(*pDbSettings = (DBContactSettings *)calloc(1, sizeof(struct DBContactSettings) + dwBlobSize)))
- return FALSE;
-
- memcpy(*pDbSettings, &pSettings, dwHead );
-
- if ((!ReadFile(hDbFile, (*pDbSettings)->blob, sizeof(struct DBContactSettings) - dwHead + dwBlobSize, &dwBytesRead, NULL)) ||
- (dwBytesRead != sizeof(struct DBContactSettings) - dwHead + dwBlobSize))
- {
- free(*pDbSettings);
- return FALSE;
- }
-
- return TRUE;
-}
-
-// pDbContact is a ptr to a struct DBContact
-// Returns pointer to a struct DBContactSettings or NULL
-struct DBContactSettings* GetSettingsGroupByModuleName(HANDLE hDbFile, struct DBContact* pDbContact, char* pszName)
-{
- char* pszGroupName;
- struct DBContactSettings* pSettingsGroup;
- DWORD dwGroupOfs;
-
- // Get ptr to first settings group
- if (!(dwGroupOfs = pDbContact->ofsFirstSettings))
- return NULL; // No settings exists in this contact
-
- // Loop over all settings groups
- while (dwGroupOfs && dwGroupOfs < dwFileSize) {
- pSettingsGroup = NULL;
-
- // Read and verify the struct
- if (!GetSettingsGroup(hDbFile, dwGroupOfs, &pSettingsGroup))
- return NULL; // Bad struct
-
- // Struct OK, now get the name
- if ((pszGroupName = GetName(hDbFile, pSettingsGroup->ofsModuleName))) {
-
- // Is it the right one?
- if (strcmp(pszGroupName, pszName) == 0) {
- #ifdef _LOGGING
- AddMessage( LPGEN("Found module: %s"), pszGroupName );
- #endif
- return pSettingsGroup;
- }
- #ifdef _LOGGING
- else AddMessage( LPGEN("Ignoring module: %s"), pszGroupName );
- #endif
- }
- else AddMessage( LPGEN("Warning: Found module with no name"));
-
- dwGroupOfs = pSettingsGroup->ofsNext;
-
- if (pSettingsGroup)
- free(pSettingsGroup);
- }
-
- // Search failed
- return NULL;
-}
-
-// pDbSettings must point to a complete DBContactSettings struct in memory
-int GetSettingByName(struct DBContactSettings* pDbSettings, char* pszSettingName, DBVARIANT* dbv)
-{
- char pszName[256];
- // We need at least one setting to start with
- char* pDbSetting = (char*)pDbSettings->blob;
- if ( !pDbSetting )
- return FALSE;
-
- // ** pDbSettings now points to the first setting in this module
-
- // Loop over all settings
- while (pDbSetting && *pDbSetting) {
- memcpy(pszName, pDbSetting+1, *pDbSetting);
- pszName[*pDbSetting] = 0;
-
- // Is this the right one?
- if (strcmp(pszSettingName, pszName) == 0) {
- return GetSettingValue(pDbSetting, dbv);
- }
-
- #ifdef _LOGGING
- AddMessage( LPGEN("Ignoring setting: %s"), pszName );
- #endif
- pDbSetting = GetNextSetting(pDbSetting);
- }
-
- // Search failed
- return FALSE;
-}
-
-// dwSettingpointer points to a valid DBSettings struct
-int GetSettingValue(char* pBlob, DBVARIANT* dbv)
-{
- #ifdef _LOGGING
- {
- char* pszName = calloc((*pBlob)+1, 1);
- memcpy(pszName, pBlob+1, *pBlob);
- AddMessage( LPGEN("Getting type %u value for setting: %s"), (BYTE)*(pBlob+(*pBlob)+1), pszName );
- free(pszName);
- }
- #endif
-
- // Skip name
- pBlob = pBlob + (*pBlob)+1;
- dbv->type = ( BYTE )*pBlob++;
-
- // Check what type it is
- switch( dbv->type ) {
- case DBVT_BYTE:
- dbv->bVal = *pBlob;
- return TRUE;
-
- case DBVT_WORD:
- dbv->wVal = *(WORD*)pBlob;
- return TRUE;
-
- case DBVT_DWORD:
- dbv->dVal = *(DWORD*)pBlob;
- return TRUE;
-
- case DBVT_ASCIIZ:
- case DBVT_UTF8:
- dbv->cchVal = *(WORD*)pBlob;
- dbv->pszVal = (char *)calloc( dbv->cchVal+1, sizeof( char ));
- memcpy( dbv->pszVal, pBlob+2, dbv->cchVal );
- dbv->pszVal[ dbv->cchVal ] = 0;
- return TRUE;
-
- case DBVTF_VARIABLELENGTH:
- case DBVT_BLOB:
- dbv->cpbVal = *(WORD*)pBlob;
- dbv->pbVal = (BYTE *)calloc( dbv->cpbVal+1, sizeof( char ));
- memcpy( dbv->pbVal, pBlob+2, dbv->cpbVal );
- dbv->pbVal[ dbv->cpbVal ] = 0;
- return TRUE;
-
- case DBVT_DELETED:
- AddMessage( LPGEN("DEBUG: Deleted setting treated as 0-length setting"));
-
- default:
- dbv->type = DBVT_DELETED;
- }
-
- return FALSE;
-}
-
-void FreeVariant( DBVARIANT* dbv )
-{
- switch( dbv->type ) {
- case DBVT_ASCIIZ:
- case DBVT_UTF8:
- if ( dbv->pszVal )
- free( dbv->pszVal );
- break;
-
- case DBVTF_VARIABLELENGTH:
- case DBVT_BLOB:
- if ( dbv->pbVal )
- free( dbv->pbVal );
- break;
- }
-
- dbv->type = 0;
-}
-
-void WriteVariant( HANDLE hContact, const char* module, const char* var, DBVARIANT* dbv )
-{
- DBCONTACTWRITESETTING dbw;
- dbw.szModule = module;
- dbw.szSetting = var;
- dbw.value = *dbv;
- CallService( MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&dbw );
-}
-
-// Returns true if pDBEI has been filled in with nice values
-// Don't forget to free those pointers!
-BOOL GetEvent(HANDLE hDbFile, DWORD dwOffset, DBEVENTINFO* pDBEI)
-{
- DWORD dwBytesRead;
- struct DBEvent pEvent;
- static char pBlob[65536];
-
- // Early reject
- if (dwOffset == 0 || dwOffset >= dwFileSize)
- return FALSE;
-
- // ** Read and verify the struct
- if (SetFilePointer(hDbFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
- return FALSE;
-
- if (!ReadFile(hDbFile, &pEvent, offsetof(struct DBEvent, blob), &dwBytesRead, NULL) ||
- (dwBytesRead != offsetof(struct DBEvent, blob)))
- return FALSE;
-
- if (pEvent.signature != DBEVENT_SIGNATURE)
- return FALSE; // Event corrupted
-
- // ** Read the blob
- if ((!ReadFile(hDbFile, pBlob, pEvent.cbBlob, &dwBytesRead, NULL)) ||
- (dwBytesRead != pEvent.cbBlob))
- {
- return FALSE;
- }
-
- // ** Copy the static part to the event info struct
- pDBEI->timestamp = pEvent.timestamp;
- pDBEI->eventType = pEvent.eventType;
- pDBEI->cbSize = sizeof(DBEVENTINFO);
- pDBEI->cbBlob = pEvent.cbBlob;
- pDBEI->pBlob = (PBYTE)pBlob;
- pDBEI->flags = (pEvent.flags & ~(DBEF_SENT+DBEF_READ)) +
- ((pEvent.flags & DBEF_SENT) ? DBEF_SENT : DBEF_READ ); // Imported events are always marked READ
-
- if (!(pDBEI->szModule = GetName(hDbFile, pEvent.ofsModuleName))) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-// Returns a pointer to a string with the name
-// from a DBModuleName struct if given a file offset
-// Returns NULL on failure
-char* GetName(HANDLE hDbFile, DWORD dwOffset)
-{
- static DWORD dwLastOffset = 0;
- static HANDLE hLastDbFile = NULL;
- static char szName[256] = {0};
-
- DWORD dwBytesRead;
- struct DBModuleName pModule;
-
- // Early reject
- if (dwOffset == 0 || dwOffset >= dwFileSize)
- return FALSE;
-
- // Quick lookup
- if (dwOffset == dwLastOffset && hDbFile == hLastDbFile)
- return szName;
-
- // ** Read and verify the name struct
- if (SetFilePointer(hDbFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
- return NULL;
-
- if ((!ReadFile(hDbFile, &pModule, offsetof(struct DBModuleName, name), &dwBytesRead, NULL)) ||
- (dwBytesRead != offsetof(struct DBModuleName, name)))
- return NULL;
-
- if (pModule.signature != DBMODULENAME_SIGNATURE) {
- AddMessage( LPGEN("Modulename corrupted"));
- return NULL; // ModuleName corrupted
- }
-
- // ** Name struct OK, now read name into string buffer
- if ((!ReadFile(hDbFile, szName, pModule.cbName, &dwBytesRead, NULL)) || (dwBytesRead != pModule.cbName)) {
- return NULL;
- }
-
- // terminate string
- szName[pModule.cbName] = 0;
-
- // update last offset
- dwLastOffset = dwOffset;
- hLastDbFile = hDbFile;
-
- return szName;
-}
-
-DWORD FindNextEvent(HANDLE hDbFile, DWORD dwOffset)
-{
- DWORD dwBytesRead;
- struct DBEvent pEvent;
-
- // Early reject
- if (dwOffset == 0 || dwOffset >= dwFileSize)
- return FALSE;
-
- // ** Read and verify the struct
- if (SetFilePointer(hDbFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
- return FALSE;
-
- if ((!ReadFile(hDbFile, &pEvent, sizeof(struct DBEvent), &dwBytesRead, NULL)) ||
- (dwBytesRead != sizeof(struct DBEvent)))
- return FALSE;
-
- if ( pEvent.signature != DBEVENT_SIGNATURE || pEvent.ofsNext > dwFileSize )
- return FALSE; // Event corrupted
-
- return pEvent.ofsNext;
-}
-
-int ImportGroups(HANDLE hDbFile, struct DBHeader* pdbHeader)
-{
- struct DBContactSettings* pDbSettings;
- struct DBContact DbContact;
- char* pSetting;
- DWORD dwOffset;
- int nGroups = 0;
-
- // Find owner data
- dwOffset = pdbHeader->ofsUser;
- if (!GetContact(hDbFile, dwOffset, &DbContact)) {
- AddMessage( LPGEN("No owner found."));
- return -1;
- }
-
- // Find the module with the groups, and import them all
- if ( pDbSettings = GetSettingsGroupByModuleName( hDbFile, &DbContact, "CListGroups" )) {
- pSetting = (char *)pDbSettings->blob;
- while ( pSetting && *pSetting ) {
- DBVARIANT dbv;
- if ( GetSettingValue( pSetting, &dbv )) {
- if ( CreateGroup( dbv.type, dbv.pszVal+1, NULL ))
- nGroups++;
- FreeVariant( &dbv );
- }
- pSetting = GetNextSetting(pSetting);
- }
- free(pDbSettings);
- }
-
- return nGroups;
-}
-
-HANDLE ImportContact(HANDLE hDbFile, struct DBContact Contact)
-{
- HANDLE hContact;
- DBVARIANT group, nick, dbv;
- char* pszProtoName;
- char* pszUniqueSetting;
- char* pszUserName;
- char id[ 40 ];
-
- // Check what protocol this contact belongs to
- if ( !GetSetting( hDbFile, &Contact, "Protocol", "p", &dbv )) {
- AddMessage( LPGEN("Skipping contact with no protocol"));
- return INVALID_HANDLE_VALUE;
- }
-
- pszProtoName = NEWSTR_ALLOCA( dbv.pszVal );
- FreeVariant( &dbv );
-
- if ( !IsProtocolLoaded( pszProtoName )) {
- AddMessage( LPGEN("Skipping contact, %s not installed."), pszProtoName );
- return INVALID_HANDLE_VALUE;
- }
-
- // Skip protocols with no unique id setting (some non IM protocols return NULL)
- pszUniqueSetting = (char*)CallProtoService(pszProtoName, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
- if ( !pszUniqueSetting || (INT_PTR)pszUniqueSetting == CALLSERVICE_NOTFOUND ) {
- AddMessage( LPGEN("Skipping non-IM contact (%s)"), pszProtoName );
- return INVALID_HANDLE_VALUE;
- }
-
- if ( !GetSetting(hDbFile, &Contact, pszProtoName, pszUniqueSetting, &dbv )) {
- AddMessage( LPGEN("Skipping %s contact, ID not found"), pszProtoName );
- return INVALID_HANDLE_VALUE;
- }
-
- // Does the contact already exist?
- if ( dbv.type == DBVT_DWORD ) {
- pszUserName = _ltoa( dbv.dVal, id, 10 );
- hContact = HContactFromNumericID( pszProtoName, pszUniqueSetting, dbv.dVal );
- }
- else {
- pszUserName = NEWSTR_ALLOCA( dbv.pszVal );
- hContact = HContactFromID( pszProtoName, pszUniqueSetting, dbv.pszVal );
- }
-
- if ( hContact != INVALID_HANDLE_VALUE ) {
- AddMessage( LPGEN("Skipping duplicate %s contact %s"), pszProtoName, pszUserName );
- FreeVariant( &dbv );
- return INVALID_HANDLE_VALUE;
- }
- // No, add contact and copy some important settings
- GetSetting(hDbFile, &Contact, "CList", "Group", &group);
-
- if ( !GetSetting( hDbFile, &Contact, "CList", "MyHandle", &nick ))
- GetSetting(hDbFile, &Contact, pszProtoName, "Nick", &nick );
-
- hContact = AddContact( hdlgProgress, pszProtoName, pszUniqueSetting, &dbv, &nick, &group );
-
- if ( hContact != INVALID_HANDLE_VALUE) {
-
- // Hidden?
- if ( GetSetting( hDbFile, &Contact, "CList", "Hidden", &dbv )) {
- WriteVariant( hContact, "CList", "Hidden", &dbv );
- FreeVariant( &dbv );
- }
- // Ignore settings
- if ( GetSetting( hDbFile, &Contact, "Ignore", "Mask1", &dbv )) {
- WriteVariant( hContact, "Ignore", "Mask1", &dbv );
- FreeVariant( &dbv );
- }
-
- // Apparent mode
- if ( GetSetting( hDbFile, &Contact, pszProtoName, "ApparentMode", &dbv )) {
- WriteVariant( hContact, pszProtoName, "ApparentMode", &dbv );
- FreeVariant( &dbv );
- }
-
- // Nick
- if ( GetSetting( hDbFile, &Contact, pszProtoName, "Nick", &dbv )) {
- WriteVariant( hContact, pszProtoName, "Nick", &dbv );
- FreeVariant( &dbv );
- }
-
- // Myhandle
- if ( GetSetting( hDbFile, &Contact, pszProtoName, "MyHandle", &dbv )) {
- WriteVariant( hContact, pszProtoName, "MyHandle", &dbv );
- FreeVariant( &dbv );
- }
-
- // First name
- if ( GetSetting( hDbFile, &Contact, pszProtoName, "FirstName", &dbv )) {
- WriteVariant( hContact, pszProtoName, "FirstName", &dbv );
- FreeVariant( &dbv );
- }
-
- // Last name
- if ( GetSetting( hDbFile, &Contact, pszProtoName, "LastName", &dbv )) {
- WriteVariant( hContact, pszProtoName, "LastName", &dbv );
- FreeVariant( &dbv );
- }
-
- // About
- if ( GetSetting( hDbFile, &Contact, pszProtoName, "About", &dbv )) {
- WriteVariant( hContact, pszProtoName, "About", &dbv );
- FreeVariant( &dbv );
- }
- }
- else AddMessage( LPGEN("Unknown error while adding %s contact %s"), pszProtoName, pszUserName );
-
- return hContact;
-}
-
-// This function should always be called after contact import. That is
-// why there are no messages for errors related to contacts. Those
-// would only be a repetition of the messages printed during contact
-// import.
-
-static void ImportHistory(HANDLE hDbFile, struct DBContact Contact, PROTOCOLDESCRIPTOR **protocol, int protoCount)
-{
- HANDLE hContact = INVALID_HANDLE_VALUE;
- DWORD dwOffset;
- MSG msg;
- DBVARIANT proto;
- int i, skipAll, bIsVoidContact;
-
- // Is it contats history import?
- if ( protoCount == 0 ) {
-
- // Check what protocol this contact belongs to
- if ( GetSetting( hDbFile, &Contact, "Protocol", "p", &proto )) {
-
- // Protocol installed?
- if ( IsProtocolLoaded( proto.pszVal )) {
- // Is contact in database?
- char* pszUniqueSetting = (char*)CallProtoService( proto.pszVal, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
-
- // Skip protocols with no unique id setting (some non IM protocols return NULL)
- if ( pszUniqueSetting && ( INT_PTR )pszUniqueSetting != CALLSERVICE_NOTFOUND ) {
- DBVARIANT dbv;
- if ( GetSetting( hDbFile, &Contact, proto.pszVal, pszUniqueSetting, &dbv )) {
- if ( dbv.type == DBVT_DWORD )
- hContact = HContactFromNumericID( proto.pszVal, pszUniqueSetting, dbv.dVal );
- else
- hContact = HContactFromID( proto.pszVal, pszUniqueSetting, dbv.pszVal );
- FreeVariant( &dbv );
- } } }
- FreeVariant( &proto );
- }
- }
- else hContact = NULL; //system history import
-
- // OK to import this chain?
- if (hContact == INVALID_HANDLE_VALUE) {
- nSkippedContacts++;
- return;
- }
-
- i = skipAll = 0;
- bIsVoidContact = CallService( MS_DB_EVENT_GETCOUNT, ( WPARAM )hContact, 0 ) == 0;
-
- // Get the start of the event chain
- dwOffset = Contact.ofsFirstEvent;
- while (dwOffset) {
- int skip = 0;
-
- // Copy the event and import it
- DBEVENTINFO dbei = { 0 };
- if (GetEvent(hDbFile, dwOffset, &dbei)) {
- // check protocols during system history import
- if (hContact == NULL) {
- int i;
- skipAll = 1;
-
- for(i = 0; i < protoCount; i++)
- if (!strcmp(dbei.szModule, protocol[i]->szName)) { //&& protocol[i]->type == PROTOTYPE_PROTOCOL)
- skipAll = 0;
- break;
- }
-
- skip = skipAll;
- }
-
- // custom filtering
- if (!skip && nImportOption == IMPORT_CUSTOM) {
- BOOL sent = (dbei.flags&DBEF_SENT);
-
- if (dbei.timestamp < (DWORD)dwSinceDate)
- skip = 1;
-
- if (!skip) {
- if (hContact) {
- skip = 1;
- switch(dbei.eventType) {
- case EVENTTYPE_MESSAGE:
- if ((sent?IOPT_MSGSENT:IOPT_MSGRECV)&nCustomOptions)
- skip = 0;
- break;
- case EVENTTYPE_FILE:
- if ((sent?IOPT_FILESENT:IOPT_FILERECV)&nCustomOptions)
- skip = 0;
- break;
- case EVENTTYPE_URL:
- if ((sent?IOPT_URLSENT:IOPT_URLRECV)&nCustomOptions)
- skip = 0;
- break;
- default:
- if ((sent?IOPT_OTHERSENT:IOPT_OTHERRECV)&nCustomOptions)
- skip = 0;
- break;
- }
- }
- else if ( !( nCustomOptions & IOPT_SYSTEM ))
- skip = 1;
- }
-
- if (skip)
- nSkippedEvents++;
- }
-
- if (!skip) {
- // Check for duplicate entries
- if ( !IsDuplicateEvent( hContact, dbei )) {
- // Add dbevent
- if (!bIsVoidContact)
- dbei.flags &= ~DBEF_FIRST;
- if (CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei))
- nMessagesCount++;
- else
- AddMessage( LPGEN("Failed to add message"));
- }
- else
- nDupes++;
- }
- }
-
- if ( !( i%10 )) {
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- } }
-
- // skip this chain if needed
- if ( skipAll )
- break;
-
- // Get next event
- dwOffset = FindNextEvent(hDbFile, dwOffset);
- i++;
- }
-}
-
-static void MirandaImport(HWND hdlg)
-{
- int nDBVersion;
- int i;
- int nNumberOfContacts = 0;
- MSG msg;
- DWORD dwTimer;
- DWORD dwOffset;
- HANDLE hFile;
- char* pszModuleName = NULL;
- struct DBHeader* pdbHeader = NULL;
- struct DBContact Contact;
-
- // Just to keep the macros happy
- hdlgProgress = hdlg;
-
- // Reset statistics
- nSkippedEvents = 0;
- nDupes = 0;
- nContactsCount = 0;
- nMessagesCount = 0;
- nGroupsCount = 0;
- nSkippedContacts = 0;
- SetProgress(0);
-
- // Open database
- hFile = CreateFile(importFile,
- GENERIC_READ, // open for reading
- 0, // do not share
- NULL, // no security
- OPEN_EXISTING, // existing file only
- FILE_ATTRIBUTE_NORMAL, // normal file
- NULL); // no attr. template
-
- // Read error
- if (hFile == INVALID_HANDLE_VALUE) {
- AddMessage( LPGEN("Could not open file."));
- SetProgress(100);
- return;
- }
-
- // Check filesize
- dwFileSize = GetFileSize(hFile, NULL) ;
- if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSize < sizeof(struct DBHeader))) {
- AddMessage( LPGEN("This is not a valid Miranda IM database."));
- SetProgress(100);
- CloseHandle(hFile);
- return;
- }
-
- // Check header and database version
- nDBVersion = CheckFileFormat(hFile);
- if (nDBVersion == DB_INVALID) {
- AddMessage( LPGEN("This is not a valid Miranda IM database."));
- SetProgress(100);
- CloseHandle(hFile);
- return;
- }
-
- // Load database header
- if (!(pdbHeader = GetHeader(hFile))) {
- AddMessage( LPGEN("Read failure."));
- SetProgress(100);
- CloseHandle(hFile);
- return;
- }
-
- // Get number of contacts
- nNumberOfContacts = pdbHeader->contactCount;
- AddMessage( LPGEN("Number of contacts in database: %d"), nNumberOfContacts );
- AddMessage( "" );
-
- // Configure database for fast writing
- CallService(MS_DB_SETSAFETYMODE, FALSE, 0);
-
- // Start benchmark timer
- dwTimer = time(NULL);
-
- // Import Groups
- if (nImportOption == IMPORT_ALL || (nCustomOptions & IOPT_GROUPS)) {
- AddMessage( LPGEN("Importing groups."));
- nGroupsCount = ImportGroups(hFile, pdbHeader);
- if (nGroupsCount == -1)
- AddMessage( LPGEN("Group import failed."));
-
- AddMessage( "" );
- }
- // End of Import Groups
-
- // Import Contacts
- if (nImportOption != IMPORT_CUSTOM || (nCustomOptions & IOPT_CONTACTS)) {
- AddMessage( LPGEN("Importing contacts."));
- i = 1;
- dwOffset = FindFirstContact(pdbHeader);
- while (dwOffset && (dwOffset < dwFileSize)) {
- if (!GetContact(hFile, dwOffset, &Contact)) {
- AddMessage( LPGEN("ERROR: Chain broken, no valid contact at %d"), dwOffset );
- SetProgress(100);
- break;
- }
-
- if (ImportContact(hFile, Contact) != INVALID_HANDLE_VALUE)
- nContactsCount++;
-
- // Update progress bar
- SetProgress(100 * i / nNumberOfContacts);
- i++;
-
- // Process queued messages
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- // Get next contact in chain
- dwOffset = FindNextContact(&Contact);
- }
- }
- else AddMessage( LPGEN("Skipping new contacts import."));
- AddMessage( "" );
- // End of Import Contacts
-
- // Import history
- if (nImportOption != IMPORT_CONTACTS) {
- // Import NULL contact message chain
- if (nImportOption == IMPORT_ALL || (nCustomOptions & IOPT_SYSTEM)) {
- AddMessage( LPGEN("Importing system history."));
- dwOffset = FindOwnerContact(pdbHeader);
- if (!GetContact(hFile, dwOffset, &Contact)) {
- AddMessage( LPGEN("ERROR: Chain broken, no valid contact at %d"), dwOffset );
- SetProgress(100);
- }
- else {
- PROTOCOLDESCRIPTOR **protocol;
- int protoCount;
-
- CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&protoCount, (LPARAM)&protocol);
-
- if (protoCount > 0)
- ImportHistory(hFile, Contact, protocol, protoCount);
- }
- }
- else AddMessage( LPGEN("Skipping system history import."));
-
- AddMessage( "" );
-
- // Import other contact messages
- if (nImportOption == IMPORT_ALL || (nCustomOptions & 2046)) { // 2 - 1024 types
- AddMessage( LPGEN("Importing history."));
- dwOffset = FindFirstContact(pdbHeader);
- for(i=1; i <= nNumberOfContacts; i++) {
- if (!GetContact(hFile, dwOffset, &Contact)) {
- AddMessage( LPGEN("ERROR: Chain broken, no valid contact at %d"), dwOffset );
- SetProgress(100);
- break;
- }
-
- ImportHistory(hFile, Contact, NULL, 0);
-
- SetProgress(100 * i / nNumberOfContacts);
- dwOffset = FindNextContact(&Contact);
- }
- }
- else AddMessage( LPGEN("Skipping history import."));
-
- AddMessage( "" );
- }
- // End of Import History
-
- // Restore database writing mode
- CallService(MS_DB_SETSAFETYMODE, TRUE, 0);
-
- // Clean up before exit
- CloseHandle(hFile);
- free(pdbHeader);
-
- // Stop timer
- dwTimer = time(NULL) - dwTimer;
-
- // Print statistics
- AddMessage( LPGEN("Import completed in %d seconds."), dwTimer );
- SetProgress(100);
- AddMessage((nImportOption == IMPORT_CONTACTS) ?
- LPGEN("Added %d contacts and %d groups.") : LPGEN("Added %d contacts, %d groups and %d events."),
- nContactsCount, nGroupsCount, nMessagesCount);
-
- if ( nImportOption != IMPORT_CONTACTS ) {
- if (nSkippedContacts)
- AddMessage( LPGEN("Skipped %d contacts."), nSkippedContacts );
-
- AddMessage((nImportOption == IMPORT_CUSTOM) ?
- LPGEN("Skipped %d duplicates and %d filtered events.") : LPGEN("Skipped %d duplicates."),
- nDupes, nSkippedEvents);
-} }
diff --git a/plugins/Import/src/mirandadb0700.h b/plugins/Import/src/mirandadb0700.h
deleted file mode 100644
index 2c77588951..0000000000
--- a/plugins/Import/src/mirandadb0700.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
-
-Import plugin for Miranda IM
-
-Copyright (C) 2001,2002,2003,2004 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede
-
-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.
-
-*/
-
-
-
-//all offsets are relative to the start of the file
-//offsets are 0 if there is nothing in the chain or this is the last in the
-//chain
-
-
-
-
-/* tree diagram
-
-DBHeader
- |-->end of file (plain offset)
- |-->first contact (DBContact)
- | |-->next contact (DBContact)
- | | \--> ...
- | |-->first settings (DBContactSettings)
- | | |-->next settings (DBContactSettings)
- | | | \--> ...
- | | \-->module name (DBModuleName)
- | \-->first/last/firstunread event
- |-->user contact (DBContact)
- | |-->next contact=NULL
- | |-->first settings as above
- | \-->first/last/firstunread event as above
- \-->first module name (DBModuleName)
- \-->next module name (DBModuleName)
- \--> ...
-*/
-
-#define DB_THIS_VERSION 0x00000700u
-
-#include <pshpack1.h>
-struct DBHeader {
- BYTE signature[16]; // 'Miranda ICQ DB',0,26
- DWORD version; //as 4 bytes, ie 1.2.3.10=0x0102030a
- //this version is 0x00000700
- DWORD ofsFileEnd; //offset of the end of the database - place to write
- //new structures
- DWORD slackSpace; //a counter of the number of bytes that have been
- //wasted so far due to deleting structures and/or
- //re-making them at the end. We should compact when
- //this gets above a threshold
- DWORD contactCount; //number of contacts in the chain,excluding the user
- DWORD ofsFirstContact; //offset to first struct DBContact in the chain
- DWORD ofsUser; //offset to struct DBContact representing the user
- DWORD ofsFirstModuleName; //offset to first struct DBModuleName in the chain
-};
-
-#define DBCONTACT_SIGNATURE 0x43DECADEu
-struct DBContact {
- DWORD signature;
- DWORD ofsNext; //offset to the next contact in the chain. zero if
- //this is the 'user' contact or the last contact
- //in the chain
- DWORD ofsFirstSettings; //offset to the first DBContactSettings in the
- //chain for this contact.
- DWORD eventCount; //number of events in the chain for this contact
- DWORD ofsFirstEvent,ofsLastEvent; //offsets to the first and last DBEvent in
- //the chain for this contact
- DWORD ofsFirstUnreadEvent; //offset to the first (chronological) unread event
- //in the chain, 0 if all are read
- DWORD timestampFirstUnread; //timestamp of the event at ofsFirstUnreadEvent
-};
-
-#define DBMODULENAME_SIGNATURE 0x4DDECADEu
-struct DBModuleName {
- DWORD signature;
- DWORD ofsNext; //offset to the next module name in the chain
- BYTE cbName; //number of characters in this module name
- char name[1]; //name, no nul terminator
-};
-
-#define DBCONTACTSETTINGS_SIGNATURE 0x53DECADEu
-struct DBContactSettings {
- DWORD signature;
- DWORD ofsNext; //offset to the next contactsettings in the chain
- DWORD ofsModuleName; //offset to the DBModuleName of the owner of these
- //settings
- DWORD cbBlob; //size of the blob in bytes. May be larger than the
- //actual size for reducing the number of moves
- //required using granularity in resizing
- BYTE blob[1]; //the blob. a back-to-back sequence of DBSetting
- //structs, the last has cbName=0
-};
-
-/* not a valid structure, content is figured out on the fly
-struct DBSetting {
- BYTE cbName; //number of bytes in the name of this setting
- //this =0 marks the end
- char szName[...]; //setting name, excluding nul
- BYTE dataType; //type of data. see m_database.h, db/contact/getsetting
- union { //a load of types of data, length is defined by dataType
- BYTE bVal; WORD wVal; DWORD dVal;
- struct {
- WORD cbString;
- char szVal[...]; //excludes nul terminator
- };
- struct {
- WORD cbBlob;
- BYTE blobVal[...];
- };
- };
-};
-*/
-
-#define DBEVENT_SIGNATURE 0x45DECADEu
-struct DBEvent {
- DWORD signature;
- DWORD ofsPrev,ofsNext; //offset to the previous and next events in the
- //chain. Chain is sorted chronologically
- DWORD ofsModuleName; //offset to a DBModuleName struct of the name of
- //the owner of this event
- DWORD timestamp; //seconds since 00:00:00 01/01/1970
- DWORD flags; //see m_database.h, db/event/add
- WORD eventType; //module-defined event type
- DWORD cbBlob; //number of bytes in the blob
- BYTE blob[1]; //the blob. module-defined formatting
-};
-#include <poppack.h>
diff --git a/plugins/Import/src/progress.cpp b/plugins/Import/src/progress.cpp
index 99412f647a..2328ce1222 100644
--- a/plugins/Import/src/progress.cpp
+++ b/plugins/Import/src/progress.cpp
@@ -1,8 +1,8 @@
/*
-Import plugin for Miranda IM
+Import plugin for Miranda NG
-Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede
+Copyright (C) 2012 George Hazan
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/plugins/Import/src/resource.h b/plugins/Import/src/resource.h
index 7bf769f14d..469bfb0259 100644
--- a/plugins/Import/src/resource.h
+++ b/plugins/Import/src/resource.h
@@ -5,7 +5,6 @@
#define IDC_BACK 3
#define IDD_WIZARD 101
#define IDD_OPTIONS 102
-#define IDD_ICQSERVER 104
#define IDD_IMPORTTYPE 106
#define IDD_WIZARDINTRO 107
#define IDD_FINISHED 108
@@ -14,17 +13,13 @@
#define IDD_PROGRESS 111
#define IDD_ADVOPTIONS 112
#define IDI_IMPORT 177
-#define IDC_MIRABILIS 1000
#define IDC_DONTLOADPLUGIN 1001
-#define IDC_MIRANDA 1001
-#define IDC_USEFINDADD 1004
+#define IDC_MIRANDA 1002
#define IDC_OTHER 1005
#define IDC_LIST 1006
#define IDC_FILENAME 1007
#define IDC_PROGRESS 1008
#define IDC_STATUS 1009
-#define IDC_MIRABILISRUNNING 1010
-#define IDC_MIRABILISACCOUNT 1011
#define IDC_RADIO_ALL 1016
#define IDC_RADIO_CONTACTS 1017
#define IDC_RADIO_CUSTOM 1018
diff --git a/plugins/Import/src/utils.cpp b/plugins/Import/src/utils.cpp
index 0e57e2479f..69489ca087 100644
--- a/plugins/Import/src/utils.cpp
+++ b/plugins/Import/src/utils.cpp
@@ -1,8 +1,8 @@
/*
-Import plugin for Miranda IM
+Import plugin for Miranda NG
-Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede
+Copyright (C) 2012 George Hazan
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -36,52 +36,6 @@ BOOL IsProtocolLoaded(char* pszProtocolName)
return CallService(MS_PROTO_ISPROTOCOLLOADED, 0, (LPARAM)pszProtocolName) ? TRUE : FALSE;
}
-BOOL EnumICQAccounts()
-{
- int count, i = 0;
- PROTOACCOUNT ** accs;
-
- while (cICQAccounts)
- {
- cICQAccounts--;
- free(szICQModuleName[cICQAccounts]);
- free(tszICQAccountName[cICQAccounts]);
- }
-
- ProtoEnumAccounts(&count, &accs);
- szICQModuleName = (char**)realloc(szICQModuleName, count * sizeof(char**));
- tszICQAccountName = (TCHAR**)realloc(tszICQAccountName, count * sizeof(TCHAR**));
- while (i < count)
- {
- if ((0 == strcmp(ICQOSCPROTONAME, accs[i]->szProtoName)) && accs[i]->bIsEnabled)
- {
- szICQModuleName[cICQAccounts] = strdup(accs[i]->szModuleName);
- tszICQAccountName[cICQAccounts] = _tcsdup(accs[i]->tszAccountName);
- cICQAccounts++;
- }
- i++;
- }
- return cICQAccounts != 0;
-}
-
-void FreeICQAccountsList()
-{
- while (cICQAccounts)
- {
- cICQAccounts--;
- free(szICQModuleName[cICQAccounts]);
- free(tszICQAccountName[cICQAccounts]);
- }
-
- if (szICQModuleName)
- free(szICQModuleName);
- if (tszICQAccountName)
- free(tszICQAccountName);
-
- szICQModuleName = NULL;
- tszICQAccountName = NULL;
-}
-
HANDLE HContactFromNumericID(char* pszProtoName, char* pszSetting, DWORD dwID)
{
char* szProto;
@@ -141,76 +95,25 @@ HANDLE HistoryImportFindContact(HWND hdlgProgress, char* szModuleName, DWORD uin
return hContact;
}
-HANDLE AddContact(HWND hdlgProgress, char* pszProtoName, char* pszUniqueSetting,
- DBVARIANT* id, DBVARIANT* nick, DBVARIANT* group)
-{
- HANDLE hContact;
- char szid[ 40 ];
- char* pszUserID = ( id->type == DBVT_DWORD ) ? _ltoa( id->dVal, szid, 10 ) : id->pszVal;
-
- hContact = (HANDLE)CallService(MS_DB_CONTACT_ADD, 0, 0);
- if ( CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)pszProtoName) != 0) {
- CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0);
- AddMessage( LPGEN("Failed to add %s contact %s"), pszProtoName, pszUserID );
- FreeVariant( id );
- FreeVariant( nick );
- FreeVariant( group );
- return INVALID_HANDLE_VALUE;
- }
-
- WriteVariant( hContact, pszProtoName, pszUniqueSetting, id );
-
- if ( group->type )
- CreateGroup( group->type, group->pszVal, hContact );
-
- if ( nick->type && nick->pszVal[0] ) {
- WriteVariant( hContact, "CList", "MyHandle", nick );
- if (nick->type == DBVT_UTF8) {
- char *tmp = mir_utf8decodeA(nick->pszVal);
- AddMessage( LPGEN("Added %s contact %s, '%s'"), pszProtoName, pszUserID, tmp );
- mir_free(tmp);
- }
- else AddMessage( LPGEN("Added %s contact %s, '%s'"), pszProtoName, pszUserID, nick->pszVal );
- }
- else AddMessage( LPGEN("Added %s contact %s"), pszProtoName, pszUserID );
-
- FreeVariant( id );
- FreeVariant( nick );
- FreeVariant( group );
- return hContact;
-}
-
// ------------------------------------------------
// Creates a group with a specified name in the
// Miranda contact list.
// If contact is specified adds it to group
// ------------------------------------------------
// Returns 1 if successful and 0 when it fails.
-int CreateGroup(BYTE type, const char* name, HANDLE hContact)
+int CreateGroup(const TCHAR* group, HANDLE hContact)
{
- int groupId;
- TCHAR *tmp, *tszGrpName;
- char groupIdStr[11];
- size_t cbName;
-
- if (type == DBVT_UTF8)
- tmp = mir_utf8decodeT( name );
- else if (type == DBVT_WCHAR)
- tmp = mir_u2t(( wchar_t* )name );
- else
- tmp = mir_a2t( name );
-
- if ( tmp == NULL )
+ if (group == NULL)
return 0;
- cbName = _tcslen(tmp);
- tszGrpName = (TCHAR*)_alloca(( cbName+2 )*sizeof( TCHAR ));
+ size_t cbName = _tcslen(group);
+ TCHAR *tszGrpName = (TCHAR*)_alloca(( cbName+2 )*sizeof( TCHAR ));
tszGrpName[0] = 1 | GROUPF_EXPANDED;
- _tcscpy( tszGrpName+1, tmp );
- mir_free( tmp );
+ _tcscpy(tszGrpName+1, group);
// Check for duplicate & find unused id
- for (groupId = 0; ; groupId++) {
+ char groupIdStr[11];
+ for (int groupId = 0; ; groupId++) {
DBVARIANT dbv;
itoa(groupId, groupIdStr,10);
if (DBGetContactSettingTString(NULL, "CListGroups", groupIdStr, &dbv))
diff --git a/plugins/Import/src/wizard.cpp b/plugins/Import/src/wizard.cpp
index 029f251943..bd92adeb6b 100644
--- a/plugins/Import/src/wizard.cpp
+++ b/plugins/Import/src/wizard.cpp
@@ -1,8 +1,8 @@
/*
-Import plugin for Miranda IM
+Import plugin for Miranda NG
-Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede
+Copyright (C) 2012 George Hazan
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -23,55 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "import.h"
#include "resource.h"
-INT_PTR CALLBACK WizardIntroPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
-INT_PTR CALLBACK FinishedPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
-INT_PTR CALLBACK MirabilisPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
-INT_PTR CALLBACK MirandaPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
-INT_PTR CALLBACK ICQserverPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam);
-
-extern HINSTANCE hInst;
-BOOL IsProtocolLoaded(char* pszProtocolName);
-BOOL EnumICQAccounts();
-void FreeICQAccountsList();
-
-INT_PTR CALLBACK ImportTypePageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
- switch( message ) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hdlg);
- CheckDlgButton(hdlg, IDC_MIRANDA, BST_CHECKED);
-
- // Disable Mirabilis import if ICQ isn't loaded.
- if (!EnumICQAccounts())
- EnableWindow(GetDlgItem(hdlg, IDC_MIRABILIS), FALSE);
-
- return TRUE;
-
- case WM_COMMAND:
- switch( LOWORD( wParam )) {
- case IDC_BACK:
- PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_WIZARDINTRO, (LPARAM)WizardIntroPageProc);
- break;
-
- case IDOK:
- if (IsDlgButtonChecked(hdlg, IDC_MIRANDA))
- PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_MIRANDADB, (LPARAM)MirandaPageProc);
- else if (IsDlgButtonChecked(hdlg, IDC_MIRABILIS))
- PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_MIRABILISDB, (LPARAM)MirabilisPageProc);
- else if (IsDlgButtonChecked(hdlg, IDC_USEFINDADD)) {
- CallService(MS_FINDADD_FINDADD, 0, 0);
- PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_FINISHED, (LPARAM)FinishedPageProc);
- }
- break;
-
- case IDCANCEL:
- PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0);
- break;
- } }
-
- return FALSE;
-}
-
INT_PTR CALLBACK WizardIntroPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch( message ) {
@@ -83,7 +34,7 @@ INT_PTR CALLBACK WizardIntroPageProc(HWND hdlg, UINT message, WPARAM wParam, LPA
case WM_COMMAND:
switch( LOWORD( wParam )) {
case IDOK:
- PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_IMPORTTYPE, (LPARAM)ImportTypePageProc);
+ PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_MIRANDADB, (LPARAM)MirandaPageProc);
break;
case IDCANCEL:
@@ -107,7 +58,7 @@ INT_PTR CALLBACK FinishedPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM
case WM_COMMAND:
switch( LOWORD( wParam )) {
case IDOK:
- PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_IMPORTTYPE, (LPARAM)ImportTypePageProc);
+ PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_MIRANDADB, (LPARAM)MirandaPageProc);
break;
case IDCANCEL:
@@ -207,8 +158,6 @@ INT_PTR CALLBACK WizardDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lP
case WM_CLOSE:
DestroyWindow(hwndPage);
DestroyWindow(hdlg);
-
- FreeICQAccountsList();
break;
}