123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547 |
- #include <kopano/platform.h>
- #include "vevent.h"
- #include <mapiutil.h>
- #include <kopano/mapiext.h>
- #include <kopano/CommonUtil.h>
- #include "nameids.h"
- #include "icaluid.h"
- #include <kopano/stringutil.h>
- #include "icalmem.hpp"
- namespace KC {
- VEventConverter::VEventConverter(LPADRBOOK lpAdrBook, timezone_map *mapTimeZones, LPSPropTagArray lpNamedProps, const std::string& strCharset, bool blCensor, bool bNoRecipients, IMailUser *lpMailUser)
- : VConverter(lpAdrBook, mapTimeZones, lpNamedProps, strCharset, blCensor, bNoRecipients, lpMailUser)
- {
- }
- HRESULT VEventConverter::HrICal2MAPI(icalcomponent *lpEventRoot, icalcomponent *lpEvent, icalitem *lpPrevItem, icalitem **lppRet)
- {
- HRESULT hr = VConverter::HrICal2MAPI(lpEventRoot, lpEvent,
- lpPrevItem, lppRet);
- if (hr != hrSuccess)
- return hr;
- (*lppRet)->eType = VEVENT;
- return hrSuccess;
- }
- HRESULT VEventConverter::HrAddBaseProperties(icalproperty_method icMethod, icalcomponent *lpicEvent, void *base, bool bisException, std::list<SPropValue> *lstMsgProps)
- {
- icalproperty *icProp = NULL;
- icalparameter *icParam = NULL;
- SPropValue sPropVal;
- bool bMeeting = false;
- bool bMeetingOrganised = false;
- std::wstring strEmail;
- time_t tNow = 0;
- icProp = icalcomponent_get_first_property(lpicEvent, ICAL_ORGANIZER_PROPERTY);
- if (icProp)
- {
- const char *lpszProp = icalproperty_get_organizer(icProp);
- strEmail = m_converter.convert_to<std::wstring>(lpszProp, rawsize(lpszProp), m_strCharset.c_str());
- if (wcsncasecmp(strEmail.c_str(), L"mailto:", 7) == 0)
- strEmail.erase(0, 7);
-
- if (bIsUserLoggedIn(strEmail))
- bMeetingOrganised = true;
- }
-
- switch (icMethod) {
- case ICAL_METHOD_REQUEST:
- bMeeting = true;
- sPropVal.ulPropTag = PR_RESPONSE_REQUESTED;
- sPropVal.Value.b = true;
- lstMsgProps->push_back(sPropVal);
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_RESPONSESTATUS], PT_LONG);
- sPropVal.Value.ul = respNotResponded;
- lstMsgProps->push_back(sPropVal);
- HrCopyString(base, L"IPM.Schedule.Meeting.Request", &sPropVal.Value.lpszW);
- break;
- case ICAL_METHOD_COUNTER:
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_COUNTERPROPOSAL], PT_BOOLEAN);
- sPropVal.Value.b = true;
- lstMsgProps->push_back(sPropVal);
-
- case ICAL_METHOD_REPLY:
-
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_RESPONSESTATUS], PT_LONG);
- sPropVal.Value.ul = respNone;
- lstMsgProps->push_back(sPropVal);
-
-
- bMeeting = false;
-
- if (icalcomponent_count_properties(lpicEvent, ICAL_ATTENDEE_PROPERTY) != 1)
- return MAPI_E_CALL_FAILED;
- icProp = icalcomponent_get_first_property(lpicEvent, ICAL_ATTENDEE_PROPERTY);
- if (icProp == NULL)
- return MAPI_E_CALL_FAILED;
- icParam = icalproperty_get_first_parameter(icProp, ICAL_PARTSTAT_PARAMETER);
- if (icParam == NULL)
- return MAPI_E_CALL_FAILED;
- switch (icalparameter_get_partstat(icParam)) {
- case ICAL_PARTSTAT_ACCEPTED:
- HrCopyString(base, L"IPM.Schedule.Meeting.Resp.Pos", &sPropVal.Value.lpszW);
- break;
- case ICAL_PARTSTAT_DECLINED:
- HrCopyString(base, L"IPM.Schedule.Meeting.Resp.Neg", &sPropVal.Value.lpszW);
- break;
- case ICAL_PARTSTAT_TENTATIVE:
- HrCopyString(base, L"IPM.Schedule.Meeting.Resp.Tent", &sPropVal.Value.lpszW);
- break;
- default:
- return MAPI_E_TYPE_NO_SUPPORT;
- }
- break;
- case ICAL_METHOD_CANCEL:
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_RESPONSESTATUS], PT_LONG);
- sPropVal.Value.ul = respNotResponded;
- lstMsgProps->push_back(sPropVal);
-
- bMeeting = true;
- HrCopyString(base, L"IPM.Schedule.Meeting.Canceled", &sPropVal.Value.lpszW);
- break;
- case ICAL_METHOD_PUBLISH:
- default:
-
-
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_RESPONSESTATUS], PT_LONG);
- if (m_ulUserStatus != 0)
- sPropVal.Value.ul = m_ulUserStatus;
- else if (bMeetingOrganised)
- sPropVal.Value.ul = 1;
- else
- sPropVal.Value.ul = 0;
- lstMsgProps->push_back(sPropVal);
-
-
- tNow = time(NULL);
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_APPTREPLYTIME], PT_SYSTIME);
- UnixTimeToFileTime(tNow, &sPropVal.Value.ft);
- lstMsgProps->push_back(sPropVal);
-
-
- HrCopyString(base, L"IPM.Appointment", &sPropVal.Value.lpszW);
-
- if (icalcomponent_get_first_property(lpicEvent, ICAL_ATTENDEE_PROPERTY) == NULL)
- bMeeting = false;
- else
- bMeeting = true;
- break;
- }
- if (!bisException) {
- sPropVal.ulPropTag = PR_MESSAGE_CLASS_W;
- lstMsgProps->push_back(sPropVal);
- }
- if (icMethod == ICAL_METHOD_CANCEL || icMethod == ICAL_METHOD_REQUEST)
- {
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_REQUESTSENT], PT_BOOLEAN);
- sPropVal.Value.b = true;
- lstMsgProps->push_back(sPropVal);
- } else if (icMethod == ICAL_METHOD_REPLY || icMethod == ICAL_METHOD_COUNTER) {
-
-
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_REQUESTSENT], PT_BOOLEAN);
- sPropVal.Value.b = false;
- lstMsgProps->push_back(sPropVal);
- } else {
-
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_REQUESTSENT], PT_BOOLEAN);
- sPropVal.Value.b = bMeetingOrganised;
- lstMsgProps->push_back(sPropVal);
- }
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_MEETINGSTATUS], PT_LONG);
- if (bMeeting) {
-
- sPropVal.Value.ul = 1 | 2;
- if (icMethod == ICAL_METHOD_CANCEL)
- sPropVal.Value.ul |= 4;
- else if(bMeetingOrganised)
- sPropVal.Value.ul = 1;
- } else {
- sPropVal.Value.ul = 0;
- }
- lstMsgProps->push_back(sPropVal);
- sPropVal.ulPropTag = PR_ICON_INDEX;
- if (!bMeeting)
- sPropVal.Value.ul = ICON_APPT_APPOINTMENT;
- else if (icMethod == ICAL_METHOD_CANCEL)
- sPropVal.Value.ul = ICON_APPT_MEETING_CANCEL;
- else
- sPropVal.Value.ul = ICON_APPT_MEETING_SINGLE;
-
-
-
-
- lstMsgProps->push_back(sPropVal);
- return hrSuccess;
- }
- HRESULT VEventConverter::HrAddTimes(icalproperty_method icMethod, icalcomponent *lpicEventRoot, icalcomponent *lpicEvent, bool bIsAllday, icalitem *lpIcalItem)
- {
- HRESULT hr = hrSuccess;
- SPropValue sPropVal;
- icalproperty* lpicDTStartProp = NULL;
- icalproperty* lpicDTEndProp = NULL;
- icalproperty* lpicOrigDTStartProp = NULL;
- icalproperty* lpicOrigDTEndProp = NULL;
- std::unique_ptr<icalproperty, icalmapi_delete> lpicFreeDTStartProp, lpicFreeDTEndProp;
- time_t timeDTStartUTC = 0, timeDTEndUTC = 0;
- time_t timeDTStartLocal = 0, timeDTEndLocal = 0;
- time_t timeEndOffset = 0, timeStartOffset = 0;
- icalproperty* lpicDurationProp = NULL;
- icalproperty* lpicProp = NULL;
- lpicDTStartProp = icalcomponent_get_first_property(lpicEvent, ICAL_DTSTART_PROPERTY);
- lpicDTEndProp = icalcomponent_get_first_property(lpicEvent, ICAL_DTEND_PROPERTY);
-
- if (lpicDTStartProp == nullptr)
- return MAPI_E_INVALID_PARAMETER;
- hr = HrAddTimeZone(lpicDTStartProp, lpIcalItem);
- if (hr != hrSuccess)
- return hr;
- if (icMethod == ICAL_METHOD_COUNTER) {
-
- lpicProp = icalcomponent_get_first_property(lpicEvent, ICAL_X_PROPERTY);
- while (lpicProp) {
- if (strcmp(icalproperty_get_x_name(lpicProp), "X-MS-OLK-ORIGINALSTART") == 0)
- lpicOrigDTStartProp = lpicProp;
- else if (strcmp(icalproperty_get_x_name(lpicProp), "X-MS-OLK-ORIGINALEND") == 0)
- lpicOrigDTEndProp = lpicProp;
- lpicProp = icalcomponent_get_next_property(lpicEvent, ICAL_X_PROPERTY);
- }
- if (lpicOrigDTStartProp && lpicOrigDTEndProp) {
-
- if (lpicDTEndProp == nullptr)
- return MAPI_E_INVALID_PARAMETER;
-
- timeDTStartUTC = ICalTimeTypeToUTC(lpicEventRoot, lpicDTStartProp);
- UnixTimeToFileTime(timeDTStartUTC, &sPropVal.Value.ft);
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_PROPOSEDSTART], PT_SYSTIME);
- lpIcalItem->lstMsgProps.push_back(sPropVal);
-
- timeDTEndUTC = ICalTimeTypeToUTC(lpicEventRoot, lpicDTEndProp);
- UnixTimeToFileTime(timeDTEndUTC, &sPropVal.Value.ft);
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_PROPOSEDEND], PT_SYSTIME);
- lpIcalItem->lstMsgProps.push_back(sPropVal);
-
- std::string strTmp;
- strTmp = icalproperty_as_ical_string_r(lpicOrigDTStartProp);
- strTmp.erase(0,strlen("X-MS-OLK-ORIGINAL"));
- strTmp.insert(0,"DT");
- lpicFreeDTStartProp.reset(icalproperty_new_from_string(strTmp.c_str()));
- lpicDTStartProp = lpicFreeDTStartProp.get();
- strTmp = icalproperty_as_ical_string_r(lpicOrigDTEndProp);
- strTmp.erase(0,strlen("X-MS-OLK-ORIGINAL"));
- strTmp.insert(0,"DT");
- lpicFreeDTEndProp.reset(icalproperty_new_from_string(strTmp.c_str()));
- lpicDTEndProp = lpicFreeDTEndProp.get();
- }
- }
-
- timeDTStartUTC = ICalTimeTypeToUTC(lpicEventRoot, lpicDTStartProp);
- timeDTStartLocal = ICalTimeTypeToLocal(lpicDTStartProp);
- timeStartOffset = timeDTStartUTC - timeDTStartLocal;
- if (bIsAllday)
- UnixTimeToFileTime(timeDTStartLocal, &sPropVal.Value.ft);
- else
- UnixTimeToFileTime(timeDTStartUTC, &sPropVal.Value.ft);
-
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_APPTSTARTWHOLE], PT_SYSTIME);
- lpIcalItem->lstMsgProps.push_back(sPropVal);
-
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_COMMONSTART], PT_SYSTIME);
- lpIcalItem->lstMsgProps.push_back(sPropVal);
-
- sPropVal.ulPropTag = PR_START_DATE;
- lpIcalItem->lstMsgProps.push_back(sPropVal);
-
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_ALLDAYEVENT], PT_BOOLEAN);
- sPropVal.Value.b = bIsAllday;
- lpIcalItem->lstMsgProps.push_back(sPropVal);
-
- if (lpicDTEndProp) {
- timeDTEndUTC = ICalTimeTypeToUTC(lpicEventRoot, lpicDTEndProp);
- timeDTEndLocal = ICalTimeTypeToLocal(lpicDTEndProp);
- } else {
-
-
-
- lpicDurationProp = icalcomponent_get_first_property(lpicEvent, ICAL_DURATION_PROPERTY);
- if (lpicDurationProp == nullptr)
-
- return MAPI_E_INVALID_PARAMETER;
- icaldurationtype dur = icalproperty_get_duration(lpicDurationProp);
- timeDTEndLocal = timeDTStartLocal + icaldurationtype_as_int(dur);
- timeDTEndUTC = timeDTStartUTC + icaldurationtype_as_int(dur);
- }
- timeEndOffset = timeDTEndUTC - timeDTEndLocal;
- if (bIsAllday)
- UnixTimeToFileTime(timeDTEndLocal, &sPropVal.Value.ft);
- else
- UnixTimeToFileTime(timeDTEndUTC, &sPropVal.Value.ft);
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_APPTENDWHOLE], PT_SYSTIME);
- lpIcalItem->lstMsgProps.push_back(sPropVal);
-
-
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_COMMONEND], PT_SYSTIME);
- lpIcalItem->lstMsgProps.push_back(sPropVal);
-
- sPropVal.ulPropTag = PR_END_DATE;
- lpIcalItem->lstMsgProps.push_back(sPropVal);
-
- sPropVal.ulPropTag = CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_APPTDURATION], PT_LONG);
- sPropVal.Value.ul = timeDTEndUTC - timeDTStartUTC;
-
- if (!bIsAllday)
- sPropVal.Value.ul += (timeEndOffset - timeStartOffset);
-
- sPropVal.Value.ul /= 60;
- lpIcalItem->lstMsgProps.push_back(sPropVal);
-
-
- return hrSuccess;
- }
- HRESULT VEventConverter::HrMAPI2ICal(LPMESSAGE lpMessage, icalproperty_method *lpicMethod, icaltimezone **lppicTZinfo, std::string *lpstrTZid, icalcomponent **lppEvent)
- {
- icalcomp_ptr lpEvent(icalcomponent_new(ICAL_VEVENT_COMPONENT));
- HRESULT hr = VConverter::HrMAPI2ICal(lpMessage, lpicMethod, lppicTZinfo, lpstrTZid, lpEvent.get());
- if (hr != hrSuccess)
- return hr;
- if (lppEvent)
- *lppEvent = lpEvent.release();
- return hrSuccess;
- }
- HRESULT VEventConverter::HrSetTimeProperties(LPSPropValue lpMsgProps, ULONG ulMsgProps, icaltimezone *lpicTZinfo, const std::string &strTZid, icalcomponent *lpEvent)
- {
- bool bIsAllDay = false;
- bool bCounterProposal = false;
- ULONG ulStartIndex = PROP_APPTSTARTWHOLE;
- ULONG ulEndIndex = PROP_APPTENDWHOLE;
- HRESULT hr = VConverter::HrSetTimeProperties(lpMsgProps, ulMsgProps,
- lpicTZinfo, strTZid, lpEvent);
- if (hr != hrSuccess)
- return hr;
-
- auto lpPropVal = PCpropFindProp(lpMsgProps, ulMsgProps, m_lpNamedProps->aulPropTag[PROP_COUNTERPROPOSAL]);
- if(lpPropVal && PROP_TYPE(lpPropVal->ulPropTag) == PT_BOOLEAN && lpPropVal->Value.b) {
- bCounterProposal = true;
- ulStartIndex = PROP_PROPOSEDSTART;
- ulEndIndex = PROP_PROPOSEDEND;
- }
-
- lpPropVal = PCpropFindProp(lpMsgProps, ulMsgProps, CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_ALLDAYEVENT], PT_BOOLEAN));
- if (lpPropVal)
- bIsAllDay = (lpPropVal->Value.b == TRUE);
-
-
-
-
- lpPropVal = PCpropFindProp(lpMsgProps, ulMsgProps, CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[ulStartIndex], PT_SYSTIME));
- if (lpPropVal == NULL)
-
- return MAPI_E_CORRUPT_DATA;
- time_t ttTime = FileTimeToUnixTime(lpPropVal->Value.ft.dwHighDateTime, lpPropVal->Value.ft.dwLowDateTime);
- hr = HrSetTimeProperty(ttTime, bIsAllDay, lpicTZinfo, strTZid, ICAL_DTSTART_PROPERTY, lpEvent);
- if (hr != hrSuccess)
- return hr;
-
- lpPropVal = PCpropFindProp(lpMsgProps, ulMsgProps, CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[ulEndIndex], PT_SYSTIME));
- if (lpPropVal == NULL) {
-
- return MAPI_E_CORRUPT_DATA;
- }
- ttTime = FileTimeToUnixTime(lpPropVal->Value.ft.dwHighDateTime, lpPropVal->Value.ft.dwLowDateTime);
- hr = HrSetTimeProperty(ttTime, bIsAllDay, lpicTZinfo, strTZid, ICAL_DTEND_PROPERTY, lpEvent);
- if (hr != hrSuccess)
- return hr;
-
- if (!bCounterProposal)
- return hrSuccess;
-
- icalproperty *lpProp = NULL;
-
- lpPropVal = PCpropFindProp(lpMsgProps, ulMsgProps, CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_APPTSTARTWHOLE], PT_SYSTIME));
- if (lpPropVal == NULL) {
-
- return MAPI_E_CORRUPT_DATA;
- }
- ttTime = FileTimeToUnixTime(lpPropVal->Value.ft.dwHighDateTime, lpPropVal->Value.ft.dwLowDateTime);
- lpProp = icalproperty_new_x("overwrite-me");
- icalproperty_set_x_name(lpProp, "X-MS-OLK-ORIGINALSTART");
- hr = HrSetTimeProperty(ttTime, bIsAllDay, lpicTZinfo, strTZid, ICAL_DTSTART_PROPERTY, lpProp);
- if (hr != hrSuccess)
- return hr;
- icalcomponent_add_property(lpEvent, lpProp);
-
- lpPropVal = PCpropFindProp(lpMsgProps, ulMsgProps, CHANGE_PROP_TYPE(m_lpNamedProps->aulPropTag[PROP_APPTENDWHOLE], PT_SYSTIME));
- if (lpPropVal == NULL) {
-
- return MAPI_E_CORRUPT_DATA;
- }
- ttTime = FileTimeToUnixTime(lpPropVal->Value.ft.dwHighDateTime, lpPropVal->Value.ft.dwLowDateTime);
- lpProp = icalproperty_new_x("overwrite-me");
- icalproperty_set_x_name(lpProp, "X-MS-OLK-ORIGINALEND");
- hr = HrSetTimeProperty(ttTime, bIsAllDay, lpicTZinfo, strTZid, ICAL_DTEND_PROPERTY, lpProp);
- if (hr != hrSuccess)
- return hr;
- icalcomponent_add_property(lpEvent, lpProp);
- return hrSuccess;
- }
- }
|