Files
libreoffice/shell/source/win32/simplemail/smplmailclient.cxx

292 lines
9.7 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2001-05-14 07:09:21 +00:00
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2001-05-14 07:09:21 +00:00
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
2001-05-14 07:09:21 +00:00
*
* OpenOffice.org - a multi-platform office productivity suite
2001-05-14 07:09:21 +00:00
*
* This file is part of OpenOffice.org.
2001-05-14 07:09:21 +00:00
*
* 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.
2001-05-14 07:09:21 +00:00
*
* 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).
2001-05-14 07:09:21 +00:00
*
* 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.
2001-05-14 07:09:21 +00:00
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_shell.hxx"
2001-05-14 07:09:21 +00:00
#include <osl/diagnose.h>
#include <osl/process.h>
CWS-TOOLING: integrate CWS sb110 2009-08-05 15:28:43 +0200 sb r274677 : CWS-TOOLING: rebase CWS sb110 to trunk@274622 (milestone: DEV300:m54) 2009-08-05 11:46:36 +0200 sb r274646 : #i104018# fixed previous svn changeset 271712 (from issue 101244) 2009-07-20 14:41:56 +0200 sb r274138 : CWS-TOOLING: rebase CWS sb110 to trunk@273858 (milestone: DEV300:m52) 2009-06-02 11:42:17 +0200 sb r272489 : CWS-TOOLING: rebase CWS sb110 to trunk@272291 (milestone: DEV300:m49) 2009-05-08 12:46:51 +0200 sb r271712 : #i101244# after DLLs have been moved from basis to brand layer on Windows, code that used SvtPathOptions::GetModulePath to located libraries had to be adapted 2009-05-08 10:10:43 +0200 sb r271703 : #i101244# for performance reasons, on Windows move DLLs from basis to brand layer (i.e., next to executables); consequently eliminated some library duplications across the layers; adapted various code to the move 2009-05-08 09:54:44 +0200 sb r271702 : #i101244# hardwire Python dynamic libraries and script files into base layer (even if other dynamic libraries will move to brand layer on Windows), mainly because the pyuno dynamic library is both linked against from other dynamic libraries (pythonloader.uno) and accessed via "import pyuno" from Python scripts 2009-05-07 17:18:30 +0200 sb r271686 : #i101244# support NativeServicesURLPrefix on individual files; to implement that, changed meaning of global unomaxservices 2009-05-07 17:15:24 +0200 sb r271685 : #i101244# take legacy_binfilters.rdb explicitly from $OOO_BASE_DIR/program (instead of implicitly next to some dynamic library); cleaned up dead code 2009-05-07 17:12:12 +0200 sb r271684 : #i101244# take senddoc.exe explicitly from $OOO_BASE_DIR/program (instead of implicitly next to some dynamic library) 2009-05-07 17:11:33 +0200 sb r271683 : #i101244# take odbcconfig.exe explicitly from $OOO_BASE_DIR/program (instead of implicitly next to some dynamic library) 2009-05-07 17:09:44 +0200 sb r271682 : #i101244# read configmgr ini file explicitly from $OOO_BASE_DIR/program (instead of next to configmgr dynamic library)
2009-08-25 13:07:56 +00:00
#include <rtl/bootstrap.hxx>
2001-05-14 07:09:21 +00:00
#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_CONSTASCII_USTRINGPARAM("--to"));
const rtl::OUString CC(RTL_CONSTASCII_USTRINGPARAM("--cc"));
const rtl::OUString BCC(RTL_CONSTASCII_USTRINGPARAM("--bcc"));
const rtl::OUString FROM(RTL_CONSTASCII_USTRINGPARAM("--from"));
const rtl::OUString SUBJECT(RTL_CONSTASCII_USTRINGPARAM("--subject"));
const rtl::OUString BODY(RTL_CONSTASCII_USTRINGPARAM("--body"));
const rtl::OUString ATTACH(RTL_CONSTASCII_USTRINGPARAM("--attach"));
const rtl::OUString FLAG_MAPI_DIALOG(RTL_CONSTASCII_USTRINGPARAM("--mapi-dialog"));
const rtl::OUString FLAG_MAPI_LOGON_UI(RTL_CONSTASCII_USTRINGPARAM("--mapi-logon-ui"));
namespace /* private */
2001-05-14 07:09:21 +00:00
{
/** @internal
look if an alternative program is configured
which should be used as senddoc executable */
rtl::OUString getAlternativeSenddocUrl()
2001-05-14 07:09:21 +00:00
{
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;
2001-05-14 07:09:21 +00:00
}
/**
Returns the absolute file Url of the senddoc executable.
2001-05-14 07:09:21 +00:00
@returns
the absolute file Url of the senddoc executable. In case
of an error an empty string will be returned.
*/
rtl::OUString getSenddocUrl()
2001-05-14 07:09:21 +00:00
{
rtl::OUString senddocUrl = getAlternativeSenddocUrl();
2001-05-14 07:09:21 +00:00
if (senddocUrl.getLength() == 0)
{
CWS-TOOLING: integrate CWS sb110 2009-08-05 15:28:43 +0200 sb r274677 : CWS-TOOLING: rebase CWS sb110 to trunk@274622 (milestone: DEV300:m54) 2009-08-05 11:46:36 +0200 sb r274646 : #i104018# fixed previous svn changeset 271712 (from issue 101244) 2009-07-20 14:41:56 +0200 sb r274138 : CWS-TOOLING: rebase CWS sb110 to trunk@273858 (milestone: DEV300:m52) 2009-06-02 11:42:17 +0200 sb r272489 : CWS-TOOLING: rebase CWS sb110 to trunk@272291 (milestone: DEV300:m49) 2009-05-08 12:46:51 +0200 sb r271712 : #i101244# after DLLs have been moved from basis to brand layer on Windows, code that used SvtPathOptions::GetModulePath to located libraries had to be adapted 2009-05-08 10:10:43 +0200 sb r271703 : #i101244# for performance reasons, on Windows move DLLs from basis to brand layer (i.e., next to executables); consequently eliminated some library duplications across the layers; adapted various code to the move 2009-05-08 09:54:44 +0200 sb r271702 : #i101244# hardwire Python dynamic libraries and script files into base layer (even if other dynamic libraries will move to brand layer on Windows), mainly because the pyuno dynamic library is both linked against from other dynamic libraries (pythonloader.uno) and accessed via "import pyuno" from Python scripts 2009-05-07 17:18:30 +0200 sb r271686 : #i101244# support NativeServicesURLPrefix on individual files; to implement that, changed meaning of global unomaxservices 2009-05-07 17:15:24 +0200 sb r271685 : #i101244# take legacy_binfilters.rdb explicitly from $OOO_BASE_DIR/program (instead of implicitly next to some dynamic library); cleaned up dead code 2009-05-07 17:12:12 +0200 sb r271684 : #i101244# take senddoc.exe explicitly from $OOO_BASE_DIR/program (instead of implicitly next to some dynamic library) 2009-05-07 17:11:33 +0200 sb r271683 : #i101244# take odbcconfig.exe explicitly from $OOO_BASE_DIR/program (instead of implicitly next to some dynamic library) 2009-05-07 17:09:44 +0200 sb r271682 : #i101244# read configmgr ini file explicitly from $OOO_BASE_DIR/program (instead of next to configmgr dynamic library)
2009-08-25 13:07:56 +00:00
senddocUrl = rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM(
"$BRAND_BASE_DIR/program/senddoc.exe"));
CWS-TOOLING: integrate CWS sb110 2009-08-05 15:28:43 +0200 sb r274677 : CWS-TOOLING: rebase CWS sb110 to trunk@274622 (milestone: DEV300:m54) 2009-08-05 11:46:36 +0200 sb r274646 : #i104018# fixed previous svn changeset 271712 (from issue 101244) 2009-07-20 14:41:56 +0200 sb r274138 : CWS-TOOLING: rebase CWS sb110 to trunk@273858 (milestone: DEV300:m52) 2009-06-02 11:42:17 +0200 sb r272489 : CWS-TOOLING: rebase CWS sb110 to trunk@272291 (milestone: DEV300:m49) 2009-05-08 12:46:51 +0200 sb r271712 : #i101244# after DLLs have been moved from basis to brand layer on Windows, code that used SvtPathOptions::GetModulePath to located libraries had to be adapted 2009-05-08 10:10:43 +0200 sb r271703 : #i101244# for performance reasons, on Windows move DLLs from basis to brand layer (i.e., next to executables); consequently eliminated some library duplications across the layers; adapted various code to the move 2009-05-08 09:54:44 +0200 sb r271702 : #i101244# hardwire Python dynamic libraries and script files into base layer (even if other dynamic libraries will move to brand layer on Windows), mainly because the pyuno dynamic library is both linked against from other dynamic libraries (pythonloader.uno) and accessed via "import pyuno" from Python scripts 2009-05-07 17:18:30 +0200 sb r271686 : #i101244# support NativeServicesURLPrefix on individual files; to implement that, changed meaning of global unomaxservices 2009-05-07 17:15:24 +0200 sb r271685 : #i101244# take legacy_binfilters.rdb explicitly from $OOO_BASE_DIR/program (instead of implicitly next to some dynamic library); cleaned up dead code 2009-05-07 17:12:12 +0200 sb r271684 : #i101244# take senddoc.exe explicitly from $OOO_BASE_DIR/program (instead of implicitly next to some dynamic library) 2009-05-07 17:11:33 +0200 sb r271683 : #i101244# take odbcconfig.exe explicitly from $OOO_BASE_DIR/program (instead of implicitly next to some dynamic library) 2009-05-07 17:09:44 +0200 sb r271682 : #i101244# read configmgr ini file explicitly from $OOO_BASE_DIR/program (instead of next to configmgr dynamic library)
2009-08-25 13:07:56 +00:00
rtl::Bootstrap::expandMacros(senddocUrl); //TODO: detect failure
}
return senddocUrl;
2001-05-14 07:09:21 +00:00
}
/**
Execute Senddoc.exe which a MAPI wrapper.
2001-05-14 07:09:21 +00:00
@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.
2001-05-14 07:09:21 +00:00
@param aFlags
[in] different flags to be used with the simple mail service.
2001-05-14 07:09:21 +00:00
@param rCommandArgs
[in|out] a buffer for the command line arguments. The buffer
is assumed to be empty.
2001-05-14 07:09:21 +00:00
@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)
2001-05-14 07:09:21 +00:00
{
OSL_ENSURE(rCommandArgs.size() == 0, "Provided command argument buffer not empty");
2001-05-14 07:09:21 +00:00
rtl::OUString to = xSimpleMailMessage->getRecipient();
if (to.getLength() > 0)
2001-05-14 07:09:21 +00:00
{
rCommandArgs.push_back(TO);
rCommandArgs.push_back(to);
}
2001-05-14 07:09:21 +00:00
Sequence<rtl::OUString> ccRecipients = xSimpleMailMessage->getCcRecipient();
for (int i = 0; i < ccRecipients.getLength(); i++)
{
rCommandArgs.push_back(CC);
rCommandArgs.push_back(ccRecipients[i]);
}
2001-05-14 07:09:21 +00:00
Sequence<rtl::OUString> bccRecipients = xSimpleMailMessage->getBccRecipient();
2004-06-21 14:16:57 +00:00
for (int i = 0; i < bccRecipients.getLength(); i++)
{
rCommandArgs.push_back(BCC);
rCommandArgs.push_back(bccRecipients[i]);
}
2001-05-14 07:09:21 +00:00
rtl::OUString from = xSimpleMailMessage->getOriginator();
if (from.getLength() > 0)
{
rCommandArgs.push_back(FROM);
rCommandArgs.push_back(from);
}
2001-05-14 07:09:21 +00:00
rtl::OUString subject = xSimpleMailMessage->getSubject();
if (subject.getLength() > 0)
{
rCommandArgs.push_back(SUBJECT);
rCommandArgs.push_back(subject);
2001-05-14 07:09:21 +00:00
}
Sequence<rtl::OUString> attachments = xSimpleMailMessage->getAttachement();
2004-06-21 14:16:57 +00:00
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(RTL_CONSTASCII_USTRINGPARAM("Invalid attachment file URL")),
static_cast<XSimpleMailClient*>(this),
1);
2001-05-14 07:09:21 +00:00
rCommandArgs.push_back(ATTACH);
rCommandArgs.push_back(sysPath);
}
2001-05-14 07:09:21 +00:00
if (!(aFlag & NO_USER_INTERFACE))
rCommandArgs.push_back(FLAG_MAPI_DIALOG);
2001-05-14 07:09:21 +00:00
if (!(aFlag & NO_LOGON_DIALOG))
rCommandArgs.push_back(FLAG_MAPI_LOGON_UI);
2001-05-14 07:09:21 +00:00
}
void SAL_CALL CSmplMailClient::sendSimpleMailMessage(
const Reference<XSimpleMailMessage>& xSimpleMailMessage, sal_Int32 aFlag)
throw (IllegalArgumentException, Exception, RuntimeException)
2001-05-14 07:09:21 +00:00
{
validateParameter(xSimpleMailMessage, aFlag);
2001-05-14 07:09:21 +00:00
StringList_t senddocParams;
assembleCommandLine(xSimpleMailMessage, aFlag, senddocParams);
2001-05-14 07:09:21 +00:00
if (!executeSenddoc(senddocParams))
throw Exception(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Send email failed")),
static_cast<XSimpleMailClient*>(this));
2001-05-14 07:09:21 +00:00
}
void CSmplMailClient::validateParameter(
const Reference<XSimpleMailMessage>& xSimpleMailMessage, sal_Int32 aFlag )
2001-05-14 07:09:21 +00:00
{
if (!xSimpleMailMessage.is())
throw IllegalArgumentException(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Empty mail message reference")),
static_cast<XSimpleMailClient*>(this),
1);
2001-05-14 07:09:21 +00:00
OSL_ENSURE(!(aFlag & NO_LOGON_DIALOG), "Flag NO_LOGON_DIALOG has currently no effect");
2001-05-14 07:09:21 +00:00
// check the flags, the allowed range is 0 - (2^n - 1)
if (aFlag < 0 || aFlag > 3)
throw IllegalArgumentException(
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid flag value")),
static_cast<XSimpleMailClient*>(this),
2);
2001-05-14 07:09:21 +00:00
// 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(RTL_CONSTASCII_USTRINGPARAM("No recipient specified")),
static_cast<XSimpleMailClient*>(this),
1);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */