/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Outlook (Win32) import mail and addressbook interfaces */ #include "nscore.h" #include "nsString.h" #include "nsMsgUtils.h" #include "nsIImportService.h" #include "nsOutlookImport.h" #include "nsIImportService.h" #include "nsIImportMail.h" #include "nsIImportMailboxDescriptor.h" #include "nsIImportGeneric.h" #include "nsIImportAddressBooks.h" #include "nsIImportABDescriptor.h" #include "nsIImportFieldMap.h" #include "nsXPCOM.h" #include "nsISupportsPrimitives.h" #include "nsIAbDirectory.h" #include "nsOutlookSettings.h" #include "nsTextFormatter.h" #include "nsOutlookStringBundle.h" #include "ImportDebug.h" #include "nsUnicharUtils.h" #include "nsOutlookMail.h" #include "MapiApi.h" class ImportOutlookMailImpl : public nsIImportMail { public: ImportOutlookMailImpl(); static nsresult Create(nsIImportMail** aImport); // nsISupports interface NS_DECL_THREADSAFE_ISUPPORTS // nsIImportmail interface /* void GetDefaultLocation (out nsIFile location, out boolean found, out * boolean userVerify); */ NS_IMETHOD GetDefaultLocation(nsIFile** location, bool* found, bool* userVerify); NS_IMETHOD FindMailboxes(nsIFile* location, nsTArray>& boxes); NS_IMETHOD ImportMailbox(nsIImportMailboxDescriptor* source, nsIMsgFolder* dstFolder, char16_t** pErrorLog, char16_t** pSuccessLog, bool* fatalError); /* unsigned long GetImportProgress (); */ NS_IMETHOD GetImportProgress(uint32_t* _retval); NS_IMETHOD TranslateFolderName(const nsAString& aFolderName, nsAString& _retval); public: static void ReportSuccess(nsString& name, int32_t count, nsString* pStream); static void ReportError(int32_t errorNum, nsString& name, nsString* pStream); static void AddLinebreak(nsString* pStream); static void SetLogs(nsString& success, nsString& error, char16_t** pError, char16_t** pSuccess); private: virtual ~ImportOutlookMailImpl(); nsOutlookMail m_mail; uint32_t m_bytesDone; }; class ImportOutlookAddressImpl : public nsIImportAddressBooks { public: ImportOutlookAddressImpl(); static nsresult Create(nsIImportAddressBooks** aImport); // nsISupports interface NS_DECL_THREADSAFE_ISUPPORTS // nsIImportAddressBooks interface NS_IMETHOD GetSupportsMultiple(bool* _retval) { *_retval = true; return NS_OK; } NS_IMETHOD GetAutoFind(char16_t** description, bool* _retval); NS_IMETHOD GetNeedsFieldMap(nsIFile* location, bool* _retval) { *_retval = false; return NS_OK; } NS_IMETHOD GetDefaultLocation(nsIFile** location, bool* found, bool* userVerify) { return NS_ERROR_FAILURE; } NS_IMETHOD FindAddressBooks(nsIFile* location, nsTArray>& books); NS_IMETHOD InitFieldMap(nsIImportFieldMap* fieldMap) { return NS_ERROR_FAILURE; } NS_IMETHOD ImportAddressBook(nsIImportABDescriptor* source, nsIAbDirectory* destination, nsIImportFieldMap* fieldMap, nsISupports* aSupportService, char16_t** errorLog, char16_t** successLog, bool* fatalError); NS_IMETHOD GetImportProgress(uint32_t* _retval); NS_IMETHOD GetSampleData(int32_t index, bool* pFound, char16_t** pStr) { return NS_ERROR_FAILURE; } NS_IMETHOD SetSampleLocation(nsIFile*) { return NS_OK; } private: virtual ~ImportOutlookAddressImpl(); void ReportSuccess(nsString& name, nsString* pStream); private: uint32_t m_msgCount; uint32_t m_msgTotal; nsOutlookMail m_address; }; //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// nsOutlookImport::nsOutlookImport() { IMPORT_LOG0("nsOutlookImport Module Created\n"); nsOutlookStringBundle::GetStringBundle(); } nsOutlookImport::~nsOutlookImport() { IMPORT_LOG0("nsOutlookImport Module Deleted\n"); } NS_IMPL_ISUPPORTS(nsOutlookImport, nsIImportModule) NS_IMETHODIMP nsOutlookImport::GetName(char16_t** name) { NS_ASSERTION(name != nullptr, "null ptr"); if (!name) return NS_ERROR_NULL_POINTER; *name = nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_NAME); return NS_OK; } NS_IMETHODIMP nsOutlookImport::GetDescription(char16_t** name) { NS_ASSERTION(name != nullptr, "null ptr"); if (!name) return NS_ERROR_NULL_POINTER; *name = nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_DESCRIPTION); return NS_OK; } NS_IMETHODIMP nsOutlookImport::GetSupports(char** supports) { NS_ASSERTION(supports != nullptr, "null ptr"); if (!supports) return NS_ERROR_NULL_POINTER; *supports = strdup(kOutlookSupportsString); return NS_OK; } NS_IMETHODIMP nsOutlookImport::GetSupportsUpgrade(bool* pUpgrade) { NS_ASSERTION(pUpgrade != nullptr, "null ptr"); if (!pUpgrade) return NS_ERROR_NULL_POINTER; *pUpgrade = true; return NS_OK; } NS_IMETHODIMP nsOutlookImport::GetImportInterface(const char* pImportType, nsISupports** ppInterface) { NS_ASSERTION(pImportType != nullptr, "null ptr"); if (!pImportType) return NS_ERROR_NULL_POINTER; NS_ASSERTION(ppInterface != nullptr, "null ptr"); if (!ppInterface) return NS_ERROR_NULL_POINTER; *ppInterface = nullptr; nsresult rv; if (!strcmp(pImportType, "mail")) { // create the nsIImportMail interface and return it! nsCOMPtr pMail; nsCOMPtr pGeneric; rv = ImportOutlookMailImpl::Create(getter_AddRefs(pMail)); if (NS_SUCCEEDED(rv)) { nsCOMPtr impSvc( do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv)); if (NS_SUCCEEDED(rv)) { rv = impSvc->CreateNewGenericMail(getter_AddRefs(pGeneric)); if (NS_SUCCEEDED(rv)) { pGeneric->SetData("mailInterface", pMail); nsString name; nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_NAME, name); nsCOMPtr nameString( do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv)); if (NS_SUCCEEDED(rv)) { nameString->SetData(name); pGeneric->SetData("name", nameString); nsCOMPtr pInterface(do_QueryInterface(pGeneric)); pInterface.forget(ppInterface); } } } } return rv; } if (!strcmp(pImportType, "addressbook")) { // create the nsIImportAddressBook interface and return it! nsCOMPtr pAddress; nsCOMPtr pGeneric; rv = ImportOutlookAddressImpl::Create(getter_AddRefs(pAddress)); if (NS_SUCCEEDED(rv)) { nsCOMPtr impSvc( do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv)); if (NS_SUCCEEDED(rv)) { rv = impSvc->CreateNewGenericAddressBooks(getter_AddRefs(pGeneric)); if (NS_SUCCEEDED(rv)) { pGeneric->SetData("addressInterface", pAddress); nsCOMPtr pInterface(do_QueryInterface(pGeneric)); pInterface.forget(ppInterface); } } } return rv; } if (!strcmp(pImportType, "settings")) { nsCOMPtr pSettings; rv = nsOutlookSettings::Create(getter_AddRefs(pSettings)); if (NS_SUCCEEDED(rv)) { nsCOMPtr pInterface(do_QueryInterface(pSettings)); pInterface.forget(ppInterface); } return rv; } return NS_ERROR_NOT_AVAILABLE; } ///////////////////////////////////////////////////////////////////////////////// nsresult ImportOutlookMailImpl::Create(nsIImportMail** aImport) { NS_ENSURE_ARG_POINTER(aImport); NS_ADDREF(*aImport = new ImportOutlookMailImpl()); return NS_OK; } ImportOutlookMailImpl::ImportOutlookMailImpl() { nsOutlookCompose::CreateIdentity(); } ImportOutlookMailImpl::~ImportOutlookMailImpl() { nsOutlookCompose::ReleaseIdentity(); } NS_IMPL_ISUPPORTS(ImportOutlookMailImpl, nsIImportMail) NS_IMETHODIMP ImportOutlookMailImpl::GetDefaultLocation(nsIFile** ppLoc, bool* found, bool* userVerify) { NS_ASSERTION(ppLoc != nullptr, "null ptr"); NS_ASSERTION(found != nullptr, "null ptr"); NS_ASSERTION(userVerify != nullptr, "null ptr"); if (!ppLoc || !found || !userVerify) return NS_ERROR_NULL_POINTER; *found = false; *ppLoc = nullptr; *userVerify = false; // We need to verify here that we can get the mail, if true then // return a dummy location, otherwise return no location CMapiApi mapi; if (!mapi.Initialize()) return NS_OK; if (!mapi.LogOn()) return NS_OK; CMapiFolderList store; if (!mapi.IterateStores(store)) return NS_OK; if (store.GetSize() == 0) return NS_OK; nsresult rv; nsCOMPtr resultFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; *found = true; resultFile.forget(ppLoc); *userVerify = false; return NS_OK; } NS_IMETHODIMP ImportOutlookMailImpl::FindMailboxes( nsIFile* pLoc, nsTArray>& boxes) { NS_ASSERTION(pLoc != nullptr, "null ptr"); if (!pLoc) return NS_ERROR_NULL_POINTER; return m_mail.GetMailFolders(boxes); } void ImportOutlookMailImpl::AddLinebreak(nsString* pStream) { if (pStream) pStream->Append(char16_t('\n')); } void ImportOutlookMailImpl::ReportSuccess(nsString& name, int32_t count, nsString* pStream) { if (!pStream) return; // load the success string char16_t* pFmt = nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_MAILBOX_SUCCESS); nsString pText; nsTextFormatter::ssprintf(pText, pFmt, name.get(), count); pStream->Append(pText); nsOutlookStringBundle::FreeString(pFmt); AddLinebreak(pStream); } void ImportOutlookMailImpl::ReportError(int32_t errorNum, nsString& name, nsString* pStream) { if (!pStream) return; // load the error string char16_t* pFmt = nsOutlookStringBundle::GetStringByID(errorNum); nsString pText; nsTextFormatter::ssprintf(pText, pFmt, name.get()); pStream->Append(pText); nsOutlookStringBundle::FreeString(pFmt); AddLinebreak(pStream); } void ImportOutlookMailImpl::SetLogs(nsString& success, nsString& error, char16_t** pError, char16_t** pSuccess) { if (pError) *pError = ToNewUnicode(error); if (pSuccess) *pSuccess = ToNewUnicode(success); } NS_IMETHODIMP ImportOutlookMailImpl::ImportMailbox(nsIImportMailboxDescriptor* pSource, nsIMsgFolder* dstFolder, char16_t** pErrorLog, char16_t** pSuccessLog, bool* fatalError) { NS_ENSURE_ARG_POINTER(pSource); NS_ENSURE_ARG_POINTER(dstFolder); NS_ENSURE_ARG_POINTER(fatalError); nsString success; nsString error; bool abort = false; nsString name; char16_t* pName; if (NS_SUCCEEDED(pSource->GetDisplayName(&pName))) { name = pName; free(pName); } uint32_t mailSize = 0; pSource->GetSize(&mailSize); if (mailSize == 0) { ReportSuccess(name, 0, &success); SetLogs(success, error, pErrorLog, pSuccessLog); return NS_OK; } uint32_t index = 0; pSource->GetIdentifier(&index); int32_t msgCount = 0; nsresult rv = NS_OK; m_bytesDone = 0; rv = m_mail.ImportMailbox(&m_bytesDone, &abort, (int32_t)index, name.get(), dstFolder, &msgCount); if (NS_SUCCEEDED(rv)) ReportSuccess(name, msgCount, &success); else ReportError(OUTLOOKIMPORT_MAILBOX_CONVERTERROR, name, &error); SetLogs(success, error, pErrorLog, pSuccessLog); return rv; } NS_IMETHODIMP ImportOutlookMailImpl::GetImportProgress(uint32_t* pDoneSoFar) { NS_ASSERTION(pDoneSoFar != nullptr, "null ptr"); if (!pDoneSoFar) return NS_ERROR_NULL_POINTER; *pDoneSoFar = m_bytesDone; return NS_OK; } NS_IMETHODIMP ImportOutlookMailImpl::TranslateFolderName( const nsAString& aFolderName, nsAString& _retval) { if (aFolderName.LowerCaseEqualsLiteral("deleted items")) _retval = NS_LITERAL_STRING_FROM_CSTRING(kDestTrashFolderName); else if (aFolderName.LowerCaseEqualsLiteral("sent items")) _retval = NS_LITERAL_STRING_FROM_CSTRING(kDestSentFolderName); else if (aFolderName.LowerCaseEqualsLiteral("outbox")) _retval = NS_LITERAL_STRING_FROM_CSTRING(kDestUnsentMessagesFolderName); else _retval = aFolderName; return NS_OK; } nsresult ImportOutlookAddressImpl::Create(nsIImportAddressBooks** aImport) { NS_ENSURE_ARG_POINTER(aImport); NS_ADDREF(*aImport = new ImportOutlookAddressImpl()); return NS_OK; } ImportOutlookAddressImpl::ImportOutlookAddressImpl() { m_msgCount = 0; m_msgTotal = 0; } ImportOutlookAddressImpl::~ImportOutlookAddressImpl() {} NS_IMPL_ISUPPORTS(ImportOutlookAddressImpl, nsIImportAddressBooks) NS_IMETHODIMP ImportOutlookAddressImpl::GetAutoFind(char16_t** description, bool* _retval) { NS_ASSERTION(description != nullptr, "null ptr"); NS_ASSERTION(_retval != nullptr, "null ptr"); if (!description || !_retval) return NS_ERROR_NULL_POINTER; *_retval = true; nsString str; nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_ADDRNAME, str); *description = ToNewUnicode(str); return NS_OK; } NS_IMETHODIMP ImportOutlookAddressImpl::FindAddressBooks( nsIFile* location, nsTArray>& books) { return m_address.GetAddressBooks(books); } NS_IMETHODIMP ImportOutlookAddressImpl::ImportAddressBook( nsIImportABDescriptor* source, nsIAbDirectory* destination, nsIImportFieldMap* fieldMap, nsISupports* aSupportService, char16_t** pErrorLog, char16_t** pSuccessLog, bool* fatalError) { m_msgCount = 0; m_msgTotal = 0; NS_ASSERTION(source != nullptr, "null ptr"); NS_ASSERTION(destination != nullptr, "null ptr"); NS_ASSERTION(fatalError != nullptr, "null ptr"); nsString success; nsString error; if (!source || !destination || !fatalError) { IMPORT_LOG0("*** Bad param passed to outlook address import\n"); nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_ADDRESS_BADPARAM, error); if (fatalError) *fatalError = true; ImportOutlookMailImpl::SetLogs(success, error, pErrorLog, pSuccessLog); return NS_ERROR_NULL_POINTER; } nsString name; source->GetPreferredName(name); uint32_t id; if (NS_FAILED(source->GetIdentifier(&id))) { ImportOutlookMailImpl::ReportError(OUTLOOKIMPORT_ADDRESS_BADSOURCEFILE, name, &error); ImportOutlookMailImpl::SetLogs(success, error, pErrorLog, pSuccessLog); return NS_ERROR_FAILURE; } nsresult rv = NS_OK; rv = m_address.ImportAddresses(&m_msgCount, &m_msgTotal, name.get(), id, destination, error); if (NS_SUCCEEDED(rv) && error.IsEmpty()) ReportSuccess(name, &success); else ImportOutlookMailImpl::ReportError(OUTLOOKIMPORT_ADDRESS_CONVERTERROR, name, &error); ImportOutlookMailImpl::SetLogs(success, error, pErrorLog, pSuccessLog); IMPORT_LOG0("*** Returning from outlook address import\n"); return NS_OK; } NS_IMETHODIMP ImportOutlookAddressImpl::GetImportProgress(uint32_t* _retval) { NS_ASSERTION(_retval != nullptr, "null ptr"); if (!_retval) return NS_ERROR_NULL_POINTER; uint32_t result = m_msgCount; if (m_msgTotal) { result *= 100; result /= m_msgTotal; } else result = 0; if (result > 100) result = 100; *_retval = result; return NS_OK; } void ImportOutlookAddressImpl::ReportSuccess(nsString& name, nsString* pStream) { if (!pStream) return; // load the success string char16_t* pFmt = nsOutlookStringBundle::GetStringByID(OUTLOOKIMPORT_ADDRESS_SUCCESS); nsString pText; nsTextFormatter::ssprintf(pText, pFmt, name.get()); pStream->Append(pText); nsOutlookStringBundle::FreeString(pFmt); ImportOutlookMailImpl::AddLinebreak(pStream); }