Contains upstream commits:
2369060328d96211a9dbe1ebaffeff7d5140e6be
Recurring events not shown on Exchange 2010 servers
ec03f046acabdb440dd44e8ddbe841453adbb55c
Fix a copy&paste error, found by a Coverity Scan
diff -up evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-recur-utils.c.show-events-owa evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-recur-utils.c
--- evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-recur-utils.c.show-events-owa 2012-10-15 10:29:54.000000000 +0200
+++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-recur-utils.c 2013-10-17 12:30:35.290075062 +0200
@@ -181,7 +181,7 @@ rp_to_gba(const struct ema_RecurrencePat
sizeof (guint32) * rp->DeletedInstanceCount);
}
GBA_APPEND_LVAL(gba, rp->ModifiedInstanceCount);
- if ( rp->DeletedInstanceCount ) {
+ if ( rp->ModifiedInstanceCount ) {
GBA_APPEND (gba, rp->ModifiedInstanceDates,
sizeof (guint32) * rp->ModifiedInstanceCount);
}
@@ -296,6 +296,10 @@ arp_to_gba(const struct ema_AppointmentR
for (i = 0; i < arp->ExceptionCount; ++i) {
ee_to_gba (&arp->ExtendedException[i], arp, i, gba);
}
+ GBA_APPEND_LVAL (gba, arp->ReservedBlock2Size);
+ if (arp->ReservedBlock2Size) {
+ GBA_APPEND (gba, arp->ReservedBlock2, arp->ReservedBlock2Size);
+ }
}
static gboolean
@@ -501,6 +505,13 @@ gba_to_arp(const GByteArray *gba, ptrdif
}
}
+ GBA_DEREF_OFFSET (gba, *off, arp->ReservedBlock2Size, guint32);
+ if (arp->ReservedBlock2Size) {
+ arp->ReservedBlock2 = g_new (gchar, arp->ReservedBlock2Size);
+ GBA_MEMCPY_OFFSET (gba, *off, arp->ReservedBlock2,
+ arp->ReservedBlock2Size);
+ }
+
return TRUE;
}
diff -up evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-tz-utils.c.show-events-owa evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-tz-utils.c
--- evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-tz-utils.c.show-events-owa 2013-03-25 10:17:54.000000000 +0100
+++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-tz-utils.c 2013-10-17 12:30:05.858075342 +0200
@@ -374,6 +374,195 @@ e_mapi_cal_tz_util_dump (void)
g_rec_mutex_unlock(&mutex);
}
+static void
+write_icaltime_as_systemtime (GByteArray *ba,
+ struct icaltimetype icaltime)
+{
+ guint16 flag16;
+
+ /* wYear */
+ flag16 = icaltime.year;
+ g_byte_array_append (ba, (const guint8 *) &flag16, sizeof (guint16));
+
+ /* wMonth */
+ flag16 = icaltime.month;
+ g_byte_array_append (ba, (const guint8 *) &flag16, sizeof (guint16));
+
+ /* wDayOfWeek */
+ flag16 = icaltime.year == 0 ? 0 : icaltime_day_of_week (icaltime);
+ g_byte_array_append (ba, (const guint8 *) &flag16, sizeof (guint16));
+
+ /* wDay */
+ flag16 = icaltime.day;
+ g_byte_array_append (ba, (const guint8 *) &flag16, sizeof (guint16));
+
+ /* wHour */
+ flag16 = icaltime.hour;
+ g_byte_array_append (ba, (const guint8 *) &flag16, sizeof (guint16));
+
+ /* wMinute */
+ flag16 = icaltime.minute;
+ g_byte_array_append (ba, (const guint8 *) &flag16, sizeof (guint16));
+
+ /* wSecond */
+ flag16 = icaltime.second;
+ g_byte_array_append (ba, (const guint8 *) &flag16, sizeof (guint16));
+
+ /* wMilliseconds */
+ flag16 = 0;
+ g_byte_array_append (ba, (const guint8 *) &flag16, sizeof (guint16));
+}
+
+static void
+write_tz_rule (GByteArray *ba,
+ gboolean is_recur,
+ guint32 bias,
+ guint32 standard_bias,
+ guint32 daylight_bias,
+ struct icaltimetype standard_date,
+ struct icaltimetype daylight_date)
+{
+ guint8 flag8;
+ guint16 flag16;
+
+ g_return_if_fail (ba != NULL);
+
+ /* Major version */
+ flag8 = 0x02;
+ g_byte_array_append (ba, (const guint8 *) &flag8, sizeof (guint8));
+
+ /* Minor version */
+ flag8 = 0x01;
+ g_byte_array_append (ba, (const guint8 *) &flag8, sizeof (guint8));
+
+ /* Reserved */
+ flag16 = 0x003e;
+ g_byte_array_append (ba, (const guint8 *) &flag16, sizeof (guint16));
+
+ /* TZRule flags */
+ flag16 = 0;
+ if (is_recur)
+ flag16 |= 1;
+ g_byte_array_append (ba, (const guint8 *) &flag16, sizeof (guint16));
+
+ /* wYear */
+ flag16 = standard_date.year;
+ g_byte_array_append (ba, (const guint8 *) &flag16, sizeof (guint16));
+
+ /* X - 14 times 0x00 */
+ flag8 = 0x00;
+ for (flag16 = 0; flag16 < 14; flag16++) {
+ g_byte_array_append (ba, (const guint8 *) &flag8, sizeof (guint8));
+ }
+
+ /* lBias */
+ g_byte_array_append (ba, (const guint8 *) &bias, sizeof (guint32));
+
+ /* lStandardBias */
+ g_byte_array_append (ba, (const guint8 *) &standard_bias, sizeof (guint32));
+
+ /* lDaylightBias */
+ g_byte_array_append (ba, (const guint8 *) &daylight_bias, sizeof (guint32));
+
+ /* stStandardDate */
+ write_icaltime_as_systemtime (ba, standard_date);
+
+ /* stDaylightDate */
+ write_icaltime_as_systemtime (ba, daylight_date);
+}
+
+static void
+extract_bias_and_date (icalcomponent *comp,
+ guint32 *bias,
+ struct icaltimetype *start)
+{
+ icalproperty *prop;
+ gint tzoffset;
+
+ g_return_if_fail (comp != NULL);
+ g_return_if_fail (bias != NULL);
+ g_return_if_fail (start != NULL);
+
+ prop = icalcomponent_get_first_property (comp, ICAL_TZOFFSETTO_PROPERTY);
+ if (prop)
+ tzoffset = icalproperty_get_tzoffsetto (prop);
+ else
+ tzoffset = 0;
+
+ *bias = tzoffset / 60;
+ *start = icalcomponent_get_dtstart (comp);
+}
+
+static void
+write_tz_rule_comps (GByteArray *ba,
+ gboolean is_recur,
+ icalcomponent *standardcomp,
+ icalcomponent *daylightcomp,
+ icaltimezone *zone)
+{
+ struct icaltimetype standard_date, daylight_date, current_time;
+ guint32 bias, standard_bias, daylight_bias;
+
+ g_return_if_fail (ba != NULL);
+ g_return_if_fail (standardcomp != NULL);
+ g_return_if_fail (daylightcomp != NULL);
+
+ extract_bias_and_date (standardcomp, &standard_bias, &standard_date);
+ extract_bias_and_date (daylightcomp, &daylight_bias, &daylight_date);
+
+ current_time = icaltime_current_time_with_zone (zone);
+ bias = current_time.is_daylight ? daylight_bias : standard_bias;
+
+ write_tz_rule (ba, is_recur, bias, standard_bias, daylight_bias, standard_date, daylight_date);
+}
+
+static void
+add_timezone_rules (GByteArray *ba,
+ gboolean is_recur,
+ icalcomponent *vtimezone,
+ icaltimezone *zone)
+{
+ gboolean any_added = FALSE;
+
+ g_return_if_fail (ba != NULL);
+
+ if (vtimezone) {
+ icalcomponent *subcomp, *standardcomp = NULL, *daylightcomp = NULL;
+
+ for (subcomp = icalcomponent_get_first_component (vtimezone, ICAL_ANY_COMPONENT);
+ subcomp;
+ subcomp = icalcomponent_get_next_component (vtimezone, ICAL_ANY_COMPONENT)) {
+ if (icalcomponent_isa (subcomp) == ICAL_XSTANDARD_COMPONENT)
+ standardcomp = subcomp;
+ if (icalcomponent_isa (subcomp) == ICAL_XDAYLIGHT_COMPONENT)
+ daylightcomp = subcomp;
+ if (standardcomp && daylightcomp) {
+ write_tz_rule_comps (ba, is_recur, standardcomp, daylightcomp, zone);
+
+ any_added = TRUE;
+ standardcomp = NULL;
+ daylightcomp = NULL;
+ }
+ }
+
+ if (standardcomp || daylightcomp) {
+ if (!standardcomp)
+ standardcomp = daylightcomp;
+ write_tz_rule_comps (ba, is_recur, standardcomp, daylightcomp, zone);
+ any_added = TRUE;
+ }
+ }
+
+ /* at least one should be always added, make it UTC */
+ if (!any_added) {
+ struct icaltimetype fake_utc;
+
+ memset (&fake_utc, 0, sizeof (struct icaltimetype));
+
+ write_tz_rule (ba, is_recur, 0, 0, 0, fake_utc, fake_utc);
+ }
+}
+
#define TZDEFINITION_FLAG_VALID_GUID 0x0001 // the guid is valid
#define TZDEFINITION_FLAG_VALID_KEYNAME 0x0002 // the keyname is valid
#define TZ_MAX_RULES 1024
@@ -383,13 +572,29 @@ e_mapi_cal_tz_util_dump (void)
void
e_mapi_cal_util_mapi_tz_to_bin (const gchar *mapi_tzid,
struct SBinary_short *bin,
- TALLOC_CTX *mem_ctx)
+ TALLOC_CTX *mem_ctx,
+ gboolean is_recur)
{
GByteArray *ba;
guint8 flag8;
guint16 flag16;
gunichar2 *buf;
glong items_written;
+ icaltimezone *zone = NULL;
+ icalcomponent *vtimezone;
+ gint rules = 0;
+ const gchar *ical_location = e_mapi_cal_tz_util_get_ical_equivalent (mapi_tzid);
+
+ if (ical_location && *ical_location)
+ zone = icaltimezone_get_builtin_timezone (ical_location);
+ if (!zone)
+ zone = icaltimezone_get_utc_timezone ();
+ vtimezone = icaltimezone_get_component (zone);
+ if (vtimezone)
+ rules = (icalcomponent_count_components (vtimezone, ICAL_XSTANDARD_COMPONENT) +
+ icalcomponent_count_components (vtimezone, ICAL_XDAYLIGHT_COMPONENT)) / 2;
+ if (!rules)
+ rules = 1;
ba = g_byte_array_new ();
@@ -401,8 +606,8 @@ e_mapi_cal_util_mapi_tz_to_bin (const gc
ba = g_byte_array_append (ba, (const guint8 *)buf, (sizeof (gunichar2) * items_written));
g_free (buf);
- /* number of rules *//* FIXME: Need to support rules */
- flag16 = 0x0000;
+ /* number of rules */
+ flag16 = rules;
ba = g_byte_array_append (ba, (const guint8 *)&flag16, sizeof (guint16));
/* wFlags: we know only keyname based names */
@@ -421,7 +626,8 @@ e_mapi_cal_util_mapi_tz_to_bin (const gc
flag8 = TZ_BIN_VERSION_MAJOR;
ba = g_byte_array_prepend (ba, (const guint8 *)&flag8, sizeof (guint8));
- /* Rules may now be appended here */
+ /* Rules */
+ add_timezone_rules (ba, is_recur, vtimezone, zone);
bin->cb = ba->len;
bin->lpb = talloc_memdup (mem_ctx, ba->data, ba->len);
diff -up evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-tz-utils.h.show-events-owa evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-tz-utils.h
--- evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-tz-utils.h.show-events-owa 2012-03-26 10:17:12.000000000 +0200
+++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-tz-utils.h 2013-10-17 12:30:05.858075342 +0200
@@ -39,7 +39,8 @@ void e_mapi_cal_tz_util_destroy (void)
void e_mapi_cal_tz_util_dump (void);
void e_mapi_cal_util_mapi_tz_to_bin (const gchar *mapi_tzid,
struct SBinary_short *bin,
- TALLOC_CTX *mem_ctx);
+ TALLOC_CTX *mem_ctx,
+ gboolean is_recur);
int e_mapi_cal_util_mapi_tz_pidlidtimezone (icaltimezone *ictz);
gchar * e_mapi_cal_util_bin_to_mapi_tz (const guint8 *lpb, guint32 cb);
diff -up evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-utils.c.show-events-owa evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-utils.c
--- evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-utils.c.show-events-owa 2013-01-15 14:03:36.000000000 +0100
+++ evolution-mapi-3.8.5/src/libexchangemapi/e-mapi-cal-utils.c 2013-10-17 12:30:05.859075342 +0200
@@ -1859,8 +1859,15 @@ e_mapi_cal_utils_comp_to_object (EMapiCo
/* Start TZ */
mapi_tzid = e_mapi_cal_tz_util_get_mapi_equivalent ((dtstart_tz_location && *dtstart_tz_location) ? dtstart_tz_location : "UTC");
if (mapi_tzid && *mapi_tzid) {
- e_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &start_tz, object);
+ e_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &start_tz, object, FALSE);
set_value (PidLidAppointmentTimeZoneDefinitionStartDisplay, &start_tz);
+
+ if (e_cal_component_has_recurrences (comp)) {
+ struct SBinary_short recur_tz;
+
+ e_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &recur_tz, object, TRUE);
+ set_value (PidLidAppointmentTimeZoneDefinitionRecur, &recur_tz);
+ }
}
set_value (PidLidTimeZoneDescription, mapi_tzid ? mapi_tzid : "");
@@ -1873,7 +1880,7 @@ e_mapi_cal_utils_comp_to_object (EMapiCo
/* End TZ */
mapi_tzid = e_mapi_cal_tz_util_get_mapi_equivalent ((dtend_tz_location && *dtend_tz_location) ? dtend_tz_location : "UTC");
if (mapi_tzid && *mapi_tzid) {
- e_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &end_tz, object);
+ e_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &end_tz, object, FALSE);
set_value (PidLidAppointmentTimeZoneDefinitionEndDisplay, &end_tz);
}