HRESULT ExchangeAdmin::DeleteProfile(wstring strProfile) { HRESULT hr = S_OK; Zimbra::Util::ScopedBuffer<char> strProfName; WtoA((LPWSTR)strProfile.c_str(), strProfName.getref()); // delete profile if (FAILED(hr = m_pProfAdmin->DeleteProfile((LPTSTR)strProfName.get(), 0)) && (hr != MAPI_E_NOT_FOUND)) throw ExchangeAdminException(hr, L"DeleteProfile(): DeleteProfile Failed.", ERR_DELETE_PROFILE, __LINE__, __FILE__); return hr; }
HRESULT ExchangeAdmin::CreateProfile(wstring strProfileName, wstring strMailboxName, wstring strPassword) { HRESULT hr = S_OK; Zimbra::Util::ScopedBuffer<char> strServer; Zimbra::Util::ScopedBuffer<char> strMBName; Zimbra::Util::ScopedBuffer<char> strProfName; Zimbra::Util::ScopedBuffer<char> strProfPwd; Zimbra::Util::ScopedInterface<IMsgServiceAdmin> pSvcAdmin; Zimbra::Util::ScopedInterface<IMAPITable> pMsgSvcTable; Zimbra::Util::ScopedRowSet pSvcRows; SPropValue rgval[2] = { 0 }; SPropValue sProps = { 0 }; SRestriction sres; WCHAR errDescrption[256] = {}; // Columns to get from HrQueryAllRows. enum { iSvcName, iSvcUID, cptaSvc }; SizedSPropTagArray(cptaSvc, sptCols) = { cptaSvc, PR_SERVICE_NAME, PR_SERVICE_UID }; WtoA((LPWSTR)strProfileName.c_str(), strProfName.getref()); WtoA((LPWSTR)strPassword.c_str(), strProfPwd.getref()); // create new profile if (FAILED(hr = m_pProfAdmin->CreateProfile((LPTSTR)strProfName.get(), (LPTSTR)strProfPwd.get(), NULL, 0))) { throw ExchangeAdminException(hr, L"CreateProfile(): CreateProfile Failed.", ERR_CREATE_EXCHPROFILE, __LINE__, __FILE__); } // Get an IMsgServiceAdmin interface off of the IProfAdmin interface. if (FAILED(hr = m_pProfAdmin->AdminServices((LPTSTR)strProfName.get(), (LPTSTR)strProfPwd.get(), NULL, 0, pSvcAdmin.getptr()))) { wcscpy(errDescrption, L"CreateProfile(): AdminServices Failed."); goto CRT_PROFILE_EXIT; } // Create the new message service for Exchange. if (FAILED(hr = pSvcAdmin->CreateMsgService((LPTSTR)"MSEMS", (LPTSTR)"MSEMS", NULL, NULL))) { wcscpy(errDescrption, L"CreateProfile(): CreateMsgService Failed."); goto CRT_PROFILE_EXIT; } // Need to obtain the entry id for the new service. This can be done by getting the message service table // and getting the entry that corresponds to the new service. if (FAILED(hr = pSvcAdmin->GetMsgServiceTable(0, pMsgSvcTable.getptr()))) { wcscpy(errDescrption, L"CreateProfile(): GetMsgServiceTable Failed."); goto CRT_PROFILE_EXIT; } sres.rt = RES_CONTENT; sres.res.resContent.ulFuzzyLevel = FL_FULLSTRING; sres.res.resContent.ulPropTag = PR_SERVICE_NAME; sres.res.resContent.lpProp = &sProps; sProps.ulPropTag = PR_SERVICE_NAME; sProps.Value.lpszA = "MSEMS"; // Query the table to obtain the entry for the newly created message service. if (FAILED(hr = HrQueryAllRows(pMsgSvcTable.get(), (LPSPropTagArray) & sptCols, NULL, NULL, 0, pSvcRows.getptr()))) { wcscpy(errDescrption, L"CreateProfile(): HrQueryAllRows Failed."); goto CRT_PROFILE_EXIT; } // Set up a SPropValue array for the properties that you have to configure. if (pSvcRows->cRows > 0) { // First, the exchange server name. ZeroMemory(&rgval[0], sizeof (SPropValue)); rgval[0].ulPropTag = PR_PROFILE_UNRESOLVED_SERVER; WtoA((LPWSTR)m_strServer.c_str(), strServer.getref()); rgval[0].Value.lpszA = (LPSTR)strServer.get(); // Next, the user's AD name. ZeroMemory(&rgval[1], sizeof (SPropValue)); rgval[1].ulPropTag = PR_PROFILE_UNRESOLVED_NAME; WtoA((LPWSTR)strMailboxName.c_str(), strMBName.getref()); rgval[1].Value.lpszA = (LPSTR)strMBName.get(); // Configure the message service by using the previous properties. // int trials = 10; int trials = 2; int itrTrials = 0; hr = 0x81002746; // WSAECONNRESET while ((hr == 0x81002746) && (itrTrials < trials)) { hr = pSvcAdmin->ConfigureMsgService( (LPMAPIUID)pSvcRows->aRow->lpProps[iSvcUID].Value.bin.lpb, NULL, 0, 2, rgval); //if (hr == 0x81002746) // Sleep(30000); //Sleep(10000); itrTrials++; } if (FAILED(hr)) { /* = * pSvcAdmin->ConfigureMsgService((LPMAPIUID)pSvcRows->aRow->lpProps[iSvcUID]. * Value.bin.lpb,NULL, 0, 2, rgval)))*/ wcscpy(errDescrption, L"CreateProfile(): ConfigureMsgService Failed."); goto CRT_PROFILE_EXIT; } } CRT_PROFILE_EXIT: if (hr != S_OK) { DeleteProfile(strProfileName); throw ExchangeAdminException(hr, errDescrption, ERR_CREATE_EXCHPROFILE, __LINE__, __FILE__); } else { //Create supporting OL profile entries else crash may happen! if(!Zimbra::MAPI::Util::SetOLProfileRegistryEntries(strProfileName.c_str())) { throw ExchangeAdminException(hr, L"ExchangeAdmin::CreateProfile()::SetOLProfileRegistryEntries Failed.", ERR_CREATE_EXCHPROFILE, __LINE__, __FILE__); } /* Zimbra::Util::ScopedBuffer<char> strProfName; WtoA((LPWSTR)strProfileName.c_str(), strProfName.getref()); hr=m_pProfAdmin->SetDefaultProfile((LPTSTR)strProfName.get(),NULL); */ } return hr; }
HRESULT MAPIRfc2445::ExtractAttachments() { // may need to break this up so we can call for exceptions, cancel exceptions LPCWSTR errMsg; Zimbra::Util::ScopedInterface<IStream> pIStream; UINT mimeLen = 0; HRESULT hr = ConvertIt( m_pMessage, pIStream.getptr(), mimeLen ); if (FAILED(hr)) { errMsg = FormatExceptionInfo(hr, L"Mime conversion of message with attachments failed", __FILE__, __LINE__); dlogw(errMsg); return hr; } mimepp::Message mimeMsg; Zimbra::Util::ScopedBuffer<CHAR> pszMimeMsg; // go to the beginning of the stream LARGE_INTEGER li = { 0 }; hr = pIStream->Seek(li, STREAM_SEEK_SET, NULL); if (FAILED(hr)) { errMsg = FormatExceptionInfo(hr, L"Stream seek failed", __FILE__, __LINE__); dlogw(errMsg); return hr; } // +1 for NULL terminator Zimbra::Mapi::Memory::AllocateBuffer(mimeLen + 1, (LPVOID *)pszMimeMsg.getptr()); if (!pszMimeMsg.get()) { errMsg = FormatExceptionInfo(S_OK, L"Mime msg Memory alloc failed", __FILE__, __LINE__); dlogw(errMsg); return hr; } ULONG ulNumRead = 0; hr = pIStream->Read((LPVOID)(pszMimeMsg.get()), mimeLen, &ulNumRead); if (FAILED(hr)) { errMsg = FormatExceptionInfo(hr, L"Mime msg read failed", __FILE__, __LINE__); dlogw(errMsg); return hr; } if (ulNumRead != mimeLen) { errMsg = FormatExceptionInfo(hr, L"Mime msg read error", __FILE__, __LINE__); dlogw(errMsg); return hr; } // terminating string pszMimeMsg.get()[mimeLen] = '\0'; mimeMsg.setString(pszMimeMsg.get()); mimeMsg.parse(); // let's see if this message is a multipart alternative before we continue mimepp::Headers &theHeaders = mimeMsg.headers(); LPSTR pszContentType; GetContentType(theHeaders, &pszContentType); if(strncmp(pszContentType, "multipart/mixed", strlen("multipart/mixed")) != 0) { // not what we are looking for delete[] pszContentType; return S_OK; } const mimepp::Body& theBody = mimeMsg.body(); int numParts = theBody.numBodyParts(); // FBS bug 73682 -- 5/23/12 int numHiddenAttachments = GetNumHiddenAttachments(); int totalAttachments = numParts - 1; if (totalAttachments == numHiddenAttachments) { return S_OK; } // let's look for a multipart mixed and grab the attachments int ctr = numHiddenAttachments; for(int i = 0; i < numParts; i++) { // now look for attachments const mimepp::BodyPart& thePart = theBody.bodyPartAt(i); mimepp::DispositionType& disposition = thePart.headers().contentDisposition(); if(disposition.asEnum() == mimepp::DispositionType::ATTACHMENT) { const mimepp::String& theFilename = disposition.filename(); LPSTR pszAttachContentType; LPSTR pszCD; LPSTR lpszRealName = new char[256]; GetContentType(thePart.headers(), &pszAttachContentType); // FBS bug 73682 -- Exceptions are at the beginning. Don't make attachments for those if (ctr > 0) { if (0 == strcmpi(pszAttachContentType, "message/rfc822")) { ctr--; continue; } } // if((LPSTR)theFilename.length()>0) { GenerateContentDisposition(&pszCD, (LPSTR)theFilename.c_str()); strcpy(lpszRealName, (LPSTR)theFilename.c_str()); } else { char cfilename[64]; sprintf(cfilename,"attachment-%d",i); GenerateContentDisposition(&pszCD, cfilename); strcpy(lpszRealName, cfilename); } // now deal with the encoding LPSTR pContent = NULL; const mimepp::String &theContent = thePart.body().getString(); mimepp::String outputString; UINT size = 0; mimepp::TransferEncodingType& transferEncoding = thePart.headers().contentTransferEncoding(); if(transferEncoding.asEnum() == mimepp::TransferEncodingType::BASE64) { // let's decode the buffer mimepp::Base64Decoder decoder; outputString = decoder.decode(theContent); pContent = (LPSTR)outputString.c_str(); size = (UINT)outputString.size(); } else if(transferEncoding.asEnum() == mimepp::TransferEncodingType::QUOTED_PRINTABLE) { mimepp::QuotedPrintableDecoder decoder; outputString = decoder.decode(theContent); pContent = (LPSTR)outputString.c_str(); size = (UINT)outputString.size(); } else { pContent = (LPSTR)theContent.c_str(); size = (UINT)theContent.size(); } // Save stream to temp file in temp dir. We'll delete in ZimbraAPI // LPCWSTR errMsg; HRESULT hr = S_OK; wstring wstrTempAppDirPath; LPSTR lpszFQFileName = new char[256]; LPSTR lpszDirName = NULL; LPSTR lpszUniqueName = NULL; Zimbra::Util::ScopedInterface<IStream> pStream; if (!Zimbra::MAPI::Util::GetAppTemporaryDirectory(wstrTempAppDirPath)) { errMsg = FormatExceptionInfo(S_OK, L"GetAppTemporaryDirectory Failed", __FILE__, __LINE__); dloge("MAPIRfc2445 -- exception"); dloge(errMsg); return E_FAIL; } WtoA((LPWSTR)wstrTempAppDirPath.c_str(), lpszDirName); WtoA((LPWSTR)Zimbra::MAPI::Util::GetUniqueName().c_str(), lpszUniqueName); strcpy(lpszFQFileName, lpszDirName); strcat(lpszFQFileName, "\\"); strcat(lpszFQFileName, lpszUniqueName); SafeDelete(lpszDirName); SafeDelete(lpszUniqueName); // Open stream on file if (FAILED(hr = OpenStreamOnFile(MAPIAllocateBuffer, MAPIFreeBuffer, STGM_CREATE | STGM_READWRITE, (LPTSTR)lpszFQFileName, NULL, pStream.getptr()))) { errMsg = FormatExceptionInfo(hr, L"Error: OpenStreamOnFile Failed.", __FILE__, __LINE__); dloge("MAPIRfc2445 -- exception"); dloge(errMsg); return hr; } ULONG nBytesToWrite = size; ULONG nBytesWritten = 0; LPBYTE pCur = (LPBYTE)pContent; while (!FAILED(hr) && nBytesToWrite > 0) { hr = pStream->Write(pCur, nBytesToWrite, &nBytesWritten); pCur += nBytesWritten; nBytesToWrite -= nBytesWritten; } if (FAILED(hr = pStream->Commit(0))) { errMsg = FormatExceptionInfo(hr, L"Error: Stream Write Failed.", __FILE__, __LINE__); dloge("MAPIRfc2445 -- exception"); dloge(errMsg); } /////////// // delete all this in MAPIAccessWrap AttachmentInfo* pAttachmentInfo = new AttachmentInfo(); pAttachmentInfo->pszTempFile = lpszFQFileName; pAttachmentInfo->pszRealName = lpszRealName; pAttachmentInfo->pszContentDisposition = pszCD; pAttachmentInfo->pszContentType = pszAttachContentType; m_vAttachments.push_back(pAttachmentInfo); } } delete[] pszContentType; return S_OK; }