1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_folders.h>
22 #include <osl/diagnose.h>
23 #include <osl/process.h>
24 #include <rtl/bootstrap.hxx>
25 #include "smplmailclient.hxx"
26 #include "smplmailmsg.hxx"
27 #include <com/sun/star/system/SimpleMailClientFlags.hpp>
28 #include <com/sun/star/system/XSimpleMailMessage2.hpp>
29 #include <osl/file.hxx>
31 #define WIN32_LEAN_AND_MEAN
33 #pragma warning(push, 1)
44 using css::uno::UNO_QUERY
;
45 using css::uno::Reference
;
46 using css::uno::Exception
;
47 using css::uno::RuntimeException
;
48 using css::uno::Sequence
;
49 using css::lang::IllegalArgumentException
;
51 using css::system::XSimpleMailClient
;
52 using css::system::XSimpleMailMessage
;
53 using css::system::XSimpleMailMessage2
;
54 using css::system::SimpleMailClientFlags::NO_USER_INTERFACE
;
55 using css::system::SimpleMailClientFlags::NO_LOGON_DIALOG
;
57 typedef std::vector
<OUString
> StringList_t
;
59 const OUString
TO("--to");
60 const OUString
CC("--cc");
61 const OUString
BCC("--bcc");
62 const OUString
FROM("--from");
63 const OUString
SUBJECT("--subject");
64 const OUString
BODY("--body");
65 const OUString
ATTACH("--attach");
66 const OUString
FLAG_MAPI_DIALOG("--mapi-dialog");
67 const OUString
FLAG_MAPI_LOGON_UI("--mapi-logon-ui");
69 namespace /* private */
72 look if an alternative program is configured
73 which should be used as senddoc executable */
74 OUString
getAlternativeSenddocUrl()
76 OUString altSenddocUrl
;
78 LONG lret
= RegOpenKeyW(HKEY_CURRENT_USER
, L
"Software\\LibreOffice\\SendAsEMailClient", &hkey
);
79 if (lret
== ERROR_SUCCESS
)
81 wchar_t buff
[MAX_PATH
];
82 LONG sz
= sizeof(buff
);
83 lret
= RegQueryValueW(hkey
, NULL
, buff
, &sz
);
84 if (lret
== ERROR_SUCCESS
)
86 osl::FileBase::getFileURLFromSystemPath(reinterpret_cast<const sal_Unicode
*>(buff
), altSenddocUrl
);
94 Returns the absolute file Url of the senddoc executable.
97 the absolute file Url of the senddoc executable. In case
98 of an error an empty string will be returned.
100 OUString
getSenddocUrl()
102 OUString senddocUrl
= getAlternativeSenddocUrl();
104 if (senddocUrl
.isEmpty())
106 senddocUrl
= ( "$BRAND_BASE_DIR/" LIBO_LIBEXEC_FOLDER
"/senddoc.exe");
107 rtl::Bootstrap::expandMacros(senddocUrl
); //TODO: detect failure
113 Execute Senddoc.exe which a MAPI wrapper.
116 [in] the arguments to be passed to Senddoc.exe
121 bool executeSenddoc(const StringList_t
& rCommandArgs
)
123 OUString senddocUrl
= getSenddocUrl();
124 if (senddocUrl
.getLength() == 0)
128 oslProcessError err
= osl_Process_E_Unknown
;
130 /* for efficiency reasons we are using a 'bad' cast here
131 as a vector or OUStrings is nothing else than
132 an array of pointers to rtl_uString's */
133 err
= osl_executeProcess(
135 (rtl_uString
**)&rCommandArgs
[0],
137 osl_Process_WAIT
| osl_Process_DETACHED
,
144 if (err
!= osl_Process_E_None
)
147 oslProcessInfo procInfo
;
148 procInfo
.Size
= sizeof(oslProcessInfo
);
149 osl_getProcessInfo(proc
, osl_Process_EXITCODE
, &procInfo
);
150 osl_freeProcessHandle(proc
);
151 return (procInfo
.Code
== SUCCESS_SUCCESS
);
153 } // namespace private
155 Reference
<XSimpleMailMessage
> SAL_CALL
CSmplMailClient::createSimpleMailMessage()
156 throw (RuntimeException
)
158 return Reference
<XSimpleMailMessage
>(new CSmplMailMsg());
162 Assemble a command line for SendDoc.exe out of the members
163 of the supplied SimpleMailMessage.
165 @param xSimpleMailMessage
166 [in] the mail message.
169 [in] different flags to be used with the simple mail service.
172 [in|out] a buffer for the command line arguments. The buffer
173 is assumed to be empty.
175 @throws com::sun::star::lang::IllegalArgumentException
176 if an invalid file URL has been detected in the attachment list.
178 void CSmplMailClient::assembleCommandLine(
179 const Reference
<XSimpleMailMessage
>& xSimpleMailMessage
,
180 sal_Int32 aFlag
, StringList_t
& rCommandArgs
)
182 OSL_ENSURE(rCommandArgs
.empty(), "Provided command argument buffer not empty");
184 Reference
<XSimpleMailMessage2
> xMessage( xSimpleMailMessage
, UNO_QUERY
);
187 OUString body
= xMessage
->getBody();
188 if (body
.getLength()>0)
190 rCommandArgs
.push_back(BODY
);
191 rCommandArgs
.push_back(body
);
195 OUString to
= xSimpleMailMessage
->getRecipient();
196 if (to
.getLength() > 0)
198 rCommandArgs
.push_back(TO
);
199 rCommandArgs
.push_back(to
);
202 Sequence
<OUString
> ccRecipients
= xSimpleMailMessage
->getCcRecipient();
203 for (int i
= 0; i
< ccRecipients
.getLength(); i
++)
205 rCommandArgs
.push_back(CC
);
206 rCommandArgs
.push_back(ccRecipients
[i
]);
209 Sequence
<OUString
> bccRecipients
= xSimpleMailMessage
->getBccRecipient();
210 for (int i
= 0; i
< bccRecipients
.getLength(); i
++)
212 rCommandArgs
.push_back(BCC
);
213 rCommandArgs
.push_back(bccRecipients
[i
]);
216 OUString from
= xSimpleMailMessage
->getOriginator();
217 if (from
.getLength() > 0)
219 rCommandArgs
.push_back(FROM
);
220 rCommandArgs
.push_back(from
);
223 OUString subject
= xSimpleMailMessage
->getSubject();
224 if (subject
.getLength() > 0)
226 rCommandArgs
.push_back(SUBJECT
);
227 rCommandArgs
.push_back(subject
);
230 Sequence
<OUString
> attachments
= xSimpleMailMessage
->getAttachement();
231 for (int i
= 0; i
< attachments
.getLength(); i
++)
234 osl::FileBase::RC err
= osl::FileBase::getSystemPathFromFileURL(attachments
[i
], sysPath
);
235 if (err
!= osl::FileBase::E_None
)
236 throw IllegalArgumentException(
237 "Invalid attachment file URL",
238 static_cast<XSimpleMailClient
*>(this),
241 rCommandArgs
.push_back(ATTACH
);
242 rCommandArgs
.push_back(sysPath
);
245 if (!(aFlag
& NO_USER_INTERFACE
))
246 rCommandArgs
.push_back(FLAG_MAPI_DIALOG
);
248 if (!(aFlag
& NO_LOGON_DIALOG
))
249 rCommandArgs
.push_back(FLAG_MAPI_LOGON_UI
);
252 void SAL_CALL
CSmplMailClient::sendSimpleMailMessage(
253 const Reference
<XSimpleMailMessage
>& xSimpleMailMessage
, sal_Int32 aFlag
)
254 throw (IllegalArgumentException
, Exception
, RuntimeException
)
256 validateParameter(xSimpleMailMessage
, aFlag
);
258 StringList_t senddocParams
;
259 assembleCommandLine(xSimpleMailMessage
, aFlag
, senddocParams
);
261 if (!executeSenddoc(senddocParams
))
264 static_cast<XSimpleMailClient
*>(this));
267 void CSmplMailClient::validateParameter(
268 const Reference
<XSimpleMailMessage
>& xSimpleMailMessage
, sal_Int32 aFlag
)
270 if (!xSimpleMailMessage
.is())
271 throw IllegalArgumentException(
272 "Empty mail message reference",
273 static_cast<XSimpleMailClient
*>(this),
276 OSL_ENSURE(!(aFlag
& NO_LOGON_DIALOG
), "Flag NO_LOGON_DIALOG has currently no effect");
278 // check the flags, the allowed range is 0 - (2^n - 1)
279 if (aFlag
< 0 || aFlag
> 3)
280 throw IllegalArgumentException(
281 "Invalid flag value",
282 static_cast<XSimpleMailClient
*>(this),
285 // check if a recipient is specified of the flags NO_USER_INTERFACE is specified
286 if ((aFlag
& NO_USER_INTERFACE
) && !xSimpleMailMessage
->getRecipient().getLength())
287 throw IllegalArgumentException(
288 "No recipient specified",
289 static_cast<XSimpleMailClient
*>(this),
293 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */