Esempio n. 1
0
HRESULT ConvertIt(LPMESSAGE pMsg, IStream** ppszMimeMsg, UINT& mimeLength )                                                                       
{
    HRESULT hr = S_OK;

    Zimbra::Util::ScopedInterface<IConverterSession> pConvSess;
    hr = CreateConverterSession( pConvSess.getptr() );
    if( FAILED(hr))
    {
        return hr;
    }

    pConvSess->SetSaveFormat( SAVE_RFC1521 );
    IStream * iStream = NULL;				
    hr = OpenStreamOnFile(Zimbra::Mapi::Memory::AllocateBuffer, Zimbra::Mapi::Memory::FreeBuffer, 
                          STGM_READWRITE | STGM_CREATE | SOF_UNIQUEFILENAME | STGM_DELETEONRELEASE,										  
                          NULL,  (LPWSTR)L"mig", &iStream);
    if( FAILED(hr))
    {
        return hr;
    }

    HGLOBAL hGlobal = GlobalAlloc(GMEM_FIXED, 0 );
    Zimbra::Util::ScopedInterface<IStream> pStream;
    CreateStreamOnHGlobal( hGlobal, TRUE, pStream.getptr() );

    UINT uFlags = CCSF_NO_MSGID |  CCSF_SMTP | CCSF_NOHEADERS ;
	
    hr = pConvSess->MAPIToMime( pMsg, iStream, uFlags);
    if( FAILED(hr) ) {
	    return hr;
    }
    if( !iStream) {
	    return E_FAIL;
    }

    // get the stream size
    STATSTG stat;
    LARGE_INTEGER li = { 0 };
    hr = iStream->Seek( li, STREAM_SEEK_SET, NULL ); 	
    if( FAILED(hr) ) {
	    return hr;
    }

    hr = iStream->Stat( &stat, STATFLAG_DEFAULT );
    if( FAILED(hr) ) {
	    return hr;
    }

    ULONG size = (UINT)stat.cbSize.QuadPart;
    *ppszMimeMsg = iStream;
    mimeLength = (UINT)size;
	
    return hr;
}
Esempio n. 2
0
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 MAPIAppointment::UpdateAttendeeFromEntryId(Attendee &pAttendee,
    SBinary &eid)
{
    Zimbra::Util::ScopedInterface<IMailUser> pUser;
    ULONG ulObjType = 0;
	if(!m_pAddrBook)
		return E_FAIL;
    HRESULT hr = m_pAddrBook->OpenEntry(eid.cb, (LPENTRYID)eid.lpb, NULL, MAPI_BEST_ACCESS,
        &ulObjType, (LPUNKNOWN *)pUser.getptr());

    if (FAILED(hr) || (ulObjType != MAPI_MAILUSER))
        return E_FAIL;
    SizedSPropTagArray(3, tags) = {
        3, { PR_ADDRTYPE_W, PR_DISPLAY_NAME_W, PR_EMAIL_ADDRESS_W }
    };

    ULONG cVals = 0;
    Zimbra::Util::ScopedBuffer<SPropValue> pVals;

    hr = pUser->GetProps((LPSPropTagArray) & tags, MAPI_UNICODE, &cVals, pVals.getptr());
    if (FAILED(hr))
        return hr;
    // no smtp address, bail
    if ((pVals->ulPropTag != PR_ADDRTYPE_W) || (wcsicmp(pVals->Value.lpszW, L"SMTP") != 0))
        return E_FAIL;
    if ((pVals[1].ulPropTag == PR_DISPLAY_NAME_W) && ((pAttendee.nam == L"")))
        pAttendee.nam = pVals[1].Value.lpszW;
    if ((pVals[2].ulPropTag == PR_EMAIL_ADDRESS_W) && (pAttendee.addr == L""))
        pAttendee.addr=pVals[2].Value.lpszW;

	return S_OK;
}
Esempio n. 4
0
HRESULT ExchangeAdmin::DeleteExchangeMailBox(LPCWSTR lpwstrMailBox, LPCWSTR lpwstrlogonuser,
    LPCWSTR lpwstrLogonUsrPwd)
{
    HRESULT hr;
    wstring UserDN;
    wstring LegacyName;
    Zimbra::Util::ScopedInterface<IDirectoryObject> pDirContainer;

    try
    {
        Zimbra::MAPI::Util::GetUserDNAndLegacyName(m_strServer.c_str(), lpwstrlogonuser,
            lpwstrLogonUsrPwd, UserDN, LegacyName);
    }
    catch (Zimbra::MAPI::ExchangeAdminException &ex)
    {
        dloge("ExchangeAdmin::DeleteExchangeMailBox ExchangeAdminException exception: %S", ex.Description().c_str());
        throw;
    }
    catch (Zimbra::MAPI::Util::MapiUtilsException &ex)
    {
        dloge("ExchangeAdmin::DeleteExchangeMailBox MapiUtilsException exception: %S", ex.Description().c_str());
        throw;
    }
    wstring twtsrlogonuserDN = UserDN;
    size_t nPos = twtsrlogonuserDN.find(_T("DC="), 0);
    wstring wstrServerDN = twtsrlogonuserDN.substr(nPos);
    wstring wstrADSPath = _T("LDAP://CN=Users,") + wstrServerDN;

    // get dir container
    if (FAILED(hr = ADsOpenObject(wstrADSPath.c_str(), lpwstrlogonuser, lpwstrLogonUsrPwd,
            ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (void **)pDirContainer.getptr())))
        throw ExchangeAdminException(hr, L"DeleteExchangeMailBox(): ADsOpenObject Failed.",
            ERR_DELETE_MBOX, __LINE__, __FILE__);

    wstring mailboxcn = L"CN=";

    mailboxcn += lpwstrMailBox;
    hr = pDirContainer->DeleteDSObject((LPWSTR)mailboxcn.c_str());

    return hr;
}
Esempio n. 5
0
void MAPITask::SetRecurValues()
{
    Zimbra::Util::ScopedInterface<IStream> pRecurrenceStream;
    HRESULT hResult = m_pMessage->OpenProperty(pr_recurstreamt, &IID_IStream, 0, 0,
                      (LPUNKNOWN *)pRecurrenceStream.getptr());
    if (FAILED(hResult))
    {
        return;
    }
    LPSTREAM pStream = pRecurrenceStream.get();
    Zimbra::Mapi::Task OlkTask(m_pMessage, NULL);
    Zimbra::Mapi::COutlookRecurrencePattern &recur = OlkTask.GetRecurrencePattern();
    hResult = recur.ReadRecurrenceStream(pStream);
    if (FAILED(hResult))
    {
        return;
    }

    /*
    // Set Timezone info
    SYSTEMTIME stdTime;
    SYSTEMTIME dsTime;
    const Zimbra::Mail::TimeZone &tzone = recur.GetTimeZone();
    m_timezone.id = m_pTimezoneId;  // don't use m_timezone.id = tzone.GetId()
    IntToWstring(tzone.GetStandardOffset(), m_timezone.standardOffset);
    IntToWstring(tzone.GetDaylightOffset(), m_timezone.daylightOffset);
    tzone.GetStandardStart(stdTime);
    tzone.GetDaylightStart(dsTime);
    IntToWstring(stdTime.wDay, m_timezone.standardStartWeek);
    IntToWstring(stdTime.wDayOfWeek + 1, m_timezone.standardStartWeekday);  // note the + 1 -- bumping weekday
    IntToWstring(stdTime.wMonth, m_timezone.standardStartMonth);
    IntToWstring(stdTime.wHour, m_timezone.standardStartHour);
    IntToWstring(stdTime.wMinute, m_timezone.standardStartMinute);
    IntToWstring(stdTime.wSecond, m_timezone.standardStartSecond);
    IntToWstring(dsTime.wDay, m_timezone.daylightStartWeek);
    IntToWstring(dsTime.wDayOfWeek + 1, m_timezone.daylightStartWeekday);   // note the + 1 -- bumping weekday
    IntToWstring(dsTime.wMonth, m_timezone.daylightStartMonth);
    IntToWstring(dsTime.wHour, m_timezone.daylightStartHour);
    IntToWstring(dsTime.wMinute, m_timezone.daylightStartMinute);
    IntToWstring(dsTime.wSecond, m_timezone.daylightStartSecond);
    //
    */

    ULONG ulType = recur.GetRecurrenceType();
    switch (ulType)
    {
    case oRecursDaily:
        m_pRecurPattern = L"DAI";
        break;
    case oRecursWeekly:
        m_pRecurPattern = L"WEE";
        break;
    case oRecursMonthly:
    case oRecursMonthNth:
        m_pRecurPattern = L"MON";
        break;
    case oRecursYearly:
    case oRecursYearNth:
        m_pRecurPattern = L"YEA";
        break;
    default:
        ;
    }
    IntToWstring(recur.GetInterval(), m_pRecurInterval);

    ULONG ulDayOfWeekMask = recur.GetDayOfWeekMask();
    if (ulDayOfWeekMask & wdmSunday)    m_pRecurWkday += L"SU";
    if (ulDayOfWeekMask & wdmMonday)    m_pRecurWkday += L"MO";
    if (ulDayOfWeekMask & wdmTuesday)   m_pRecurWkday += L"TU";
    if (ulDayOfWeekMask & wdmWednesday) m_pRecurWkday += L"WE";
    if (ulDayOfWeekMask & wdmThursday)  m_pRecurWkday += L"TH";
    if (ulDayOfWeekMask & wdmFriday)    m_pRecurWkday += L"FR";
    if (ulDayOfWeekMask & wdmSaturday)  m_pRecurWkday += L"SA";

    /*if ((m_pRecurPattern == L"DAI") && (m_pRecurWkday.length() > 0))	// every weekday
    {
    m_pRecurPattern = L"WEE";
    }*/

    if (m_pRecurPattern == L"MON")
    {
        if (ulType == oRecursMonthly)
        {
            IntToWstring(recur.GetDayOfMonth(), m_pRecurDayOfMonth);
        }
        else if (ulType == oRecursMonthNth)
        {
            ULONG ulMonthOccurrence = recur.GetInstance();
            if (ulMonthOccurrence == 5)	    // last
            {
                m_pRecurMonthOccurrence = L"-1";
            }
            else
            {
                IntToWstring(ulMonthOccurrence, m_pRecurMonthOccurrence);
            }
        }
    }

    if (m_pRecurPattern == L"YEA")
    {
        ULONG ulMonthOfYear = recur.GetMonthOfYear();
        IntToWstring(ulMonthOfYear, m_pRecurMonthOfYear);
        if (ulType == oRecursYearly)
        {
            IntToWstring(recur.GetDayOfMonth(), m_pRecurDayOfMonth);
        }
        else if (ulType == oRecursYearNth)
        {
            ULONG ulMonthOccurrence = recur.GetInstance();
            if (ulMonthOccurrence == 5)	    // last
            {
                m_pRecurMonthOccurrence = L"-1";
            }
            else
            {
                IntToWstring(ulMonthOccurrence, m_pRecurMonthOccurrence);
            }
        }
    }

    ULONG ulRecurrenceEndType = recur.GetEndType();
    Zimbra::Mapi::CRecurrenceTime rtEndDate = recur.GetEndDate();
    Zimbra::Mapi::CFileTime ft = (FILETIME)rtEndDate;
    m_pTaskFilterDate = Zimbra::MAPI::Util::CommonDateString(ft);
    if (ulRecurrenceEndType == oetEndAfterN)
    {
        IntToWstring(recur.GetOccurrences(), m_pRecurCount);
    }
    else if (ulRecurrenceEndType == oetEndDate)
    {
        SYSTEMTIME st;
        FileTimeToSystemTime(&ft, &st);
        wstring temp = Zimbra::Util::FormatSystemTime(st, TRUE, TRUE);
        m_pRecurEndDate = temp.substr(0, 8);
    }
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
HRESULT ExchangeAdmin::CreateExchangeMailBox(LPCWSTR lpwstrNewUser, LPCWSTR lpwstrNewUserPwd,
    LPCWSTR lpwstrlogonuser, LPCWSTR lpwstrLogonUsrPwd)
{
    HRESULT hr = S_OK;

    // Get Logon user DN
    wstring LogonUserDN;
    wstring legacyName;
	wstring msExchHomeSvrName;
    Zimbra::MAPI::Util::GetUserDNAndLegacyName(m_strServer.c_str(), lpwstrlogonuser,
        lpwstrLogonUsrPwd, LogonUserDN, legacyName);
	Zimbra::MAPI::Util::GetmsExchHomeServerName(m_strServer.c_str(), lpwstrlogonuser,
        lpwstrLogonUsrPwd, msExchHomeSvrName);
    Zimbra::Util::ScopedInterface<IDirectoryObject> pLogonContainer;
	Zimbra::Util::ScopedInterface<IADsUser> pIAdUser;
	Zimbra::Util::ScopedInterface<IADs> pIAds;
    wstring strContainer = L"LDAP://";

    strContainer += LogonUserDN.c_str();

    dloge("strContainer %S  msExchHomeSvrName: %S", strContainer.c_str(), msExchHomeSvrName.c_str());
    // Get loggedin user container
    hr = ADsOpenObject(strContainer.c_str(), NULL, NULL, ADS_SECURE_AUTHENTICATION,
        IID_IDirectoryObject, (void **)pLogonContainer.getptr());
    if (FAILED(hr))
    {
        if (hr == 0x8007052e)                   // credentials are not valid
        {
            hr = ADsOpenObject((LPTSTR)strContainer.c_str(), lpwstrlogonuser, lpwstrLogonUsrPwd,
				ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (void **)pLogonContainer.getptr());
			if (FAILED(hr)||(pLogonContainer.get()==NULL))
                throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): ADsOpenObject Failed.",
				ERR_ADOBJECT_OPEN, __LINE__, __FILE__);
        }
        else
        {
            throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsOpenObject Failed.",
                ERR_ADOBJECT_OPEN, __LINE__, __FILE__);
        }
    }

    ADS_ATTR_INFO *pAttrInfo = NULL;
    DWORD dwReturn;
    LPWSTR pAttrNames[] = { L"mail", L"homeMDB", L"homeMTA" };
    DWORD dwNumAttr = sizeof (pAttrNames) / sizeof (LPWSTR);
    wstring strLogonHomeMDB;
    wstring strLogonHomeMTA;
    wstring strLogonMail;

    // Get attribute values requested. Its not necessary the order is same as requested.
    if (FAILED(hr = pLogonContainer->GetObjectAttributes(pAttrNames, dwNumAttr, &pAttrInfo,
            &dwReturn)))
        throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): GetObjectAttributes Failed.", 
		ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    for (DWORD idx = 0; idx < dwReturn; idx++)
    {
        if (_wcsicmp(pAttrInfo[idx].pszAttrName, L"mail") == 0)
            strLogonMail = pAttrInfo[idx].pADsValues->Email.Address;

        else if (_wcsicmp(pAttrInfo[idx].pszAttrName, L"homeMTA") == 0)
            strLogonHomeMTA = pAttrInfo[idx].pADsValues->DNString;

        else if (_wcsicmp(pAttrInfo[idx].pszAttrName, L"homeMDB") == 0)
            strLogonHomeMDB = pAttrInfo[idx].pADsValues->DNString;
    }
    // Use FreeADsMem for all memory obtained from the ADSI call.
    FreeADsMem(pAttrInfo);

    wstring twtsrlogonuserDN = LogonUserDN;
    size_t nPos = twtsrlogonuserDN.find(_T("DC="), 0);
    wstring wstrServerDN = twtsrlogonuserDN.substr(nPos);
    wstring wstrADSPath = _T("LDAP://CN=Users,") + wstrServerDN;
    ADSVALUE cnValue;
    ADSVALUE classValue;
    ADSVALUE sAMValue;
    ADSVALUE uPNValue;
	ADSVALUE controlValue;
    ADS_ATTR_INFO attrInfo[] = {
        { L"objectClass", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &classValue, 1 },
        { L"cn", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &cnValue, 1 },
        { L"sAMAccountName", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &sAMValue, 1 },
        { L"userPrincipalName", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &uPNValue, 1 },
		{L"userAccountControl", ADS_ATTR_UPDATE, ADSTYPE_INTEGER,&controlValue, 1},
    };
    DWORD dwAttrs = sizeof (attrInfo) / sizeof (ADS_ATTR_INFO);

    classValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
    classValue.CaseIgnoreString = L"user";

	//int UF_ACCOUNTDISABLE = 0x0002;
	int UF_PASSWD_NOTREQD = 0x0020;
	//int UF_PASSWD_CANT_CHANGE = 0x0040;
	int UF_NORMAL_ACCOUNT = 0x0200;
	int UF_DONT_EXPIRE_PASSWD = 0x10000;
	//int UF_PASSWORD_EXPIRED = 0x800000;

	controlValue.dwType = ADSTYPE_INTEGER;
	controlValue.Integer=UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD |UF_DONT_EXPIRE_PASSWD;

    cnValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
    cnValue.CaseIgnoreString = (LPWSTR)lpwstrNewUser;

    sAMValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
    sAMValue.CaseIgnoreString = (LPWSTR)lpwstrNewUser;

    wstring wstrMail;
    size_t nPosMail = strLogonMail.find(_T("@"), 0);

    wstrMail = strLogonMail.substr(nPosMail);
    wstrMail = lpwstrNewUser + wstrMail;

    LPWSTR upnval = (LPWSTR)wstrMail.c_str();

    uPNValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
    uPNValue.CaseIgnoreString = upnval;

    Zimbra::Util::ScopedInterface<IDirectoryObject> pDirContainer;
    Zimbra::Util::ScopedInterface<IDispatch> pDisp;
    Zimbra::Util::ScopedInterface<IADsUser> pIADNewUser;
    wstring wstrLoggedUserName(LogonUserDN);
    size_t snPos = 0;
    size_t enPos = 0;

    if ((snPos = wstrLoggedUserName.find(L"CN=")) != wstring::npos)
    {
        if ((enPos = wstrLoggedUserName.find(L",", snPos)) != wstring::npos)
            wstrLoggedUserName = wstrLoggedUserName.substr(snPos + 3, (enPos - (snPos + 3)));
    }
    // get dir container
    if (FAILED(hr = ADsOpenObject(wstrADSPath.c_str(), wstrLoggedUserName.c_str(),
            lpwstrLogonUsrPwd, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject,
            (void **)pDirContainer.getptr())))
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsOpenObject Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);

    wstring wstrUserCN = L"CN=";

    wstrUserCN += lpwstrNewUser;
    dloge("CreateDSObject: %S",wstrUserCN.c_str());
    if (FAILED(hr = pDirContainer->CreateDSObject((LPWSTR)wstrUserCN.c_str(), attrInfo, dwAttrs,
            pDisp.getptr())))
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): CreateDSObject Failed.",
            ERR_CREATE_EXCHMBX,__LINE__, __FILE__);
    if (FAILED(hr = pDisp->QueryInterface(IID_IADsUser, (void **)pIADNewUser.getptr())))
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): QueryInterface Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);

    CComVariant varProp;
    varProp.Clear();

    // set samAccount
    varProp = lpwstrNewUser;
    if (FAILED(hr = pIADNewUser->Put(CComBSTR(L"sAMAccountName"), varProp)))
        throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): Put(sAMAccountName) Failed.",
		ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    if(FAILED(hr = pIADNewUser->SetInfo()))
        throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): Put(sAMAccountName) Failed.", 
		ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    // set userAccountControl
    varProp.Clear();
    hr = pIADNewUser->Get(CComBSTR(L"userAccountControl"), &varProp);
    varProp = varProp.lVal & ~(ADS_UF_ACCOUNTDISABLE);
    if (FAILED(hr = pIADNewUser->Put(CComBSTR(L"userAccountControl"), varProp)))
        throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): Put(userAccountControl) Failed.",
		ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - Put(userAccountControl) Failed.");
    // set Account enabled
    if (FAILED(hr = pIADNewUser->put_AccountDisabled(VARIANT_FALSE)))
    {
        throw
            ExchangeAdminException(hr, L"CreateExchangeMailBox(): put_AccountDisabled Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - put_AccountDisabled Failed.");
    // set password
    if (FAILED(hr = pIADNewUser->SetPassword(CComBSTR(lpwstrNewUserPwd))))
    {
        throw
            ExchangeAdminException(hr, L"CreateExchangeMailBox(): SetPassword Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - SetPassword Failed.");
    // user account password does not expire
    varProp.Clear();

    VARIANT var;

    VariantInit(&var);
    if (!FAILED(hr = pIADNewUser->Get(CComBSTR(L"userAccountControl"), &var)))
    {
        V_I4(&var) |= ADS_UF_DONT_EXPIRE_PASSWD;
        if (FAILED(hr = pIADNewUser->Put(CComBSTR(L"userAccountControl"), var)))
        {
            throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): Put(userAccountControl) Failed.", 
				ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
        }
    }
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - userAccountControl Failed.");
    varProp.Clear();
    // set the homeMDB;
    if (!strLogonHomeMDB.empty())
    {
        varProp = strLogonHomeMDB.c_str();
        if (FAILED(hr = pIADNewUser->Put(CComBSTR("homeMDB"), varProp)))
            throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(homeMDB) Failed.",
                ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - Put(homeMDB) Failed.");

	varProp.Clear();
    if (!strLogonHomeMTA.empty())
    {
        varProp = strLogonHomeMTA.c_str();
        if (FAILED(hr = pIADNewUser->Put(CComBSTR("homeMTA"), varProp)))
            throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(homeMTA) Failed.",
                ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - Put(homeMTA) Failed.");

	varProp.Clear();
	if (!msExchHomeSvrName.empty())
    {
        varProp = msExchHomeSvrName.c_str();
        if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchHomeServerName"), varProp)))
            throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(msExchHomeServerName) Failed.",
                ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - Put(msExchHomeServerName) Failed.");
	varProp.Clear();

	varProp.Clear();
	wstring newUsrLegacyName=legacyName;
	size_t nwpos=newUsrLegacyName.rfind(L"cn=");
	if(nwpos !=wstring::npos)
	{
		newUsrLegacyName = newUsrLegacyName.substr(0,nwpos);
		newUsrLegacyName += L"cn=";
		newUsrLegacyName += lpwstrNewUser;
	}
	if (!newUsrLegacyName.empty())
    {
        varProp = newUsrLegacyName.c_str();
        if (FAILED(hr = pIADNewUser->Put(CComBSTR("legacyExchangeDN"), varProp)))
            throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(legacyExchangeDN) Failed.",
                ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - Put(legacyExchangeDN) Failed.");

    // set nickname
    varProp.Clear();
    varProp = lpwstrNewUser;
    if (FAILED(hr = pIADNewUser->Put(CComBSTR("mailNickname"), varProp)))
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(mailNickname) Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - Put(mailNickname) Failed.");

    // set the displayName
    varProp.Clear();
    varProp = lpwstrNewUser;
    if (FAILED(hr = pIADNewUser->Put(CComBSTR("displayName"), varProp)))
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(displayName) Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - Put(displayName) Failed.");
    // set the mail atrribute
    varProp.Clear();
    varProp = wstrMail.c_str();
    if (FAILED(hr = pIADNewUser->Put(CComBSTR("mail"), varProp)))
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(mail) Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - Put(mail) Failed.");
    // set email
    if (FAILED(hr = pIADNewUser->put_EmailAddress(CComBSTR(wstrMail.c_str()))))
    {
        throw
            ExchangeAdminException(hr, L"CreateExchangeMailBox(): put_EmailAddress Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - put_EmailAddress Failed.");

	varProp.Clear();
	wstrMail=L"SMTP:"+wstrMail;
	varProp = wstrMail.c_str();
	if (FAILED(hr = pIADNewUser->Put(CComBSTR("proxyAddresses"),varProp)))
	{
        throw
            ExchangeAdminException(hr, L"CreateExchangeMailBox(): proxyAddressess Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }
    if(FAILED(hr = pIADNewUser->SetInfo()))
        ThrowSetInfoException(hr, L"SetInfo - proxyAddressess Failed.");

    // add to Domain Admins group
    BSTR bstrADSPath;

    if (FAILED(hr = pIADNewUser->get_ADsPath(&bstrADSPath)))
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): get_ADsPath Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);

    wstring wstrGroup = _T("LDAP://CN=Domain Admins,CN=Users,") + wstrServerDN;
    Zimbra::Util::ScopedInterface<IADsGroup> pGroup;

    if (FAILED(hr = ADsGetObject(wstrGroup.c_str(), IID_IADsGroup, (void **)pGroup.getptr())))
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsGetObject Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    if (FAILED(hr = ADsOpenObject(wstrGroup.c_str(), wstrLoggedUserName.c_str(),
            lpwstrLogonUsrPwd, ADS_SECURE_AUTHENTICATION, IID_IADsGroup,
            (void **)pGroup.getptr())))
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsOpenObject Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    if (SUCCEEDED(hr = pGroup->Add(bstrADSPath)))
    {
        if (FAILED(hr = pGroup->SetInfo()))
            throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): pGroup SetInfo Failed.",
                ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }
    else
    {
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): pGroup Add Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }

	GUID guid;
    if(FAILED(hr = CoCreateGuid(&guid)))
    {
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): CoCreateGuid Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }

    BYTE *str;
    hr = UuidToString((UUID *)&guid, (RPC_WSTR *)&str);
    if (hr != RPC_S_OK)
    {
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): UuidToString Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }

	varProp.Clear();
	//BYTE bytArr[]="3429bb3084703348b8023e94fabf16ea";
	PutBinaryIntoVariant(&varProp,str,16);
	RpcStringFree((RPC_WSTR *)&str);
	if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchMailboxGuid"), varProp)))
	{
		throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put msExchMailboxGuid Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
	}
	if(FAILED(hr = pIADNewUser->SetInfo()))
            ThrowSetInfoException(hr, L"SetInfo - msExchMailboxGuid Failed.");

	if (FAILED(hr = ADsOpenObject(strContainer.c_str(), NULL, NULL, ADS_SECURE_AUTHENTICATION,
        IID_IDirectoryObject, (void **)pIAdUser.getptr())))
	{
		throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsOpenObject2 Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
	}	
	if (FAILED(hr = pIAdUser->QueryInterface(IID_IADs, (void**) pIAds.getptr())))
	{
		throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): pIAdUser->QueryInterface Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
	}

	varProp.Clear();
	if( FAILED(hr= pIAds->Get(CComBSTR("msExchMailboxSecurityDescriptor"),&varProp)))
	{
        throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Get msExchMailboxSecurityDescriptor Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
    }
	if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchMailboxSecurityDescriptor"), varProp)))
	{
		throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put msExchMailboxSecurityDescriptor Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
	}
	if(FAILED(hr = pIADNewUser->SetInfo()))
            ThrowSetInfoException(hr, L"SetInfo - msExchMailboxSecurityDescriptor Failed.");

	varProp.Clear();
	if( FAILED(hr=pIAds->Get(CComBSTR("msExchPoliciesIncluded"),&varProp)))
	{
		throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Get msExchPoliciesIncluded Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);        
    }
	if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchPoliciesIncluded"), varProp)))
	{
		throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put msExchPoliciesIncluded Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);     
	}
	if(FAILED(hr = pIADNewUser->SetInfo()))
            ThrowSetInfoException(hr, L"SetInfo - msExchPoliciesIncluded Failed.");

	varProp.Clear();
	if( FAILED(hr= pIAds->Get(CComBSTR("msExchUserAccountControl"),&varProp)))
	{
		throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Get msExchUserAccountControl Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);        
    }
	if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchUserAccountControl"), varProp)))
	{
		throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put msExchUserAccountControl Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);    
	}
	if(FAILED(hr = pIADNewUser->SetInfo()))
            ThrowSetInfoException(hr, L"SetInfo - msExchUserAccountControl Failed.");

	varProp.Clear();
	if(FAILED(hr = pIAds->GetEx(CComBSTR("showInAddressBook"), &varProp )))
	{
		throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Get showInAddressBook Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);		
	}
	if(FAILED(hr = pIADNewUser->Put(CComBSTR("showInAddressBook"), varProp)))
	{
		throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put showInAddressBook Failed.",
            ERR_CREATE_EXCHMBX, __LINE__, __FILE__);
	}
	if(FAILED(hr = pIADNewUser->SetInfo()))
            ThrowSetInfoException(hr, L"SetInfo - showInAddressBook Failed.");
    return hr;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
}
void MAPIAppointment::SetExceptions()
{
    Zimbra::Util::ScopedInterface<IStream> pRecurrenceStream;
    HRESULT hResult = m_pMessage->OpenProperty(pr_recurstream, &IID_IStream, 0, 0,
						(LPUNKNOWN *)pRecurrenceStream.getptr());
    if (FAILED(hResult))
    {
	return;
    }
    LPSTREAM pStream = pRecurrenceStream.get();
    Zimbra::Mapi::Appt OlkAppt(m_pMessage, NULL);
    Zimbra::Mapi::COutlookRecurrencePattern &recur = OlkAppt.GetRecurrencePattern();
    hResult = recur.ReadRecurrenceStream(pStream);
    if (FAILED(hResult))
    {
	return;
    }
    LONG lExceptionCount = recur.GetExceptionCount();

    for (LONG i = 0; i < lExceptionCount; i++)
    {
        Zimbra::Mapi::CRecurrenceTime rtDate = recur.GetExceptionOriginalDate(i);
        Zimbra::Mapi::CFileTime ftOrigDate = (FILETIME)rtDate;

        Zimbra::Mapi::COutlookRecurrenceException *lpException = recur.GetException(i);
        if (lpException != NULL)    
        {
            Zimbra::Util::ScopedInterface<IMessage> lpExceptionMessage;
            Zimbra::Util::ScopedInterface<IAttach> lpExceptionAttach;

            // FBS bug 70987 -- 5/27/12 -- since Exchange provider doesn't seem to support restriction on
            // attachment table, call OpenApptNR instead of OpenAppointment
            HRESULT hResult = lpException->OpenApptNR((LPMESSAGE)OlkAppt.MapiMsg(),
                lpExceptionMessage.getptr(), lpExceptionAttach.getptr(), pr_exceptionreplacetime);

            if (FAILED(hResult))
            {
                //dlogd(L"could not open appointment message for this occurrence"));
                return;
            }

            // We have everything for the object
            Zimbra::Mapi::Appt pOccurrence(lpExceptionMessage.get(), OlkAppt.GetStore(),
                                           lpException, lpExceptionAttach.get(),
                                           OlkAppt.MapiMsg());
            MAPIMessage exMAPIMsg;
            if (lpExceptionMessage.get() != NULL)
            {
                exMAPIMsg.Initialize(lpExceptionMessage.get(), *m_session);
                MAPIAppointment* pEx = new MAPIAppointment(*m_session, *m_mapiStore, exMAPIMsg, NORMAL_EXCEPTION);   // delete done in CMapiAccessWrap::GetData
                FillInExceptionAppt(pEx, lpException);
                m_vExceptions.push_back(pEx);
            }
        }
        else
        {
            MAPIAppointment* pEx = new MAPIAppointment(*m_session, *m_mapiStore, *m_mapiMessage, CANCEL_EXCEPTION);
            FillInCancelException(pEx, ftOrigDate);
            m_vExceptions.push_back(pEx);
        }
    }
}
Esempio n. 13
0
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;
}