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