1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_shell.hxx" 30 #include <osl/diagnose.h> 31 32 #ifndef _RTL_STRING_HXX_ 33 //#include <rtl/string.hxx> 34 #endif 35 #include "simplemapi.hxx" 36 37 #define WIN32_LEAN_AND_MEAN 38 #if defined _MSC_VER 39 #pragma warning(push, 1) 40 #endif 41 #include <windows.h> 42 #if defined _MSC_VER 43 #pragma warning(pop) 44 #endif 45 #include <tchar.h> 46 47 #include <iostream> 48 #include <vector> 49 #include <sstream> 50 #include <stdexcept> 51 52 #if OSL_DEBUG_LEVEL > 2 53 void dumpParameter(); 54 #endif 55 56 typedef std::vector<std::string> StringList_t; 57 typedef StringList_t::const_iterator StringListIterator_t; 58 typedef std::vector<MapiRecipDesc> MapiRecipientList_t; 59 typedef std::vector<MapiFileDesc> MapiAttachmentList_t; 60 61 const int LEN_SMTP_PREFIX = 5; // "SMTP:" 62 63 namespace /* private */ 64 { 65 std::string gFrom; 66 std::string gSubject; 67 std::string gBody; 68 StringList_t gTo; 69 StringList_t gCc; 70 StringList_t gBcc; 71 StringList_t gAttachments; 72 int gMapiFlags = 0; 73 } 74 75 /** 76 Add a prefix to an email address. MAPI requires that that 77 email addresses have an 'SMTP:' prefix. 78 79 @param aEmailAddress 80 [in] the email address. 81 82 @param aPrefix 83 [in] the prefix to be added to the email address. 84 85 @returns 86 the email address prefixed with the specified prefix. 87 */ 88 inline std::string prefixEmailAddress( 89 const std::string& aEmailAddress, 90 const std::string& aPrefix = "SMTP:") 91 { 92 return (aPrefix + aEmailAddress); 93 } 94 95 /** @internal */ 96 void addRecipient( 97 ULONG recipClass, 98 const std::string& recipAddress, 99 MapiRecipientList_t* pMapiRecipientList) 100 { 101 MapiRecipDesc mrd; 102 ZeroMemory(&mrd, sizeof(mrd)); 103 104 mrd.ulRecipClass = recipClass; 105 mrd.lpszName = const_cast<char*>(recipAddress.c_str()) + LEN_SMTP_PREFIX; 106 mrd.lpszAddress = const_cast<char*>(recipAddress.c_str()); 107 pMapiRecipientList->push_back(mrd); 108 } 109 110 /** @internal */ 111 void initRecipientList(MapiRecipientList_t* pMapiRecipientList) 112 { 113 OSL_ASSERT(pMapiRecipientList->size() == 0); 114 115 // add to recipients 116 StringListIterator_t iter = gTo.begin(); 117 StringListIterator_t iter_end = gTo.end(); 118 for (; iter != iter_end; ++iter) 119 addRecipient(MAPI_TO, *iter, pMapiRecipientList); 120 121 // add cc recipients 122 iter = gCc.begin(); 123 iter_end = gCc.end(); 124 for (; iter != iter_end; ++iter) 125 addRecipient(MAPI_CC, *iter, pMapiRecipientList); 126 127 // add bcc recipients 128 iter = gBcc.begin(); 129 iter_end = gBcc.end(); 130 for (; iter != iter_end; ++iter) 131 addRecipient(MAPI_BCC, *iter, pMapiRecipientList); 132 } 133 134 /** @internal */ 135 void initAttachementList(MapiAttachmentList_t* pMapiAttachmentList) 136 { 137 OSL_ASSERT(pMapiAttachmentList->size() == 0); 138 139 StringListIterator_t iter = gAttachments.begin(); 140 StringListIterator_t iter_end = gAttachments.end(); 141 for (/**/; iter != iter_end; ++iter) 142 { 143 MapiFileDesc mfd; 144 ZeroMemory(&mfd, sizeof(mfd)); 145 mfd.lpszPathName = const_cast<char*>(iter->c_str()); 146 mfd.nPosition = sal::static_int_cast<ULONG>(-1); 147 pMapiAttachmentList->push_back(mfd); 148 } 149 } 150 151 /** @internal */ 152 void initMapiOriginator(MapiRecipDesc* pMapiOriginator) 153 { 154 ZeroMemory(pMapiOriginator, sizeof(MapiRecipDesc)); 155 156 pMapiOriginator->ulRecipClass = MAPI_ORIG; 157 pMapiOriginator->lpszName = ""; 158 pMapiOriginator->lpszAddress = const_cast<char*>(gFrom.c_str()); 159 } 160 161 /** @internal */ 162 void initMapiMessage( 163 MapiRecipDesc* aMapiOriginator, 164 MapiRecipientList_t& aMapiRecipientList, 165 MapiAttachmentList_t& aMapiAttachmentList, 166 MapiMessage* pMapiMessage) 167 { 168 ZeroMemory(pMapiMessage, sizeof(MapiMessage)); 169 170 pMapiMessage->lpszSubject = const_cast<char*>(gSubject.c_str()); 171 pMapiMessage->lpszNoteText = (gBody.length() ? const_cast<char*>(gBody.c_str()) : NULL); 172 pMapiMessage->lpOriginator = aMapiOriginator; 173 pMapiMessage->lpRecips = aMapiRecipientList.size() ? &aMapiRecipientList[0] : 0; 174 pMapiMessage->nRecipCount = aMapiRecipientList.size(); 175 pMapiMessage->lpFiles = &aMapiAttachmentList[0]; 176 pMapiMessage->nFileCount = aMapiAttachmentList.size(); 177 } 178 179 char* KnownParameter[] = 180 { 181 "--to", 182 "--cc", 183 "--bcc", 184 "--from", 185 "--subject", 186 "--body", 187 "--attach", 188 "--mapi-dialog", 189 "--mapi-logon-ui" 190 }; 191 192 const size_t nKnownParameter = (sizeof(KnownParameter)/sizeof(KnownParameter[0])); 193 194 /** @internal */ 195 bool isKnownParameter(const char* aParameterName) 196 { 197 for (size_t i = 0; i < nKnownParameter; i++) 198 if (_tcsicmp(aParameterName, KnownParameter[i]) == 0) 199 return true; 200 201 return false; 202 } 203 204 /** @internal */ 205 void initParameter(int argc, char* argv[]) 206 { 207 for (int i = 1; i < argc; i++) 208 { 209 if (!isKnownParameter(argv[i])) 210 { 211 OSL_ENSURE(false, "Wrong parameter received"); 212 continue; 213 } 214 215 if ((_tcsicmp(argv[i], TEXT("--mapi-dialog")) == 0)) 216 { 217 gMapiFlags |= MAPI_DIALOG; 218 } 219 else if ((_tcsicmp(argv[i], TEXT("--mapi-logon-ui")) == 0)) 220 { 221 gMapiFlags |= MAPI_LOGON_UI; 222 } 223 else if ((i+1) < argc) // is the value of a parameter available too? 224 { 225 if (_tcsicmp(argv[i], TEXT("--to")) == 0) 226 gTo.push_back(prefixEmailAddress(argv[i+1])); 227 else if (_tcsicmp(argv[i], TEXT("--cc")) == 0) 228 gCc.push_back(prefixEmailAddress(argv[i+1])); 229 else if (_tcsicmp(argv[i], TEXT("--bcc")) == 0) 230 gBcc.push_back(prefixEmailAddress(argv[i+1])); 231 else if (_tcsicmp(argv[i], TEXT("--from")) == 0) 232 gFrom = prefixEmailAddress(argv[i+1]); 233 else if (_tcsicmp(argv[i], TEXT("--subject")) == 0) 234 gSubject = argv[i+1]; 235 else if (_tcsicmp(argv[i], TEXT("--body")) == 0) 236 gBody = argv[i+1]; 237 else if ((_tcsicmp(argv[i], TEXT("--attach")) == 0)) 238 gAttachments.push_back(argv[i+1]); 239 240 i++; 241 } 242 } 243 } 244 245 /** 246 Main. 247 NOTE: Because this is program only serves implementation 248 purposes and should not be used by any end user the 249 parameter checking is very limited. Every unknown parameter 250 will be ignored. 251 */ 252 int main(int argc, char* argv[]) 253 { 254 //MessageBox(NULL, "Debug", "Debug", MB_OK); 255 256 initParameter(argc, argv); 257 258 #if OSL_DEBUG_LEVEL > 2 259 dumpParameter(); 260 #endif 261 262 ULONG ulRet = MAPI_E_FAILURE; 263 264 try 265 { 266 CSimpleMapi mapi; 267 268 // #93007# we have to set the flag MAPI_NEW_SESSION, 269 // because in the case Outlook xxx (not Outlook Express!) 270 // is installed as Exchange and Mail Client a Profile 271 // selection dialog must appear because we specify no 272 // profile name, so the user has to specify a profile 273 FLAGS flFlag = MAPI_NEW_SESSION | MAPI_LOGON_UI; 274 LHANDLE hSession; 275 ulRet = mapi.MAPILogon(0, NULL, NULL, flFlag, 0L, &hSession); 276 277 if (ulRet == SUCCESS_SUCCESS) 278 { 279 MapiRecipDesc mapiOriginator; 280 MapiRecipientList_t mapiRecipientList; 281 MapiAttachmentList_t mapiAttachmentList; 282 MapiMessage mapiMsg; 283 284 initMapiOriginator(&mapiOriginator); 285 initRecipientList(&mapiRecipientList); 286 initAttachementList(&mapiAttachmentList); 287 initMapiMessage((gFrom.length() ? &mapiOriginator : NULL), mapiRecipientList, mapiAttachmentList, &mapiMsg); 288 289 ulRet = mapi.MAPISendMail(hSession, 0, &mapiMsg, gMapiFlags, 0); 290 291 mapi.MAPILogoff(hSession, 0, 0, 0); 292 } 293 } 294 catch (const std::runtime_error& 295 #if OSL_DEBUG_LEVEL > 0 296 ex 297 #endif 298 ) 299 { 300 OSL_ENSURE(false, ex.what()); 301 } 302 return ulRet; 303 } 304 305 #if OSL_DEBUG_LEVEL > 2 306 void dumpParameter() 307 { 308 std::ostringstream oss; 309 310 if (gFrom.length() > 0) 311 oss << "--from" << " " << gFrom << std::endl; 312 313 if (gSubject.length() > 0) 314 oss << "--subject" << " " << gSubject << std::endl; 315 316 if (gBody.length() > 0) 317 oss << "--body" << " " << gBody << std::endl; 318 319 StringListIterator_t iter = gTo.begin(); 320 StringListIterator_t iter_end = gTo.end(); 321 for (/**/;iter != iter_end; ++iter) 322 oss << "--to" << " " << *iter << std::endl; 323 324 iter = gCc.begin(); 325 iter_end = gCc.end(); 326 for (/**/;iter != iter_end; ++iter) 327 oss << "--cc" << " " << *iter << std::endl; 328 329 iter = gBcc.begin(); 330 iter_end = gBcc.end(); 331 for (/**/;iter != iter_end; ++iter) 332 oss << "--bcc" << " " << *iter << std::endl; 333 334 iter = gAttachments.begin(); 335 iter_end = gAttachments.end(); 336 for (/**/;iter != iter_end; ++iter) 337 oss << "--attach" << " " << *iter << std::endl; 338 339 if (gMapiFlags & MAPI_DIALOG) 340 oss << "--mapi-dialog" << std::endl; 341 342 if (gMapiFlags & MAPI_LOGON_UI) 343 oss << "--mapi-logon-ui" << std::endl; 344 345 MessageBox(NULL, oss.str().c_str(), "Arguments", MB_OK | MB_ICONINFORMATION); 346 } 347 #endif 348