diff options
Diffstat (limited to 'shell/source/win32/simplemail/smplmailclient.cxx')
-rw-r--r-- | shell/source/win32/simplemail/smplmailclient.cxx | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/shell/source/win32/simplemail/smplmailclient.cxx b/shell/source/win32/simplemail/smplmailclient.cxx new file mode 100644 index 000000000000..49c546e5721d --- /dev/null +++ b/shell/source/win32/simplemail/smplmailclient.cxx @@ -0,0 +1,289 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_shell.hxx" +#include <osl/diagnose.h> +#include <osl/process.h> +#include <rtl/bootstrap.hxx> +#include "smplmailclient.hxx" +#include "smplmailmsg.hxx" +#include <com/sun/star/system/SimpleMailClientFlags.hpp> +#include <osl/file.hxx> + +#define WIN32_LEAN_AND_MEAN +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#include <mapi.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <process.h> +#include <vector> + +using css::uno::Reference; +using css::uno::Exception; +using css::uno::RuntimeException; +using css::uno::Sequence; +using css::lang::IllegalArgumentException; + +using css::system::XSimpleMailClient; +using css::system::XSimpleMailMessage; +using css::system::SimpleMailClientFlags::NO_USER_INTERFACE; +using css::system::SimpleMailClientFlags::NO_LOGON_DIALOG; + +typedef std::vector<rtl::OUString> StringList_t; +typedef StringList_t::const_iterator StringListIterator_t; + +const rtl::OUString TO = rtl::OUString::createFromAscii("--to"); +const rtl::OUString CC = rtl::OUString::createFromAscii("--cc"); +const rtl::OUString BCC = rtl::OUString::createFromAscii("--bcc"); +const rtl::OUString FROM = rtl::OUString::createFromAscii("--from"); +const rtl::OUString SUBJECT = rtl::OUString::createFromAscii("--subject"); +const rtl::OUString BODY = rtl::OUString::createFromAscii("--body"); +const rtl::OUString ATTACH = rtl::OUString::createFromAscii("--attach"); +const rtl::OUString FLAG_MAPI_DIALOG = rtl::OUString::createFromAscii("--mapi-dialog"); +const rtl::OUString FLAG_MAPI_LOGON_UI = rtl::OUString::createFromAscii("--mapi-logon-ui"); + +namespace /* private */ +{ + /** @internal + look if an alternative program is configured + which should be used as senddoc executable */ + rtl::OUString getAlternativeSenddocUrl() + { + rtl::OUString altSenddocUrl; + HKEY hkey; + LONG lret = RegOpenKeyW(HKEY_CURRENT_USER, L"Software\\OpenOffice.org\\SendAsEMailClient", &hkey); + if (lret == ERROR_SUCCESS) + { + wchar_t buff[MAX_PATH]; + LONG sz = sizeof(buff); + lret = RegQueryValueW(hkey, NULL, buff, &sz); + if (lret == ERROR_SUCCESS) + { + osl::FileBase::getFileURLFromSystemPath(reinterpret_cast<const sal_Unicode*>(buff), altSenddocUrl); + } + RegCloseKey(hkey); + } + return altSenddocUrl; + } + + /** + Returns the absolute file Url of the senddoc executable. + + @returns + the absolute file Url of the senddoc executable. In case + of an error an empty string will be returned. + */ + rtl::OUString getSenddocUrl() + { + rtl::OUString senddocUrl = getAlternativeSenddocUrl(); + + if (senddocUrl.getLength() == 0) + { + senddocUrl = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "$OOO_BASE_DIR/program/senddoc.exe")); + rtl::Bootstrap::expandMacros(senddocUrl); //TODO: detect failure + } + return senddocUrl; + } + + /** + Execute Senddoc.exe which a MAPI wrapper. + + @param rCommandArgs + [in] the arguments to be passed to Senddoc.exe + + @returns + <TRUE/> on success. + */ + bool executeSenddoc(const StringList_t& rCommandArgs) + { + rtl::OUString senddocUrl = getSenddocUrl(); + if (senddocUrl.getLength() == 0) + return false; + + oslProcess proc; + oslProcessError err = osl_Process_E_Unknown; + + /* for efficiency reasons we are using a 'bad' cast here + as a vector or rtl::OUStrings is nothing else than + an array of pointers to rtl_uString's */ + err = osl_executeProcess( + senddocUrl.pData, + (rtl_uString**)&rCommandArgs[0], + rCommandArgs.size(), + osl_Process_WAIT | osl_Process_DETACHED, + NULL, + NULL, + NULL, + 0, + &proc); + + if (err != osl_Process_E_None) + return false; + + oslProcessInfo procInfo; + procInfo.Size = sizeof(oslProcessInfo); + osl_getProcessInfo(proc, osl_Process_EXITCODE, &procInfo); + osl_freeProcessHandle(proc); + return (procInfo.Code == SUCCESS_SUCCESS); + } +} // namespace private + +Reference<XSimpleMailMessage> SAL_CALL CSmplMailClient::createSimpleMailMessage() + throw (RuntimeException) +{ + return Reference<XSimpleMailMessage>(new CSmplMailMsg()); +} + +/** + Assemble a command line for SendDoc.exe out of the members + of the supplied SimpleMailMessage. + + @param xSimpleMailMessage + [in] the mail message. + + @param aFlags + [in] different flags to be used with the simple mail service. + + @param rCommandArgs + [in|out] a buffer for the command line arguments. The buffer + is assumed to be empty. + + @throws com::sun::star::lang::IllegalArgumentException + if an invalid file URL has been detected in the attachment list. +*/ +void CSmplMailClient::assembleCommandLine( + const Reference<XSimpleMailMessage>& xSimpleMailMessage, + sal_Int32 aFlag, StringList_t& rCommandArgs) +{ + OSL_ENSURE(rCommandArgs.size() == 0, "Provided command argument buffer not empty"); + + rtl::OUString to = xSimpleMailMessage->getRecipient(); + if (to.getLength() > 0) + { + rCommandArgs.push_back(TO); + rCommandArgs.push_back(to); + } + + Sequence<rtl::OUString> ccRecipients = xSimpleMailMessage->getCcRecipient(); + for (int i = 0; i < ccRecipients.getLength(); i++) + { + rCommandArgs.push_back(CC); + rCommandArgs.push_back(ccRecipients[i]); + } + + Sequence<rtl::OUString> bccRecipients = xSimpleMailMessage->getBccRecipient(); + for (int i = 0; i < bccRecipients.getLength(); i++) + { + rCommandArgs.push_back(BCC); + rCommandArgs.push_back(bccRecipients[i]); + } + + rtl::OUString from = xSimpleMailMessage->getOriginator(); + if (from.getLength() > 0) + { + rCommandArgs.push_back(FROM); + rCommandArgs.push_back(from); + } + + rtl::OUString subject = xSimpleMailMessage->getSubject(); + if (subject.getLength() > 0) + { + rCommandArgs.push_back(SUBJECT); + rCommandArgs.push_back(subject); + } + + Sequence<rtl::OUString> attachments = xSimpleMailMessage->getAttachement(); + for (int i = 0; i < attachments.getLength(); i++) + { + rtl::OUString sysPath; + osl::FileBase::RC err = osl::FileBase::getSystemPathFromFileURL(attachments[i], sysPath); + if (err != osl::FileBase::E_None) + throw IllegalArgumentException( + rtl::OUString::createFromAscii("Invalid attachment file URL"), + static_cast<XSimpleMailClient*>(this), + 1); + + rCommandArgs.push_back(ATTACH); + rCommandArgs.push_back(sysPath); + } + + if (!(aFlag & NO_USER_INTERFACE)) + rCommandArgs.push_back(FLAG_MAPI_DIALOG); + + if (!(aFlag & NO_LOGON_DIALOG)) + rCommandArgs.push_back(FLAG_MAPI_LOGON_UI); +} + +void SAL_CALL CSmplMailClient::sendSimpleMailMessage( + const Reference<XSimpleMailMessage>& xSimpleMailMessage, sal_Int32 aFlag) + throw (IllegalArgumentException, Exception, RuntimeException) +{ + validateParameter(xSimpleMailMessage, aFlag); + + StringList_t senddocParams; + assembleCommandLine(xSimpleMailMessage, aFlag, senddocParams); + + if (!executeSenddoc(senddocParams)) + throw Exception( + rtl::OUString::createFromAscii("Send email failed"), + static_cast<XSimpleMailClient*>(this)); +} + +void CSmplMailClient::validateParameter( + const Reference<XSimpleMailMessage>& xSimpleMailMessage, sal_Int32 aFlag ) +{ + if (!xSimpleMailMessage.is()) + throw IllegalArgumentException( + rtl::OUString::createFromAscii("Empty mail message reference"), + static_cast<XSimpleMailClient*>(this), + 1); + + // #93077# + OSL_ENSURE(!(aFlag & NO_LOGON_DIALOG), "Flag NO_LOGON_DIALOG has currently no effect"); + + // check the flags, the allowed range is 0 - (2^n - 1) + if (aFlag < 0 || aFlag > 3) + throw IllegalArgumentException( + rtl::OUString::createFromAscii("Invalid flag value"), + static_cast<XSimpleMailClient*>(this), + 2); + + // check if a recipient is specified of the flags NO_USER_INTERFACE is specified + if ((aFlag & NO_USER_INTERFACE) && !xSimpleMailMessage->getRecipient().getLength()) + throw IllegalArgumentException( + rtl::OUString::createFromAscii("No recipient specified"), + static_cast<XSimpleMailClient*>(this), + 1); +} |