int MAPIRfc2445::GetNumHiddenAttachments() { int retval = 0; HRESULT hr = S_OK; LPCWSTR errMsg; Zimbra::Util::ScopedInterface<IStream> pSrcStream; Zimbra::Util::ScopedRowSet pAttachRows; Zimbra::Util::ScopedInterface<IMAPITable> pAttachTable; SizedSPropTagArray(1, attachProps) = { 1, { PR_ATTACHMENT_HIDDEN } }; hr = m_pMessage->GetAttachmentTable(MAPI_UNICODE, pAttachTable.getptr()); if (SUCCEEDED(hr)) { if (FAILED(hr = pAttachTable->SetColumns((LPSPropTagArray) &attachProps, 0))) { errMsg = FormatExceptionInfo(hr, L"Error setting attachment table columns", __FILE__, __LINE__); dlogw(errMsg); return 0; } ULONG ulRowCount = 0; if (FAILED(hr = pAttachTable->GetRowCount(0, &ulRowCount))) { errMsg = FormatExceptionInfo(hr, L"Error getting attachment table row count", __FILE__, __LINE__); dlogw(errMsg); return 0; } if (FAILED(hr = pAttachTable->QueryRows(ulRowCount, 0, pAttachRows.getptr()))) { errMsg = FormatExceptionInfo(hr, L"Error querying attachment table rows", __FILE__, __LINE__); dlogw(errMsg); return 0; } if (SUCCEEDED(hr)) { hr = MAPI_E_NOT_FOUND; for (unsigned int i = 0; i < pAttachRows->cRows; i++) { // if property couldn't be found or returns error, skip it if ((pAttachRows->aRow[i].lpProps[0].ulPropTag != PT_ERROR) && (pAttachRows->aRow[i].lpProps[0].Value.err != MAPI_E_NOT_FOUND)) { if (pAttachRows->aRow[i].lpProps[0].Value.b) { retval++; } } } } } else { errMsg = FormatExceptionInfo(hr, L"Error getting attachment tables", __FILE__, __LINE__); dlogw(errMsg); return 0; } return retval; }
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 ExchangeAdmin::GetAllProfiles(vector<string> &vProfileList) { HRESULT hr = S_OK; Zimbra::Util::ScopedInterface<IMAPITable> pProftable; // get profile table if ((hr = m_pProfAdmin->GetProfileTable(0, pProftable.getptr())) == S_OK) { SizedSPropTagArray(3, proftablecols) = { 3, { PR_DISPLAY_NAME_A, PR_DEFAULT_PROFILE, PR_SERVICE_NAME } }; Zimbra::Util::ScopedRowSet profrows; // get all profile rows if ((hr = HrQueryAllRows(pProftable.get(), (SPropTagArray *)&proftablecols, NULL, NULL, 0, profrows.getptr())) == S_OK) { for (unsigned int i = 0; i < profrows->cRows; i++) { if (profrows->aRow[i].lpProps[0].ulPropTag == PR_DISPLAY_NAME_A) { Zimbra::Util::ScopedInterface<IMsgServiceAdmin> spServiceAdmin; Zimbra::Util::ScopedInterface<IMAPITable> spServiceTable; string strpname = profrows->aRow[i].lpProps[0].Value.lpszA; // get profile's admin service hr = m_pProfAdmin->AdminServices((LPTSTR)strpname.c_str(), NULL, NULL, 0, spServiceAdmin.getptr()); if (FAILED(hr)) throw ExchangeAdminException(hr,L"GetAllProfiles(): AdminServices Failed.", ERR_GETALL_PROFILE, __LINE__, __FILE__); // get message service table hr = spServiceAdmin->GetMsgServiceTable(0, spServiceTable.getptr()); if (FAILED(hr)) { throw ExchangeAdminException(hr,L"GetAllProfiles(): GetMsgServiceTable Failed.", ERR_GETALL_PROFILE, __LINE__, __FILE__); } // lets get the service name and the service uid for the primary service SizedSPropTagArray(2, tags) = { 2, { PR_SERVICE_NAME, PR_SERVICE_UID } }; spServiceTable->SetColumns((LPSPropTagArray) & tags, 0); DWORD dwCount = 0; hr = spServiceTable->GetRowCount(0, &dwCount); if (FAILED(hr)) throw ExchangeAdminException(hr, L"GetAllProfiles(): GetRowCount Failed.", ERR_GETALL_PROFILE, __LINE__, __FILE__); else if (!dwCount) return hr; Zimbra::Util::ScopedRowSet pRows; hr = spServiceTable->QueryRows(dwCount, 0, pRows.getptr()); if (FAILED(hr)) throw ExchangeAdminException(hr, L"GetAllProfiles(): QueryRows Failed.", ERR_GETALL_PROFILE, __LINE__, __FILE__); for (ULONG j = 0; j < pRows->cRows; j++) { if (PR_SERVICE_NAME == pRows->aRow[j].lpProps[0].ulPropTag) { // if MSExchange service if (0 == lstrcmpiW(pRows->aRow[j].lpProps[0].Value.LPSZ, L"MSEMS")) { if (profrows->aRow[i].lpProps[0].ulPropTag == PR_DISPLAY_NAME_A) vProfileList.push_back( profrows->aRow[i].lpProps[0].Value.lpszA); break; } } } } } } } return hr; }
HRESULT MAPIContact::GetContactImage(wstring &wstrImagePath) { HRESULT hr = S_OK; Zimbra::Util::ScopedInterface<IStream> pSrcStream; { Zimbra::Util::ScopedRowSet pAttachRows; Zimbra::Util::ScopedInterface<IMAPITable> pAttachTable; SizedSPropTagArray(3, attachProps) = { 3, { PR_ATTACH_NUM, PR_ATTACH_SIZE, PR_ATTACH_LONG_FILENAME } }; hr = m_pMessage->GetAttachmentTable(MAPI_UNICODE, pAttachTable.getptr()); if (SUCCEEDED(hr)) { if (FAILED(hr = pAttachTable->SetColumns((LPSPropTagArray) & attachProps, 0))) return hr; ULONG ulRowCount = 0; if (FAILED(hr = pAttachTable->GetRowCount(0, &ulRowCount))) return hr; if (FAILED(hr = pAttachTable->QueryRows(ulRowCount, 0, pAttachRows.getptr()))) return hr; if (SUCCEEDED(hr)) { hr = MAPI_E_NOT_FOUND; for (unsigned int i = 0; i < pAttachRows->cRows; i++) { // if property couldn't be found or returns error, skip it if ((pAttachRows->aRow[i].lpProps[2].ulPropTag == PT_ERROR) || (pAttachRows->aRow[i].lpProps[2].Value.err == MAPI_E_NOT_FOUND)) continue; // Discard the attachmetnt if its not contact picture if (_tcscmp(pAttachRows->aRow[i].lpProps[2].Value.LPSZ, _T( "ContactPicture.jpg"))) continue; Zimbra::Util::ScopedInterface<IAttach> pAttach; if (FAILED(hr = m_pMessage->OpenAttach( pAttachRows->aRow[i].lpProps[0].Value.l, NULL, 0, pAttach.getptr()))) continue; if (FAILED(hr = pAttach->OpenProperty(PR_ATTACH_DATA_BIN, &IID_IStream, STGM_READ, 0, (LPUNKNOWN FAR *)pSrcStream.getptr()))) return hr; break; } } } } if (hr != S_OK) return hr; // copy image to file wstring wstrTempAppDirPath; char *lpszDirName = NULL; char *lpszUniqueName = NULL; Zimbra::Util::ScopedInterface<IStream> pDestStream; if (!Zimbra::MAPI::Util::GetAppTemporaryDirectory(wstrTempAppDirPath)) return MAPI_E_ACCESS_DENIED; WtoA((LPWSTR)wstrTempAppDirPath.c_str(), lpszDirName); string strFQFileName = lpszDirName; WtoA((LPWSTR)Zimbra::MAPI::Util::GetUniqueName().c_str(), lpszUniqueName); strFQFileName += "\\ZmContact_"; strFQFileName += lpszUniqueName; strFQFileName += ".jpg"; SafeDelete(lpszDirName); SafeDelete(lpszUniqueName); // Open stream on file if (FAILED(hr = OpenStreamOnFile(MAPIAllocateBuffer, MAPIFreeBuffer, STGM_CREATE | STGM_READWRITE, (LPTSTR)strFQFileName.c_str(), NULL, pDestStream.getptr()))) return hr; ULARGE_INTEGER liAll = { 0 }; liAll.QuadPart = (ULONGLONG)-1; if (FAILED(hr = pSrcStream->CopyTo(pDestStream.get(), liAll, NULL, NULL))) return hr; if (FAILED(hr = pDestStream->Commit(0))) { return hr; ; } // mime file path LPWSTR lpwstrFQFileName = NULL; AtoW((LPSTR)strFQFileName.c_str(), lpwstrFQFileName); wstrImagePath = lpwstrFQFileName; SafeDelete(lpwstrFQFileName); return hr; }
HRESULT MAPIAppointment::SetOrganizerAndAttendees() { Zimbra::Util::ScopedInterface<IMAPITable> pRecipTable; HRESULT hr = 0; hr = m_pMessage->GetRecipientTable(fMapiUnicode, pRecipTable.getptr()); if (FAILED(hr)) { return hr; } typedef enum _AttendeePropTagIdx { AT_ADDRTYPE, AT_ENTRYID, AT_DISPLAY_NAME, AT_SMTP_ADDR, AT_RECIPIENT_FLAGS, AT_RECIPIENT_TYPE, AT_RECIPIENT_TRACKSTATUS,AT_EMAIL_ADDRESS, AT_NPROPS } AttendeePropTagIdx; SizedSPropTagArray(AT_NPROPS, reciptags) = { AT_NPROPS, { PR_ADDRTYPE, PR_ENTRYID, PR_DISPLAY_NAME_W, PR_SMTP_ADDRESS_W, PR_RECIPIENT_FLAGS, PR_RECIPIENT_TYPE, PR_RECIPIENT_TRACKSTATUS,PR_EMAIL_ADDRESS } }; ULONG ulRows = 0; Zimbra::Util::ScopedRowSet pRecipRows; hr = pRecipTable->SetColumns((LPSPropTagArray) & reciptags, 0); if (FAILED(hr)) { //LOG_ERROR(_T("could not get the recipient table, hr: %x"), hr); return hr; } hr = pRecipTable->GetRowCount(0, &ulRows); if (FAILED(hr)) { //LOG_ERROR(_T("could not get the recipient table row count, hr: %x"), hr); return hr; } hr = pRecipTable->QueryRows(ulRows, 0, pRecipRows.getptr()); if (FAILED(hr)) { //LOG_ERROR(_T("Failed to query table rows. hr: %x"), hr); return hr; } if (pRecipRows != NULL) { for (ULONG iRow = 0; iRow < pRecipRows->cRows; iRow++) { if (pRecipRows->aRow[iRow].lpProps[AT_RECIPIENT_FLAGS].ulPropTag == reciptags.aulPropTag[AT_RECIPIENT_FLAGS]) { if (pRecipRows->aRow[iRow].lpProps[AT_RECIPIENT_FLAGS].Value.l == 3) { if (PROP_TYPE(pRecipRows->aRow[iRow].lpProps[AT_DISPLAY_NAME].ulPropTag) != PT_ERROR) { m_pOrganizerName = pRecipRows->aRow[iRow].lpProps[AT_DISPLAY_NAME].Value.lpszW; } if (PROP_TYPE(pRecipRows->aRow[iRow].lpProps[AT_SMTP_ADDR].ulPropTag) != PT_ERROR) { m_pOrganizerAddr = pRecipRows->aRow[iRow].lpProps[AT_SMTP_ADDR].Value.lpszW; } if((lstrcmpiW(m_pOrganizerAddr.c_str(),L"") == 0) ||(m_pOrganizerName ==L"")) { Attendee* pAttendee = new Attendee(); dlogi("Going to Update organizer from EID..."); if(UpdateAttendeeFromEntryId(*pAttendee,pRecipRows->aRow[iRow].lpProps[AT_ENTRYID].Value.bin) !=S_OK) { dlogi("Going to update organizer from AD"); RECIP_INFO tempRecip; tempRecip.pAddrType = NULL; tempRecip.pEmailAddr = NULL; tempRecip.cbEid = 0; tempRecip.pEid = NULL; tempRecip.pAddrType = pRecipRows->aRow[iRow].lpProps[AT_ADDRTYPE].Value.lpszW; tempRecip.pEmailAddr = pRecipRows->aRow[iRow].lpProps[AT_EMAIL_ADDRESS].Value.lpszW; if (pRecipRows->aRow[iRow].lpProps[AT_ENTRYID].ulPropTag != PT_ERROR) { tempRecip.cbEid = pRecipRows->aRow[iRow].lpProps[AT_ENTRYID].Value.bin.cb; tempRecip.pEid = (LPENTRYID)pRecipRows->aRow[iRow].lpProps[AT_ENTRYID].Value .bin.lpb; } std::wstring wstrEmailAddress; try { Zimbra::MAPI::Util::GetSMTPFromAD(*m_session, tempRecip,L"" , L"",wstrEmailAddress); } catch(...) { dlogw("mapiappointment::exception from MAPi::util::GetSMTPFromAD "); } pAttendee->addr = wstrEmailAddress; dlogi("Email address(AD):",wstrEmailAddress); dlogi("AD update end."); } dlogi("EID update end."); if(m_pOrganizerAddr==L"") m_pOrganizerAddr = pAttendee->addr; if(m_pOrganizerName==L"") m_pOrganizerName = pAttendee->nam; } dlogi("OrganizerAddr: ",m_pOrganizerAddr, " OrganizerName: ",m_pOrganizerName); } else { if (!(RECIP_FLAG_EXCEP_DELETED & pRecipRows->aRow[iRow].lpProps[AT_RECIPIENT_FLAGS].Value.l)) // make sure attendee wasn't deleted { Attendee* pAttendee = new Attendee(); // delete done in CMapiAccessWrap::GetData after we allocate dict string for ZimbraAPI if (PROP_TYPE(pRecipRows->aRow[iRow].lpProps[AT_DISPLAY_NAME].ulPropTag) != PT_ERROR) pAttendee->nam = pRecipRows->aRow[iRow].lpProps[AT_DISPLAY_NAME].Value.lpszW; if (PROP_TYPE(pRecipRows->aRow[iRow].lpProps[AT_SMTP_ADDR].ulPropTag) != PT_ERROR) pAttendee->addr = pRecipRows->aRow[iRow].lpProps[AT_SMTP_ADDR].Value.lpszW; wstring attaddress = pAttendee->addr; if(lstrcmpiW(attaddress.c_str(),L"") == 0) { if (((pAttendee->nam==L"") || (pAttendee->addr==L"")) && (PROP_TYPE(pRecipRows->aRow[iRow].lpProps[AT_ENTRYID].ulPropTag) != PT_ERROR)) { dlogi("Going to Update attendee from EID..."); if(UpdateAttendeeFromEntryId(*pAttendee,pRecipRows->aRow[iRow].lpProps[AT_ENTRYID].Value.bin)!=S_OK) { dlogi("Going to update attendee from AD"); RECIP_INFO tempRecip; tempRecip.pAddrType = NULL; tempRecip.pEmailAddr = NULL; tempRecip.cbEid = 0; tempRecip.pEid = NULL; tempRecip.pAddrType = pRecipRows->aRow[iRow].lpProps[AT_ADDRTYPE].Value.lpszW; tempRecip.pEmailAddr = pRecipRows->aRow[iRow].lpProps[AT_EMAIL_ADDRESS].Value.lpszW; if (pRecipRows->aRow[iRow].lpProps[AT_ENTRYID].ulPropTag != PT_ERROR) { tempRecip.cbEid = pRecipRows->aRow[iRow].lpProps[AT_ENTRYID].Value.bin.cb; tempRecip.pEid = (LPENTRYID)pRecipRows->aRow[iRow].lpProps[AT_ENTRYID].Value .bin.lpb; } std::wstring wstrEmailAddress; try { Zimbra::MAPI::Util::GetSMTPFromAD(*m_session, tempRecip,L"" , L"",wstrEmailAddress); } catch(...) { dlogw(" Mapiappoinemtn::Exception in MAPI::Util::GetSMTPFromAD"); } pAttendee->addr = wstrEmailAddress; dlogi("Email address(AD):",wstrEmailAddress); dlogi("AD update end."); } dlogi("EID update end."); } } dlogi("AttendeeAddr: ",pAttendee->addr," AttendeeName :",pAttendee->nam); if (PROP_TYPE(pRecipRows->aRow[iRow].lpProps[AT_RECIPIENT_TYPE].ulPropTag) != PT_ERROR) pAttendee->role = ConvertValueToRole(pRecipRows->aRow[iRow].lpProps[AT_RECIPIENT_TYPE].Value.l); if (PROP_TYPE(pRecipRows->aRow[iRow].lpProps[AT_RECIPIENT_TRACKSTATUS].ulPropTag) != PT_ERROR) pAttendee->partstat = ConvertValueToPartStat(pRecipRows->aRow[iRow].lpProps[AT_RECIPIENT_TRACKSTATUS].Value.l); m_vAttendees.push_back(pAttendee); } } } } } return hr; }
HRESULT MAPIContact::GetContactImage(wstring &wstrImagePath,wstring &wstrContentType,wstring &wstrContentDisposition) { HRESULT hr = S_OK; LPSTR strExtension=".jpg"; Zimbra::Util::ScopedInterface<IStream> pSrcStream; { Zimbra::Util::ScopedRowSet pAttachRows; Zimbra::Util::ScopedInterface<IMAPITable> pAttachTable; SizedSPropTagArray(4, attachProps) = { 4, { PR_ATTACH_NUM, PR_ATTACH_SIZE, PR_ATTACH_LONG_FILENAME,PR_ATTACH_EXTENSION } }; hr = m_pMessage->GetAttachmentTable(MAPI_UNICODE, pAttachTable.getptr()); if (SUCCEEDED(hr)) { if (FAILED(hr = pAttachTable->SetColumns((LPSPropTagArray) & attachProps, 0))) return hr; ULONG ulRowCount = 0; if (FAILED(hr = pAttachTable->GetRowCount(0, &ulRowCount))) return hr; if (FAILED(hr = pAttachTable->QueryRows(ulRowCount, 0, pAttachRows.getptr()))) return hr; if (SUCCEEDED(hr)) { hr = MAPI_E_NOT_FOUND; for (unsigned int i = 0; i < pAttachRows->cRows; i++) { // if property couldn't be found or returns error, skip it if ((pAttachRows->aRow[i].lpProps[2].ulPropTag == PT_ERROR) || (pAttachRows->aRow[i].lpProps[2].Value.err == MAPI_E_NOT_FOUND)) continue; // Discard the attachmetnt if its not contact picture if (_tcscmp(pAttachRows->aRow[i].lpProps[2].Value.LPSZ, _T( "ContactPicture.jpg"))) continue; Zimbra::Util::ScopedInterface<IAttach> pAttach; if (FAILED(hr = m_pMessage->OpenAttach( pAttachRows->aRow[i].lpProps[0].Value.l, NULL, 0, pAttach.getptr()))) continue; if (FAILED(hr = pAttach->OpenProperty(PR_ATTACH_DATA_BIN, &IID_IStream, STGM_READ, 0, (LPUNKNOWN FAR *)pSrcStream.getptr()))) return hr; // LPSPropValue pProps = NULL; // ULONG cProps = 0; // hr = pAttach->GetProps((LPSPropTagArray) & attachProps, 0, &cProps, &pProps); if(pAttachRows->aRow[i].lpProps[3].ulPropTag == PR_ATTACH_EXTENSION_A) //if (pProps[PR_ATTACH_EXTENSION].ulPropTag == PR_ATTACH_EXTENSION_A) { // add a custom header for content location to support rfc2557 LPSTR pContentType = NULL; strExtension = pAttachRows->aRow[i].lpProps[3].Value.lpszA; Zimbra::MAPI::Util::GetContentTypeFromExtension(pAttachRows->aRow[i].lpProps[3].Value.lpszA, pContentType); LPWSTR lpwstrContentType = NULL; AtoW((LPSTR)pContentType, lpwstrContentType); wstrContentType = lpwstrContentType; } break; } } } } if (hr != S_OK) return hr; // copy image to file wstring wstrTempAppDirPath; char *lpszDirName = NULL; char *lpszUniqueName = NULL; Zimbra::Util::ScopedInterface<IStream> pDestStream; if (!Zimbra::MAPI::Util::GetAppTemporaryDirectory(wstrTempAppDirPath)) return MAPI_E_ACCESS_DENIED; WtoA((LPWSTR)wstrTempAppDirPath.c_str(), lpszDirName); string strFQFileName = lpszDirName; WtoA((LPWSTR)Zimbra::MAPI::Util::GetUniqueName().c_str(), lpszUniqueName); strFQFileName += "\\ZmContact_"; strFQFileName += lpszUniqueName; //strFQFileName += ".jpg"; strFQFileName += strExtension; SafeDelete(lpszDirName); SafeDelete(lpszUniqueName); // Open stream on file if (FAILED(hr = OpenStreamOnFile(MAPIAllocateBuffer, MAPIFreeBuffer, STGM_CREATE | STGM_READWRITE, (LPTSTR)strFQFileName.c_str(), NULL, pDestStream.getptr()))) return hr; ULARGE_INTEGER liAll = { 0 }; liAll.QuadPart = (ULONGLONG)-1; if (FAILED(hr = pSrcStream->CopyTo(pDestStream.get(), liAll, NULL, NULL))) return hr; if (FAILED(hr = pDestStream->Commit(0))) { return hr; ; } // mime file path LPWSTR lpwstrFQFileName = NULL; AtoW((LPSTR)strFQFileName.c_str(), lpwstrFQFileName); wstrImagePath = lpwstrFQFileName; LPSTR ppszCD; mimepp::String theCD; theCD.append("Content-Disposition: form-data; name=\""); theCD.append(strFQFileName.c_str()); theCD.append("\"; filename=\""); theCD.append(strFQFileName.c_str()); theCD.append("\""); const char *pFinal = theCD.c_str(); Zimbra::Util::CopyString(ppszCD, (LPSTR)pFinal); LPWSTR lpwstrContentDisp = NULL; AtoW((LPSTR)theCD.c_str(), lpwstrContentDisp); wstrContentDisposition = lpwstrContentDisp; /* LPSTR pContentType = NULL; Zimbra::MAPI::Util::GetContentTypeFromExtension(".jpg", pContentType); LPWSTR lpwstrContentType = NULL; AtoW((LPSTR)pContentType, lpwstrContentType); wstrContentType = lpwstrContentType;*/ SafeDelete(lpwstrFQFileName); return hr; }