Source code

Revision control

Copy as Markdown

Other Tools

/* -*- 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<RefPtr<nsIImportMailboxDescriptor>>& 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<RefPtr<nsIImportABDescriptor>>& 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<nsIImportMail> pMail;
nsCOMPtr<nsIImportGeneric> pGeneric;
rv = ImportOutlookMailImpl::Create(getter_AddRefs(pMail));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIImportService> 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<nsISupportsString> nameString(
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv));
if (NS_SUCCEEDED(rv)) {
nameString->SetData(name);
pGeneric->SetData("name", nameString);
nsCOMPtr<nsISupports> pInterface(do_QueryInterface(pGeneric));
pInterface.forget(ppInterface);
}
}
}
}
return rv;
}
if (!strcmp(pImportType, "addressbook")) {
// create the nsIImportAddressBook interface and return it!
nsCOMPtr<nsIImportAddressBooks> pAddress;
nsCOMPtr<nsIImportGeneric> pGeneric;
rv = ImportOutlookAddressImpl::Create(getter_AddRefs(pAddress));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIImportService> 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<nsISupports> pInterface(do_QueryInterface(pGeneric));
pInterface.forget(ppInterface);
}
}
}
return rv;
}
if (!strcmp(pImportType, "settings")) {
nsCOMPtr<nsIImportSettings> pSettings;
rv = nsOutlookSettings::Create(getter_AddRefs(pSettings));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsISupports> 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<nsIFile> 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<RefPtr<nsIImportMailboxDescriptor>>& 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<RefPtr<nsIImportABDescriptor>>& 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);
}